| Player Client | Owns client protocol, request identity, retry, and resume behavior. In this design it participates in: Route all commands for a match to one session actor/serialized mailbox. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents the external caller from also owning the contract and failure behavior of Lobby / Matchmaking. | Keep this behavior inside an adjacent service. Prefer that simpler option until independent scale, ownership, policy, or failure isolation is measurable. Here that simpler choice would couple “Duplicate move after reconnect” to the external caller. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Player Client boundary before extracting or scaling it. |
| Lobby / Matchmaking | Owns one bounded domain decision, transition, or operational capability. In this design it participates in: Check player, turn, sequence, clock, and dedupe client_move_id. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Player Client from also owning the contract and failure behavior of Game Gateway. | Keep this behavior inside an adjacent service. Prefer that simpler option until independent scale, ownership, policy, or failure isolation is measurable. Here that simpler choice would couple “Clock expires during valid move” to Player Client. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Lobby / Matchmaking boundary before extracting or scaling it. |
| Game Gateway | Owns authentication, validation, quotas, deadlines, and routing. In this design it participates in: Pure rules engine validates move and returns deterministic next state plus events. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Lobby / Matchmaking from also owning the contract and failure behavior of Session Actor. | Put protocol, authentication, quotas, and business transitions in one process. Acceptable at low scale, but it couples external traffic risk to domain releases. Here that simpler choice would couple “Session owner crashes after append” to Lobby / Matchmaking. | Costs another hop, policy distribution, and a high-blast-radius fleet. Introduce it when many clients or services need one protocol and protection boundary. Measure the latency, saturation, lag, or mismatch at the Game Gateway boundary before extracting or scaling it. |
| Session Actor | Owns one bounded domain decision, transition, or operational capability. In this design it participates in: Append move/state hash durably, update snapshot, acknowledge player, and fan out. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Game Gateway from also owning the contract and failure behavior of Turn Coordinator. | Keep this behavior inside an adjacent service. Prefer that simpler option until independent scale, ownership, policy, or failure isolation is measurable. Here that simpler choice would couple “Random deck differs across replicas” to Game Gateway. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Session Actor boundary before extracting or scaling it. |
| Turn Coordinator | Owns one bounded domain decision, transition, or operational capability. In this design it participates in: Reconnect loads snapshot plus moves; anti-cheat verifies hidden information and timing server-side. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Session Actor from also owning the contract and failure behavior of Rules Engine. | Keep this behavior inside an adjacent service. Prefer that simpler option until independent scale, ownership, policy, or failure isolation is measurable. Here that simpler choice would couple “Spectator receives hidden state” to Session Actor. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Turn Coordinator boundary before extracting or scaling it. |
| Rules Engine | Owns one bounded domain decision, transition, or operational capability. In this design it participates in: Route all commands for a match to one session actor/serialized mailbox. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Turn Coordinator from also owning the contract and failure behavior of Legal Move Generator. | Keep this behavior inside an adjacent service. Prefer that simpler option until independent scale, ownership, policy, or failure isolation is measurable. Here that simpler choice would couple “Duplicate move after reconnect” to Turn Coordinator. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Rules Engine boundary before extracting or scaling it. |
| Legal Move Generator | Owns one bounded domain decision, transition, or operational capability. In this design it participates in: Check player, turn, sequence, clock, and dedupe client_move_id. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Rules Engine from also owning the contract and failure behavior of Random Seed / Deck. | Keep this behavior inside an adjacent service. Prefer that simpler option until independent scale, ownership, policy, or failure isolation is measurable. Here that simpler choice would couple “Clock expires during valid move” to Rules Engine. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Legal Move Generator boundary before extracting or scaling it. |
| Random Seed / Deck | Owns one bounded domain decision, transition, or operational capability. In this design it participates in: Pure rules engine validates move and returns deterministic next state plus events. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Legal Move Generator from also owning the contract and failure behavior of Authoritative State. | Keep this behavior inside an adjacent service. Prefer that simpler option until independent scale, ownership, policy, or failure isolation is measurable. Here that simpler choice would couple “Session owner crashes after append” to Legal Move Generator. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Random Seed / Deck boundary before extracting or scaling it. |
| Authoritative State | Owns one bounded domain decision, transition, or operational capability. In this design it participates in: Append move/state hash durably, update snapshot, acknowledge player, and fan out. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Random Seed / Deck from also owning the contract and failure behavior of Immutable Move Log. | Embed policy in every caller. Rules then drift by deployment version and emergency changes require fleet-wide redeployment. Here that simpler choice would couple “Random deck differs across replicas” to Random Seed / Deck. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Authoritative State boundary before extracting or scaling it. |
| Immutable Move Log | Preserves durable ordering, replay, and consumer checkpoints. In this design it participates in: Reconnect loads snapshot plus moves; anti-cheat verifies hidden information and timing server-side. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Authoritative State from also owning the contract and failure behavior of Snapshot Store. | Call every downstream consumer synchronously. That couples user latency and availability to analytics, notification, indexing, and audit dependencies. Here that simpler choice would couple “Spectator receives hidden state” to Authoritative State. | Costs eventual consistency, schema evolution, replay tooling, idempotent consumers, and lag operations. Earn it when bursts or downstream failure must not block acknowledgment. Measure the latency, saturation, lag, or mismatch at the Immutable Move Log boundary before extracting or scaling it. |
| Snapshot Store | Owns authoritative versioned state or immutable evidence. In this design it participates in: Route all commands for a match to one session actor/serialized mailbox. | Defines the source of truth and commit boundary. It prevents Immutable Move Log from also owning the contract and failure behavior of Clock Service. | Let each service persist its own interpretation. That removes one clear commit boundary and makes retries, support, and reconciliation ambiguous. Here that simpler choice would couple “Duplicate move after reconnect” to Immutable Move Log. | Costs schema migration, replication, backup, and shard ownership. Split storage only when access patterns, retention, or compliance boundaries materially differ. Measure the latency, saturation, lag, or mismatch at the Snapshot Store boundary before extracting or scaling it. |
| Clock Service | Owns one bounded domain decision, transition, or operational capability. In this design it participates in: Check player, turn, sequence, clock, and dedupe client_move_id. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Snapshot Store from also owning the contract and failure behavior of Spectator Fanout. | Keep this behavior inside an adjacent service. Prefer that simpler option until independent scale, ownership, policy, or failure isolation is measurable. Here that simpler choice would couple “Clock expires during valid move” to Snapshot Store. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Clock Service boundary before extracting or scaling it. |
| Spectator Fanout | Executes idempotent asynchronous work under lease and retry policy. In this design it participates in: Pure rules engine validates move and returns deterministic next state plus events. | Separates a distinct scale, ownership, policy, or failure boundary. It prevents Clock Service from also owning the contract and failure behavior of Anti-Cheat / Audit. | Perform the work before acknowledging the caller. This gives simpler consistency but unbounded tail latency and fragile retries. Here that simpler choice would couple “Session owner crashes after append” to Clock Service. | Costs leases, checkpoints, retries, DLQs, and lag operations. Separate once execution time or burstiness no longer fits the request deadline. Measure the latency, saturation, lag, or mismatch at the Spectator Fanout boundary before extracting or scaling it. |
| Anti-Cheat / Audit | Owns one bounded domain decision, transition, or operational capability. In this design it participates in: Append move/state hash durably, update snapshot, acknowledge player, and fan out. | Proves correctness and supports controlled recovery. It prevents Spectator Fanout from also owning the contract and failure behavior of operators and repair tooling. | Infer correctness from request logs. Logs do not prove durable business state, detect silent drift, or safely repair ambiguous outcomes. Here that simpler choice would couple “Random deck differs across replicas” to Spectator Fanout. | Costs an interface, deployment, telemetry, ownership, and failure mode. Keep it in-process first; extract when independent scale or reliability pays for the boundary. Measure the latency, saturation, lag, or mismatch at the Anti-Cheat / Audit boundary before extracting or scaling it. |