docs: add NS-14 click-to-move implementation plan

Made-with: Cursor
feature/ns-14-click-to-move
don 2026-03-29 21:09:43 -04:00
parent 353fa23d29
commit 9a9f4ab3ad
1 changed files with 82 additions and 0 deletions

View File

@ -0,0 +1,82 @@
# NS-14 — Implementation plan
## Story reference
| Field | Value |
|--------|--------|
| **Key** | NS-14 |
| **Title** | E1.M1: Click-to-move prototype (client-only) |
| **Jira** | [NS-14](https://neon-sprawl.atlassian.net/browse/NS-14) |
| **Parent context** | [NS-10 — E1.M1 InputAndMovementRuntime](https://neon-sprawl.atlassian.net/browse/NS-10) |
## Goal, scope, and out-of-scope
**Goal:** On the Godot client only, prove click-to-move locomotion and the input → world-target path before any networking or server authority.
**In scope**
- Placeholder avatar in the prototype scene (`main.tscn` or a dedicated movement test scene; default choice: extend `main.tscn` so F5 still runs the prototype).
- Ground pick via camera raycast; on valid hit, command movement to that point.
- Flat prototype terrain and simple obstacles sufficient to validate stopping behavior.
- Brief note in README and/or scene that this is **temporary** until authoritative movement sync exists.
**Out of scope (per Jira)**
- Game server, persistence, `MoveCommand` / wire protocol, Protobuf contracts.
## Acceptance criteria checklist
- [ ] Clicking walkable ground moves the avatar to the destination without requiring WASD (mouse-only locomotion for this prototype).
- [ ] Movement stops at obstacles when using navigation; **or** if using a direct move-to approach instead, the limitation is documented (README and/or plan).
- [ ] README or an in-editor scene note states this behavior is provisional until authoritative sync lands.
## Technical approach
1. **Scene setup (`main.tscn`)**
- Add a **Camera3D** suitable for ground picking (angled downward at a `StaticBody3D` floor with collision).
- Add a **CharacterBody3D** placeholder (e.g. `CapsuleMesh` + `CollisionShape3D`) as the avatar.
- Add at least one **obstacle** (`StaticBody3D`) so “stop at obstacles” is observable.
- Add a **NavigationRegion3D** covering the walkable floor; bake a navigation mesh from the floor (and subtract or exclude obstacles per Godot 4 workflow).
2. **Movement model**
- Prefer **NavigationAgent3D** on the avatar: set `target_position` from the raycast hit on the ground; each frame move the body toward the agents next path position (e.g. `velocity` + `move_and_slide`, or equivalent Godot 4 pattern). This satisfies the AC path that expects stopping at obstacles via navigation.
- Fallback only if navigation proves unnecessarily heavy for the first slice: direct `move_toward` / velocity toward the click point with `move_and_slide` and document that there is no pathfinding.
3. **Input**
- `_unhandled_input` or `_input`: on left mouse button, raycast from camera through cursor into the physics world; if the collider is the ground (or a dedicated “walkable” layer/mask), set the navigation target.
4. **Documentation**
- Update `client/README.md` with a short “Movement prototype (NS-14)” subsection: mouse click-to-move, navigation-based obstacle avoidance, **not** server-authoritative.
- Optional: `Editable Children` note on root node in scene or a comment in `main.gd` pointing to NS-14 / temporariness.
## Files to add
| Path | Purpose |
|------|--------|
| None required initially | If `main.gd` grows unwieldy, optionally extract `scripts/player_navigation.gd` (or similar) attached to the avatar—only if it keeps the scene readable. |
*(Default: implement in existing `scripts/main.gd` + scene edits unless script size forces a split.)*
## Files to modify
| Path | Rationale |
|------|-----------|
| `client/scenes/main.tscn` | Add camera, terrain, obstacles, navigation region, avatar, and wire scripts. |
| `client/scripts/main.gd` | Raycast-on-click, navigation target updates, and any per-frame movement driver if kept on root. |
| `client/README.md` | Document prototype movement, temporary nature, and manual verification steps. |
| `client/project.godot` | Only if needed (e.g. input map, layer names, or feature flags)—prefer minimal diffs. |
## Tests
- **Automated:** None for this story; the repo has no Godot test harness yet ([testing expectations](../../.cursor/rules/testing-expectations.md)).
- **Manual verification:**
1. Open `client/` in Godot 4.2+, run main scene.
2. Click on the floor: avatar moves to the point without using WASD.
3. Click a destination behind an obstacle: avatar path avoids or stops appropriately per navigation behavior.
4. Confirm README/scene note mentions provisional client-only movement.
## Open questions / risks
- **Navigation baking:** First-time contributors need to bake the navigation mesh in the editor after pulling scene changes; document that in README if it is not obvious.
- **Isometric later:** Camera rig may be replaced for isometric; keep movement logic independent of camera style where possible (raycast from current camera).
- **Performance:** Single-agent prototype is sufficient; no need to optimize for crowds in NS-14.