Outcome
Choose a deterministic server architecture that makes gameplay correctness testable and prevents Go concurrency from turning world state into shared mutable state.
Decisions to record
- One application lifecycle owner composes transport, simulation, persistence, content, metrics, and operator services.
- Each mutable world region/map partition has exactly one simulation owner. Network, storage, and background workers submit typed commands; they never mutate entities directly.
- No goroutine-per-entity or goroutine-per-timer design. Concurrency is bounded and visible in configuration/metrics.
- Stable generational entity handles prevent stale-reference reuse.
- Game time, monotonic deadlines, wall time, and seeded random streams are distinct injected types.
- Gameplay mutations use explicit preflight/commit/cancel transactions and deterministic event ordering.
- Package dependencies point inward toward domain contracts; adapters for QUIC, SQLite, telemetry, and compiled content remain replaceable.
- Failures have an owner: malformed client input, invalid content, persistence conflict, and internal invariant violation do not share one recovery path.
- Expensive work has explicit per-tick and queue budgets with backpressure.
Deliverables
- Architecture and concurrency ADRs.
- Package/dependency diagram and forbidden-edge test.
- Skeleton interfaces for clocks, RNG, command queues, storage transactions, content catalogs, and event publication.
- Shutdown sequence covering admission stop, connection drain, simulation quiescence, persistence checkpoint, and telemetry flush.
- A benchmark harness for empty-loop/tick overhead and bounded queue behavior.
Acceptance criteria
- Deterministic tests replay the same command sequence to the same state digest.
- The race detector passes a test with concurrent connections/storage while simulation state remains single-owned.
- Dependency tooling rejects transport or SQLite types inside core gameplay packages.
- Queue saturation, cancellation, shutdown, and panic containment have tested behavior.
- Later gameplay issues reference these common mutation/event contracts instead of creating private schedulers.
Parallel work
Protocol schemas, content contracts, renderer work, and behavior inventory are independent. Simulation implementation waits only for the core ADRs, not for gameplay migration.
Outcome
Choose a deterministic server architecture that makes gameplay correctness testable and prevents Go concurrency from turning world state into shared mutable state.
Decisions to record
Deliverables
Acceptance criteria
Parallel work
Protocol schemas, content contracts, renderer work, and behavior inventory are independent. Simulation implementation waits only for the core ADRs, not for gameplay migration.