Commit Graph

22 Commits (3dccab8edbe8161dc45e2153bda2796d36673a08)

Author SHA1 Message Date
VinPropane 3dccab8edb NEO-29: normalize hotbar API tests to explicit AAA style
Add explicit Arrange/Act/Assert sections to each hotbar API test method to align with the C# test style guide while preserving existing coverage and behavior.
2026-04-25 22:52:03 -04:00
VinPropane e6f3d63318 NEO-29: move AAA enforcement to test authoring time
Remove the AAA pre-commit gate and instead provide write-time scaffolding via C# snippets and a test template, then document those defaults in the C# style and testing expectations rules.
2026-04-25 22:50:03 -04:00
VinPropane 4dc9f76f79 NEO-29: align hotbar persistence test to AAA style
Refactor the Postgres hotbar persistence integration test to explicit Arrange/Act/Assert structure so it matches the team testing style guide.
2026-04-25 22:47:44 -04:00
VinPropane d25d7d0211 NEO-29: apply code review follow-ups
Set E1.M4 documentation status to In Progress across decomposition tracking docs and add lower-bound slot validation coverage. Mark the corresponding review suggestions and nit as resolved in the saved review file.
2026-04-25 22:44:58 -04:00
VinPropane b92b86a407 NEO-29: cover hotbar edge paths and add Bruno requests
Add server/client tests for duplicate-slot, schema, missing-player, normalization, and busy/error handling paths, and include Bruno requests for the new hotbar routes with happy and representative failure checks.
2026-04-25 22:36:23 -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 0e72d98177 NEO-25: move resource_node anchor clear of Obstacle at (6,1,5) 2026-04-24 20:42:12 -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 d6ef4fd811 NEO-24: race-free target/select via optional positionHint
Followup #5: after locking alpha, walking into beta's ring, stopping and
pressing Tab could still return `out_of_range` even when client and server
agreed on position (Δ=0). The freshness-kick move-stream POST and the
target/select POST race on separate HTTP connections so the select can be
validated against a stale stored snap.

Extend TargetSelectRequest v1 with an optional positionHint {x,y,z}.
Server uses the hint for the radius check and for the echoed
targetState.validity; the hint is advisory and does not write to the
position store (move-stream stays the sole write path). Client attaches
the hint automatically whenever set_freshness_kick(...) is wired, so
headless unit tests that skip the wiring fall through to the no-hint
behavior. Freshness kick is kept in place to refresh the stored snap for
later validity GETs but is no longer load-bearing for denial correctness.

Server: 3 new tests (hint accepts when stored is stale, hint-far denies,
hint never writes to position store). Client: 1 new test asserting the
hint is in the POST body when wired. All 62 server + 96 client tests
pass.

Plan Decision 8, review follow-up #5, manual QA section 6, and NEO-23
contract notes updated. New bruno request exercises the hint path.
2026-04-21 23:52:20 -04:00
VinPropane a7453eb82f NEO-24: unify prototype target radius at 6 m, overlap rings at origin
All prototype targets now share `PrototypeTargetRegistry.SharedLockRadius`
(= 6 m). Anchors moved to alpha `(-3, 0.5, -3)` and beta `(3, 0, 3)` so
the two 6 m rings overlap ~3.5 m wide centered at origin, letting Tab
flip between targets without locomotion. Spawn `(-5, -5)` keeps alpha
in range (~2.83 m) and beta out (~11.31 m) so the existing soft-lock
denial QA path at spawn still holds.

