Commit Graph

73 Commits (f5ff0b8dc3c2fcfc5c7205c35d9eae18b11ced86)

Author SHA1 Message Date
VinPropane bf9fd84b1c NEO-85: Apply gdformat to client scripts and tests. 2026-05-25 13:26:22 -04:00
VinPropane 4d32d068dc NEO-85: Fix gdlint max line length in combat HP label render. 2026-05-25 13:26:09 -04:00
VinPropane 79b8a68364 NEO-85: Make combat dummies visible with labels and lock highlight.
Replace subtle mast markers with capsule bodies, Dummy α/β Label3D names,
and brighten the Tab-locked target; HUD hints point to orange/purple dummies.
2026-05-25 13:23:13 -04:00
VinPropane 35ff76b532 NEO-85: Auto-bind pulse to slot 0 and show cast HUD errors.
Fresh hotbar starts empty so digit 1 was a silent no-op; bootstrap
prototype_pulse on first sync and surface empty-slot/send failures on CastFeedbackLabel.
2026-05-25 13:22:06 -04:00
VinPropane 493e963a28 NEO-85: Wire client combat feedback and target HP HUD.
Parse combatResolution on cast accept, add combat-targets GET client,
CombatTargetHpLabel, and event-driven HP refresh on lock change and cast.
2026-05-25 13:15:59 -04:00
VinPropane a38ab660b4 NEO-75: fix gdlint/gdformat on economy HUD node paths
Resolve economy HUD @onready paths via EconomyHudSection.get_node
so gdlint max-line-length and gdformat both pass pre-push.
2026-05-24 20:41:01 -04:00
VinPropane 025d6e529d NEO-75: add collapsible economy HUD section
Reparent inventory, skills, and craft panel under EconomyHudSection
with an Economy HUD toggle; update main.gd node paths and GdUnit tests.
2026-05-24 20:33:48 -04:00
VinPropane a8cedcbd64 NEO-74: Repopulate recipe panel when item defs load.
Run craft panel refresh before inventory-error guard in
_on_item_definitions_ready so display names resolve even when
inventory GET failed first.
2026-05-24 20:21:37 -04:00
VinPropane 501834279e NEO-74: Apply gdformat to main and craft refresh test. 2026-05-24 20:02:47 -04:00
VinPropane 2fec42f8f6 NEO-74: Address code review — recipe sync HUD and test uids.
Wire recipes_sync_failed to CraftFeedbackLabel, remove unused _scroll
binding, add GdUnit .uid companions, extend recipe client HTTP error
test, strike through review items.
2026-05-24 19:59:00 -04:00
VinPropane c16b610468 NEO-74: Implement client craft UI, recipe list, and tests.
Add recipe-definitions and craft HTTP clients, scrollable recipe panel with
Craft buttons, CraftFeedbackLabel, refine skill HUD row, GdUnit coverage,
manual QA, and plan/module doc reconciliation.
2026-05-24 19:56:38 -04:00
VinPropane 07ca427f2f NEO-73: preserve gather finalize across coalesced terminal POST.
Use awaiting-inventory flag so R-then-E still paints GatherFeedbackLabel
after inventory sync; only clear session on true orphans (Bugbot #107).
2026-05-24 19:42:39 -04:00
VinPropane d0622701eb NEO-73: clear orphaned gather pending on coalesced interact.
Track pending gather interactable id; drop flag when a different
interact completes (Bugbot PR #107). Add GdUnit coalescing test.
2026-05-24 19:24:00 -04:00
VinPropane 8de08a67a8 NEO-73: fix gdlint max-line-length for pre-push hook. 2026-05-24 19:14:27 -04:00
VinPropane 434226a069 NEO-73: address code review follow-ups.
Emit interaction_request_failed to clear stale gather pending flag;
add deny/HTTP failure tests; update alignment docs and review file.
2026-05-24 19:09:36 -04:00
VinPropane aa013d4be7 NEO-73: wire client gather feedback on resource interact.
Add skill progression client, nearest-node R picker, interaction
result signal, GatherFeedbackLabel and SkillProgressionLabel HUD.
2026-05-24 19:07:19 -04:00
VinPropane 68b9b9c8c8 NEO-72: satisfy gdlint/gdformat for pre-push hook.
Extract interact key routing helper to fix max-returns; wrap long lines and gdformat.
2026-05-24 18:50:10 -04:00
VinPropane 751fea3db4 NEO-72: add client inventory snapshot HUD and HTTP clients.
Wire GET inventory + item-definitions into InventoryLabel with I-key refresh,
displayName labels, and GdUnit coverage for happy/error paths.
2026-05-24 18:41:24 -04:00
VinPropane 76fd1cc70a NEO-32: gdformat main.gd; touch cooldown state tests 2026-04-30 22:06:15 -04:00
VinPropane ee953cbdfd NEO-32: gdformat-style cast accept cooldown refresh 2026-04-30 22:05:22 -04:00
VinPropane c83d8c8ed2 NEO-32: satisfy gdlint line length (pre-push) 2026-04-30 22:05:01 -04:00
VinPropane 56f7ae8a81 NEO-32: fix cooldown HUD anchor when serverTimeUtc parse fails 2026-04-30 21:45:25 -04:00
VinPropane 361a6800d2 NEO-32: cooldown snapshot API, on_cooldown deny, client HUD sync 2026-04-30 21:19:32 -04:00
VinPropane 94cec78053 NEO-30: wrap telemetry doc comments for gdlint 2026-04-30 21:05:42 -04:00
VinPropane b5478782a8 NEO-30: cast funnel telemetry hook sites and docs 2026-04-30 20:59:47 -04:00
VinPropane 7de8e7ecfd NEO-28: cast target authority, HUD feedback, tests + docs 2026-04-27 21:03:04 -04:00
VinPropane 18e55f717a NEO-31: wrap long lines for gdlint pre-push 2026-04-27 20:49:11 -04:00
VinPropane af1fdef816 NEO-31: single authority mirror for hotbar and ability cast clients 2026-04-27 20:45:48 -04:00
VinPropane cc1c6f711e NEO-31: request_cast bool for telemetry hook; document cast API in server README 2026-04-27 20:44:40 -04:00
VinPropane e88e59f3a6 NEO-31: hotbar cast resolver tests, doc alignment, review follow-up 2026-04-27 20:42:36 -04:00
VinPropane 7e97eb4c1d NEO-31: ability cast POST, client hotbar keys, tests, Bruno 2026-04-27 20:17:57 -04:00
VinPropane 23da39f7d3 NEO-29: fix main script definition order for hook lint
Move hotbar state/client field declarations above onready definitions for class order compliance, and include a non-behavioral test file restage so client hooks can validate.
2026-04-25 23:28:14 -04:00
VinPropane acde9e8145 NEO-29: add HotbarLoadout v1 contract and hydration path
Ship a server-owned hotbar loadout API with Postgres-or-memory persistence so slot bindings survive reconnects in configured environments. Wire client boot hydration and add tests/docs/manual QA to keep the prototype contract and policy explicit.
2026-04-25 22:29:52 -04:00
VinPropane 9c054fbcf2 NEO-27: add Slice 3 telemetry hook-site documentation
Map SelectionEvent to target_changed, reserve ability_cast_requested and ability_cast_denied hook locations, and align plan/manual QA/decomposition docs with TODO(E9.M1) telemetry follow-up.
2026-04-25 21:56:28 -04:00
VinPropane ac2916bfee NEO-25: satisfy gdlint/gdformat for pre-push hook 2026-04-24 20:56:04 -04:00
VinPropane c17526e611 NEO-25: close code review follow-up (alignment, warning, tests) 2026-04-24 20:54:26 -04:00
VinPropane 06d9104157 NEO-25: route E/R interact via main _unhandled_key_input for reliable input 2026-04-24 20:44:43 -04:00
VinPropane ce54fcc44f NEO-25: world interactables GET, registry rows, fetch-driven Godot props + glow 2026-04-24 20:36:15 -04:00
VinPropane e31cd2df68 NEO-24: freshen server position before target-select + surface divergence on HUD
Fix "Tab says denied even though I'm in range of beta": root cause is the
race between the 20 Hz move-stream sampler and the target-select POST. A
Tab press right after the capsule stops can be validated against the
server's last sampled position, which trails the visible capsule by
several meters.

Client-side fixes (server contract unchanged):

- TargetSelectionClient.set_freshness_kick(authority, player): before each
  POST /target/select, submit a move-stream with the current player
  position so the server's stored snapshot is as fresh as possible when
  the range check runs. Wired in main.gd; optional so tests without the
  wiring still pass (regression-covered).
- PlayerPositionLabel now shows a "srv: (x,y,z) Δ=<d>m age=<ms>" line
  populated from PositionAuthorityClient.authoritative_ack, so any
  residual client/server divergence is visible in the HUD and future
  reports can point at it directly.
- Two new tests: select POST kicks exactly one freshness stream with the
  current player position before POSTing, and the kick is a no-op when
  the wiring is absent.

Docs: plan Decision 5, review follow-up #2, manual QA section 5 and
section 1, and client README updated to describe the new behaviors.
2026-04-21 23:21:16 -04:00
VinPropane 71ae829482 NEO-24: add visible target-anchor markers + HUD distance lines
Players reported targeting "feels inconsistent" because the server
PrototypeTargetRegistry anchors (alpha (-5,-5) r=8, beta (8,8) r=4) have
no visible meshes — the only console visible in the scene is the NEO-9
PrototypeTerminal at origin, which is unrelated to NEO-23/24 targeting.

Adds a display-only mirror of the server registry:

- client/scripts/prototype_target_markers.gd spawns a colored mast +
  translucent flat radius ring per anchor so the lock radius is
  visible in-world.
- client/scripts/prototype_target_constants.gd gains ANCHORS with
  position/radius/color, matching PrototypeTargetRegistry.cs. Marked
  display-only; server remains authoritative for validity.
- TargetLockLabel now renders a per-anchor distance line each physics
  tick ("<id>: <d> m / <radius> (in|out)") so players can see the
  relationship between the visible capsule and the lock radius and
  immediately spot client/server position drift.

Also updates README, plan (Decision 4), manual QA (Section 1 boot +
Section 4 locomotion), and the review file's follow-up section to
describe the UX fix.
2026-04-21 23:04:03 -04:00
VinPropane 435a32b3b3 NEO-24: fix movement-driven target refresh via authoritative_ack signal
Review 2026-04-21 caught that the hybrid soft-lock refresh path is
unreachable during normal WASD locomotion. `main.gd` was wiring
`TargetSelectionClient` to `PositionAuthorityClient.authoritative_position_received`,
which only fires on boot sync and move-rejection resync — successful
`move-stream` 200s are intentionally silent to avoid RTT rubber-banding.
So walking out of an alpha/beta radius never triggered the throttled
`GET /target` the HUD depends on, and validity stayed stuck at `ok`.

Add a separate `authoritative_ack(world)` signal on `PositionAuthorityClient`
emitted from both `BOOT_GET` 200 and successful `move-stream` 200, and
switch `TargetSelectionClient` (+ `main.gd`) to it. The snap signal keeps
its current semantics so rubber-band suppression is untouched; the ack
signal is a pure heartbeat that cooldown-throttled consumers can hook.

Also adds an integration test that wires both real clients together (per
the review's suggestion 1) so renames or mis-wires between the two
scripts fail loudly rather than silently skipping the end-to-end path.

- `client/scripts/position_authority_client.gd`: new `authoritative_ack`
  signal; extracted `_parse_world_from_response` helper to share JSON
  parse across `BOOT_GET` and `STREAM_POST`; emit ack from both.
- `client/scripts/target_selection_client.gd`: rename
  `on_authoritative_position_snap` to `on_authoritative_ack`; drop
  `apply_as_snap` gate (no longer meaningful).
- `client/scripts/main.gd`: connect the new signal.
- `client/test/position_authority_client_test.gd`: assert ack on boot
  200 and stream 200.
- `client/test/target_selection_client_test.gd`: rename tests for new
  handler.
- `client/test/target_refresh_on_locomotion_test.gd`: new integration
  suite wiring real authority + target clients.
- Plan Decision 3 + Tests row + Files-to-modify row updated.
- `docs/reviews/2026-04-21-NEO-24.md`: committed with blocking issue +
  suggestions struck through with `Done.` notes per
  planning-implementation-docs rule.
- `docs/decomposition/modules/documentation_and_implementation_alignment.md`:
  E1.M3 row now reflects NEO-24 landed.
- `client/README.md` + `docs/manual-qa/NEO-24.md`: refreshed signal names
  so the soft-lock refresh description matches the wiring.

Tests: 88/88 GdUnit headless passed locally.
2026-04-21 22:35:41 -04:00
VinPropane ee572e3661 NEO-24: client tab-target + lock HUD synced to server
Adds `TargetSelectionClient` (Godot, HTTP to NEO-23 targeting endpoints):
- Tab cycles ids in ascending order matching `PrototypeTargetRegistry`
  (`prototype_target_alpha`, `prototype_target_beta`) and wraps.
- Esc clears by POSTing with `targetId` omitted.
- UI always paints from the server's authoritative `targetState`
  (success and denials alike); `UICanvas/TargetLockLabel` shows
  `lockedTargetId`, `validity`, `sequence`, and (on deny) `reasonCode`.
- Movement-triggered refresh: while a lock is held, subsequent
  `authoritative_position_received` snaps fire a throttled GET
  (~250 ms cooldown) so `validity` flips to `out_of_range` after
  locomotion without duplicating server radius math on the client.

Registers `target_tab` (Tab) / `target_clear` (Esc) in `project.godot`;
documents bindings + manual QA in `client/README.md`.

Tests: `target_selection_client_test.gd` covers GET parse, tab ordering
from empty/alpha/wrap, POST body shape, denial preserves server state,
clear omits targetId, movement refresh fires only while locked, cooldown
collapses bursts to one GET, and `apply_as_snap=false` is ignored.
All 85 client GdUnit cases pass; gdlint and gdformat clean.

See `docs/plans/NEO-24-implementation-plan.md`.
2026-04-21 22:14:16 -04:00
VinPropane 90a17bc43d NEO-22: Extract WASD locomotion for gdlint max-file-lines
Move the WASD physics tick into player_locomotion_wasd.gd so player.gd
stays under the 1600-line CI cap. Fix gdlint class order (enum before
consts), load-constant naming, and wrap long doc lines. Update NEO-22
review and plan; refresh gdlintrc comment.
2026-04-17 20:13:36 -04:00
VinPropane a4095cb9bf NEO-22: Remove click-to-move client and legacy move POST/verify
Delete ground_pick and GroundPick wiring; PositionAuthorityClient now only
boot GET and move-stream POST. main.gd snaps on authoritative position only.
Update client/server READMEs, cursor rule example, NEO-22 plan note, and
GdUnit authority tests (stream 400 + boot resync).
2026-04-17 20:06:46 -04:00
VinPropane 39a41ac62c NEO-22: suppress stream snap-back while locomoting
Stream HTTP responses can lag integrated move_and_slide by roughly one RTT,
so apply_as_snap was pulling the capsule backward each tick while moving.
Skip small XZ corrections when wish or horizontal speed indicates locomotion,
with a cap so large desync still snaps. move_rejected sets a one-shot flag so
resync after move-stream 400 still applies the authoritative pose.
2026-04-17 19:29:56 -04:00
VinPropane 878b1f4aee NEO-22: fix stream rubber-banding (coalesce, idle gate, soft snap)
Queue only latest move-stream target per POST; clear pending while busy.
Skip stream submits when idle; skip tiny authoritative snaps after boot.
2026-04-17 19:27:10 -04:00
VinPropane a2c6c9f93e NEO-22: add move-stream API and WASD client locomotion
Introduce POST /game/players/{id}/move-stream with ordered targets, full-chain
validation before apply, and PositionStateResponse. Godot client uses camera-
relative WASD, queues samples, and snaps to stream responses; debug builds keep
click-to-move via ground_pick. Update READMEs, E1.M1 snapshot, and tests.
2026-04-17 19:21:33 -04:00
VinPropane 2b72d6bcb9 NEON-29: Prototype smooth hill piece, movement script updates, NEO-22 plan
Add prototype_smooth_hill_piece for QA geometry alongside main scene wiring.
Refresh player locomotion and main scene integration from stashed work.
Track docs/plans/NEO-22-implementation-plan.md (WASD replaces click-to-move).
2026-04-15 23:39:47 -04:00
VinPropane a7ad695143 NEON-29: Apply stashed WIP (main.tscn, movement validation, docs) 2026-04-13 13:24:05 -04:00
VinPropane 4a51e64f25 Merge branch 'main' into NEON-29-expand-prototype-district 2026-04-13 13:22:51 -04:00