Skip to content

feat(world-builder): NPC placement, movement, and map persistence API (Closes #8) - #218

Open
Rodrigoue9 wants to merge 5 commits into
Bitcoindefi:mainfrom
Rodrigoue9:feat/map-npc-placement-api
Open

feat(world-builder): NPC placement, movement, and map persistence API (Closes #8)#218
Rodrigoue9 wants to merge 5 commits into
Bitcoindefi:mainfrom
Rodrigoue9:feat/map-npc-placement-api

Conversation

@Rodrigoue9

Copy link
Copy Markdown

Summary

Implements the Stage 2 World Builder API for placing, moving, removing, and listing NPCs on game maps with robust validation and persistence, as specified and assigned in #8.

Closes #8


Changes

  1. api/src/lib/mapNpcStorage.ts:

    • Added MAX_NPCS_PER_MAP = 50 as an exported, single-source named constant.
    • Implemented placeMapNpc with coordinate boundary (1-100), catalog validity (isValidNpcIndex), blocked tile check (isTileBlocked), duplicate placement rejection, and map quota enforcement.
    • Implemented moveMapNpc supporting smooth destination updates while handling self-tile in-place repositioning (fromX === toX && fromY === toY) without spurious collision errors.
    • Implemented removeMapNpc for atomic NPC deletion and disk synchronization.
    • Deterministic sorting and serialization across api/src/mapas_source/mapa_<n>/npcs.json.
  2. api/src/server.ts:

    • Exposing authorized endpoints under /admin/game-data/maps/:mapNum/npcs:
      • GET /admin/game-data/maps/:mapNum/npcs -> lists placed NPCs
      • POST /admin/game-data/maps/:mapNum/npcs -> places NPC
      • PUT /admin/game-data/maps/:mapNum/npcs/move -> moves NPC
      • DELETE /admin/game-data/maps/:mapNum/npcs/:x/:y -> removes NPC
  3. api/src/tests/mapNpcPlacement.test.ts:

    • 12 comprehensive unit and integration tests verifying all CRUD operations, boundary constraints, collision handling, self-tile movements, and file persistence.

Verification

npx tsx api/src/tests/mapNpcPlacement.test.ts
  • Output: 12 passed, 0 failed (100% green).

Comment thread api/src/server.ts Outdated
Comment thread api/src/server.ts
Comment thread api/src/lib/mapNpcStorage.ts Outdated
Comment thread api/src/server.ts
@gitar-bot

gitar-bot Bot commented Aug 29, 2026

Copy link
Copy Markdown
Code Review ✅ Approved 4 resolved / 4 findings

Implements Stage 2 World Builder API for NPC placement, movement, removal, and persistence on game maps with full CRUD endpoints and validation. Fixed config initialization, exported missing utilities, added concurrency mutex to prevent race conditions on concurrent writes, and tightened mapNum validation to reject values ≤ 0.

✅ 4 resolved
Bug: config.mapsSourceDir does not exist on Config

📄 api/src/server.ts:3092 📄 api/src/server.ts:3112 📄 api/src/server.ts:3146 📄 api/src/server.ts:3180
server.ts references config.mapsSourceDir in all four new NPC endpoints (GET/POST/PUT/DELETE), but the Config type and the config object in api/src/config.ts define no mapsSourceDir field. This is a TypeScript compile error, and at runtime the value is undefined, so every storage call resolves paths like undefined/mapa_N/npcs.json and the entire feature is broken. The codebase already resolves this directory via resolveMapsSourceDir() in repositories/worldBuilder.ts — export/reuse that helper (or add mapsSourceDir to config) and pass it to the storage functions.

Bug: isValidGameNpcIndex not exported from gameNpcs

📄 api/src/server.ts:8 📄 api/src/server.ts:3116
server.ts imports isValidGameNpcIndex from ./repositories/gameNpcs and calls it in the POST endpoint, but no such symbol is defined or exported in api/src/repositories/gameNpcs.ts (the only occurrences of the name in the codebase are the import and call site in server.ts). This breaks the build (missing named export) and would make NPC catalog validation impossible. Implement and export isValidGameNpcIndex in gameNpcs.ts, or use an existing catalog-lookup function.

Bug: Concurrent NPC writes lose updates (read-modify-write race)

📄 api/src/lib/mapNpcStorage.ts:175-189 📄 api/src/lib/mapNpcStorage.ts:212-226 📄 api/src/lib/mapNpcStorage.ts:238-246
placeMapNpc/moveMapNpc/removeMapNpc each do loadMapNpcPlacements → mutate in memory → saveMapNpcPlacements with no locking. Two concurrent requests to the same map both read the same base state and the last writer overwrites the first, silently dropping a placement (and defeating the duplicate-tile and MAX_NPCS_PER_MAP checks). Serialize writes per map (e.g. an async mutex/queue keyed by mapNum) or write atomically with a compare step.

Edge Case: move/delete endpoints accept mapNum <= 0

📄 api/src/server.ts:3137-3143 📄 api/src/server.ts:3171-3178
The GET and POST endpoints reject mapNum <= 0, but the PUT /npcs/move and DELETE /npcs/:x/:y handlers only check Number.isInteger, so mapNum values of 0 or negative pass through to the storage layer and resolve directories like mapa_0 or mapa_-1. Add the same mapNum <= 0 rejection to the move and delete handlers for consistency.

Options

Auto-apply is off → Gitar will not commit updates to this branch.
Display: compact → Showing less information.

Comment with these commands to change the behavior for this request:

Auto-apply Compact
gitar auto-apply:on         
gitar display:verbose         

Important

Your trial ends in 3 days — upgrade now to keep code review, CI analysis, auto-apply, custom automations, and more.

Was this helpful? React with 👍 / 👎 | Gitar

@Rodrigoue9

Copy link
Copy Markdown
Author

¡Hola @leocagli! Espero que hayas tenido un excelente inicio de semana.

Te comento que el PR #218 (Closes #8) está completamente listo, probado y validado:

  • ✅ Cumple con todos los criterios de aceptación de la Etapa 2 definidos en la issue (colocación, movimiento, eliminación, catálogo de 340 templates, validación de tiles bloqueados y límite de 50 por mapa).
  • ✅ Los 12 tests de integración pasan al 100% en verde.
  • ✅ Código auditado y aprobado por gitar-bot (✅ Approved: 4 resolved / 4 findings).
  • ✅ 0 conflictos de merge con main (mergeable: true).

Quedo totalmente a tu disposición por si requieres algún ajuste adicional, o si ya podemos proceder con la revisión final y merge de esta etapa para cerrar el milestone. ¡Muchas gracias! 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Etapa 2: API de colocacion y movimiento de NPCs en mapa

1 participant