`prototype_target_constants.gd` mirrors the shared radius + new anchors.
The range-aware Tab picker now **skips the currently-locked id** so Tab
always expresses a swap intent — if the only in-range target is already
locked, the fallback picks the next cycle id and the server denies
(preserves NEO-23's "Tab = visible denial when no swap possible" rule).

Tests:
- Server: new `PlayerTargetStateReaderTests.ComputeValidity_AtOrigin_…`
  asserts both targets report `Ok` at origin. Existing boundary test
  rewritten for the new alpha anchor.
- Client: new `test_tab_from_locked_alpha_at_origin_swaps_to_beta_when_both_in_range`
  and `test_tab_when_only_current_lock_is_in_range_falls_back_to_cycle_for_denial`.
  Existing in-range/out-of-range positions updated for the new layout.

Server 59/59 and client 95/95 suites pass.

Plan Decision 7, review follow-up #4, manual QA section 5 (new "Tab-flip
at origin" overlap sanity), and README updated. Per-target radii will
return with real combat design (E5.M1) — this is a prototype stub.
2026-04-21 23:37:42 -04:00
VinPropane 17f87aa747 NEO-23: code review follow-up (E1.M3 docs, GET 404 test, radius bounds) 2026-04-17 21:14:43 -04:00
VinPropane 465c4b14eb NEO-23: add targeting HTTP API (TargetState v1, select intent) 2026-04-17 21:06:59 -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 a442f02dbd NEON-29: Fix CI tests (horizontal step flag, idle_support vectors) 2026-04-15 23:57:13 -04:00
VinPropane ac75af9c73 NEON-29: remove horizontal step limit; add HorizontalStepEnabled flag
Expanded 45×45 district made the 18 m MaxHorizontalStep too restrictive
(floor diagonal ~63 m). Add HorizontalStepEnabled to MovementValidationOptions
(default false, matching DistrictBoundsEnabled pattern) so the check is
skipped unless explicitly opted in. Add test for disabled case (9 pass).
Update README and plan with the decision.
2026-04-11 18:17:32 -04:00
VinPropane 90fcd1b717 NEON-15: dispose shared NpgsqlDataSource on host shutdown 2026-04-08 21:42:33 -04:00
VinPropane 32d2153acb NS-19: server move validation, client rejection UX, scene QA props 2026-04-04 23:39:40 -04:00
VinPropane b043e8ac45 NS-18: InteractionRequest, client prototype, Postgres test UX
Server: POST /game/players/{id}/interact, HorizontalReach, prototype registry, DTOs, tests; default spawn (-5,0.9,-5); dev HttpLogging.

Client: terminal, radius glow preview, interaction_request_client (interact/E), main wiring; obstacle moved off center.

Tests: postgres.runsettings, launchSettings, Docker compose auto-start/teardown harness, async-safe init.

Docs: plan AC, E1.M1 snapshot, alignment table, server/client README, code review 2026-04-04.
2026-04-04 20:19:33 -04:00
VinPropane d20b3931af style: primary constructors for position state types
Use C# primary constructors and camelCase private fields per csharp-style.
Refactor InMemoryPositionStateStore seeding into CreateInitialMap; align
Postgres integration tests and PositionStateApiTests with factory/httpClient
naming.
2026-03-30 23:01:36 -04:00
VinPropane e2d64a7a57 NS-17: PostgreSQL position persistence and integration tests
Wire IPositionStateStore to Npgsql when ConnectionStrings:NeonSprawl is set,
with versioned DDL under server/db/migrations and a shared PostgresPositionBootstrap
for schema plus dev-player seeding at host startup. In-memory tests override Postgres
registrations when CI sets the connection string globally.

Add GitHub Actions Postgres service for dotnet test, server README updates,
decomposition and implementation-plan docs, code review write-up, and C# brace
conventions in csharp-style rule.
2026-03-30 22:55:17 -04:00
VinPropane 3882b0e2c6 NS-16: MoveCommand → server PositionState, Godot sync, tests
Implement E1.M1 intent → authority: POST /game/players/{id}/move with v1 JSON
MoveCommandRequest (snap + sequence), extend in-memory store and
PositionStateApi. Godot client splits ground_pick and position_authority_client
with thin main.gd; snap_to_server on player.

Tests live under NeonSprawl.Server.Tests/Game/PositionState/ with AAA layout
and MethodName_ShouldExpectedOutcome_WhenScenario naming. Debug builds use
UseAppHost=false so Linux IDEs resolve .NET 10 from a user-local SDK.

Add NS-16 implementation plan, code review doc, godot-client-script-organization
rule, csharp test layout/naming rules, and refresh E1.M1 / alignment docs.
Server and client README updates include move API, prerequisites, and Rider
notes.

Made-with: Cursor
2026-03-30 19:54:17 -04:00
VinPropane f7bfd7cb32 NS-15 implement position state api 2026-03-29 23:08:17 -04:00