neon-sprawl-archived/docs/plans/NS-14-implementation-plan.md

83 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

# 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.