DRIFTLANDS co-op survival on drifting tides — studio progress

Architecture Traceability Index

Last Updated: 2026-09-07 (/architecture-review; report: architecture-review-2026-09-07.md) — coverage unchanged since 2026-09-01 Engine: Unity 6.3 LTS (6000.3)

Coverage Summary

Changed 2026-09-01: ADR-0013 and ADR-0014 were Accepted (after review findings E14/E15/E16/E17 and F1/F2 were applied), moving coverage from 64 / 28 / 19 → 73 / 26 / 12. tr-registry.yaml is unmodified — no new requirements were surfaced, so all 111 IDs keep their numbers.

2026-08-28 2026-09-01
✅ Covered6473
⚠️ Partial2826
❌ Gap1912

2026-09-07 (architecture-review-2026-09-07.md): no coverage change — no GDD technical requirement changed and no ADR was added, so the matrix below stands at 73 / 26 / 12 and tr-registry.yaml is untouched. First Requirements Traceability Matrix published at requirements-traceability.md: 61/112 (54 %) requirements have the full GDD → ADR → Story → Test chain (Foundation 79 %, Presentation 75 %, Core 55 %, Feature 11 %). Note TR-inv-002/TR-inv-004: the ❌ below is correct for the ADR column, but their single-machine halves are implemented and tested (core-inventory-carry) — only the ADR-0010 authority-rail halves remain. Same session: the review's HIGH + MEDIUM amendment sets were applied to ADR-0001/0003/0004/0005/0006/0013/0015 (no coverage effect — none adds or removes a requirement).

