godot-2d-physics

$npx mdskill add thedivergentai/GD-Agentic-Skills/godot-2d-physics

Implement collision detection, triggers, and raycasting in Godot 2D.

  • Set up collision layers and masks for proper interaction filtering.
  • Uses Area2D, RayCast2D, and PhysicsDirectSpaceState2D for queries.
  • Recommends based on collision layer/mask configuration and trigger events.
  • Provides code patterns for move_and_slide, body_entered, and manual raycasts.

SKILL.md

.github/skills/godot-2d-physicsView on GitHub ↗
---
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_exited` signals instead [16].
- **NEVER modify `RigidBody2D` state directly in `_process`** — Use `_integrate_forces()` for safe, synchronized access to `PhysicsDirectBodyState2D` [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 `PhysicsServer2D` to 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()` or `ShapeCast2D` for 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()` or `PhysicsServer2D` instead.
- **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.

---

## Godot 4.7: 2D Physics

- `body_set_shape_as_one_way_collision` adds **direction** parameter — set relative to shape orientation for one-way platforms.
- `CollisionShape2D` supports one-way collision **direction relative to the shape** (not just global up).

## 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.gd` for combat AOE; `shapecast_aoe_detection.gd` only for grounded/volume checks — never both for one feature.
- **Space queries**: start with `physics_queries.gd`; add `physics_direct_query.gd` / `physics_direct_space_query.gd` only if that specialist matches.
- **Custom physics**: CharacterBody → `custom_physics_2d.gd`; RigidBody integrate → `custom_physics.gd`.
- **Interpolation**: `jitter_interpolation_fix.gd` wins over `physics_interpolation_smoothing.gd`.

