4.7 KiB
Code review — NEO-25 (InteractableDescriptor list / fetch-driven client)
Date: 2026-04-24
Scope: Branch NEO-25-e1m3-interactable-descriptor-list vs main (full story: server GET /game/world/interactables, registry + two rows, Godot catalog + world build + dual keys, tests, Bruno, docs).
Base: main (inferred from git diff main).
Follow-up: Suggestions below addressed in-repo (decomposition alignment, catalog-failure warning, GdUnit public + last-wins tests).
Verdict
Approve with nits
Summary
The branch delivers the NEO-25 plan end-to-end: versioned GET /game/world/interactables with stable ascending ids, PrototypeInteractableRegistry extended with kind and a second anchor clear of the scene obstacle, integration tests for GET and per-id POST …/interact range behavior, Godot fetch-driven props and multi-row glow preview, interact / interact_secondary wired to fixed ids with main.gd forwarding keys through _unhandled_key_input (reasonable fix for embedded dock focus), and last-wins queuing on the interaction client when POST overlaps. Overall risk is low for a prototype spike; server authority for interact outcomes is unchanged. All 65 dotnet test solutions tests pass in this environment.
Documentation checked
| Path | Assessment |
|---|---|
docs/plans/NEO-25-implementation-plan.md |
Matches — acceptance criteria, route shape, anchors, client option A, tests, Bruno, manual QA path align with the diff. |
docs/manual-qa/NEO-25.md |
Matches — steps match implemented behavior and anchors. |
docs/decomposition/modules/E1_M3_InteractionAndTargetingLayer.md |
Matches — implementation snapshot updated to cite GET /game/world/interactables and client scripts. |
docs/decomposition/modules/client_server_authority.md |
Matches (spot-check) — client preview + server POST …/interact authority preserved. |
docs/decomposition/modules/contracts.md |
N/A for blocking — JSON v1 spike discipline unchanged; no contradiction. |
docs/decomposition/modules/module_dependency_register.md |
Matches — E1.M3 note now includes NEO-25 partial (GET /game/world/interactables, DTOs/API, Godot catalog + builder); SelectionEvent / richer descriptor consumers called out as still in progress. (Was Partially matches at review time; register updated in follow-up.) |
docs/decomposition/modules/documentation_and_implementation_alignment.md |
Matches — E1.M3 snapshot documents NEO-25 list projection + open SelectionEvent / richer consumers. (Was Partially matches at review time; tracking row updated in follow-up.) |
Blocking issues
(none)
Suggestions
Tracking table / register copy — UpdateDone. Both files updated (E1.M3 snapshot + E1.M3 note; server README anchor links).documentation_and_implementation_alignment.md(E1.M3 row) and optionallymodule_dependency_register.md(E1.M3 note) to record NEO-25: versionedGET /game/world/interactables,InteractablesListDtos/InteractablesWorldApi, and Godotinteractables_catalog_client.gd+interactable_world_builder.gd, clarifying that fullSelectionEvent/ richer descriptor consumers remain future work.Done.main.gdcatalog failure handler —_on_interactables_catalog_failedis intentionally empty (errors already come fromInteractablesCatalogClient). A one-linepush_warningor comment pointing to README “server first” would make the no-op obvious to future readers.push_warningwith reason + pointer to client README section “Interaction + range preview (NEO-9 + NEO-25)”; comment notes catalog client alreadypush_errors.
Nits
- Nit:
InteractableWorldBuilderusesextends Objectand is invoked viaload(...).call("build_from_catalog", …)frommain.gd; aRefCountedorNode-attached helper would avoidloadat runtime, but this is consistent enough for prototype scope. Nit: GdUnitDone. Addedinteraction_request_client_test.gdcalls_post_interactdirectly; optionally add cases forpost_interact_terminal/post_interact_resourcepublic entrypoints and for last-wins_pending_interactable_idbehavior if regressions become a concern.test_post_interact_*_public_entrypointandtest_last_wins_second_press_before_first_completes(HoldFirstThenAutoTransport).
Verification
dotnet test /path/to/NeonSprawl.sln(from repo root) — expect all tests green.- Manual: follow
docs/manual-qa/NEO-25.md— curl GET, F5 with server, E/R at both anchors, server-down degradation. - Optional: run GdUnit client suites if your CI does not already.
Review produced per code review agent.