96x96 arena with multi-level layout, grapple points, wall-run/climb
surfaces, 6 team spawns with anti-camping cover, and varied movement
challenges.
Map Features:
- Central multi-level structure: 20x20 platform (3u), 10x10 tower (6u),
14x14 top platform (9u) with crown cover walls and internal stairs
- 4 corner towers (5u high) with railings and top platforms
- 4 elevated mid-side walkways (3u) with railings connecting center to edges
- 8 ramps: cardinal to central, diagonal to corners, to walkways
- Quarter-pipe curve (8 segments) near NE corner
- 4 parkour stepping stone chains (NW, NE, SW, SE quadrants)
- Wall-run corridor (N side) with parallel walls, obstacles, and floor gap
- Wall-run surfaces on all 4 outer wall sections
- Wall-climb surfaces around central tower and mid-map (warm color)
- 4 grapple anchor pillars (15u tall) with visible tops at cardinal points
- Cover system: low walls, crate clusters, corridor walls, structural pillars
- Speed corridor with side rails, speed bumps, and floor markings
- 6 spawn alcoves (3 red: NW/SW/West, 3 blue: NE/SE/East) with cover walls
- Anti-spawn-camping: each alcove has 2+ exits and blocking walls
- Floor accent tiles in central area
- Atmospheric sky with procedural sky material and fog
- Directional sun + fill light + center omni + 6 spawn accent lights
- Decorative: barrels, hazard stripes, accent beams, spawn area lights
- Full multiplayer spawning, weapon system, HUD, entities preserved
- All movement states: ground, air, wall_run, wall_climb, wall_cling,
slide, dash, grapple
Parse verified clean with Godot 4.2.1 headless.
Root cause: builder created plain Node instances for the state machine
and states, so _machine.player = self in PlayerMovementController
crashed with 'Invalid assignment ... on base object of type Node'.
Now each node gets its real script attached before _ready() runs.
- _build_player: creates Player (CharacterBody3D) with capsule,
MovementStateMachine + 6 state children, attaches movement script
- Calls player._ready() manually after set_script (GDScript
set_script does not auto-trigger _ready)
- Camera parented under Player so it follows movement
- Restores _build_camera() which was accidentally dropped
- test_level.tscn: minimal Node3D root (zero SubResource references)
- debug/test_level_builder.gd: runtime floor/walls/lighting/camera/UI
shapes/meshes created from BoxShape3D/BoxMesh — no .tscn subresources
- project.godot: revert features to 4.6 (installed build is 4.6.3)
- scenes/test_level/test_level.tscn — playable test environment (30x30 floor + 4 walls + ramp)
Floor at y=-1, Player spawn at (0, 1.5, 8), FpsCamera at head height (y=1.7)
DirectionalLight + WorldEnvironment + UI label overlay (speed/state/chain)
- debug/debug_test_env.sh — launch wrapper for manual playtesting
No code changes: raw physics testbed. Intended to be opened as first scene in Godot window.
Closes#2 (test-level scene task)