Available Scripts
MANDATORY for common paths — read before implementing (do not improvise query APIs from memory):
- direct_space_state_raycast.gd — high-frequency
intersect_ray without RayCast nodes.
- query_exclusion_optimization.gd — RID exclude lists so casters never self-hit.
- shapecast_ground_detection.gd — footing / volume casts when thin rays tunnel or miss.
Do NOT Load every script below for one task. Open only the row that matches the decision table.
direct_space_state_raycast.gd
Expert usage of PhysicsDirectSpaceState2D/3D for bypassing node-based overhead in high-frequency queries.
shapecast_ground_detection.gd
Reliable ground/footing detection using volume-based ShapeCast instead of thin rays.
multiple_hit_piercing_ray.gd
Implementing piercing projectiles that detect and return multiple hits in a single line.
field_of_view_scanner.gd
AI sensor logic using a fan of raycasts to detect targets within a FOV cone.
raycast_reflection_logic.gd
Calculating bounces for lasers or bullets using collision normal reflection.
point_in_shape_query.gd
Checking for overlapping physics bodies at a single point (Explosion epicenters).
rest_info_3d_stuck_fix.gd
Using get_rest_info to detect stuck objects and resolve overlaps immediately.
mouse_pick_3d_query.gd
Converting 2D screen coordinates to 3D world rays for point-and-click interaction.
water_buoyancy_surface_calc.gd
Finding water surface height for buoyancy systems using high-to-low raycasting.
query_exclusion_optimization.gd
Optimizing performance by excluding specific RIDs (Resource IDs) from intersection checks.
NEVER Do in Physics Queries
- NEVER access
direct_space_state outside of _physics_process() — The physics space can be locked or running on a separate thread; querying it in _process() is unsafe [1, 2].
- NEVER use ShapeCast when a thin RayCast is sufficient — Volume queries are significantly more expensive. Default to rays unless you need volumetric detection [3, 4].
- NEVER assume results return
CollisionObject nodes — CSG shapes, GridMap, and TileMapLayer return themselves, not a generic physics body [5, 6].
- NEVER assume
RayCast nodes update instantly — They update once per physics frame. If you move a node and query it immediately, you MUST call force_raycast_update() [3, 9].
- NEVER use complex visual meshes for physics queries — GPU-only data requires expensive thread locking to parse. Use simplified primitive collision shapes [10, 11].
- NEVER iterate results to find the first valid hit — Use
collision_mask and collision_layer to filter queries at the server level for maximum performance.
- NEVER forget to exclude the caster — A ray starting from the center of a character will hit the character itself. Use
query.exclude = [self.get_rid()] [20].
- NEVER use rays for small, fast detection areas — Rays can "tunnel" through thin walls if the frame rate drops. Use
cast_motion or high-frequency stepping for bullets.
- NEVER query 1000+ rays individually in GDScript — Batch your queries or use the
PhysicsServer directly in C++ if you reach extreme query counts.
- NEVER ignore the
result.rid — RIDs are the fastest way to identify and exclude objects in subsequent queries, bypassing node-path lookups [20].
Query-Type Decision Table
Pick the cheapest API that answers the question. Always pair rays/shapes with RID exclude + masks (query_exclusion_optimization.gd).
| Need |
Prefer |
Cost |
When |
Script |
| Persistent sensor in the scene (ledge, aim assist debug) |
RayCast2D/RayCast3D node |
Low–med |
Few casts; OK waiting one physics frame (or force_raycast_update()) |
Scene node + NEVER rules |
| Hitscan / LOS / one-shot mid-frame ray |
PhysicsDirectSpaceState*.intersect_ray |
Low |
High frequency, no permanent node |
MANDATORY direct_space_state_raycast.gd |
| Footing, thick walls, melee volume |
ShapeCast* / intersect_shape |
Med–high |
Thin ray tunnels or misses volume |
MANDATORY shapecast_ground_detection.gd |
| Explosion / occupancy at a point |
intersect_point |
Low–med |
Epicenter overlap list |
point_in_shape_query.gd |
| Stuck / penetration resolve |
get_rest_info |
Med |
Overlap recovery |
rest_info_3d_stuck_fix.gd |
| Pierce / multi-hit along a line |
Repeated intersect_ray + exclude RIDs |
Med |
Projectiles that keep going |
multiple_hit_piercing_ray.gd |
| Screen → world click |
Camera project + intersect_ray |
Low |
Picking |
mouse_pick_3d_query.gd |
3D Mouse Picking Example
func screen_point_to_ray():
var space_state = get_world_3d().direct_space_state
var mouse_pos = get_viewport().get_mouse_position()
var origin = project_ray_origin(mouse_pos)
var end = origin + project_ray_normal(mouse_pos) * 2000
var query = PhysicsRayQueryParameters3D.create(origin, end)
var result = space_state.intersect_ray(query)
if result:
return result.collider
return null
Expert WHY (query timing & LOS)
- Physics step only —
direct_space_state in _physics_process, not _process.
- Self-hit —
query.exclude = [get_rid()] on rays from character center.
- NavMesh LOS — physics ray ≠ carved nav hole;
path.size() == 2 on NavigationServer3D.map_get_path for strict mesh LOS (see deep dive).
- Surface types —
collider.get_meta(&"surface_type") beats class/group checks for decals/footsteps.
- Compute GPU rays — out of scope; not a drop-in for gameplay
intersect_ray.
Deep dive (load on demand)
NavMesh LOS validator, surface metadata, picking baseline, tunneling notes — references/query-elite-patterns.md.
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
- Ray-casting — Node
RayCast* vs PhysicsDirectSpaceState* queries, result dictionaries, and exclude to avoid self-hits.
- Physics introduction — Collision layers/masks that filter every ray, shape, and point query at the physics server.
- Collision shapes (3D) — Why queries need primitive/convex shapes instead of visual meshes for reliable, cheap intersections.
- PhysicsDirectSpaceState3D —
intersect_ray / intersect_shape / intersect_point / get_rest_info / cast_motion contracts for mid-frame space queries.
- PhysicsDirectSpaceState2D — 2D twin of direct space queries for LOS, hitscan, and point epicenters without permanent cast nodes.
- PhysicsRayQueryParameters3D — Mask, exclude RIDs,
hit_from_inside, and collide-with flags for reusable ray parameter objects.
- PhysicsShapeQueryParameters3D — Shape RID + transform setup for volume casts, rest info, and stuck-overlap resolution.
- PhysicsPointQueryParameters3D — Point-in-shape overlap lists for explosion epicenters and occupancy checks.
- RayCast3D — Scene-tree cast nodes, collision exceptions, and when
force_raycast_update() is required after moving.
- ShapeCast3D — Volume casts and
force_shapecast_update() for footing/melee detection that thin rays miss.
- Camera3D —
project_ray_origin / project_ray_normal for screen-to-world picking rays from the active camera.
- Mouse and input coordinates — Viewport mouse position vs canvas/world space before building a pick ray.
Related Skills
Prerequisites
- godot-project-foundations — Named physics layers and tick settings must exist before query masks and water/ground layer bits stay coherent.
- godot-gdscript-mastery — Typed query parameters, RID arrays, and
_physics_process-only space access are language-level contracts this skill depends on.
- godot-2d-physics — 2D body/area layer matrices and when to prefer
RayCast2D nodes vs direct space state for sensors.
Complements
- godot-physics-3d — 3D body types, CCD, and collision setup that determine what your rays and shape casts can actually hit.
- godot-characterbody-2d — Grounding, ledges, and coyote-time feel often consume ShapeCast/ray footing results from this domain.
- godot-input-handling — Physics-step click/aim sampling couples with mouse-pick rays and hitscan timing.
- godot-navigation-pathfinding — Physics LOS vs NavMesh path-straightness checks; keep obstacle carve and collision worlds consistent.
- godot-ai-navigation — FOV fans and vision sensors feed AI perception stacks that still need correct query masks/exclusions.
- godot-performance-optimization — Budgeting hundreds of rays, reusing query params, and knowing when node casts become SceneTree overhead.
- godot-debugging-profiling — Visualizing cast lines/shapes and diagnosing missed hits from mask, exclude, or update-timing mistakes.
Downstream / consumers
- godot-combat-system — Hitscan, piercing rays, and melee volumes resolve damage from query results produced here.
- godot-genre-shooter — Hitscan weapons, bullet pierce, and aim assist consume exclusion/mask recipes and multi-hit pierce loops.
- godot-monte-carlo-balancer — View distance, FOV ray counts, pierce max-hits, and query tick rate change fairness and difficulty; simulate those knobs instead of guessing.
Master
- godot-master — Library router and mirrored entry point for discovering raycasting/query patterns alongside sibling domains.
1---2name: godot-raycasting-queries3description: Expert blueprint for physics queries using RayCast, ShapeCast, and DirectSpaceState. Covers hit detection, volume overlap, mouse picking, and high-performance server-side intersection queries. Use when implementing projectiles, LOS, terrain grounding, or AI sensors. Keywords raycast, shapecast, direct_space_state, intersect_ray, intersect_shape, PhysicsRayQueryParameters, collision mask, mouse picking.4---5
6## Available Scripts
7
8> **MANDATORY** for common paths — read before implementing (do not improvise query APIs from memory):
9> - [direct_space_state_raycast.gd](scripts/direct_space_state_raycast.gd) — high-frequency `intersect_ray` without RayCast nodes.
10> - [query_exclusion_optimization.gd](scripts/query_exclusion_optimization.gd) — RID exclude lists so casters never self-hit.
11> - [shapecast_ground_detection.gd](scripts/shapecast_ground_detection.gd) — footing / volume casts when thin rays tunnel or miss.
12>
13> **Do NOT Load** every script below for one task. Open only the row that matches the decision table.
14
15### [direct_space_state_raycast.gd](scripts/direct_space_state_raycast.gd)
16Expert usage of `PhysicsDirectSpaceState2D/3D` for bypassing node-based overhead in high-frequency queries.
17
18### [shapecast_ground_detection.gd](scripts/shapecast_ground_detection.gd)
19Reliable ground/footing detection using volume-based `ShapeCast` instead of thin rays.
20
21### [multiple_hit_piercing_ray.gd](scripts/multiple_hit_piercing_ray.gd)
22Implementing piercing projectiles that detect and return multiple hits in a single line.
23
24### [field_of_view_scanner.gd](scripts/field_of_view_scanner.gd)
25AI sensor logic using a fan of raycasts to detect targets within a FOV cone.
26
27### [raycast_reflection_logic.gd](scripts/raycast_reflection_logic.gd)
28Calculating bounces for lasers or bullets using collision normal reflection.
29
30### [point_in_shape_query.gd](scripts/point_in_shape_query.gd)
31Checking for overlapping physics bodies at a single point (Explosion epicenters).
32
33### [rest_info_3d_stuck_fix.gd](scripts/rest_info_3d_stuck_fix.gd)
34Using `get_rest_info` to detect stuck objects and resolve overlaps immediately.
35
36### [mouse_pick_3d_query.gd](scripts/mouse_pick_3d_query.gd)
37Converting 2D screen coordinates to 3D world rays for point-and-click interaction.
38
39### [water_buoyancy_surface_calc.gd](scripts/water_buoyancy_surface_calc.gd)
40Finding water surface height for buoyancy systems using high-to-low raycasting.
41
42### [query_exclusion_optimization.gd](scripts/query_exclusion_optimization.gd)
43Optimizing performance by excluding specific RIDs (Resource IDs) from intersection checks.
44
45## NEVER Do in Physics Queries
46
47- **NEVER access `direct_space_state` outside of `_physics_process()`** — The physics space can be locked or running on a separate thread; querying it in `_process()` is unsafe [1, 2].
48- **NEVER use ShapeCast when a thin RayCast is sufficient** — Volume queries are significantly more expensive. Default to rays unless you need volumetric detection [3, 4].
49- **NEVER assume results return `CollisionObject` nodes** — CSG shapes, `GridMap`, and `TileMapLayer` return themselves, not a generic physics body [5, 6].
50- **NEVER assume `RayCast` nodes update instantly** — They update once per physics frame. If you move a node and query it immediately, you MUST call `force_raycast_update()` [3, 9].
51- **NEVER use complex visual meshes for physics queries** — GPU-only data requires expensive thread locking to parse. Use simplified primitive collision shapes [10, 11].
52- **NEVER iterate results to find the first valid hit** — Use `collision_mask` and `collision_layer` to filter queries at the server level for maximum performance.
53- **NEVER forget to exclude the caster** — A ray starting from the center of a character will hit the character itself. Use `query.exclude = [self.get_rid()]` [20].
54- **NEVER use rays for small, fast detection areas** — Rays can "tunnel" through thin walls if the frame rate drops. Use `cast_motion` or high-frequency stepping for bullets.
55- **NEVER query 1000+ rays individually in GDScript** — Batch your queries or use the `PhysicsServer` directly in C++ if you reach extreme query counts.
56- **NEVER ignore the `result.rid`** — RIDs are the fastest way to identify and exclude objects in subsequent queries, bypassing node-path lookups [20].
57
58## Query-Type Decision Table
59
60Pick the cheapest API that answers the question. Always pair rays/shapes with RID exclude + masks ([query_exclusion_optimization.gd](scripts/query_exclusion_optimization.gd)).
61
62| Need | Prefer | Cost | When | Script |
63|------|--------|------|------|--------|
64| Persistent sensor in the scene (ledge, aim assist debug) | `RayCast2D`/`RayCast3D` node | Low–med | Few casts; OK waiting one physics frame (or `force_raycast_update()`) | Scene node + NEVER rules |
65| Hitscan / LOS / one-shot mid-frame ray | `PhysicsDirectSpaceState*.intersect_ray` | Low | High frequency, no permanent node | **MANDATORY** [direct_space_state_raycast.gd](scripts/direct_space_state_raycast.gd) |
66| Footing, thick walls, melee volume | `ShapeCast*` / `intersect_shape` | Med–high | Thin ray tunnels or misses volume | **MANDATORY** [shapecast_ground_detection.gd](scripts/shapecast_ground_detection.gd) |
67| Explosion / occupancy at a point | `intersect_point` | Low–med | Epicenter overlap list | [point_in_shape_query.gd](scripts/point_in_shape_query.gd) |
68| Stuck / penetration resolve | `get_rest_info` | Med | Overlap recovery | [rest_info_3d_stuck_fix.gd](scripts/rest_info_3d_stuck_fix.gd) |
69| Pierce / multi-hit along a line | Repeated `intersect_ray` + exclude RIDs | Med | Projectiles that keep going | [multiple_hit_piercing_ray.gd](scripts/multiple_hit_piercing_ray.gd) |
70| Screen → world click | Camera project + `intersect_ray` | Low | Picking | [mouse_pick_3d_query.gd](scripts/mouse_pick_3d_query.gd) |
71
72---
73
74## 3D Mouse Picking Example
75
76```gdscript
77func screen_point_to_ray():
78 var space_state = get_world_3d().direct_space_state
79 var mouse_pos = get_viewport().get_mouse_position()
80
81 var origin = project_ray_origin(mouse_pos)
82 var end = origin + project_ray_normal(mouse_pos) * 2000
83
84 var query = PhysicsRayQueryParameters3D.create(origin, end)
85 var result = space_state.intersect_ray(query)
86
87 if result:
88 return result.collider
89 return null
90```
91
92---
93
94## Expert WHY (query timing & LOS)
95
96- **Physics step only** — `direct_space_state` in `_physics_process`, not `_process`.
97- **Self-hit** — `query.exclude = [get_rid()]` on rays from character center.
98- **NavMesh LOS** — physics ray ≠ carved nav hole; `path.size() == 2` on `NavigationServer3D.map_get_path` for strict mesh LOS (see deep dive).
99- **Surface types** — `collider.get_meta(&"surface_type")` beats class/group checks for decals/footsteps.
100- **Compute GPU rays** — out of scope; not a drop-in for gameplay `intersect_ray`.
101
102## Deep dive (load on demand)
103
104NavMesh LOS validator, surface metadata, picking baseline, tunneling notes — [references/query-elite-patterns.md](references/query-elite-patterns.md).
105
106## Reference
107
108> Progressive disclosure: open Official Documentation links only when researching a specific API;
109> load Related Skills when routing work to a peer domain — do not preload the whole lattice.
110
111### Official Documentation
112- [Ray-casting](https://docs.godotengine.org/en/stable/tutorials/physics/ray-casting.html) — Node `RayCast*` vs `PhysicsDirectSpaceState*` queries, result dictionaries, and `exclude` to avoid self-hits.
113- [Physics introduction](https://docs.godotengine.org/en/stable/tutorials/physics/physics_introduction.html) — Collision layers/masks that filter every ray, shape, and point query at the physics server.
114- [Collision shapes (3D)](https://docs.godotengine.org/en/stable/tutorials/physics/collision_shapes_3d.html) — Why queries need primitive/convex shapes instead of visual meshes for reliable, cheap intersections.
115- [PhysicsDirectSpaceState3D](https://docs.godotengine.org/en/stable/classes/class_physicsdirectspacestate3d.html) — `intersect_ray` / `intersect_shape` / `intersect_point` / `get_rest_info` / `cast_motion` contracts for mid-frame space queries.
116- [PhysicsDirectSpaceState2D](https://docs.godotengine.org/en/stable/classes/class_physicsdirectspacestate2d.html) — 2D twin of direct space queries for LOS, hitscan, and point epicenters without permanent cast nodes.
117- [PhysicsRayQueryParameters3D](https://docs.godotengine.org/en/stable/classes/class_physicsrayqueryparameters3d.html) — Mask, exclude RIDs, `hit_from_inside`, and collide-with flags for reusable ray parameter objects.
118- [PhysicsShapeQueryParameters3D](https://docs.godotengine.org/en/stable/classes/class_physicsshapequeryparameters3d.html) — Shape RID + transform setup for volume casts, rest info, and stuck-overlap resolution.
119- [PhysicsPointQueryParameters3D](https://docs.godotengine.org/en/stable/classes/class_physicspointqueryparameters3d.html) — Point-in-shape overlap lists for explosion epicenters and occupancy checks.
120- [RayCast3D](https://docs.godotengine.org/en/stable/classes/class_raycast3d.html) — Scene-tree cast nodes, collision exceptions, and when `force_raycast_update()` is required after moving.
121- [ShapeCast3D](https://docs.godotengine.org/en/stable/classes/class_shapecast3d.html) — Volume casts and `force_shapecast_update()` for footing/melee detection that thin rays miss.
122- [Camera3D](https://docs.godotengine.org/en/stable/classes/class_camera3d.html) — `project_ray_origin` / `project_ray_normal` for screen-to-world picking rays from the active camera.
123- [Mouse and input coordinates](https://docs.godotengine.org/en/stable/tutorials/inputs/mouse_and_input_coordinates.html) — Viewport mouse position vs canvas/world space before building a pick ray.
124
125### Related Skills
126
127#### Prerequisites
128- [godot-project-foundations](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-project-foundations/SKILL.md) — Named physics layers and tick settings must exist before query masks and water/ground layer bits stay coherent.
129- [godot-gdscript-mastery](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-gdscript-mastery/SKILL.md) — Typed query parameters, RID arrays, and `_physics_process`-only space access are language-level contracts this skill depends on.
130- [godot-2d-physics](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-2d-physics/SKILL.md) — 2D body/area layer matrices and when to prefer `RayCast2D` nodes vs direct space state for sensors.
131
132#### Complements
133- [godot-physics-3d](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-physics-3d/SKILL.md) — 3D body types, CCD, and collision setup that determine what your rays and shape casts can actually hit.
134- [godot-characterbody-2d](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-characterbody-2d/SKILL.md) — Grounding, ledges, and coyote-time feel often consume ShapeCast/ray footing results from this domain.
135- [godot-input-handling](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-input-handling/SKILL.md) — Physics-step click/aim sampling couples with mouse-pick rays and hitscan timing.
136- [godot-navigation-pathfinding](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-navigation-pathfinding/SKILL.md) — Physics LOS vs NavMesh path-straightness checks; keep obstacle carve and collision worlds consistent.
137- [godot-ai-navigation](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-ai-navigation/SKILL.md) — FOV fans and vision sensors feed AI perception stacks that still need correct query masks/exclusions.
138- [godot-performance-optimization](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-performance-optimization/SKILL.md) — Budgeting hundreds of rays, reusing query params, and knowing when node casts become SceneTree overhead.
139- [godot-debugging-profiling](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-debugging-profiling/SKILL.md) — Visualizing cast lines/shapes and diagnosing missed hits from mask, exclude, or update-timing mistakes.
140
141#### Downstream / consumers
142- [godot-combat-system](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-combat-system/SKILL.md) — Hitscan, piercing rays, and melee volumes resolve damage from query results produced here.
143- [godot-genre-shooter](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-genre-shooter/SKILL.md) — Hitscan weapons, bullet pierce, and aim assist consume exclusion/mask recipes and multi-hit pierce loops.
144- [godot-monte-carlo-balancer](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-monte-carlo-balancer/SKILL.md) — View distance, FOV ray counts, pierce max-hits, and query tick rate change fairness and difficulty; simulate those knobs instead of guessing.
145
146#### Master
147- [godot-master](https://github.com/thedivergentai/gd-agentic-skills/blob/main/skills/godot-master/SKILL.md) — Library router and mirrored entry point for discovering raycasting/query patterns alongside sibling domains.