Legend: ✅ covered · ⚠️ partial (the model half is decided; the named remainder is another ADR's) · ❌ gap (no ADR). TR-IDs are stable — see tr-registry.yaml.

Full Matrix

Requirement ID System Requirement ADR Coverage Status
TR-tide-001TideDockedLands(seed, t, config) pure function in an engine-free assemblyADR-0001, ADR-0003✅
TR-tide-002Tidelong UTC seconds, StableHash64, FloorDiv/FloorMod; System.Random/GetHashCode/Mathf/float bannedADR-0001✅
TR-tide-003Tidehost-authoritative t replicated; client evaluation presentation-onlyADR-0001 (roles)⚠️ wire → ADR-0008
TR-tide-004Tidemonotonic lastKnownGoodT, persistedADR-0001, ADR-0004✅
TR-tide-005TideNextBoundary schedule-one-wake-up, no polling, ±5 sADR-0001✅ (conflict C1 — caller to be single)
TR-tide-006Tidedock/undock edge events + PreloadLeadTime noticeADR-0001, ADR-0005✅
TR-tide-007Tidederived-only API; raw t/φ/W never exposedADR-0001✅
TR-tide-008Tideamber/violet intensities (double); violet held through EvictionGraceADR-0001, ADR-0013 §5 (driver; neutral on LandTornDown; V5)✅
TR-tide-009TideTideConfig data-driven, validated, versioned; epoch on N changeADR-0001, ADR-0006✅
TR-tide-010Tide≤ 50 µs / 0 alloc hard gates (TD ruling); ≤ 0.1 ms advisoryADR-0001✅ (GDD header still says advisory — sync)
TR-tide-011Tidesigned long cycle/docking/round indices — negatives legitimateADR-0001✅
TR-tide-012Tideculture/thread-independent bit-identical schedule mathADR-0001✅
TR-tide-013Tideclient extrapolated t ≤ host t + one replication interval—⚠️ → ADR-0008
TR-net-001NetcodeNGO 2.x host-and-play; no dedicated server / migration / rollbacktechnical-preferences; every ADR⚠️ → ADR-0008
TR-net-002Netcodetwo authority railsADR-0002 (host rail)⚠️ owner rail → ADR-0009
TR-net-003Netcodelate-join full snapshot—❌ → ADR-0008
TR-net-004Netcodedisconnect retains HP/Downed/timer; rejoin = late joinADR-0015 (PlayerKey rows), ADR-0004 §6⚠️ → ADR-0008
TR-net-005NetcodeSteam transport (package TBD)—❌ → ADR-0008
TR-net-006Netcodeone ordered arrival channel; tiebreak lowest OwnerClientIdADR-0002✅
TR-net-007Netcodeevery host-rail commit a non-yielding critical sectionADR-0002, ADR-0003✅
TR-net-008Netcodedrain phase pinned vs owner movement writesADR-0002✅ (stage measured → ADR-0008)
TR-net-009Netcodefired commits never un-happen on disconnect; un-fired intents are no-opsADR-0002 §9✅
TR-cam-001Cameraorthographic 64 px/u at 1080p, integer multiples; PPU 32, pointADR-0003 (unit/PPU pin), ADR-0013 (fragment-stage tint changes no sampling/geometry)✅
TR-cam-002Camerasmoothed follow + aim bias; never detaches; hard cuts; no shake—❌ deferred to implementation (architecture ruling)
TR-save-001Saveone host-owned file; write-temp-then-swap; rolling backupsADR-0004✅
TR-save-002Savepersisted tables incl. both instanceId counters, TideState, equipped instancesADR-0004✅
TR-save-003Saveper-drain durability within flushDeadlineMs; loss unit = drains since lastDurableDrainADR-0004✅
TR-save-004SavesaveFormatVersion/configVersion gate; never migrate silentlyADR-0004✅
TR-save-005Savefixed reconcile pipeline; owners' predicates; only HarvestDiff droppableADR-0004, ADR-0003✅
TR-save-006Saveload: full HP, no Downed, position per tide EC1; no merge/import pathADR-0004, ADR-0003✅
TR-save-007Saveno file I/O on the host main thread during playADR-0004✅
TR-save-008Savelate flush = loud log, never a gameplay effectADR-0004✅
TR-save-009Saveloading raises no gameplay eventsADR-0004✅
TR-move-001MovementInput System; one action map; decoupled persistent aimADR-0007✅
TR-move-002Movementowner-authoritative predicted locomotion 6 u/s, instant accel—❌ → ADR-0009
TR-move-003Movementcollision blocks never damages; no player/enemy body collision—❌ → ADR-0011
TR-move-004Movementremotes interpolated never extrapolated—❌ → ADR-0009
TR-move-005Movementclosed teleport-snap list; EC21 correction as interpolated writeADR-0015 (Snap), ADR-0005 (deposit events)⚠️ write mode → ADR-0009
TR-move-006Movementschema-negative: no MoveSpeedModifier/stamina/encumbranceADR-0003✅
TR-inv-001InventoryItemStack + CanAdd/Add/Remove/Count; tagged stacks never mergeADR-0003 (shape)⚠️ ops → ADR-0010
TR-inv-002InventoryCarryInventory owner-auth; SharedStorage host-auth instances—❌ → ADR-0010
TR-inv-003Inventorytransfers atomic host transactions in arrival orderADR-0002 (model)⚠️ IInventoryTx → ADR-0010
TR-inv-004Inventoryno world-item entities; 2 equipment slots—❌ → ADR-0010
TR-inv-005Inventorystack-list serialization (CARRY per player, STORAGE per container)ADR-0004⚠️ owner impl → ADR-0010
TR-inv-006InventorytransferBatchWindow host-transaction batching knob—⚠️ → ADR-0010
TR-inv-007InventoryCARRY replication representation (undefined in the quick-spec)—❌ → ADR-0010
TR-combat-001Combatplayer state machine + Hurt overlayADR-0015✅
TR-combat-002Combatunified strike intent at windup startADR-0015✅ (encoding → ADR-0008)
TR-combat-003Combathost resolves at host-stamped instant vs current positionsADR-0015✅
TR-combat-004Combatpredicted vs host-confirmed feedback splitADR-0015 §6⚠️ presenters deferred
TR-combat-005CombatF1–F5 pure, AwayFromZero, EditModeADR-0003, ADR-0015✅
TR-combat-006CombatIEnemyCombat.EnterTelegraph; telegraph ≥ 400 ms; stagger; knockback; interruptADR-0015✅
TR-combat-007Combattelegraph phase replicated stateADR-0015 (named)⚠️ representation → ADR-0008
TR-combat-008Combatdash i-frames owner-auth; host wins if not receivedADR-0015✅
TR-combat-009CombatDowned/revive/bleed-out/Dead → home; keep-everythingADR-0015✅
TR-combat-010Combatsoft-close first on the host tickADR-0002✅
TR-combat-011CombatSwingLanded/DamageAbsorbed host-confirmed onlyADR-0003, ADR-0015✅
TR-combat-012Combatload validation (telegraph, phase sum, DR, bands, unarmed)ADR-0006✅
TR-combat-013CombatHUD data: own/party HP, Downed indicator, damage numbersADR-0015 (IPlayerCombatView), ADR-0014 (HUD panel + world-space flyouts)✅
TR-combat-014Combatsame-tick mutual kill: enemy damage first, both applyADR-0002 (1b), ADR-0015✅
TR-combat-015Combatcombat state never persistedADR-0004 §6✅
TR-ldu-001LDUpreload / activate at φ / teardown at grace expiryADR-0005✅
TR-ldu-002LDUlayout() pure, byte-identicalADR-0003, ADR-0005✅
TR-ldu-003LDUKnownLandTemplates append-only, seeded, permanentADR-0004, ADR-0005✅
TR-ldu-004LDUsole-source warning; depositPoint + socketNoBuildRadius per socketADR-0005, ADR-0006✅
TR-ldu-005LDUenemy spawn contractADR-0005 (call)⚠️ → ADR-0012
TR-ldu-006LDUtraversalProfile; stripTimeEstimate CI readoutADR-0006✅
TR-ldu-007LDUmemory: ≤ 2 GB; one atlas per template; 64 MB budget owned by LandLifecycleADR-0005✅
TR-ldu-008LDUAppend at first φ only, never at preloadADR-0005✅
TR-harv-001Harvestingnode swingsRemaining host-auth, replicatedADR-0005 (LandNet list home)⚠️ → ADR-0010
TR-harv-002Harvestingthree-gate resolution in one critical sectionADR-0002✅
TR-harv-003HarvestingHarvestDiff sparse, synchronous writeADR-0004 (order/predicate)⚠️ key schema → ADR-0010
TR-harv-004Harvestingreferent chosen at windup start; own phase constantsADR-0003, ADR-0015✅
TR-harv-005Harvestinginteger deterministic yield; teardown after last-tick resolutionADR-0002, ADR-0003✅
TR-harv-006Harvestingload validationADR-0006✅
TR-harv-007Harvestinghost proximity sanity check; confirmed crack/flyoutADR-0002, ADR-0015⚠️ bound → ADR-0008
TR-harv-008HarvestingharvestWindup + harvestActive ≥ 0.18 load ruleADR-0006 stage 3✅
TR-craft-001CraftingRecipeDef + 11-row validationADR-0006✅
TR-craft-002CraftingKnownRecipes union reconcileADR-0004✅
TR-craft-003Craftingcraft legality + commit critical sectionADR-0002 (model)⚠️ command unowned — crafting runtime ADR
TR-craft-004CraftingInstanceMetadata table; orphan/mystery reconcileADR-0004, ADR-0003 (IGearHooks)⚠️ owner impl unowned
TR-craft-005Craftinghook values per tier + override; ceilings validatedADR-0006✅
TR-craft-006Craftingdurability drain from events; instant repairADR-0003, ADR-0015 (events)⚠️ drain/repair impl — no Required-ADR row
TR-craft-007Craftingera gate reads KnownLandTemplates; ItemDef.SourceTemplatesADR-0006, ADR-0005✅
TR-craft-008Craftingcraft beat predicted; host commit; no occupancy lock—❌ → ADR-0008 / crafting runtime ADR
TR-craft-009Craftingschema-negatives; instant swap equipADR-0003✅
TR-craft-010CraftingstationRange one knob, two semantics (Craft reach / BB cost draw)ADR-0006 stage 6✅
TR-bb-001Base BuildingStructureDef + 12-row validationADR-0006✅
TR-bb-002Base BuildingStructureInstance registry; replicationADR-0003 (shape)⚠️ → ADR-0011
TR-bb-003Base Buildingclient-local build mode; pure snap; no-alloc F1ADR-0003✅
TR-bb-004Base BuildingplacementLegality 8 conjuncts, pure; one critical sectionADR-0002, ADR-0003✅
TR-bb-005Base BuildingdemolishLegality; refund to CARRY; relic reconcileADR-0004⚠️ command → ADR-0011
TR-bb-006Base Buildingtwo station predicates; storage placement spawns SharedStorageADR-0003⚠️ SharedStorage → ADR-0010
TR-bb-007Base Buildingwall colliders; EC21 owner-rail correctionADR-0003 (FindCorrectionCell)⚠️ → ADR-0011 / ADR-0009
TR-bb-008Base BuildingCI gates live-recomputedADR-0006 stage 10✅
TR-bb-009Base Buildingghost outline + grid overlay < 100 draw callsADR-0013 §8 (ghost 0 + grid 1 = +1; V4 marginal delta)✅
TR-bb-010Base BuildingEC21 four-neighbour ring-check algorithm pinnedADR-0003✅
TR-bb-011Base Buildinghost-position read semantics (exact host / one-RTT remote)ADR-0003 (IHostPositions)✅
TR-ai-001Enemy AIhost-simulated flat state machines; no client AIADR-0015 (step 3)⚠️ → ADR-0012
TR-ai-002Enemy AIseparation steering; aggro/leash/de-aggro heal—❌ → ADR-0012
TR-ai-003Enemy AImaxUninterruptibleTelegraphsPerTarget = 1ADR-0006, ADR-0015✅
TR-ai-004Enemy AIcomposition pure of (template, variationSeed); ephemeralADR-0003 (home)⚠️ → ADR-0012
TR-ai-005Enemy AIdensity monotonic load-check; only EnterTelegraphADR-0006, ADR-0015✅
TR-ui-001UI/HUDclosed screen-space HUD list; UI Toolkit (architecture ruling)ADR-0014 §1 (UI Toolkit screens + sprite world-space)✅
TR-ui-002UI/HUDco-op affordancesADR-0014 (edge indicators, who-took-what)⚠️ ping → ADR-0007 Ping binding; tags → ADR-0010 payload
TR-ui-003UI/HUDreason-string precedence / stability / hysteresisADR-0014 §6 (ReasonSelector.Step pure, in Rules)✅
TR-ui-004UI/HUDaggregation ban; gamepad nav + focus; contrast; no animation-gated inputADR-0007 (rebind, capture), ADR-0014 (schema-negative aggregation test, focus, USS gate)✅
TR-tint-001Tide-Tintone Shader Graph sprite shader; _TideTint/_TideAmount globals; never MPBsADR-0013 §1 (Scope = Global; V1 + absence editor test)✅
TR-tint-002Tide-TintDriftLayer taxonomy exclusionsADR-0013 §2 (exclusion by material, not runtime branch; V3)✅
TR-tint-003Tide-Tintconsumes tide floats per frame; future post-process Render-Graph-nativeADR-0013 §5–§6 (TideTintDriver; no custom pass at MVP)✅
TR-tint-004Art/Netcodeflipbook animation via synced frameIndex—❌ → ADR-0008 / ADR-0012

Known Gaps

ID Suggested ADR
TR-net-003, TR-net-005, TR-tint-004ADR-0008 Netcode wire (playtest-gated)
TR-move-002, TR-move-004ADR-0009 Player transform authority
TR-inv-002, TR-inv-004, TR-inv-007ADR-0010 Inventory replication
TR-craft-008ADR-0008 + crafting runtime ADR (proposed Required-ADR row 16)
TR-move-003ADR-0011 Structure registry + colliders
TR-ai-002ADR-0012 Enemy simulation
TR-bb-009, TR-tint-001, TR-tint-002, TR-tint-003ADR-0013 Tide-tint render pipeline
TR-ui-001, TR-ui-002, TR-ui-003ADR-0014 UI stack
TR-cam-002deferred to implementation (architecture ruling)

Superseded Requirements

ID What changed
TR-save-003Quick-spec Rule 3 restated by ADR-0004 (per-drain durability); registry text updated 2026-08-28, ID retained
TR-ui-001"UI Toolkit" attributed to architecture.md, not the quick-spec; text updated
TR-net-006/007/008Source attributed to TD reviews / ADR-0002 rather than the netcode quick-spec