3.9 KiB
Code review — NEO-23 (targeting API)
Date: 2026-04-17
Scope: Branch NEO-23-e1m3-targetstate-selection-api; git range main...HEAD (working tree clean at review time). Linear NEO-23.
Base: main (local origin/main implied).
Verdict
Approve with nits
Summary
The branch adds the NEO-23 targeting surface under server/NeonSprawl.Server/Game/Targeting/: prototype registry, in-memory per-player lock + sequence, horizontal reach–based validity (soft lock), GET /game/players/{id}/target and POST …/target/select, DTOs aligned with the plan (selectionApplied, optional reasonCode, always-present lockedTargetId), integration tests in the same spirit as interaction APIs, and server README coverage. Behavior matches the written implementation plan for denials (200 + reasonCode when not applied), 400/404 boundaries, clear via omitted/null targetId, and movement-driven validity without auto-clear. dotnet test NeonSprawl.sln passes (55 tests).
Documentation checked
| Path | Result |
|---|---|
docs/plans/NEO-23-implementation-plan.md (branch) |
Matches — routes, DTO names as documented (PlayerTargetStateResponse, TargetSelectRequest/Response), soft lock, sequence rules, README scope, and acceptance bullets align with the code under review. |
docs/decomposition/modules/E1_M3_InteractionAndTargetingLayer.md |
Matches (post–follow-up) — Summary Status, Implementation snapshot, and NEO-23 Game/Targeting/ + README pointers reflect the JSON v1 spike; later contracts remain explicitly open. |
docs/decomposition/modules/module_dependency_register.md |
Matches (post–follow-up) — E1.M3 In Progress; note text covers NEO-23 partial slice vs remaining contracts. |
docs/decomposition/modules/documentation_and_implementation_alignment.md |
Matches (post–follow-up) — E1.M3 row register + snapshot + plans cell aligned with NEO-23 merge and follow-on Linear issues. |
docs/decomposition/modules/contracts.md (versioned JSON spike discipline) |
Matches — explicit schemaVersion, throwaway JSON over HTTP, consistent with other prototype routes. |
Register / tracking table: After merge, should update Done on branch (same PR window as NEO-23).module_dependency_register.md and documentation_and_implementation_alignment.md (and optionally the E1.M3 module snapshot) so status and inventory match the new Game/Targeting/ + README section.
Blocking issues
(none)
Suggestions
-
Doc alignment in merge train: UpdateDone.module_dependency_register.md,documentation_and_implementation_alignment.md, and the Implementation snapshot inE1_M3_InteractionAndTargetingLayer.mdso E1.M3 is not described as having zero implementation once NEO-23 lands (per this repo’s own alignment policy). A follow-up doc-only PR is acceptable if called out explicitly for the merge. -
Test gap —Done.GET404:PostSelect_ShouldReturnNotFound_WhenPlayerUnknowncovers unknown player on POST. Adding a parallel test forGET /game/players/{id}/targetwould lock the same contract as position/interact read paths. -
Done.PlayerTargetStateReaderTestsdepth: The plan’s optional table called out inclusive-radius boundary cases (similar toHorizontalReachTests). Current unit tests covernulllock and unknown registry id only; adding one boundary assertion would better match the plan’s optional coverage intent.
Nits
- Nit: Wire type name
PlayerTargetStateResponsevs illustrative doc nameTargetStateis already explained in the NEO-23 plan and README; no change required if PR text points readers there once.
Verification
dotnet test NeonSprawl.sln(author ran: all passed).- Manual:
curlexamples fromserver/README.mdTargeting (NEO-23) against a running server (optional smoke).