Retraining from scratch removes the constraint that blocked these: the
existing checkpoints in Game/bots/promoted/ no longer need byte-identical
geometry.
- Fix the goal aperture constants (were 1.85/1.65, now match
objects/goal.tscn's actual sensor exactly at 1.75/1.5) so a ball crossing
the visible edge can't fail to score.
- Cut a real navigable hole in each end wall's collision
(_build_end_wall_colliders), replacing the previous solid box — the ball
now genuinely enters the net instead of triggering the sensor a hair
before hitting a solid wall. Correct for both FLOOR and ELEVATED goal
modes via _goal_surround_bounds. A separate, slightly wider
GOAL_VISUAL_APERTURE_* pair keeps the collision hole exact while still
giving goal.gd's bezel/rim frame clearance to be seen against the hull cut.
- Resize the play volume 1.5x (INNER_HALF_X/Z/HEIGHT 12/18/12 -> 18/27/18) to
comfortably fit a 5v5 roster: updates every hand-authored literal in
arena_boundary.tscn/arena_base.tscn/the elevated arena variants that
doesn't derive from those constants, adds 5 spawn markers per team, and
rescales ship_observations.gd's normalization scales and arena_02's
cosmetic decoration/nebula-dust shader uniforms to match.
- Bake the ~170 runtime-generated CollisionShape3D nodes into the scene via
a new bake_colliders()/tools/bake_arena_boundary.gd instead of rebuilding
them on every load — a real load-time cost repeated in every parallel
headless training env. Colliders must be direct children of the
StaticBody3D to register at all, so bake_colliders() parents them onto
self and tags them with a group for idempotent re-baking, rather than
grouping them under an intermediate container node. _ready() self-heals:
it skips regenerating only when an existing bake's goal_mode metadata
matches the current one, so the FLOOR-mode bake in the shared scene is
never silently reused by an ELEVATED arena variant.
The dust emitter's box fully encloses the arena, so motes drifted through the
pitch and hazed the surfaces the player is trying to read.
Fade each mote by the Chebyshev distance of its world-space origin outside
the play volume, taken from MODEL_MATRIX's translation column so it is
unaffected by the billboard rewrite of VERTEX. Motes inside the box are fully
hidden and fade in over arena_clear_distance beyond it, so the effect reads as
weather drifting around the station rather than through the match.
Extents default to ArenaBoundary's play volume and are exposed as uniforms.
Also adds the missing .uid sidecar for the shader.
Replace NebulaDust's flat unshaded glow material with a custom
ShaderMaterial: a fake per-pixel puff normal on the billboarded quad
feeds a light() override so motes catch the directional light and a
nebula-core color bias, alpha gets a depth-texture soft-particle fade
so motes no longer hard-clip through boundary/decoration geometry,
and a per-particle hash adds subtle sparkle.