7.3 KiB
7.3 KiB
NS-23 — Implementation plan
Story reference
| Field | Value |
|---|---|
| Key | NS-23 |
| Title | E1.M1: Client path-follow baseline (navigation + visible locomotion) |
| Jira | NS-23 |
| Parent context | NS-10 — E1.M1 InputAndMovementRuntime · NS-1 — Epic 1 · Slice 1 — Movement and position sync |
| Decomposition | E1.M1 — InputAndMovementRuntime |
Delivery: Ship docs/plans/NS-23-implementation-plan.md on the same branch / PR as the NS-23 implementation (plan + code together), matching the NS-19 pattern.
Goal, scope, and out-of-scope
Goal: Deliver visible click-to-move: the avatar follows a path toward the clicked point using a navigation mesh baseline (obstacle-aware), not only steering at a goal or snapping on server ack alone. Aligns with E1.M1: path-follow baseline under server authority.
In scope
- Godot:
NavigationRegion3D(baked mesh) over the prototype walkable floor inmain.tscn, respecting existing static obstacles;NavigationAgent3D(on player or child node) drivingCharacterBody3Dmotion (move_and_slidetoward next path position — follow Godot 4.x recommended pattern). - Pick integration: Reuse
ground_pick.gd(walkablegroup, upward normal); clicked point becomesNavigationAgent3D.target_position(after any needed Y / agent height adjustment consistent with current capsule). - Server authority (unchanged contract): One
MoveCommandper successful pick with the same world target as today (NS-16); server v1 snap + NS-19 validation unchanged.
Out of scope (per Jira)
- Full prediction/reconciliation, MMO-grade netcode, server-side nav mesh validation.
- Replacing
InteractionRequest/ range rules.
Locked — client nav vs server authority (this slice)
| Topic | Decision |
|---|---|
| When to POST | Once per click, immediately with the picked destination (same JSON as today). No waypoint streaming to the server in this story. |
| Server truth | Still snap to target on 200 after validation; GET /position after POST remains the reconciliation read (existing PositionAuthorityClient flow). |
| Straight-line vs path | NS-19 validates displacement from current authoritative position to target (horizontal + vertical limits). It does not check path clearance through geometry; client nav is responsible for visible obstacle avoidance. |
| After successful move | Do not teleport the avatar on the verifying GET when the player is expected to walk: apply the authoritative position as a navigation goal and let the agent complete the path; initial boot sync_from_server remains a hard snap so spawn matches the server. |
| POST 400 | Existing behavior: emit move_rejected, show NS-19 UX; do not start (or clear) a nav path to that target. |
| Distance limits | Default MaxHorizontalStep (e.g. 18 m) remains compatible with single-command long clicks across the prototype; if a future scene needs shorter steps, chain commands or tune limits in a later story. |
Acceptance criteria checklist
- Clicking a valid floor target produces continuous motion along a plausible path around static obstacles in the prototype scene (not sliding through walls).
- Authoritative position still converges with the server (
MoveCommand+GET); no regression on NS-19 rejection UX (reasonCode/ label timeout). - Short note in
server/README.mdand/or client script header: client nav vs server authority for this slice.
Technical approach
-
main.tscn/ navigation- Add
NavigationRegion3Dcovering walkable floor; include obstacleStaticBody3Dgeometry in baking as required by Godot 4 so paths wrap obstacles. - Bake after layout changes; document any editor step in
client/README.mdif bake is not fully reproducible from scene alone.
- Add
-
Player / agent
- Attach
NavigationAgent3D; replace NS-14-style direct steering toward_goalwith path following (velocity towardget_next_path_position()or equivalent,move_and_slide). - Keep
snap_to_serverfor boot and any hard reconcile case you explicitly document (default: boot only).
- Attach
-
Wiring (
main.gd/PositionAuthorityClient)- On
target_chosen: callsubmit_move_targetas today (POST → GET). - Distinguish authoritative position from boot vs after successful move so
main.gdsnaps on boot but sets nav target (no snap) after verify when implementing path-follow. - Optional small API: second signal, enum on existing signal, or
sync_from_server-only snap path — pick the smallest change that stays readable per godot-client-script-organization.
- On
-
Documentation
client/README.md: Update movement section: navmesh path-follow + server authority one-liner.server/README.md: One short subsection or bullet: server validates end target and step; client nav is presentational for obstacle following in this slice.
Files to add (expected)
| Path | Purpose |
|---|---|
| None required by name | Prefer extending existing player.gd / scene unless a dedicated player_navigation.gd reduces main.gd bloat. |
Files to modify
| Path | Rationale |
|---|---|
client/scenes/main.tscn |
NavigationRegion3D, bake source meshes, agent node setup. |
client/scripts/player.gd |
Path-follow via NavigationAgent3D; clarify header (NS-14 → NS-23 evolution). |
client/scripts/main.gd |
Boot snap vs post-move nav goal wiring. |
client/scripts/position_authority_client.gd |
If needed: signal shape or phase so main can snap only on boot. |
client/README.md |
Manual check steps for path-follow + server. |
server/README.md |
Client nav vs authority note (AC). |
docs/decomposition/modules/E1_M1_InputAndMovementRuntime.md |
Implementation snapshot when NS-23 ships. |
Tests
| Action | What to cover |
|---|---|
| Manual (required) | Server running; click around obstacles — path goes around; click NS-19 reject targets — same rejection behavior as before; cold start — player matches server position. |
| Automated | None required for this story unless an existing headless hook can assert nav baking (unlikely); prefer manual for Godot nav. |
Open questions / risks
- Agent radius / height vs capsule: mis-tuning causes clipping or “stuck”; match
CollisionShape3Dto agent parameters. - Frame ordering:
NavigationServersync — follow Godot docs (await get_tree().physics_frameif required before first path query).
PR / review
Cross-check E1.M1, client README, and server README. Confirm NS-19 props in main.tscn still behave after nav region changes.