godot-2d
Installation
SKILL.md
Godot 2D (developer and artist)
Version 0.1 (2026-10-02). Target: Godot 4.7.2 standard build, macOS, run headless or in small windows through the godot-expert toolkit.
Expert level in 2D means feel and pixels are measured, not eyeballed: a jump has a height in tiles and a coyote window in ticks, a camera has a lag in pixels, a pixel-art screen has an integer factor and a fringe count. The agent builds tiles, controllers and cameras in code, proves them with deterministic physics runs and frame read-backs, and only then calls them done.
REQUIRED BACKGROUND: godot-expert (channels, review loop, toolkit gd_env, gd_run, gd_review, 4.x traps).
Stance (the expert delta)
- Feel is numbers you can test. Solve gravity and take-off speed from jump height and time to apex, and make the height a multiple of the tile size (The Shaggy Dev, Bsy8pknHc0M [00:04:13]). Godot then loses about v·dt/2 of it: 53.5 px for a 56 px design at 60 ticks, measured. The kit adds g·dt/2 and lands 56.25 px [added].
- Forgive in time and space. Coyote time, jump buffer, corner correction and a jump cut are each a few lines (The Shaggy Dev). Count windows in whole ticks: float timers gave 5 coyote moves for 0.1 s instead of 6 [added, measured].
- Top-down:
move_toward, not length arithmetic. Additive acceleration needslimit_length; subtracting decel from the length goes negative and vibrates (55 sign flips in 60 ticks, measured). Steering never arrives without a minimum step (BT Plays Games, m71-kZgYXlw [00:07:30], [00:14:08]). - A camera is designed, not parented. Lookahead, ignore jumps and re-baseline on landing, damping, shake with an off switch (Mark Brown, GMTK). Damping lags by speed/damping and eats lookahead: 32 px of lookahead gave a 16 px lead at 120 px/s, so state both numbers. Zoom with
Camera2D.zoom(2 zooms in), never by resizing the viewport (DevWorm, RlSpjIb7TLo [00:08:14]). - Jitter is a tick-rate problem. At 144 Hz with 60 physics ticks, physics interpolation gave the ideal 0.289 px RMS for every camera setup. Without it the background stepped 0, 1, 2 px, and Idle camera smoothing made the player wobble 3 px.
Camera2D.process_callbackdefaults to Idle: with interpolation off, setCAMERA2D_PROCESS_PHYSICSyourself (Chris' Tutorials, 43c-Sm5GMbc [00:28:37]); with it on, Godot forces Physics. - Pixel-perfect is a stretch decision.
viewport+ integer locks everything to art pixels, lights included. 640x360 (the docs' base) and 320x180 both integer-scale to 720p, 1080p, 1440p and 4K with no bars, measured; pick by native art size. Ship Exclusive Fullscreen (window mode 4): a 1 px strip drops 640x360 on 4K from 6x to 5x, measured (docs, Multiple resolutions).canvas_itemsgives smooth rotation and sub-pixel motion (Heartbeast prefers it). For locked art with a gliding camera, render a SubViewport at base + 2 px and shift the upscaled image by the remainder (Barry's Dev Hell). - Tiles are data you can audit. One TileMapLayer per layer, an external TileSet, terrain mode matched to the tile count, and peering bits checked cell by cell. Paint the land, never the water side (DevWorm, ZutpG0_CYrQ [00:32:47]); in the GUI, paint bits outer ring first, then the centre cross (bluuDevGames, CLcFC6ku240 [00:12:28]). Pick a dual grid (16 tiles, display layer offset half a tile) when every corner must round the same (jess::codes, jEWFSv3ivTg [00:02:26]). Then look at a sampler capture, because index checks pass on wrong art [added].
- Generated art is checked before import. Find the pixel scale and grid phase, snap if off-grid, register every clip on its feet line, and check the key-colour fringe under linear filtering [added, with scenario-sprite-pipeline].
- Physics layers are named and single. One collision layer per object, many masks; name layers by what the checker needs ("bombable"), in
layer_names/2d_physics/layer_N(Bogner, HFBNd4Z4vXM [00:10:58] to [00:14:17]). A new body starts on layer 1 and mask 1: adding a layer without clearing 1 gives 2 bits, measured.