4.9 KiB
Code review — NEO-6 (authoritative position read API)
Review metadata
| Field | Value |
|---|---|
| Date | 2026-03-29 |
| Scope | Branch NEO-6-position-state-api vs origin/main, plus working tree: modified tracked files and untracked implementation/tests/agent files (full change set as present locally) |
| Base | origin/main |
| Issue | NEO-6 — E1.M1: Authoritative PositionState API (in-memory) |
Verdict
Request changes (for merge readiness). Implementation quality is Approve with nits; the request changes is because the feature and tests are largely not yet in git relative to origin/main (untracked paths), so a PR built only from pushed commits would be incomplete.
Summary
The NEO-6 work adds an in-memory IPositionStateStore, Game configuration for a dev player id and default position, PositionStateApi.MapPositionStateApi() for GET /game/players/{id}/position, XML-documented DTOs with schemaVersion, integration tests via WebApplicationFactory<Program>, and Program.Waf.cs for the test host. Program.cs stays thin (DI + map extension calls only), matching docs/plans/NEO-6-implementation-plan.md. README documents curl and sample JSON. Separately, .cursor/rules/csharp-style.md gains primary-constructor guidance, and the code-review agent + AGENTS.md add process docs. Overall risk is low for a read-only spike; no persistence or client integration.
Blocking issues
- Version control gap — As of this review,
server/NeonSprawl.Server/Game/,server/NeonSprawl.Server.Tests/,server/NeonSprawl.Server/Program.Waf.cs,.cursor/rules/code-review-agent.md, andAGENTS.mdare untracked, whileProgram.cs,appsettings.json,server/README.md,NeonSprawl.sln,docs/plans/NEO-6-implementation-plan.md, and.cursor/rules/csharp-style.mdare modified but uncommitted. Before merge:git addall intended files and push so CI/reviewers see the real diff.
Suggestions
-
Null-safe
DefaultPosition— InInMemoryPositionStateStore, configuration binding could theoretically setGamePositionOptions.DefaultPositiontonull. Usevar p = o.DefaultPosition ?? new DefaultPositionOptions();before readingp.X/p.Y/p.Zto avoid a startupNullReferenceException. -
Case sensitivity — Lookups use
StringComparer.Ordinal. Document that player ids in URLs are case-sensitive, or normalize route id and stored keys the same way if product expects case-insensitivity. -
Implementation plan markdown — In
docs/plans/NEO-6-implementation-plan.md, the acceptance section mixes raw**markers with bullets (e.g.`**dotnet test**`) and no longer uses- [ ]checkboxes. Restoring valid Markdown and checkboxes improves scanability. -
Solution file noise — If
NeonSprawl.slnpicks up a UTF-8 BOM or Windows-style path separators, consider normalizing to reduce cross-platform diff churn (non-functional). -
PR description — When opening the PR, paste the sample JSON contract (as in README) so acceptance criteria (“document field names”) is satisfied outside the repo alone (e.g. in the Linear issue description or a PR comment).
Nits
- Nit:
SchemaVersionis set to1in bothPositionStateResponseand the handler; a single named constant could prevent drift. - Nit: No logging on 404 vs success—acceptable for NEO-6; revisit when debugging multi-player seeds.
Verification
Run from repo root (.NET 10 SDK on PATH):
git status # expect clean after add/commit, no missing Game/ or Tests/
dotnet build NeonSprawl.sln
dotnet test NeonSprawl.sln
Manual:
cd server/NeonSprawl.Server && dotnet run
# elsewhere:
curl -s http://localhost:5253/game/players/dev-local-1/position
Expect HTTP 200 and JSON including schemaVersion, playerId, position with x/y/z, and sequence. Unknown id should return 404.
Files touched (review scope)
Modified (tracked): .cursor/rules/csharp-style.md, NeonSprawl.sln, docs/plans/NEO-6-implementation-plan.md, server/NeonSprawl.Server/Program.cs, server/NeonSprawl.Server/appsettings.json, server/README.md
Untracked (must be added for a complete PR): .cursor/rules/code-review-agent.md, AGENTS.md, server/NeonSprawl.Server/Program.Waf.cs, server/NeonSprawl.Server/Game/PositionState/*.cs, server/NeonSprawl.Server.Tests/*
Conformance notes
- architecture-authority: Server-held in-memory state, HTTP read spike; no client or move submission—matches NEO-6 out-of-scope.
- testing-expectations: First server module gets
NeonSprawl.Server.Testswith integration-style coverage for happy path and 404—appropriate. - csharp-style: Test class uses primary constructor and
using Xunit;—aligned with updated rule. - Plan alignment: Separate
PositionStateApi,PositionStateServiceCollectionExtensions, no position routes inlined inProgram.cs—matches plan.