godot-physics
gamedev-skills/awesome-gamedev-agent-skills
Configure Godot 4.x physics bodies, collision layers/masks, overlap detection, and raycasts in 2D and 3D.
What is godot-physics?
Master Godot's physics system across 2D and 3D projects. Use this skill to choose the right body type (StaticBody, RigidBody, Area, CharacterBody), set up collision layers and masks, detect overlaps with Area signals, apply forces to rigid bodies, and cast rays for line-of-sight checks. Essential for any physics-based gameplay.
- Choose between StaticBody, RigidBody, CharacterBody, and Area body types for different collision behaviors
- Configure collision layers and masks so the correct objects interact with each other
- Detect overlaps and triggers using Area2D/Area3D signals (body_entered, area_entered)
- Apply forces and impulses to RigidBody objects for realistic physics-driven movement
- Cast rays using RayCast2D/3D nodes or direct space-state queries for ground checks and line-of-sight
- Handle Jolt Physics engine differences in 3D projects (Godot 4.6+)
How to install godot-physics
npx skills add https://github.com/gamedev-skills/awesome-gamedev-agent-skills --skill godot-physics- Godot 4.7 installed
- A .tscn scene with at least one physics body (RigidBody, StaticBody, Area, or CharacterBody)
- Basic understanding of Godot's node hierarchy and scripting
How to use godot-physics
- 1.Check which 3D physics engine your project uses (Project Settings > Physics > 3D > Physics Engine) if working in 3D
- 2.Choose the appropriate body type for your use case and add a CollisionShape child node
- 3.Set collision layers and masks either in the Inspector or via code using set_collision_layer_value() and set_collision_mask_value()
- 4.For triggers and overlaps, connect to Area signals (body_entered, area_entered) in _ready()
- 5.For moving objects, apply forces/impulses with apply_central_force() or apply_central_impulse() instead of setting position directly
- 6.Add RayCast2D/3D nodes or use PhysicsRayQueryParameters to cast rays and detect what lies ahead
Use cases
- Setting up a damage zone (hurtbox) that triggers when the player enters an Area2D
- Applying knockback or explosion forces to a RigidBody3D when hit
- Checking if a character is grounded using a raycast before allowing a jump
- Configuring collision layers so enemies only collide with walls and the player, not each other
- Detecting when a projectile hits a target using Area overlap signals
- Game developers building physics-based gameplay in Godot 4.x
- Level designers setting up collision geometry and trigger zones
- Programmers implementing character controllers, projectiles, or physics interactions
- Anyone migrating 3D projects to Jolt Physics and needing to understand behavioral differences
godot-physics FAQ
Layers define what you are; masks define what you detect. A body is on its layers and scans for its masks. Two bodies interact only if one's layer is in the other's mask. This allows one-directional detection.
Check that monitoring is enabled on the Area, monitorable is true if you want others to detect it, and the collision layers/masks overlap between the Area and the body you're trying to detect.
Never set position directly on a RigidBody. Instead, use apply_central_impulse(), apply_central_force(), or set linear_velocity. If you must teleport, set position and zero velocities inside _integrate_forces().
Jolt (default in Godot 4.6+) has different joint behavior, doesn't report face_index in raycasts by default, and handles kinematic contacts differently. Check the Jolt Physics differences section for specifics.
Use a RayCast2D/3D pointing downward, or cast a ray via PhysicsRayQueryParameters with a downward direction and check if it hits a layer marked as ground.
Full instructions (SKILL.md)
Source of truth, from gamedev-skills/awesome-gamedev-agent-skills.
name: godot-physics description: > Use Godot 4.7 physics bodies and detection in 2D and 3D: RigidBody, StaticBody, Area, and CharacterBody; collision layers vs masks; contact/overlap signals; and raycasts (RayCast nodes and direct space-state queries). Use when configuring collision layers/masks, detecting overlaps with Area2D/Area3D, applying forces to a RigidBody, or casting rays in a Godot project (.tscn with physics bodies), including 3D projects running Jolt Physics, the default 3D engine for projects created in 4.6+.
Godot Physics (4.x, 2D + 3D)
Pick the right physics body, wire up collision layers/masks, detect overlaps, and cast
rays. Concepts apply to both 2D and 3D (swap the 2D/3D suffix). Targets
Godot 4.7. In 3D, projects created with Godot 4.6 or later run Jolt Physics by
default; older projects keep GodotPhysics3D unless someone switched them. 2D always
uses Godot's own 2D engine.
When to use
- Use when choosing between body types, setting collision layers/masks so the right
things collide, detecting overlaps (triggers, hurtboxes) with
Area, applying forces/impulses to aRigidBody, or casting rays for line-of-sight/ground checks.
When not to use: kinematic character controllers (move_and_slide) →
godot-2d-movement; tile collision setup → godot-tilemap; tuning the feel of physics
(timestep, mass, jitter) → physics-tuning.
Core workflow
- For 3D, check which engine runs before debugging behavior: Project Settings >
Physics > 3D > Physics Engine (
[physics]3d/physics_engine="Jolt Physics"inproject.godot). The API is the same, but joints, ray-cast face indices, kinematic contacts, and collision margins behave differently (see Pitfalls). - Choose the body type:
StaticBody— never moves (floors, walls). Collides, no simulation.RigidBody— fully simulated (gravity, forces, bouncing). Don't set itspositiondirectly; apply forces/impulses or setlinear_velocity.CharacterBody— script-driven kinematic (seegodot-2d-movement).Area— detects overlaps and can apply gravity/damping; no solid collision. Every body needs aCollisionShape(orCollisionPolygon) child.
- Configure layers and masks. A body is on its layers and scans for its masks. Two bodies interact only if one's layer is in the other's mask. Name layers in Project Settings > Layer Names for clarity.
- Detect overlaps with
Areasignals (body_entered,area_entered). - Drive RigidBodies with forces/impulses, or override
_integrate_forcesfor full control. - Cast rays with a
RayCast2D/3Dnode (polled each frame) or a one-shot space-state query from code.
Patterns
1. Collision layers vs masks (set from code)
# Player is on layer 1, scans layers 2 (walls) and 3 (enemies).
func _ready() -> void:
set_collision_layer_value(1, true) # I am on layer 1
set_collision_mask_value(2, true) # I collide with things on layer 2
set_collision_mask_value(3, true) # ...and layer 3
# Bit-field forms also exist: collision_layer = 1; collision_mask = 0b110
2. Area2D as a trigger / hurtbox
extends Area2D # e.g. a damage zone
func _ready() -> void:
body_entered.connect(_on_body_entered)
area_entered.connect(_on_area_entered)
func _on_body_entered(body: Node2D) -> void:
if body.has_method("take_damage"):
body.take_damage(10)
func _on_area_entered(area: Area2D) -> void:
print("Overlapped area: ", area.name)
3. Applying force and impulse to a RigidBody3D
extends RigidBody3D
func push(direction: Vector3) -> void:
apply_central_impulse(direction * 8.0) # instantaneous velocity change
func _physics_process(_delta: float) -> void:
apply_central_force(Vector3.FORWARD * 4.0) # continuous force (per tick)
# Never set `position` on a RigidBody to move it; use forces/impulses or
# set linear_velocity. Use freeze=true if you must hold it in place.
4. Raycast two ways
# A) RayCast2D node: enable it, then poll after physics has updated.
@onready var ray: RayCast2D = $RayCast2D # set target_position in the editor
func _physics_process(_delta: float) -> void:
if ray.is_colliding():
var hit := ray.get_collider()
var point := ray.get_collision_point()
# B) One-shot query from code (no node needed).
func ground_under(global_from: Vector2) -> Dictionary:
var space := get_world_2d().direct_space_state
var query := PhysicsRayQueryParameters2D.create(global_from, global_from + Vector2(0, 64))
query.collision_mask = 1 # only layer 1
return space.intersect_ray(query) # {} if nothing hit, else collider/position/normal
Pitfalls
- Layer vs mask confusion is the #1 bug. Layer = "what I am"; mask = "what I look for". For A to detect B, B's layer must be in A's mask. Detection can be one-directional.
- Moving a RigidBody by
positionfights the solver and causes tunneling/jitter. Use impulses/forces, setlinear_velocity, orfreezeit. To teleport, set position and zero the velocities inside_integrate_forces. Areadoesn't fire when neither monitoring nor monitorable is set, or layers/masks don't overlap.monitoringmust be on for the Area to detect;monitorablelets others detect it.- RayCast2D/3D read stale or no data if
enabledis false, or if you read it before physics updated — read in_physics_process, and callforce_raycast_update()after moving it within the same tick. - Forgetting a
CollisionShape(or leaving it empty) means the body never collides. - Fast objects tunnel through thin walls; enable continuous CD on the RigidBody
(
continuous_cd) or use a raycast-based check. intersect_rayexcludes its own body? Passquery.exclude = [self.get_rid()](anArray[RID], not an array of nodes) to skip self-hits.
Jolt Physics (3D) differences
face_indexis always-1inintersect_ray()/RayCast3Dresults under Jolt. Turn on Project Settings > Physics > Jolt Physics 3D > Queries > Enable Ray Cast Face Index if you need it (it costs roughly 25% more memory forConcavePolygonShape3D).- A joint with only one body gets inverted limits after switching engines. Jolt treats
the lone body as
node_bwithnode_aas the world; GodotPhysics3D always treats it asnode_a. Assign the body to the slot Jolt expects, or use Physics > Jolt Physics 3D > Joints > World Node for compatibility with an older project. - Joint soft-limit properties do nothing under Jolt (e.g.
bias/softness/relaxationon Pin, Hinge and ConeTwist joints; limit softness/restitution/damping on Slider and Generic6DOF joints). Godot warns when they are set to non-default values. - A frozen kinematic
RigidBody3Dreports no contacts with static or kinematic bodies, even withmax_contacts_reported > 0. Enable Physics > Jolt Physics 3D > Simulation > Generate All Kinematic Contacts if gameplay depends on those contacts. - Shape
marginshrinks the shape instead of padding it under Jolt, so sizes stay true but shape queries can return odd normals on small shapes; the effective margin comes from Physics > Jolt Physics 3D > Collisions > Collision Margin Fraction. Area3Dnow firesbody_enteredforSoftBody3Dunder Jolt (GodotPhysics3D never did). Filter soft bodies out with layers/masks if the old behavior is expected.
References
- For
_integrate_forces, joints, one-way collision,PhysicsServerdirect access, shape queries (intersect_shape), and 3Dmove_and_collide, readreferences/bodies-and-queries.md. - Jolt specifics: Godot docs "Using Jolt Physics"
(
https://docs.godotengine.org/en/stable/tutorials/physics/using_jolt_physics.html).
Related skills
godot-2d-movement— kinematicCharacterBody2Dcontrollers.godot-tilemap— tile collision shapes and their layers.physics-tuning— engine-agnostic feel: timestep, mass, drag, CCD.godot-3d-essentials— 3D scene setup these bodies live in.
Related skills
More from gamedev-skills/awesome-gamedev-agent-skills and the wider catalog.

godot-resources
Design data-driven Godot 4.7 games with custom Resource classes and .tres/.res files.

godot-shaders
Write Godot 4.7 shaders (2D canvas_item and 3D spatial) with uniforms, TIME animation, and screen-reading.

godot-signals-groups
Decouple Godot 4.x gameplay with signals and node groups instead of hard-coded references.

godot-tilemap
Build and edit tile-based 2D levels in Godot 4.7 with TileMapLayer, collision, terrains, and runtime cell manipulation.

godot-ui-control
Build responsive Godot 4.7 UIs with Control nodes, Containers, Themes, and keyboard/gamepad focus.

input-systems
Design game input as named actions with rebinding, multi-device support, deadzones, and feel features like buffering and coyote time.