perf(physics): name and assign collision layers

Adds a [layer_names] section to project.godot (Ships/Ball/Arena/
GoalSensor) and sets collision_layer/collision_mask on the 4 physics
body roots (Ship, Ball, Goal Area3D, ArenaBoundary StaticBody3D),
which previously all sat on the default layer 1 / mask 1 so every
body broadphase-tested against every other.

Ships collide with ships/ball/arena but no longer test against the
goal sensor; the goal's mask (Ball only) is the physics-level fix for
what goal.gd's is_in_group("ball") check was doing defensively in
code (left in place, now a no-op guard). ArenaBoundary's runtime-
generated CollisionShape3D children inherit layer/mask from the
StaticBody3D root automatically.

Verified live via godot-mcp under Jolt Physics: ship-vs-ship and
ship-vs-ball collisions still transfer momentum, the ball still
bounces off arena walls, a ball entering a goal still fires
goal_scored (score updates / HUD reset), and a ship teleported into a
goal recess produces zero overlapping bodies on the goal Area3D (was
reachable before, physics-level fix confirmed, not just the code
guard). Headless smoke test (free_play.tscn) is clean.
This commit is contained in:
Josh Creek
2026-08-04 18:32:54 +01:00
parent 96ff503fa8
commit c75e142c8a
6 changed files with 15 additions and 1 deletions
+2
View File
@@ -12,6 +12,8 @@ size = Vector3(1, 13, 38)
size = Vector3(26, 13, 1)
[node name="ArenaBoundary" type="StaticBody3D"]
collision_layer = 4
collision_mask = 3
script = ExtResource("1_bndry")
[node name="FloorShape" type="CollisionShape3D" parent="."]
+2
View File
@@ -10,6 +10,8 @@ bounce = 0.5
friction = 0.4
[node name="Ball" type="RigidBody3D" groups=["ball"]]
collision_layer = 2
collision_mask = 13
mass = 3
physics_material_override = SubResource("PhysicsMaterial_ball")
continuous_cd = true
+2
View File
@@ -6,6 +6,8 @@
size = Vector3(3.5, 1.5, 0.1)
[node name="Goal" type="Area3D"]
collision_layer = 8
collision_mask = 2
script = ExtResource("1_v8ikr")
[node name="CollisionShape3D" type="CollisionShape3D" parent="."]
+2
View File
@@ -12,6 +12,8 @@ bounce = 0.15
size = Vector3(1, 1, 4)
[node name="Ship" type="RigidBody3D"]
collision_layer = 1
collision_mask = 7
mass = 5.0
physics_material_override = SubResource("PhysicsMaterial_ship")
inertia = Vector3(1, 1, 1)
+7
View File
@@ -119,6 +119,13 @@ roll_right={
]
}
[layer_names]
3d_physics/layer_1/name="Ships"
3d_physics/layer_2/name="Ball"
3d_physics/layer_3/name="Arena"
3d_physics/layer_4/name="GoalSensor"
[physics]
3d/physics_engine="Jolt Physics"
-1
View File
@@ -25,7 +25,6 @@ Bugs found in an adversarial review. None are gameplay- or physics-affecting, so
## Performance
- [ ] Name collision layers in `project.godot` and assign them — nothing configures `collision_layer`/`collision_mask` today, so every body tests against every other.
- [ ] Measure `nebula_dust.gdshader`'s per-fragment depth-texture sample across 500 large soft billboards before adding more particle work.
- [ ] Bake `ArenaBoundary`'s ~160 runtime-generated `CollisionShape3D` nodes into the scene. Costs a load hitch on every arena entry and repeats in every parallel headless training env. **Blocked on the trained-bot decision below**`arena_boundary.gd:235` notes this geometry is what the shipped policies were fitted against, so the bake must be verified byte-identical.