Transmission #063: PDD scaffold — enter buildings via attack

Started Prompt-Driven Development for building enter/exit: attack-to-enter (same gesture family as quest boards), teleport to a roofless interior far above the map (~10k Y), attack interior wall to exit back to the saved overworld pose. Scoped gray cube placeholders with future procedural prefabs; overworld and interior collisions must block the player.

Artifacts live under .agents/planning/2026-05-15-building-enter-via-attack/ (rough-idea.md, idea-honing.md, plus research/, design/, implementation/ for subsequent steps).

Research-first track

Owner chose to start with preliminary research. Draft plan and early codebase anchors are in .agents/planning/2026-05-15-building-enter-via-attack/research/research-plan.md (melee/board parity, projectile parity, interact vs attack, movement/collision audit — including that WASDPlayerMovement applies terrain height only with no horizontal obstacle resolution, OSM building colliders from OSM3DBuilder, interior lifecycle and exit detection). Awaiting feedback on topics and any scene/prefab pointers before locking deeper notes.

Research closed → detailed design

Owner confirmed research sufficient. Added research/synthesis.md (findings + flow/state mermaid) and design/detailed-design.md (standalone requirements, architecture, components, data models, errors, testing, appendices). Defaults for v1: projectile parity with boards; Use-to-enter deferred; shared obstacle motor (CharacterController recommended) for WASD and mobile PlayerController.

Requirements refinement

Expanded Detailed requirements in design/detailed-design.md: definitions (player, session, portal, exit surface, saved pose), explicit in/out scope, numbered REQ-F / REQ-C / REQ-NF / REQ-E with acceptance criteria, RFC 2119 language, assumptions A-01–A-04, traceability table. InteriorReturnPose now specifies full Quaternion rotation (aligned with REQ definitions). Error-handling table references REQ-E; manual test bullet checks full pose restore. Batch note appended to idea-honing.md.

Implementation plan

Added implementation/plan.md: eleven demoable steps (layers + CharacterController, shared motor for WASD + PlayerController, InteriorSessionManager, sky gray cell, OSM3DBuilder portals, melee/projectile enter/exit, failure/death ForceExit Option A, camera + regression); checklist mirrors steps; melee precedence and REQ-E-02 choice documented. summary.md lists all artifacts and next actions.

Unity implementation (building interiors)

Shipped first playable slice aligned with the PDD plan:

Manual QA: punch/fireball building → interior at altitude → punch south (-Z) wall tagged exit → pose restore; verify overworld walls block movement.

Building interior session matching (exit reliability)

Deferred Destroy can leave a prior InteriorCell in the scene for a frame with overlap geometry overlapping the next session. InteriorExitWall now carries BoundSessionId stamped when the cell is built; InteriorSessionManager tracks _activeSessionId per successful TryEnter. TryExitFromHit rejects exit-wall hits unless BoundSessionId == _activeSessionId and the collider is under the active _interiorRoot, so stale walls cannot steal overlaps after re-entering. An earlier attempt disabled colliders before Destroy to force overlaps gone immediately; that interfered with reliable melee OverlapSphere hits against the active exit wall, so it was replaced by session IDs plus plain Destroy.

Building interior exit — melee overlap evidence

Runtime logs (debug-beff96) showed exitWallCols":0 while playerInsideInterior":true with hitCount":2–3: Physics.OverlapSphere was hitting interior geometry but only the south wall had InteriorExitWall, so punches aimed along typical facing never overlapped that collider. Fix: stamp InteriorExitWall (+ same session id) on all four vertical walls (floor unchanged); instrumentation kept for verification.

Server: character inventory path + tests

The character branch had left Java in a non-compiling middle state (partial player / inventory_item model, CharactersApiImpl still stub-patching against StubModels, and Javalin InventoryRepository APIs removed while handlers still called them). This pass wires the story end-to-end: PlayerRepository owns create + patch (JSON Patch applies to the real /v1 character document), persists a player row plus character inventory on create, replaces inventory rows on update to match PATCH /items, and restores Map-shaped /api/inventories helpers for Unity’s mirror (composite PK (inventory_id, item_id) — slot index is only a synthetic index in JSON for deletes). InternalPlayer is a proper @AutoValue, PlayerModelMapper sets id on outbound Characters, tests seed player rows before inventory FK inserts, and integration tests now assert create → GET and PATCH items → GET instead of assuming id == 1.