neon-sprawl/docs/plans/NEON-29-implementation-plan.md

7.5 KiB
Raw Blame History

NEON-29 Implementation Plan — Expand prototype client district for camera/nav stress QA

Story reference


Goal, scope, and out-of-scope

Goal

Provide a ~5× footprint (order-of-magnitude) prototype play space versus the current district, with more obstacles and height-changing regions (steps, terraces, bumps) so day-to-day client work can stress motion, framing, and readability for the camera, navigation, ground pick, and interaction systems.

Scope

  • client/scenes/main.tscn: expand walkable floor / nav source geometry; add props that participate in NavigationRegion3D bake and walkable picking as today; include elevated terrace/step platforms for vertical variation.
  • client/README.md: short runbook note covering district scale, intent, and any new designer-facing limits.
  • Optional: pointer in docs/decomposition/modules/E1_M2_IsometricCameraController.md that this geography is the default stress playground for client stories.

Out of scope

  • New camera features (zoom bands NEON-26, occlusion NEON-27) — geography may help test them, but this story does not implement them.
  • Server schema or MoveCommand contract changes unless existing NEON-7 step/bounds defaults visibly break on the larger map (in that case: document + minimal config tune only).
  • Production art pass or zone graph / Epic 4 content.

Acceptance criteria checklist

  • Playable area is materially larger (~5× order of magnitude vs pre-change footprint) with additional obstacles and vertical variation usable with click-to-move.
  • NavigationRegion3D bakes successfully at startup; long clicks behave per existing NEON-8 tradeoffs (document if new geometry exposes new edge cases).
  • Ground pick and walkable grouping remain correct on new surfaces.
  • README updated for anyone running F5 + server.

Technical approach

Current baseline

The current main.tscn district is a single 20 × 20 unit flat floor (BoxMesh_floor, placed at Y = -0.1), giving an approximate playable area of ~400 sq units. Static props:

  • PrototypeTerminal (0.9 × 1 × 0.4) at origin
  • MoveRejectPedestal (1.5 × 2.5 × 1.5) at (7.5, 0, -6.5)
  • MoveRejectFarPad (2.5 × 0.12 × 2.5) at (9, 0.06, 9)
  • Obstacle (2 × 2 × 2, occluder group) at (6, 0, 5)
  • Player spawn at (-5, 0.9, -5)

The NavigationMesh stored in the scene file is intentionally stale; main.gd calls bake_navigation_mesh(false) at startup so the live mesh always reflects actual collision geometry.

Expansion plan

Floor size: Replace the 20 × 20 floor with a 45 × 45 unit floor, giving ~2025 sq units (~5× of 400). Keep floor mesh center at origin (X=0, Z=0) so spawn position and existing props stay roughly central.

Additional obstacles (nav stress + camera occlusion): Add 34 extra StaticBody3D nodes in the occluder group, distributed across the expanded area — positioned so the follow camera must work around varying angles.

Vertical variation (terraces / steps): Add 23 raised terrace platforms as StaticBody3D nodes in the walkable group, elevated ~0.52.5 m above the main floor, with ramp/step approach geometry. These are StaticBody3D siblings of Floor under NavigationRegion3D so the runtime bake includes them as nav sources. Each terrace:

  • Has its own CollisionShape3D (BoxShape3D).
  • Is in the walkable group so ground-pick raycasts hit it correctly.
  • Has a small StaticBody3D ramp or step approach (also walkable) so NavigationAgent3D can route onto it within the NEON-8 step/climb parameters (agent_max_climb = 0.35 in existing NavMesh settings — ramp grade must respect this, or use multi-step approach).

MoveReject props: Keep MoveRejectPedestal and MoveRejectFarPad in place — they exercise NEON-7 reject behavior and must remain reachable. Shift MoveRejectFarPad outward if needed to stay within the expanded floor bounds and remain "far."

NavigationMesh settings: No changes to agent parameters (height=1.0, radius=0.4, max_climb=0.35, cell_size=0.15) — they remain aligned with the player capsule per NEON-8. The stale baked mesh in the scene will update at runtime. The geometry_collision_mask = 1 stays, so all collision-layer-1 bodies under the region contribute.

NEON-7 edge case check: With a larger floor the server's step_size / MaxDistance defaults may now allow clicks that would previously have been out-of-range. Document in the README if this changes observed reject behavior; no server code change unless a new reject case is broken (not just shifted in range).


Files to add

None. All geometry lives in the existing scene file; no new GDScript logic is required.


Files to modify

File Rationale
client/scenes/main.tscn Replace 20×20 floor with 45×45; add terrace/step platforms and extra obstacle props; update pre-baked NavigationMesh vertices (will be overwritten at runtime, but keeping a reasonable approximation avoids editor warnings).
client/README.md Add district runbook note: new footprint, vertical variation, intent as stress playground, updated manual-check geometry references.
docs/decomposition/modules/E1_M2_IsometricCameraController.md Optional lightweight pointer that this expanded geography is the default QA map for E1.M2 camera stories.

Tests

No new automated GDScript tests are added for this story — there is no new GDScript logic. This story is pure scene geometry.

Manual verification replaces automated tests:

  1. F5 with server running: confirm player spawns and nav bake completes without errors in Output.
  2. Click-to-move across the expanded floor, up/down each terrace, and through obstacles — confirm NavigationAgent3D routes and move_and_slide behaves per NEON-8 tradeoffs.
  3. Ground-pick regression: click behind each new occluder-tagged obstacle with player in and out of occlusion fade range (per NEON-30 manual check in README).
  4. Confirm MoveRejectPedestal and MoveRejectFarPad still reject correctly.
  5. Follow camera: walk to far corners of the expanded floor — confirm IsometricFollowCamera tracks smoothly without snapping or losing the player (snap_distance not tripped by longer walks).
  6. Interaction radius: walk near PrototypeTerminal to confirm range indicators still work correctly.

Open questions / risks

  • NavMesh bake time: A 45×45 floor with several terraces will bake more polygons than the 20×20 baseline. Expected to be negligible for bake_navigation_mesh(false) on desktop, but monitor Output for a perceptible pause.
  • NEON-7 reject range change: The server's MaxDistance is currently tuned for the old district. Clicks from the far corners of the new floor will be within server range (they're not "too far" in server terms — the server checks xz step size from current position to target, not total map size). Confirm no new silent-reject edge cases; document if found.
  • Agent climb on terraces: agent_max_climb = 0.35 limits single-step height. Ramps must grade gently enough for the bake to include them as traversable, or use stacked step geometry (~0.30 m rise per step). Verify in Godot editor nav mesh debug overlay before shipping.