Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use when working with physics bodies, collision shapes, raycasting, areas, rigid bodies, ragdolls, soft bodies, Jolt physics, and physics interpolation in Godot 4.3+
.claude/skills/jame581-physics-system/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-16 | ✗→✓ | ▲ Improved | 108% | 0% |
| case-14 | ✗→✓ | ▲ Improved | 318% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 148% | 0% |
| case-05 | ✗→✓ | ▲ Improved | 134% | 0% |
| case-18 | ✗→✓ | ▲ Improved | 89% | 0% |
All examples target Godot 4.3+ with no deprecated APIs. GDScript is shown first, then C#.
> Related skills: player-controller for CharacterBody2D/3D movement patterns, component-system for hitbox/hurtbox composition, godot-optimization for physics performance tuning, camera-system for camera follow and interpolation, multiplayer-sync for networked physics, 2d-essentials for tile collision setup and 2D canvas layers.
Four collision-object types (the last three extend PhysicsBody2D/3D):
| Type | Moved by | Use for | |------|----------|---------| | Area2D/3D | Code | Overlap detection, gravity zones, audio zones | | StaticBody2D/3D | Not moved (or constant_linear_velocity) | Walls, floors, conveyor belts | | RigidBody2D/3D | Physics engine | Crates, projectiles, debris, ragdolls | | CharacterBody2D/3D | Code | Players, enemies, NPCs (see player-controller) |
Every collision object needs at least one CollisionShape2D/3D (or CollisionPolygon2D/3D) child. Jolt Physics is the default 3D engine since 4.4 (non-experimental from 4.6) — see Section 8. 2D always uses GodotPhysics.
> Critical rule: NEVER scale collision shapes or physics bodies via scale. Use the shape's own size parameters (radius, extents, height) — scaling breaks collision accuracy.
| Method | Effect | When to use | |---|---|---| | apply_force(force, position) | Continuous accel at point | Thrusters, wind, magnets | | apply_central_force(force) | Continuous accel at center | Gravity, constant push | | apply_impulse(impulse, position) | Instant velocity change at point | Bullet hit, explosion | | apply_central_impulse(impulse) | Instant velocity change at center | Jump, knockback | | apply_torque(torque) | Continuous angular accel | Steering, spinning | | apply_torque_impulse(impulse) | Instant angular velocity change | Impact spin |
> See references/rigidbody-recipes.md for a thrust-and-spin example (GDScript + C#) using apply_force + apply_central_impulse + apply_torque.
Use _integrate_forces(state) instead of _physics_process() to read/modify a RigidBody's transform, velocity, or angular velocity. Setting position or linear_velocity directly in _physics_process() fights the physics engine.
> Warning: _integrate_forces() is NOT called while the body is sleeping. Set can_sleep = false if you need continuous callbacks; otherwise let bodies sleep for performance.
> See references/rigidbody-recipes.md for the thrust + torque example using state.apply_force / state.apply_torque (GDScript + C#).
contact_monitor = true + max_contacts_reported > 0. Then body_entered/body_exited fire.PhysicsMaterial resource controls friction (0 ice → 1 rubber) and bounce (0 → 1).FREEZE_MODE_STATIC (acts like a StaticBody) or FREEZE_MODE_KINEMATIC (code-moved, pushes others).look_at() a RigidBody — use _integrate_forces and set state.angular_velocity from a cross-product steering term.> See references/rigidbody-recipes.md for full GDScript + C# recipes (contact handler with take_damage, PhysicsMaterial property table, freeze toggle, RigidBody3D homing-via-angular-velocity).
StaticBody is not moved by the physics engine but can push other bodies via constant_linear_velocity (e.g. conveyor belts). For platforms that move via code AND push CharacterBodies, use AnimatableBody2D/3D — a code-moved StaticBody won't push CharacterBodies reliably.
> See references/staticbody-recipes.md for the conveyor belt and moving-platform recipes (GDScript + C#, with Tween-driven AnimatableBody2D loop).
Areas detect overlaps and override physics properties within their bounds. They do NOT produce collision responses — bodies pass through them. Connect body_entered / body_exited for body overlaps; use area_entered / area_exited for Area-to-Area (hitbox vs hurtbox — see component-system). Areas can also override gravity (zero-G zones, point gravity / black holes), linear_damp / angular_damp (water, slow-mo), and redirect audio to a specific AudioBus. When multiple areas overlap, priority decides order; pick a space_override mode (COMBINE, REPLACE, COMBINE_REPLACE, REPLACE_COMBINE).
> See references/area-recipes.md for the GDScript + C# overlap-detection canonical example, the space-override mode reference table, and zero-G + point-gravity recipes.
> ⚠️ Changed in Godot 4.7: With Jolt Physics, Area3D now reports overlaps with SoftBody3D from its signals and methods. Configure collision layers/masks so any unwanted Area3D ↔ SoftBody3D interactions are ignored. See the 4.7 migration guide.
| Shape (2D / 3D) | Use case | |---|---| | Rectangle / Box | Crates, platforms, rooms | | Circle / Sphere | Balls, projectiles, simple characters, trigger zones | | Capsule (2D & 3D) | Characters — rounded, slides over edges | | Segment2D / — | Thin walls, laser beams | | SeparationRay2D / — | Character ground snapping | | WorldBoundary2D / — | Infinite floor/wall/ceiling | | — / Cylinder3D | Pillars, barrels (Jolt only — unstable on GodotPhysics) |
Prefer primitives for dynamic bodies. ConvexPolygonShape is fast but cannot express holes or inward curves; ConcavePolygonShape is accurate for level geometry but is StaticBody-only and the slowest. Never translate, rotate, or scale a CollisionShape node — an untransformed shape unlocks a broad-phase optimization. Godot 4.7+ adds one_way_collision_direction for sideways one-way platforms.
Convex/concave cost table, shape-generation menus, the full performance rules, and the 4.7+ one-way direction API (GDScript + C#): references/collision-shapes.md
Godot provides 32 physics layers per dimension (2D and 3D separately).
> Mental model: Layer = "I am", Mask = "I scan for". A collision happens when object A's mask includes object B's layer, OR vice versa.
Name layers in Project Settings → Layer Names → 2D Physics (or 3D Physics); set them in code with set_collision_layer_value(N, true) / set_collision_mask_value(N, true) (1-indexed).
> See references/collision-layers.md for layer naming conventions, bitmask shorthand, Inspector export flags, and the GDScript + C# examples.
Add a RayCast2D / RayCast3D as a child node — it casts every physics frame automatically. Read with is_colliding() and get_collider() / get_collision_point() / get_collision_normal().
> See references/raycasting-recipes.md for the GDScript + C# RayCast node example.
For on-demand queries, access the space state via get_world_2d().direct_space_state (or get_world_3d()) and call intersect_ray(query) with PhysicsRayQueryParameters2D/3D.create(from, to). Set query.exclude = [get_rid()] to skip self, query.collision_mask to filter layers. Only safe inside _physics_process() — the physics space is locked during rendering.
> See references/raycasting-recipes.md for the full GDScript + C# code-based raycast example with self-exclusion and mask filtering, plus the 3D mouse-picking recipe.
The intersect_ray result dictionary contains position, normal, collider, collider_id, rid, shape. PhysicsDirectSpaceState also supports intersect_point (overlapping shapes at a point), intersect_shape (area query), cast_motion (shape sweep), collide_shape (contact points), get_rest_info (resting collision info). For 3D mouse picking, Camera3D.project_ray_origin(screen_pos) + project_ray_normal(screen_pos) builds the ray.
> See references/raycasting-recipes.md for the full mouse-picking recipe (GDScript + C#).
Jolt is a built-in alternative physics engine, the default for new 3D projects since Godot 4.4. (Godot 4.6+) Jolt is no longer marked experimental and is the confirmed stable default for all new 3D projects.
Project Settings → Physics → 3D → Physics Engine → Jolt Physics → Save → Restart editor. (3D only; 2D always uses GodotPhysics.)
Wins: better stacking stability, reliable CylinderShape3D, better SoftBody3D, optional thread-safe mode, active-edge detection (fixes ghost collisions).
> See references/jolt-differences.md for the behavioral differences from GodotPhysics (stabilization, collision margins, single-body joints, face_index, unsupported joint properties).
> ⚠️ Changed in Godot 4.7: With Jolt Physics, WorldBoundaryShape3D.plane.d now follows the same sign convention as Godot Physics — the plane distance is interpreted with the opposite sign compared to Godot 4.6. Flip the sign yourself to keep the 4.6 behavior. See the 4.7 migration guide.
Smooths visual motion between physics ticks, eliminating "staircase" jitter when tick rate ≠ frame rate. Enable in Project Settings → Physics → Common → Physics Interpolation. Godot 4.5+ restructured the 3D interpolation pipeline (RenderingServer → SceneTree) for more accurate results in nested transforms — no API change, automatic improvement on upgrade.
_physics_process() — transforms set outside physics ticks cause jitterreset_physics_interpolation() after teleporting or initial placement to prevent "streaking"> See references/interpolation-tuning.md for the teleport-reset example (GDScript + C#), per-node physics_interpolation_mode control, and tick-rate guidance.
Cameras need special handling under physics interpolation. Make the camera independent (or top_level = true), update it in _process() (not _physics_process()), and read the target's smooth position with get_global_transform_interpolated().
> See references/interpolation-camera.md for the full smooth-follow Camera3D recipe (GDScript + C#).
Ragdolls replace animation with physics for procedural death, explosions, or limp characters. Generate via Skeleton3D → Skeleton menu → Create Physical Skeleton. Use ConeJoint for shoulders/hips/neck, HingeJoint for elbows/knees — PinJoint (default) tends to crumple. Drive via physical_bones_start_simulation(), blend with Influence.
> See references/ragdoll-recipes.md for setup, joint guidance, full GDScript + C# control, animation blending, and collision exceptions.
SoftBody3D simulates deformable objects (cloth, capes, jelly). Mesh subdivision drives the simulation; no CollisionShape child needed. Jolt Physics recommended. Set Simulation Precision ≥ 5 to prevent collapse. Pressure > 0.0 only on closed meshes.
Godot 4.5+ adds apply_central_impulse() / apply_central_force() for RigidBody3D-style force application — distributes across all simulation points.
> See references/softbody-recipes.md for the cloth/cape walk-through (PlaneMesh, BoneAttachment3D pinning, Parent Collision Ignore) and the 4.5+ force/impulse API with GDScript and C# (explosion knockback, continuous wind).
> ⚠️ Changed in Godot 4.7: With Jolt Physics, SoftBody3D mass no longer defaults to 0 (which auto-calculated 1 kg per point, giving a very high total mass) — it now defaults to 1 kg for the entire body, matching Godot Physics. linear_stiffness is also applied differently, so re-tweak linear_stiffness and damping_coefficient after upgrading. See the 4.7 migration guide.
Symptom → causes & fixes quick table covering tunneling, wobbly stacks, scaled shapes, tile collision bumps, unstable cylinders, the physics spiral of death, and float-precision issues far from origin.
> See references/troubleshooting.md for the full table.
scale on collision shapes or bodies — use shape size parameters directly_integrate_forces(), not _physics_process()contact_monitor = true + max_contacts_reported > 0AnimatableBody2D/3D (not manually moved StaticBody)PhysicsDirectSpaceState inside _physics_process() onlyreset_physics_interpolation() called after teleport / initial placement| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-16 | fail→pass | 14,169 | 7,062 | -50% | 1 | 1 | 0% | 2,455 | 5,115 | +108% | 0 | 0 | — |
case-17 | pass→pass | 12,795 | 8,830 | -31% | 1 | 1 | 0% | 2,078 | 5,367 | +158% | 0 | 0 | — |
case-14 | fail→pass | 6,850 | 2,959 | -57% | 1 | 1 | 0% | 1,022 | 4,272 | +318% | 0 | 0 | — |
case-01 | fail→pass | 13,078 | 9,879 | -24% | 1 | 1 | 0% | 2,245 | 5,565 | +148% | 0 | 0 | — |
case-02 | pass→pass | 12,517 | 11,184 | -11% | 1 | 1 | 0% | 2,250 | 5,802 | +158% | 0 | 0 | — |
case-03 | pass→pass | 11,769 | 8,389 | -29% | 1 | 1 | 0% | 1,866 | 5,237 | +181% | 0 | 0 | — |
case-04 | pass→pass | 8,734 | 5,042 | -42% | 1 | 1 | 0% | 1,464 | 4,779 | +226% | 0 | 0 | — |
case-15 | pass→pass | 6,524 | 3,294 | -50% | 1 | 1 | 0% | 1,041 | 4,385 | +321% | 0 | 0 | — |
case-05 | fail→pass | 13,083 | 9,164 | -30% | 1 | 1 | 0% | 2,311 | 5,416 | +134% | 0 | 0 | — |
case-06 | pass→pass | 10,704 | 10,188 | -5% | 1 | 1 | 0% | 1,856 | 5,719 | +208% | 0 | 0 | — |
case-07 | pass→pass | 7,912 | 5,866 | -26% | 1 | 1 | 0% | 1,369 | 4,957 | +262% | 0 | 0 | — |
case-08 | pass→pass | 14,642 | 8,168 | -44% | 1 | 1 | 0% | 2,329 | 5,224 | +124% | 0 | 0 | — |
case-09 | pass→pass | 10,676 | 8,362 | -22% | 1 | 1 | 0% | 1,675 | 5,252 | +214% | 0 | 0 | — |
case-10 | pass→pass | 11,841 | 9,414 | -20% | 1 | 1 | 0% | 1,773 | 5,355 | +202% | 0 | 0 | — |
case-11 | pass→pass | 10,246 | 7,249 | -29% | 1 | 1 | 0% | 1,730 | 5,158 | +198% | 0 | 0 | — |
case-12 | pass→pass | 9,566 | 7,228 | -24% | 1 | 1 | 0% | 1,680 | 5,169 | +208% | 0 | 0 | — |
case-13 | pass→pass | 9,473 | 8,462 | -11% | 1 | 1 | 0% | 1,640 | 5,332 | +225% | 0 | 0 | — |
case-18 | fail→pass | 16,622 | 6,805 | -59% | 1 | 1 | 0% | 2,731 | 5,153 | +89% | 0 | 0 | — |
case-19 | fail→pass | 13,732 | 5,770 | -58% | 1 | 1 | 0% | 2,017 | 4,821 | +139% | 0 | 0 | — |
case-20 | pass→pass | 13,891 | 17,025 | +23% | 1 | 1 | 0% | 2,579 | 7,075 | +174% | 0 | 0 | — |
case-21 | pass→pass | 17,350 | 19,502 | +12% | 1 | 1 | 0% | 3,107 | 7,596 | +144% | 0 | 0 | — |
case-22 | pass→pass | 15,914 | 12,180 | -23% | 1 | 1 | 0% | 2,622 | 6,027 | +130% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +27 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.