### Script index
- [collision_setup.gd](scripts/collision_setup.gd) / [collision_bitmask_helper.gd](scripts/collision_bitmask_helper.gd) / [collision_layer_matrix_manager.gd](scripts/collision_layer_matrix_manager.gd)
- [physics_queries.gd](scripts/physics_queries.gd) / [physics_direct_query.gd](scripts/physics_direct_query.gd) / [physics_direct_space_query.gd](scripts/physics_direct_space_query.gd) / [physics_query_cache.gd](scripts/physics_query_cache.gd)
- [raycast_vision_stack.gd](scripts/raycast_vision_stack.gd) / [raycast_hit_prediction.gd](scripts/raycast_hit_prediction.gd)
- [shapecast_aoe.gd](scripts/shapecast_aoe.gd) / [shapecast_aoe_detection.gd](scripts/shapecast_aoe_detection.gd)
- [physics_server_swarm.gd](scripts/physics_server_swarm.gd) / [physics_server_direct_body.gd](scripts/physics_server_direct_body.gd)
- [continuous_collision_detection.gd](scripts/continuous_collision_detection.gd) / [substepping_logic.gd](scripts/substepping_logic.gd)
- [safe_rigidbody_state.gd](scripts/safe_rigidbody_state.gd) / [custom_physics.gd](scripts/custom_physics.gd) / [custom_physics_2d.gd](scripts/custom_physics_2d.gd)
- [custom_gravity_area.gd](scripts/custom_gravity_area.gd) / [custom_gravity_override.gd](scripts/custom_gravity_override.gd)
- [collision_debouncer.gd](scripts/collision_debouncer.gd) / [jitter_interpolation_fix.gd](scripts/jitter_interpolation_fix.gd)
- [compound_body_sync.gd](scripts/compound_body_sync.gd) / [collision_visual_debugger.gd](scripts/collision_visual_debugger.gd)
- [move_and_collide_precision.gd](scripts/move_and_collide_precision.gd) / [performance_batch_mover.gd](scripts/performance_batch_mover.gd)
- [physics_interpolation_smoothing.gd](scripts/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](references/collision-layers-masks.md).
- **Area2D with multiple shapes** fires `body_entered` **once per shape** — dedupe with a Set/dict or [collision_debouncer.gd](scripts/collision_debouncer.gd).
- Mid-frame ray/shape changes require `force_raycast_update()` / `force_shapecast_update()`.
- `_ready` physics queries are false until after a physics frame (`await get_tree().physics_frame`).
- `CharacterBody2D` ships with `collision_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](references/collision-layers-masks.md) |
| Area2D, raycast, shape queries | [area2d-and-queries.md](references/area2d-and-queries.md) |
| Compound RID bodies | [compound_body_sync.gd](scripts/compound_body_sync.gd) |
| Contact normal debug draw | [collision_visual_debugger.gd](scripts/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](https://docs.godotengine.org/en/stable/tutorials/physics/physics_introduction.html) — Collision layers vs masks, body types, and the mental model every 2D setup depends on.
- [Collision shapes (2D)](https://docs.godotengine.org/en/stable/tutorials/physics/collision_shapes_2d.html) — Correct shape sizing and why scaling `CollisionShape2D` nodes breaks normals and contacts.
- [Using CharacterBody2D](https://docs.godotengine.org/en/stable/tutorials/physics/using_character_body_2d.html) — `move_and_slide` / `move_and_collide`, floor detection, and kinematic movement contracts.
- [Using Area2D](https://docs.godotengine.org/en/stable/tutorials/physics/using_area_2d.html) — Trigger monitoring, overlap signals, and space/gravity overrides for zones.
- [Ray-casting](https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html) — `RayCast2D` vs `PhysicsDirectSpaceState2D` rays, exclusions, and mid-frame `force_raycast_update`.
- [RigidBody](https://docs.godotengine.org/en/stable/tutorials/physics/rigid_body.html) — Safe rigid-body control via `_integrate_forces` / `PhysicsDirectBodyState2D` instead of fighting the solver in `_process`.
- [Troubleshooting physics issues](https://docs.godotengine.org/en/stable/tutorials/physics/troubleshooting_physics_issues.html) — Tunneling, jitter, one-way platforms, and common layer/mask misconfigurations.
- [Physics interpolation introduction](https://docs.godotengine.org/en/stable/tutorials/physics/interpolation/physics_interpolation_introduction.html) — Why fixed physics ticks stutter on high-refresh displays and when interpolation fixes it.
- [PhysicsServer2D](https://docs.godotengine.org/en/stable/classes/class_physicsserver2d.html) — RID-based body/shape APIs for swarm-scale 2D physics without SceneTree overhead.
- [PhysicsDirectSpaceState2D](https://docs.godotengine.org/en/stable/classes/class_physicsdirectspacestate2d.html) — Point, ray, and shape queries for LOS, AOE, and click-picking without permanent query nodes.
- [ShapeCast2D](https://docs.godotengine.org/en/stable/classes/class_shapecast2d.html) — Volume casts for frame-perfect melee/AOE detection when `Area2D` signal lag is unacceptable.

### Related Skills

#### Prerequisites
- [godot-project-foundations](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-project-foundations/SKILL.md) — Project Settings layer names, physics ticks, and default gravity must be set before layer/mask matrices stay sane.
- [godot-gdscript-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-gdscript-mastery/SKILL.md) — Bitmask enums, typed dictionaries for overlap sets, and `_physics_process` discipline underpin every pattern here.
- [godot-signal-architecture](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-signal-architecture/SKILL.md) — `body_entered` / `body_exited` wiring and debounce patterns need clean signal ownership to avoid spam.

#### Complements
- [godot-characterbody-2d](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-characterbody-2d/SKILL.md) — Coyote time, jump buffers, and one-way platforms sit on top of the collision contracts this skill defines.
- [godot-raycasting-queries](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-raycasting-queries/SKILL.md) — Deeper query parameter recipes (exclusions, masks, shape casts) when vision/hitscan systems grow beyond basics.
- [godot-tilemap-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-tilemap-mastery/SKILL.md) — Tile physics layers and one-way tile collisions must match the same layer matrix used by bodies and areas.
- [godot-input-handling](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-input-handling/SKILL.md) — Physics-step input sampling and vsync/latency choices couple tightly with `move_and_slide` feel.
- [godot-physics-3d](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-physics-3d/SKILL.md) — Parallel 3D body/query concepts when porting or sharing layer policy across dimensions.
- [godot-performance-optimization](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-performance-optimization/SKILL.md) — Profiling and batching guidance when `PhysicsServer2D` swarms or query caches become bottlenecks.
- [godot-debugging-profiling](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-debugging-profiling/SKILL.md) — Visible collision shapes, contact normals, and frame-time traps when diagnosing jitter or missed hits.

#### Downstream / consumers
- [godot-combat-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-combat-system/SKILL.md) — Hitboxes/hurtboxes are `Area2D` + layer/mask products; damage timing inherits overlap and CCD choices.
- [godot-genre-platformer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-platformer/SKILL.md) — Platformer feel (floors, ledges, one-ways) consumes CharacterBody2D + collision setup from this domain.
- [godot-navigation-pathfinding](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-navigation-pathfinding/SKILL.md) — Agents still need physics layers for blockers and LOS; keep nav meshes and collision worlds consistent.
- [godot-monte-carlo-balancer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-monte-carlo-balancer/SKILL.md) — 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](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — Library router and mirrored entry point for discovering 2D physics alongside sibling domains.

More from thedivergentai/GD-Agentic-Skills

SkillDescription
godot-2d-animationExpert patterns for 2D animation in Godot using AnimatedSprite2D and skeletal cutout rigs. Use when implementing sprite frame animations, procedural animation (squash/stretch), cutout bone hierarchies, or frame-perfect timing systems. Trigger keywords: AnimatedSprite2D, SpriteFrames, animation_finished, animation_looped, frame_changed, frame_progress, set_frame_and_progress, cutout animation, skeletal 2D, Bone2D, procedural animation, animation state machine, advance(0).
godot-3d-lightingExpert patterns for Godot 3D lighting including DirectionalLight3D shadow cascades, OmniLight3D attenuation, SpotLight3D projectors, VoxelGI vs SDFGI, and LightmapGI baking. Use when implementing realistic 3D lighting, shadow optimization, global illumination, or light probes. Trigger keywords: DirectionalLight3D, OmniLight3D, SpotLight3D, shadow_enabled, directional_shadow_mode, directional_shadow_split, omni_range, omni_attenuation, spot_range, spot_angle, VoxelGI, SDFGI, LightmapGI, ReflectionProbe, Environment, WorldEnvironment.
godot-3d-materialsExpert patterns for Godot 3D PBR materials using StandardMaterial3D including albedo, metallic/roughness workflows, normal maps, ORM texture packing, transparency modes, and shader conversion. Use when creating realistic 3D surfaces, PBR workflows, or material optimization. Trigger keywords: StandardMaterial3D, BaseMaterial3D, albedo_texture, metallic, metallic_texture, roughness, roughness_texture, normal_texture, normal_enabled, orm_texture, transparency, alpha_scissor, alpha_hash, cull_mode, ShaderMaterial, shader parameters.
godot-3d-world-buildingExpert patterns for 3D level design using GridMap with MeshLibrary, CSG constructive solid geometry, occlusion, and runtime GridMap builders. Use when building 3D levels, modular tilesets, or BSP-style geometry. For sky/fog/Environment recipes, route to godot-3d-lighting. Trigger keywords: GridMap, MeshLibrary, set_cell_item, get_cell_item, map_to_local, local_to_map, CSGCombiner3D, CSGBox3D, CSGSphere3D, CSGPolygon3D, OccluderInstance3D, bake CSG.
godot-ability-systemExpert patterns for RPG/action ability systems including cooldown strategies, combo systems, ability chaining, skill trees with prerequisites, upgrade paths, and resource management. Use when implementing unlockable abilities, character progression, or complex skill systems. Trigger keywords: PlayerAbility, AbilityManager, cooldown, SkillTree, SkillNode, prerequisites, can_use, execute, ComboSystem, ability_chain, global_cooldown, charge_system, upgrade_path.
godot-adapt-2d-to-3dExpert patterns for migrating 2D games to 3D including node type conversions, camera systems (third-person, first-person, orbit), physics layer migration, sprite-to-model art pipeline, and control scheme adaptations. Use when porting 2D projects to 3D or adding 3D elements. Trigger keywords: CharacterBody2D to CharacterBody3D, Area2D to Area3D, Camera2D to Camera3D, Vector2 to Vector3, collision_layer migration, sprite to MeshInstance3D, 2D to 3D conversion.
godot-adapt-3d-to-2dExpert patterns for simplifying 3D games to 2D including dimension reduction strategies, 2.5D fake-depth, isometric ports, camera flattening, physics conversion, 3D-to-sprite art pipeline, and control simplification. Use when porting 3D to 2D, building 2.5D / isometric / fake-depth gameplay, creating 2D versions for mobile, or prototyping. Trigger keywords: CharacterBody3D to CharacterBody2D, Camera3D to Camera2D, Vector3 to Vector2, flatten Z-axis, 2.5D, isometric, fake depth, Y-sort, simulated Z, orthogonal projection, 3D to sprite conversion, performance optimization.
godot-adapt-desktop-to-mobileExpert patterns for porting desktop games to mobile including touch control schemes (virtual joystick, gesture detection), UI scaling for small screens, performance optimization for mobile GPUs, battery life management, and platform-specific features. Use when creating mobile ports or cross-platform mobile builds. Trigger keywords: TouchScreenButton, virtual_joystick, gesture_detector, InputEventScreenTouch, InputEventScreenDrag, mobile_optimization, battery_saving, adaptive_performance, MOBILE_ENABLED.
godot-adapt-mobile-to-desktopExpert patterns for scaling mobile games to desktop including mouse/keyboard controls, increased resolution and graphical fidelity, expanded UI layouts, settings menus, window management, and platform-specific features. Use when creating desktop ports or cross-platform releases. Trigger keywords: mouse_controls, keyboard_shortcuts, resolution_scaling, graphics_settings, fullscreen_toggle, window_modes, Steam_integration, desktop_optimization.
godot-adapt-single-to-multiplayerExpert patterns for adding multiplayer to single-player games including client-server architecture, authoritative server design, MultiplayerSynchronizer, lag compensation (client prediction, server reconciliation), input buffering, and anti-cheat measures. Use when retrofitting multiplayer, porting to online play, or designing networked gameplay. Trigger keywords: MultiplayerPeer, ENetMultiplayerPeer, SceneMultiplayer, MultiplayerSynchronizer, rpc, rpc_id, multiplayer_authority, client_prediction, server_reconciliation, lag_compensation, rollback.