Support ACG room layouts, chests and doors in PRK.Client
Goal Support ACG interiors in PRK.Client using the server-provided PlayfieldAnarchyF room layout and local RDB room-template assets. Reuse the static indoor rendering/physics/door pipeline; do not generate a layout locally or reference PlayfieldEngine from the client. Workspace Active checkout: /home/mathias/Projects/engines on feature/client-acg-layout, clean and synchronized with origin at 7394102dd after the user-authorized chest/door commit and push. No worktree was created for this follow-up, per the user's request. Dedicated worktree /home/mathias/Projects/worktrees/engines-client-acg removed after committing and pushing the correction, per the user's request; initial base origin/develop 4dbe350b2; rebased onto origin/develop 0b532ed7a at the user's request. Other worktrees remain untouched. Further implementation is authorized directly in /home/mathias/Projects/engines, without a worktree; the user confirms no parallel work is ongoing. User subsequently authorized committing and opening a PR through /open-pr; deployment remains unauthorized. Confirmed evidence - Shared PlayfieldAnarchyFMessage already decodes PlayfieldACGInfo (template, dimensions, floor field, ambient RGB and room ID/floor/grid/rotation). Its count/input validation needs review and malformed-input tests rather than a second decoder. - PlayfieldAnarchyFMessageHandler currently drops this metadata and passes PlayfieldId1.Instance to LoadPlayfield. ACG zone-in uses an ACGBuildingGeneratorData instance handle there, not an RDB playfield asset ID. - WorldManager and Anarchy.Playfield independently load static RDB layout. IndoorPlayfieldData, IndoorSurface/RoomFrame, ClientIndoorAutotiler, indoor mesh/deformation helpers, IndoorDoorWorld and PlayfieldPresenter provide the reusable indoor pipeline. - Shared RoomInstance/RoomTemplate provide ACG placement precedent, including authored room pivots and floor offsets. Verify wire-derived placement against server fixtures before sharing/adapting these semantics; do not infer undocumented floor behavior from names alone. Scope and proposed behavior Carry a validated zone-entry/layout snapshot from message handling into world loading, separating server instance identity, template asset identity and room-instance identity. Resolve server-selected templates from RDB, instantiate each supplied room placement in wire order, and supply the same resolved layout/transforms to ground, shell collision, statels, lights, room visibility and doors. Retain local assets but replace static placement with the server layout. Preserve static indoor/outdoor and offline behavior. Use existing door/dynel messages as authoritative runtime state; do not spawn duplicate static-template doors. Include floor transitions and repeated template rooms. Verify stepped floors and coplanar SL floors using current server packet/coordinate fixtures, including same-instance re-entry/transition and replacement door state. Keep ambient and authored lighting attached to the resolved interior. Consolidate static and ACG consumers around one resolved indoor layout input; only source selection/assembly differs. Do not mutate cached RDB templates. Prefer a bounded refactor at loading boundaries over a new world/rendering subsystem. Expanded scope: complete ChestItemFullUpdate and DoorFullUpdate support required by ACG. Decode bounded full packet bodies (including owner-conditional poses and counted tails); render/update/remove server world objects using shared placement and asset ownership; distinguish world loot containers from carried bags; use the existing server-authoritative open/close, take-only loot and item-on-object lockpick flows. Door full updates must also replace static/ordinary playfield doors without duplicates, preserve lock/swing/passage state, and clean up on despawn/zoning. Preserve supported carried-bag CIFU compatibility and do not paint owned bags into the world. Acceptance for expanded scope: packet round-trip/truncation/version/count tests, real server-style chest/door fixtures, typed-identity collision/replacement/despawn/stale callback checks, room visibility and mesh/scale overrides, owned/world bag inventory separation and loot open/take/close, door lock/status/passages, and affected builds/regressions all pass. The user confirmed full testing and working behavior, satisfying the final manual graphical acceptance gate. Out of scope: client-side procedural generation, seeded Live interiors without a supplied room list, mission generation/gameplay changes, new navmesh tooling and unrelated audio work. CharInPlay remains intentionally unchanged. Acceptance and validation - Real server-style ACG packet round-trip/handler tests preserve all required metadata and never resolve the server instance handle as an asset ID. Invalid/truncated/count-overflow/unsupported layouts fail with actionable diagnostics and no unbounded allocations or partial world publication. - Synthetic room fixtures prove rotations, grid dimensions/Z inversion, repeated templates, authored pit/shaft pivots and floor offsets; render, physics and room/door identity agree. - ACG re-entry, floor transitions, teardown and a newer zone entry cannot retain or publish stale geometry, doors, lights or resources. Missing assets/layout are refused safely, not replaced silently with static geometry. - Existing indoor/outdoor, autotiler, surface, visibility, collision and door regressions pass alongside focused ACG tests and affected builds. - Representative server-provided RK, cave, SL and alien layouts are replayed with available local assets; at least one graphical zone-in/walk/door/zone-out smoke verifies placement and collision. Record any unavailable asset/display gates rather than claiming completion. Current implementation and validation - Implemented in the dedicated worktree; committed and pushed as c767d8c94 (feature: Load server-provided ACG layouts in PRK.Client), replacing 38122e9d7 through the user-authorized rebase and an explicit old-SHA force-with-lease. PlayfieldEntry/AcgLayout snapshot the packet metadata and separate the instance handle from the template asset ID. The shared PAF and DoorFullUpdate decoders now reject impossible counts/truncation; outdoor empty ACG catalogs remain outdoor. - AcgRoomAssembler uses shared RoomInstance placement and copies door connections without modifying RDB templates. Each wire room has a distinct instance index. Authored pivots, RK stepped floors and SL 400-unit coplanar bands are preserved. Ground/shells, transformed collision copies, repeated statel chunks, lights, ambient, room visibility and music room mapping use those resolved rooms. Template-global water and debug attractor markers are not incorrectly copied into the generated interior. - Added DoorFullUpdate decoding/handling and server room-pair binding, initial lock suppression, idempotent retransmission and replacement cleanup. Early statuses are retained until spawn. Dynamic requests share a gate with the streaming-owned asset cache; their completions enqueue to the world update rather than mutate visual lists on the asset thread. Generation/identity checks and disposal reject stale completions. ACG load refusal tears down simulation/presentation rather than silently using static geometry. - Verified 50 focused ACG/world-load tests, including the existing captured Live Clan packet and read-only local RK/cave/SL/alien assets, all passing without skips. These exercise packet/identity snapshots, malformed inputs, repeated rooms, rotations/Z inversion, floor transitions with stale hints, authored pit heights, collision placement, actual room shell/statel loads and server-style door coordinates, door locks/retransmission/late status, worker-thread completion ownership, stale completion after replacement/disposal and queued-state teardown. - Full non-install client suite after rebase: 3,350 passed, 46 environment-dependent tests skipped, zero failures. Client/test build with TreatWarningsAsErrors passes. TheThreeEngines.sln builds with zero warnings/errors, covering the changed shared packet readers. git diff --check passes; original worktree remains clean. Validation used a .NET 10 SDK container with SQLite/fontconfig dependencies; game assets were mounted read-only and patch scratch stayed in temporary directories. - Final acceptance: the user confirmed that all work is fully tested and working and explicitly requested task completion. This satisfies the remaining manual graphical acceptance gate; no additional assistant-run GUI test is claimed. No deployment, production connection or game-data changes. Implementation order 1. Packet validation and zone-entry identity/layout handoff. 2. Validated ACG room assembly and shared resolved indoor layout boundary. 3. Shared rendering, ground/collision, statel/light and visibility integration. 4. Server door/dynel binding and floor/re-entry lifecycle integration. 5. Regression, asset replay and graphical validation. Pull request - Ready for review #2631: feature: Load server-provided ACG layouts in PRK.Client - https://git.project-rk.com/prk/engines/pulls/2631 - Published head feature/client-acg-layout -> develop is 7394102dd, including the verified outdoor loading correction and chest/door lifecycle implementation. Dedicated worktree removed; main engines checkout is now on this branch. - Rebased onto develop 0b532ed7a and resolved all four integration conflicts while preserving merged map/audio behavior. PlayfieldEntry now retains both model/resource identities; the shared map/shell origin helper uses placed ACG rooms, and generated maps do not copy static template fixtures. Focused ACG/world tests (50 passed, including real assets) and the full non-install suite (3,350 passed, 46 environment-dependent skips) were rerun successfully on c767d8c94. Client/test and lean engine builds pass with TreatWarningsAsErrors; engine build has zero warnings/errors. Range-diff reviewed, git diff --check and merge-tree check clean. PR branch updated with an explicit old-SHA force-with-lease. The user subsequently confirmed full testing; PR #2631 is now ready for review and task completion is authorized. Outdoor 566 regression follow-up - Reproduced the user's exact ArgumentOutOfRangeException at Playfield.Load line 109 using read-only local playfield 566 assets. The ACG placement loop unconditionally indexed RdbPlayfieldResource.Zones for outdoor statel chunks; their chunk count exceeds the indoor room metadata count. This was introduced by the ACG change, not a malformed server layout. - Fixed Playfield.cs to select room templates only for indoor layouts, preserving outdoor identity transforms and raw chunk indexing. Missing indoor metadata now produces an actionable InvalidDataException. Existing generated room instances still select their source chunk via RoomId. - Added four asset-independent room selection regressions and the actual outdoor 566 catalog load test. The 566 test failed with the exact original exception before the fix and passes afterward. Updated focused suite: 55 passed/no skips, including 566 and existing ACG real assets. Full non-install suite: 3,354 passed, 46 environment-dependent skips, zero failures. Client/test build with TreatWarningsAsErrors and git diff --check pass. - Committed and pushed as ae9fa64e0 (fix: Avoid indoor room lookup for outdoor statel chunks), touching only Playfield.cs, AcgInstallTests.cs and new PlayfieldRoomSelectionTests.cs. The user authorized push, worktree removal and switching the main engines checkout onto feature/client-acg-layout; all three operations completed and the checkout is clean/up to date. CharInPlay remains unchanged per the user's explicit scope. Chest and door full-update implementation - Implemented directly in the main checkout; committed and pushed as 7394102dd (feature: Support chest and door full-update lifecycles). CIFU now decodes through the real catalogue and handler, validates supported SIFU/LIFU/CIFU versions, conditional world poses, bounded stats/names/identity and animation-effect lists, and consumes the complete tail. Legacy owned-bag CIFUs without a tail remain compatible. A shared bounded full-update reader also hardens DFU. - Shared immutable world-object snapshots and typed-identity/generation ownership serve chest and door placement, template/mesh/can/scale overrides, names/lock metadata, picking, cached room visibility, mesh rig opening, replacement/despawn/teardown and rejected stale mesh completions. Full updates replace RDB doors without duplicate visuals or retained requests; ordinary playfields bind authored doors while ACG uses server room pairs. Server stat updates and accepted use echoes apply through one ordered world-owner queue sharing the asset-cache gate. Door removal clears links/pairs and old statuses cannot poison reused IDs. - World CIFU Bag/Terminal/TempBag identities are classified as take-only loot, separately from owned backpacks. The existing loot window follows the most recently server-opened chest/corpse, uses its packet name, preserves older pages until server close, takes items through existing first-free moves, closes through the correct world use command, and supports existing item-on-object lockpick requests. Despawn, ownership changes and zoning clean up classification/pages; late inventory updates cannot recreate a despawned chest until a new full update arrives. Owned CIFUs never paint inventory bags into the world. - Verified 89 focused tests without skips, including real barrel/treasure templates (23149/23155/23163/162447/162448), the actual door template (41556), prior ACG room fixtures and outdoor 566. Tests cover packet round trips/nonempty counted tails/every world CIFU truncation/version/count failures, owner separation, loot open/take/close, utility/bag aliases, newest-page selection, lockpick targets, scaled picking bounds, rig animation, same-instance different identity types, static door replacement, ordinary playfield identity filtering, FIFO spawn/despawn, late statuses/contents and cancelled callbacks. - Full non-install client suite: 3,386 passed, 46 environment-dependent skips, zero failures. Client/test build with TreatWarningsAsErrors and git diff --check pass. TheThreeEngines.sln builds with zero warnings/errors. Container build uses NativeBuildDirectory=/src/PRK.Common/PRK.Navigation/obj/native-container-world-objects to avoid the existing host-path CMake cache; host cache and repository build configuration were not changed. - User-reported full testing and working behavior satisfy the final graphical acceptance gate. No additional assistant-run authenticated game session or deployment is claimed. Current PFE world CIFUs send an empty animation-effect tail. Nonempty effect fields are parsed and round-tripped; this follow-up does not add per-container nano/VFX attachment beyond the authored mesh rig. The user authorized commit/push; PR #2631 now includes 7394102dd and its validation/caveats are recorded in a PR comment. Main checkout is clean/up to date. The user confirmed final acceptance and requested completion; all checklist outcomes are verified.
Checklist
7 of 7 complete- ACG packet validation and zone-entry handoff preserve layout metadata and distinguish instance handles from asset IDs; round-trip and malformed-input tests pass.
- Server room entries assemble into a shared resolved indoor layout without modifying cached templates; repeated rooms, rotations, grid/floor offsets and authored pivots have fixture tests.
- Rendering, ground/collision, statels, lighting and visibility consume the same resolved placements; static indoor/outdoor regressions pass.
- Server-authoritative doors/dynels, floor transitions, re-entry and teardown work without duplicate doors or stale layout/resource publication; lifecycle tests pass.
- Affected builds and focused regressions pass; representative RK/cave/SL/alien asset replays and a graphical zone/walk/door/exit smoke validate behavior, with unavailable gates explicitly recorded.
- CIFU packet validation, owned/world bag separation, world chest placement/updates/animation/despawn and take-only loot open/take/close flows are implemented and verified without breaking carried bags.
- Door full updates work across ACG and ordinary playfields, replace static instances safely, preserve locks/status/passage and picking, and remove all bindings/visuals on despawn or zone teardown; shared lifecycle regression tests pass.
- Area
- Project Rubi-Ka
- Project
- engines
- Kind
- Feature
- Task ID
tsk_3ty4ugypka- Updated