godot-characterbody-2d
Installation
SKILL.md
CharacterBody2D Implementation
Expert guidance for player-controlled 2D movement using Godot's physics system.
NEVER Do
- NEVER use
RigidBody2Dfor standard player controllers — RigidBody is for physics-simulated objects. For responsive, feel-driven player movement, always useCharacterBody2D. - NEVER multiply
velocitybydeltabeforemove_and_slide()—move_and_slide()handles delta internally. Manual multiplication makes movement framerate-dependent [12]. - NEVER use
global_positionupdates for movement — Usevelocityandmove_and_slide(). Direct position updates bypass collision detection and floor snapping. - NEVER ignore the return value of
move_and_slide()— While optional, checkingis_on_floor()orget_last_motion()immediately after is critical for state logic. - NEVER rely on default
floor_snap_lengthfor fast stair-climbing — Default snapping is too small for high-velocity characters. Use custom raycast-based stair logic for smooth transitions. - NEVER apply gravity while
is_on_floor()is true — Constant downward force on the floor can cause "micro-jitter" or prevent floor-snap from working correctly. Resetvelocity.yto 0 or a small constant. - NEVER use
Area2Dfor ground detection — Real collisions (rays/shapecasts) are more precise.is_on_floor()is highly optimized; only augment it if necessary. - NEVER forget Ceiling Bonk detection — If you don't reset
velocity.yto 0 whenis_on_ceiling(), the player will "float" against the ceiling until gravity pulls them down. - NEVER use high-precision physics for pixel art visuals — Keep physics math high-precision, but round your Sprite nodal positions in
_processto avoid visual sub-pixel jitter. - NEVER use
queue_free()on characters every frame — Use object pooling for bullets or enemies to avoid SceneTree performance spikes.