<< All versions
Skill v1.0.2
currentAutomated scan100/100thedivergentai/gd-agentic-skills/godot-2d-physics
+5 new, ~26 modified
──Details
PublishedAugust 19, 2026 at 04:41 AM
Content Hashsha256:b7e2b64678ea9a0b...
Git SHA90634dfedc1b
Bump Typepatch
──Files
Files (1 file, 15.7 KB)
SKILL.md15.7 KBactive
SKILL.md · 152 lines · 15.7 KB
version: "1.0.2" name: godot-2d-physics description: "Expert patterns for Godot 2D physics including collision layers/masks, Area2D triggers, raycasting, and PhysicsDirectSpaceState2D queries. Use when implementing collision detection, trigger zones, line-of-sight systems, or manual physics queries. Trigger keywords: CollisionShape2D, CollisionPolygon2D, collision_layer, collision_mask, set_collision_layer_value, set_collision_mask_value, Area2D, body_entered, body_exited, RayCast2D, force_raycast_update, PhysicsPointQueryParameters2D, PhysicsShapeQueryParameters2D, direct_space_state, move_and_collide, move_and_slide."
2D Physics
Expert guidance for collision detection, triggers, and raycasting in Godot 2D.
NEVER Do
- NEVER scale `CollisionShape2D` nodes — Use the shape handles in the editor, NOT the Node2D scale property. Scaling causes unpredictable physics behavior and incorrect collision normals [12].
- NEVER confuse `collision_layer` with `collision_mask` — Layer = "What AM I?", Mask = "What do I DETECT?". Setting both to the same value is usually wrong [13].
- NEVER multiply velocity by delta when using `move_and_slide()` —
move_and_slide()automatically includes timestep. Only multiply gravity/acceleration by delta [14]. - NEVER forget `force_raycast_update()` for manual mid-frame raycasts — Raycasts update once per physics frame. If you change target_position, you MUST force an update [15].
- NEVER use `get_overlapping_bodies()` every frame — It is expensive. Cache results with
body_entered/body_exitedsignals instead [16]. - NEVER modify `RigidBody2D` state directly in `_process` — Use
_integrate_forces()for safe, synchronized access toPhysicsDirectBodyState2D[17, 411]. - NEVER move `PhysicsBody2D` nodes in `_process()` — Use
_physics_process(). Moving bodies outside the physics step causes stutter and unreliable collision detection. - NEVER use `RigidBody2D` for 1000+ simple entities — Use
PhysicsServer2Dto bypass node overhead for massive performance gains (Swarms/Bullets) [18, 397]. - NEVER use `Area2D` for high-frequency blocking (Bullets) — Area signals can be delayed. Use
move_and_collide()orShapeCast2Dfor frame-perfect results [19]. - NEVER ignore 'Physics Jitter' on high-refresh monitors — Enable Physics Interpolation to prevent micro-stutter in motion [21, 400].
- NEVER scale collision shapes directly at runtime — It causes major instability. Resize the shape resource (size/radius) instead.
- NEVER use `set_deferred` for immediate physics transform logic — It happens at the end of the frame. Use
force_raycast_update()orPhysicsServer2Dinstead. - NEVER leave Continuous CD (CCD) enabled for slow objects — It adds significant CPU overhead. Reserve it for high-speed projectiles to prevent tunneling.
- NEVER use a single collision layer for all tiles/entities — Separate layers (Ground, Walls, Enemies) to allow selective filtering via masks.
- NEVER forget to free `PhysicsServer2D` RIDs manually — They are not garbage collected and will leak memory permanently.
Available Scripts
MANDATORY: Read the script matching your workflow branch before coding. Query/Area cookbook samples live in scripts — not in this body.
Workflow router (MANDATORY / Do NOT Load)
| Branch | Load | Do NOT Load | |
|---|---|---|---|
| Layer/mask matrix setup | collision_bitmask_helper.gd or collision_setup.gd; matrix policy → collision_layer_matrix_manager.gd | Swarm / CCD scripts | |
| LOS / vision cones | raycast_vision_stack.gd (+ physics_direct_query.gd for nodeless rays) | shapecast_aoe*.gd, physics_server_swarm.gd | |
| AOE / melee volume | Prefer shapecast_aoe.gd (faction mask); ground/volume sensing → shapecast_aoe_detection.gd | Area2D spam + lava DoT tutorials; do not load both shapecast scripts for the same feature | |
| Hitscan / point pick / one-shot shape | physics_queries.gd (canonical). Specialists: physics_direct_space_query.gd (LOS bool), raycast_hit_prediction.gd | Re-load all three query helpers at once | |
| Bullet hell / 1000+ bodies | MANDATORY physics_server_swarm.gd (+ physics_server_direct_body.gd for RID shapes) | Per-bullet Area2D / RigidBody2D nodes | |
| High-speed tunneling | continuous_collision_detection.gd + substepping_logic.gd | CCD on slow props | |
| RigidBody safe mutate | safe_rigidbody_state.gd (_integrate_forces) | Direct transform writes in _process | |
| Custom CharacterBody forces | custom_physics_2d.gd | custom_physics.gd (that file is RigidBody _integrate_forces) | |
| Gravity zones | custom_gravity_area.gd (Area override) or custom_gravity_override.gd (character weight/zones) | Both unless you need Area + character paths | |
| Overlap signal spam | collision_debouncer.gd | Polling get_overlapping_bodies every frame | |
| Compound multi-shape RID | compound_body_sync.gd | Multiple nodes for one logical body | |
| Debug contact normals | collision_visual_debugger.gd | Visible collision menu insufficient | |
| High-refresh jitter | Prefer jitter_interpolation_fix.gd | physics_interpolation_smoothing.gd (legacy/manual; only if built-in interpolation is unavailable) | |
| Precision bounce / slide | move_and_collide_precision.gd | — | |
| Batch static movers | performance_batch_mover.gd | — | |
| Query result cache | physics_query_cache.gd | Duplicate space queries same frame |
Canonical vs overlap (dedupe guide)
- ShapeCast AOE: load
shapecast_aoe.gdfor combat AOE;shapecast_aoe_detection.gdonly for grounded/volume checks — never both for one feature. - Space queries: start with
physics_queries.gd; addphysics_direct_query.gd/physics_direct_space_query.gdonly if that specialist matches. - Custom physics: CharacterBody →
custom_physics_2d.gd; RigidBody integrate →custom_physics.gd. - Interpolation:
jitter_interpolation_fix.gdwins overphysics_interpolation_smoothing.gd.
Script index
- collision_setup.gd / collision_bitmask_helper.gd / collision_layer_matrix_manager.gd
- physics_queries.gd / physics_direct_query.gd / physics_direct_space_query.gd / physics_query_cache.gd
- raycast_vision_stack.gd / raycast_hit_prediction.gd
- shapecast_aoe.gd / shapecast_aoe_detection.gd
- physics_server_swarm.gd / physics_server_direct_body.gd
- continuous_collision_detection.gd / substepping_logic.gd
- safe_rigidbody_state.gd / custom_physics.gd / custom_physics_2d.gd
- custom_gravity_area.gd / custom_gravity_override.gd
- collision_debouncer.gd / jitter_interpolation_fix.gd
- compound_body_sync.gd / collision_visual_debugger.gd
- move_and_collide_precision.gd / performance_batch_mover.gd
- physics_interpolation_smoothing.gd — legacy; prefer jitter fix script
Decision Tree: Collision Detection Methods
| Use Case | Method | Why / script | |
|---|---|---|---|
| Continuous trigger zone | Area2D + signals | Memory of occupants; debounce with collision_debouncer.gd | |
| One-time pickup | Area2D + queue_free on enter | Simple cleanup | |
| Line-of-sight | RayCast2D / direct ray | raycast_vision_stack.gd or physics_direct_query.gd | |
| Click-to-select | PhysicsPointQueryParameters2D | physics_queries.gd | |
| AOE spell / melee volume | ShapeCast2D / shape query | shapecast_aoe.gd (not Area signal lag) | |
| Instant-hit weapon | PhysicsRayQueryParameters2D | physics_queries.gd / raycast_hit_prediction.gd | |
| Platformer ground / ledge | Ray or ShapeCast down | CharacterBody skill + shapecast_aoe_detection.gd | |
| 1000+ projectiles | PhysicsServer2D RIDs | MANDATORY physics_server_swarm.gd |
Mental model (keep short)
- Layer = who I am; Mask = who I detect. Bitmask cookbook → collision-layers-masks.md.
- Area2D with multiple shapes fires
body_enteredonce per shape — dedupe with a Set/dict or collision_debouncer.gd. - Mid-frame ray/shape changes require
force_raycast_update()/force_shapecast_update(). _readyphysics queries are false until after a physics frame (await get_tree().physics_frame).CharacterBody2Dships withcollision_layer = 0— Areas won't see it until you set a layer.- Free PhysicsServer RIDs yourself — they are not GC'd.
Deep recipes (on demand)
| Topic | Reference / script | |
|---|---|---|
| Layer/mask patterns | collision-layers-masks.md | |
| Area2D, raycast, shape queries | area2d-and-queries.md | |
| Compound RID bodies | compound_body_sync.gd | |
| Contact normal debug draw | collision_visual_debugger.gd |
Reference
Progressive disclosure: open Official Documentation links only when researching a specific API;load Related Skills when routing work to a peer domain — do not preload the whole lattice.
Official Documentation
- Physics introduction — Collision layers vs masks, body types, and the mental model every 2D setup depends on.
- Collision shapes (2D) — Correct shape sizing and why scaling
CollisionShape2Dnodes breaks normals and contacts. - Using CharacterBody2D —
move_and_slide/move_and_collide, floor detection, and kinematic movement contracts. - Using Area2D — Trigger monitoring, overlap signals, and space/gravity overrides for zones.
- Ray-casting —
RayCast2DvsPhysicsDirectSpaceState2Drays, exclusions, and mid-frameforce_raycast_update. - RigidBody — Safe rigid-body control via
_integrate_forces/PhysicsDirectBodyState2Dinstead of fighting the solver in_process. - Troubleshooting physics issues — Tunneling, jitter, one-way platforms, and common layer/mask misconfigurations.
- Physics interpolation introduction — Why fixed physics ticks stutter on high-refresh displays and when interpolation fixes it.
- PhysicsServer2D — RID-based body/shape APIs for swarm-scale 2D physics without SceneTree overhead.
- PhysicsDirectSpaceState2D — Point, ray, and shape queries for LOS, AOE, and click-picking without permanent query nodes.
- ShapeCast2D — Volume casts for frame-perfect melee/AOE detection when
Area2Dsignal lag is unacceptable.
Related Skills
Prerequisites
- godot-project-foundations — Project Settings layer names, physics ticks, and default gravity must be set before layer/mask matrices stay sane.
- godot-gdscript-mastery — Bitmask enums, typed dictionaries for overlap sets, and
_physics_processdiscipline underpin every pattern here. - godot-signal-architecture —
body_entered/body_exitedwiring and debounce patterns need clean signal ownership to avoid spam.
Complements
- godot-characterbody-2d — Coyote time, jump buffers, and one-way platforms sit on top of the collision contracts this skill defines.
- godot-raycasting-queries — Deeper query parameter recipes (exclusions, masks, shape casts) when vision/hitscan systems grow beyond basics.
- godot-tilemap-mastery — Tile physics layers and one-way tile collisions must match the same layer matrix used by bodies and areas.
- godot-input-handling — Physics-step input sampling and vsync/latency choices couple tightly with
move_and_slidefeel. - godot-physics-3d — Parallel 3D body/query concepts when porting or sharing layer policy across dimensions.
- godot-performance-optimization — Profiling and batching guidance when
PhysicsServer2Dswarms or query caches become bottlenecks. - godot-debugging-profiling — Visible collision shapes, contact normals, and frame-time traps when diagnosing jitter or missed hits.
Downstream / consumers
- godot-combat-system — Hitboxes/hurtboxes are
Area2D+ layer/mask products; damage timing inherits overlap and CCD choices. - godot-genre-platformer — Platformer feel (floors, ledges, one-ways) consumes CharacterBody2D + collision setup from this domain.
- godot-navigation-pathfinding — Agents still need physics layers for blockers and LOS; keep nav meshes and collision worlds consistent.
- godot-monte-carlo-balancer — Jump windows, projectile speed/CCD, gravity, and hitbox size directly change win-rate and difficulty curves; simulate those physics knobs instead of guessing.
Master
- godot-master — Library router and mirrored entry point for discovering 2D physics alongside sibling domains.