[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill-rivet-multiplayer-game":3,"mdc--xegpc7-key":38,"related-repo-rivet-multiplayer-game":6667,"related-org-rivet-multiplayer-game":6784},{"slug":4,"name":4,"fn":5,"description":6,"org":7,"tags":12,"stars":27,"repoUrl":28,"updatedAt":29,"license":30,"forks":31,"topics":32,"repo":33,"sourceUrl":36,"mdContent":37},"multiplayer-game","build multiplayer games with Rivet","Pragmatic patterns for building multiplayer games: matchmaking, tick loops, realtime state, interest management, and validation.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},"rivet","Rivet","https:\u002F\u002Fpexgzepcugksgbtrxkhf.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Forg-logos\u002Frivet.png","rivet-dev",[13,15,18,21,24],{"name":9,"slug":8,"type":14},"tag",{"name":16,"slug":17,"type":14},"Architecture","architecture",{"name":19,"slug":20,"type":14},"Game Development","game-development",{"name":22,"slug":23,"type":14},"Engineering","engineering",{"name":25,"slug":26,"type":14},"Real-time","real-time",17,"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Fskills","2026-07-21T05:37:44.627991",null,7,[],{"repoUrl":28,"stars":27,"forks":31,"topics":34,"description":35},[],"Generated skill files for Rivet AI integrations","https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Fskills\u002Ftree\u002FHEAD\u002Fmultiplayer-game","---\nname: \"multiplayer-game\"\ndescription: \"Pragmatic patterns for building multiplayer games: matchmaking, tick loops, realtime state, interest management, and validation.\"\n---\n\n# Multiplayer Game\n\n**IMPORTANT: Before doing anything, you MUST read `BASE_SKILL.md` in this skill's directory. It contains essential guidance on debugging, error handling, state management, deployment, and project setup. Those rules and patterns apply to all RivetKit work. Everything below assumes you have already read and understood it.**\n\n## Working Examples\n\nIf you need a reference implementation, read the raw working example code in these templates:\n\n- [multiplayer-game-patterns](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns)\n\n\nPatterns for building multiplayer games with RivetKit, intended as a practical checklist you can adapt per genre.\n\n## Starter Code\n\nStart with one of the working examples on [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002F) and adapt it to your game. Do not start from scratch for matchmaking and lifecycle flows.\n\n| Game Classification | Starter Code | Common Examples |\n| --- | --- | --- |\n| Battle Royale | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fbattle-royale\u002F) | Fortnite, Apex Legends, PUBG, Warzone |\n| Arena | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Farena\u002F) | Call of Duty TDM\u002FFFA, Halo Slayer, Counter-Strike casual, VALORANT unrated, Overwatch Quick Play, Rocket League |\n| IO Style | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fio-style\u002F) | Agar.io, Slither.io, surviv.io |\n| Open World | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fopen-world\u002F) | Minecraft survival servers, Rust-like worlds, MMO zone\u002Fchunk worlds |\n| Party | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fparty\u002F) | Fall Guys private lobbies, custom game rooms, social party sessions |\n| Physics 2D | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fphysics-2d\u002F) | Top-down physics brawlers, 2D arena games, platform fighters |\n| Physics 3D | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fphysics-3d\u002F) | Physics sandbox sessions, 3D arena games, movement playgrounds |\n| Ranked | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Franked\u002F) | Chess ladders, competitive card games, duel arena ranked queues |\n| Turn-Based | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fturn-based\u002F) | Chess correspondence, Words With Friends, async board games |\n| Idle | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fidle\u002F) | Cookie Clicker, Idle Miner Tycoon, Adventure Capitalist |\n\n## Server Simulation\n\n### Game Loop And Tick Rates\n\n| Pattern | Use When | Implementation Guidance |\n| --- | --- | --- |\n| Fixed realtime loop | Battle Royale, Arena, IO Style, Open World, Ranked | Run in `run` with `sleep(tickMs)` and exit on `c.aborted`. |\n| Action-driven updates | Party, Turn-Based | Mutate and broadcast only on actions\u002Fevents rather than scheduled ticks. |\n| Coarse offline progression | Any mode with idle progression | Use `c.schedule.after(...)` with coarse windows (for example 5 to 15 minutes) and apply catch-up from elapsed wall clock time. |\n\n### Physics\n\nStart with custom kinematic logic for simple games. Switch to a full physics engine when you need joints, stacked bodies, high collision density, or complex shapes (rotated polygons, capsules, convex hulls, triangle meshes).\n\nPick one engine per simulation. Keep frontend-only libs out of backend simulation paths and treat server state as authoritative.\n\n| Dimension | Primary Engine | Fallback Engines | Example Code |\n| --- | --- | --- | --- |\n| 2D | `@dimforge\u002Frapier2d` | `planck-js`, `matter-js` | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fphysics-2d\u002F) |\n| 3D | `@dimforge\u002Frapier3d` | `cannon-es`, `ammo.js` | [GitHub](https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fphysics-3d\u002F) |\n\n### Spatial Indexing\n\nFor non-physics spatial queries, use a dedicated index instead of naive `O(n^2)` checks:\n\n| Index Type | Recommendation |\n| --- | --- |\n| AABB index | For AOI, visibility, and non-collider entities, use `rbush` for dynamic sets or `flatbush` for static-ish sets. |\n| Point index | For nearest-neighbor or within-radius queries, use `d3-quadtree`. |\n\n## Networking & State Sync\n\n### Netcode\n\n| Model | When To Use | Implementation |\n| --- | --- | --- |\n| Hybrid (client movement, server combat) | Shooters, action sports, ranked duels | Client owns movement and sends capped-rate position updates. Server validates for anti-cheat. Combat (projectiles, hits, damage) is fully server-authoritative. |\n| Server-authoritative with interpolation | IO Style, persistent worlds | Client sends input commands. Server simulates on fixed ticks and publishes authoritative snapshots. Client interpolates between snapshots. |\n| Server-authoritative (basic logic) | Turn-based, event-driven | Server validates and applies discrete actions (turns, phase transitions, votes). Client displays confirmed state. |\n\n### Realtime Data Model\n\n- **Snapshots and diffs**: Publish state as events. Send a full snapshot on join\u002Fresync, then per-tick diffs for regular updates.\n- **Batch per tick**: Keep events small and typed. Batch high-frequency updates per tick.\n- **Avoid UI framework state for game updates**: Use `requestAnimationFrame` or a Canvas\u002FThree.js loop for simulation, not React state. Reserve UI framework state for menus, HUD, and forms.\n- **Broadcast vs per-connection**: Use `c.broadcast(...)` for shared updates and `conn.send(...)` for private\u002Fper-player data.\n\n### Shared Simulation Logic\n\nShared simulation logic runs on both the client and the server. For example, an `applyInput(state, input, dt)` function that integrates velocity and clamps to world bounds can run on the client for prediction and on the server for validation.\n\n- **Hybrid modes**: Client runs shared movement as primary authority, server runs it for anti-cheat validation.\n- **Server-authoritative modes**: Client uses shared logic for interpolation and prediction only.\n- **Keep it pure**: Movement integration, input transforms, collision helpers, and constants only.\n- **Put shared code in `src\u002Fshared\u002F`**: Keep deterministic helpers in `src\u002Fshared\u002Fsim\u002F*` with no side effects.\n\n### Interest Management\n\nControl what each client receives to reduce bandwidth and prevent information leaks.\n\n#### Per-Player Replication Filters\n\n- **Filter by relevance**: Send each client only state relevant to that player (proximity, line-of-sight, team, or game phase).\n- **Shooters and action games**: Limit replication by proximity and optional field-of-view checks.\n- **Server-side only**: Clients should never receive data they should not see.\n\n#### Sharded Worlds\n\n- **Partition large worlds**: Use chunk actors keyed by `worldId:chunkX:chunkY`.\n- **Subscribe to nearby chunks**: Clients connect only to nearby partitions (for example a 3x3 chunk window).\n- **Use sparingly**: Only when the world is large and state-heavy (sandbox builders, MMOs), not as a default for small matches.\n\n## Backend Infrastructure\n\n### Persistence\n\n- **In-memory state**: Best for realtime game state that changes every tick (player positions, inputs, match phase, scores).\n- **SQLite (`rivetkit\u002Fdb`)**: Better for large or table-like state that needs queries, indexes, or long-term persistence (tiles, inventory, matchmaking pools). Serialize DB work through a queue since multiple actions can hit the same actor concurrently.\n\n### Matchmaking Patterns\n\nCommon building blocks used across the architecture patterns below.\n\n#### Actor Topology\n\n| Primitive | Use When | Typical Ownership |\n| --- | --- | --- |\n| `matchmaker[\"main\"]` + `match[matchId]` | Session-based multiplayer (battle royale, arena, ranked, party, turn-based) | Matchmaker owns discovery\u002Fassignment. Match owns lifecycle and gameplay state. |\n| `chunk[worldId,chunkX,chunkY]` | Large continuous worlds that need sharding | Each chunk owns local players, chunk state, and local simulation. |\n| `world[playerId]` | Per-player progression loops (idle\u002Fsolo world state) | Per-player resources, buildings, timers, and progression. |\n| `player[username]` | Canonical profile\u002Frating reused across matches | Durable player stats (for example rating and win\u002Floss). |\n| `leaderboard[\"main\"]` | Shared rankings across many matches\u002Fplayers | Global ordered score rows and top lists. |\n\n#### Queueing Strategy\n\n- Multiple players can hit the matchmaker at the same time, so actions like find\u002Fcreate, queue\u002Funqueue, and close need to be serialized through actor queues to avoid races.\n- Match-local actions (gameplay, scoring) do not need queueing unless they write back to the matchmaker.\n\n## Security And Anti-Cheat\n\nStart with this baseline, then harden further for competitive or high-risk environments.\n\n### Baseline Checklist\n\n- **Identity**: Use `c.conn.id` as the authoritative transport identity. Treat `playerId`\u002F`username` in params as untrusted input and bind through server-issued assignment\u002Fjoin tickets.\n- **Authorization**: Validate the caller is allowed to mutate the target entity (room membership, turn ownership, host-only actions).\n- **Input validation**: Clamp sizes\u002Flengths, validate enums, and validate usernames (length, allowed chars, avoid unbounded Unicode).\n- **Rate limiting**: Per-connection rate limits for spammy actions (chat, join\u002Fleave, fire, movement updates).\n- **State integrity**: Server recomputes derived state (scores, win conditions, placements). Never allow client-authoritative changes to inventory\u002Fcurrency\u002Fleaderboard totals.\n\n### Movement Validation\n\nFor any mode with client-authoritative movement (hybrid flows), clients may send position\u002Frotation updates for smoothness, but the server must:\n\n- Enforce max delta per update (speed cap) based on elapsed time.\n- Reject or clamp teleports.\n- Enforce world bounds (and basic collision if applicable).\n- Rate limit update frequency (for example 20Hz max).\n\n## Architecture Patterns\n\nEach game type below starts with a quick summary table, then details actors and lifecycle.\n\n### Battle Royale\n\n| Topic | Summary |\n| --- | --- |\n| Matchmaking | Immediate routing to the fullest non-started lobby (oldest tie-break); players wait in lobby until capacity, then the match starts. |\n| Netcode | Hybrid. Client owns movement, camera, and local prediction. Server owns zone state, projectiles, hit resolution, eliminations, loot, and final placement. |\n| Tick Rate | 10 ticks\u002Fsec (`100ms`) with a fixed loop for zone progression and lifecycle checks. |\n| Physics | Client owns movement with server anti-cheat validation; projectiles, hits, and damage are server-authoritative. Use `@dimforge\u002Frapier3d` for 3D or `@dimforge\u002Frapier2d` for top-down 2D. |\n\n**Actors**\n\n- **Key**: `matchmaker[\"main\"]`\n- **Responsibility**: Finds or creates lobbies, tracks pending reservations, and maintains occupancy.\n- **Actions**\n  - `findMatch`\n  - `pendingPlayerConnected`\n  - `updateMatch`\n  - `closeMatch`\n- **Queues**\n  - `findMatch`\n  - `pendingPlayerConnected`\n  - `updateMatch`\n  - `closeMatch`\n- **State**\n  - SQLite\n  - `matches`\n  - `pending_players`\n  - `player_count` includes connected and pending players\n\n- **Key**: `match[matchId]`\n- **Responsibility**: Runs lobby\u002Flive\u002Ffinished phases, owns player state, zone progression, and eliminations.\n- **Actions**\n  - `connect`\n  - Movement and combat actions\n- **Queues**\n  - None\n- **State**\n  - JSON\n  - `phase`\n  - `players`\n  - `zone`\n  - `eliminations`\n  - `snapshot data`\n\n**Lifecycle**\n\n```mermaid\nsequenceDiagram\n\tparticipant C as Client\n\tparticipant MM as matchmaker\n\tparticipant M as match\n\n\tC->>MM: findMatch()\n\talt no open lobby\n\t\tMM->>M: create(matchId)\n\tend\n\tMM-->>C: {matchId, playerId}\n\tC->>M: connect(playerId)\n\tM->>MM: pendingPlayerConnected(matchId, playerId)\n\tMM-->>M: accepted\n\tNote over M: lobby countdown -> live\n\tM-->>C: snapshot + shoot events\n\tM->>MM: closeMatch(matchId)\n```\n\n### Arena\n\n| Topic | Summary |\n| --- | --- |\n| Matchmaking | Mode-based fixed-capacity queues (`duo`, `squad`, `ffa`) that build only full matches and pre-assign teams (except FFA). |\n| Netcode | Hybrid. Client owns movement plus prediction and smoothing. Server owns team or FFA assignment, projectiles, hit resolution, phase transitions, and scoring. |\n| Tick Rate | 20 ticks\u002Fsec (`50ms`) with a tighter loop for live team and FFA snapshots. |\n| Physics | Medium to high intensity; client movement with server validation and server-authoritative combat\u002Fentities. |\n\n**Actors**\n\n- **Key**: `matchmaker[\"main\"]`\n- **Responsibility**: Runs mode queues, builds full matches, assigns teams, and publishes assignments.\n- **Actions**\n  - `queueForMatch`\n  - `unqueueForMatch`\n  - `matchCompleted`\n- **Queues**\n  - `queueForMatch`\n  - `unqueueForMatch`\n  - `matchCompleted`\n- **State**\n  - SQLite\n  - `player_pool`\n  - `matches`\n  - `assignments` keyed by connection and player\n\n- **Key**: `match[matchId]`\n- **Responsibility**: Runs match phases and in-match player\u002Fteam state for score and win conditions.\n- **Actions**\n  - `connect`\n  - Gameplay actions\n- **Queues**\n  - None\n- **State**\n  - JSON\n  - `phase`\n  - `players`\n  - `team assignments`\n  - `score and win state`\n\n**Lifecycle**\n\n```mermaid\nsequenceDiagram\n\tparticipant C as Client\n\tparticipant MM as matchmaker\n\tparticipant M as match\n\n\tC->>MM: queueForMatch(mode)\n\tNote over MM: enqueue in player_pool\n\tNote over MM: fill when capacity reached\n\tMM->>M: create(matchId, assignments)\n\tNote over MM: persist assignments\n\tMM-->>C: assignmentReady\n\tC->>M: connect(playerId)\n\tNote over M: waiting -> live when all players connect\n\tM->>MM: matchCompleted(matchId)\n```\n\n### IO Style\n\n| Topic | Summary |\n| --- | --- |\n| Matchmaking | Open-lobby routing to the fullest room below capacity; room counts are heartbeated and new lobbies are auto-created when needed. |\n| Netcode | Server-authoritative with interpolation. Client sends input intents and interpolates. Server owns movement, bounds, room membership, and canonical snapshots. |\n| Tick Rate | 10 ticks\u002Fsec (`100ms`) with lightweight periodic room snapshots. |\n| Physics | Low to medium intensity; server-authoritative kinematic movement, escalating to a physics engine only when collisions get complex. |\n\n**Actors**\n\n- **Key**: `matchmaker[\"main\"]`\n- **Responsibility**: Routes players into the fullest open lobby and tracks reservations and occupancy.\n- **Actions**\n  - `findLobby`\n  - `pendingPlayerConnected`\n  - `updateMatch`\n  - `closeMatch`\n- **Queues**\n  - `findLobby`\n  - `pendingPlayerConnected`\n  - `updateMatch`\n  - `closeMatch`\n- **State**\n  - SQLite\n  - `matches`\n  - `pending_players`\n  - Occupancy includes pending reservations\n\n- **Key**: `match[matchId]`\n- **Responsibility**: Runs per-match movement simulation and broadcasts snapshots.\n- **Actions**\n  - `connect`\n  - `setInput`\n- **Queues**\n  - None\n- **State**\n  - JSON\n  - `players`\n  - `inputs`\n  - `movement state`\n  - `snapshot cache`\n\n**Lifecycle**\n\n```mermaid\nsequenceDiagram\n\tparticipant C as Client\n\tparticipant MM as matchmaker\n\tparticipant M as match\n\n\tC->>MM: findLobby()\n\talt no open lobby\n\t\tMM->>M: create(matchId)\n\tend\n\tMM-->>C: {matchId, playerId}\n\tC->>M: connect(playerId)\n\tM->>MM: pendingPlayerConnected(matchId, playerId)\n\tMM-->>M: accepted\n\tNote over M: fixed tick simulation\n\tM-->>C: snapshot events\n\tM->>MM: closeMatch(matchId)\n```\n\n### Open World\n\n| Topic | Summary |\n| --- | --- |\n| Matchmaking | Client-driven chunk routing from world coordinates, with nearby chunk windows preloaded via adjacent chunk connections. |\n| Netcode | Hybrid for sandbox (client movement with validation) or server-authoritative for MMO-like flows. Server owns chunk routing, persistence, and canonical world state. |\n| Tick Rate | 10 ticks\u002Fsec per chunk actor (`100ms`), so load scales with active chunks. |\n| Physics | Medium to high at scale; chunk-local simulation can be server-authoritative (MMO-like) or client movement with server validation (sandbox-like). |\n\n**Actors**\n\n- **Key**: `chunk[worldId,chunkX,chunkY]`\n- **Responsibility**: Owns chunk-local players, blocks, movement tick, and chunk membership.\n- **Actions**\n  - `connect`\n  - `enterChunk`\n  - `addPlayer`\n  - `setInput`\n  - `leaveChunk`\n  - `removePlayer`\n- **Queues**\n  - None\n- **State**\n  - JSON\n  - `connections`\n  - `players`\n  - `blocks` scoped to one chunk key\n\n**Lifecycle**\n\n```mermaid\nsequenceDiagram\n\tparticipant C as Client\n\tparticipant CH as chunk\n\n\tNote over C: resolve chunk keys from world position\n\tloop each visible chunk\n\t\tC->>CH: connect(worldId, chunkX, chunkY, playerId)\n\t\tNote over CH: store connection metadata\n\tend\n\tC->>CH: enterChunk\u002FaddPlayer\n\tloop movement updates\n\t\tC->>CH: setInput(...)\n\t\tCH-->>C: snapshot\n\tend\n\tC->>CH: leaveChunk\u002FremovePlayer or disconnect\n\tNote over CH: remove membership and metadata\n```\n\n### Party\n\n| Topic | Summary |\n| --- | --- |\n| Matchmaking | Host-created private party flow using party codes and explicit joins. |\n| Netcode | Server-authoritative (basic logic). Server owns membership, host permissions, and phase transitions. |\n| Tick Rate | No continuous tick; updates are event-driven (`join`, `start`, `finish`). |\n| Physics | Low intensity for lobby-first flows; usually no dedicated physics or indexing unless you add realtime mini-games. |\n\n**Actors**\n\n- **Key**: `matchmaker[\"main\"]`\n- **Responsibility**: Handles party create\u002Fjoin flow, validates join tickets, and tracks party size.\n- **Actions**\n  - `createParty`\n  - `joinParty`\n  - `verifyJoin`\n  - `updatePartySize`\n  - `closeParty`\n- **Queues**\n  - `createParty`\n  - `joinParty`\n  - `verifyJoin`\n  - `updatePartySize`\n  - `closeParty`\n- **State**\n  - SQLite\n  - `parties`\n  - `join_tickets` for party lookup and join validation\n\n- **Key**: `match[matchId]`\n- **Responsibility**: Owns party members, host role, ready flags, and phase transitions.\n- **Actions**\n  - `connect`\n  - `startGame`\n  - `finishGame`\n- **Queues**\n  - None\n- **State**\n  - JSON\n  - `members`\n  - `host`\n  - `ready state`\n  - `phase`\n  - `party events`\n\n**Lifecycle**\n\n### Host Flow\n\n```mermaid\nsequenceDiagram\n\tparticipant H as Host Client\n\tparticipant MM as matchmaker\n\tparticipant M as match\n\n\tH->>MM: createParty()\n\tMM-->>H: {matchId, partyCode, playerId, joinToken}\n\tH->>M: connect(playerId, joinToken)\n\tM->>MM: verifyJoin(...)\n\tMM-->>M: allowed\n\tM->>MM: updatePartySize(playerCount)\n\tH->>M: startGame() \u002F finishGame()\n\tM->>MM: closeParty(matchId)\n```\n\n### Joiner Flow\n\n```mermaid\nsequenceDiagram\n\tparticipant J as Joiner Client\n\tparticipant MM as matchmaker\n\tparticipant M as match\n\n\tJ->>MM: joinParty(partyCode)\n\tMM-->>J: {matchId, playerId, joinToken}\n\tJ->>M: connect(playerId, joinToken)\n\tM->>MM: verifyJoin(...)\n\tMM-->>M: allowed \u002F denied\n\tM->>MM: updatePartySize(playerCount)\n```\n\n### Ranked\n\n| Topic | Summary |\n| --- | --- |\n| Matchmaking | ELO-based queue pairing with a widening search window as wait time increases. |\n| Netcode | Hybrid. Client owns movement with local prediction and interpolation. Server owns projectiles, hit resolution, match results, and rating updates. |\n| Tick Rate | 20 ticks\u002Fsec (`50ms`) with fixed live ticks for deterministic pacing and broadcast cadence. |\n| Physics | Medium to high intensity; client movement with server validation and server-authoritative combat\u002Fhit resolution. |\n\n**Actors**\n\n- **Key**: `matchmaker[\"main\"]`\n- **Responsibility**: Runs rating-based queueing, pairing, assignment persistence, and completion fanout.\n- **Actions**\n  - `queueForMatch`\n  - `unqueueForMatch`\n  - `matchCompleted`\n- **Queues**\n  - `queueForMatch`\n  - `unqueueForMatch`\n  - `matchCompleted`\n- **State**\n  - SQLite\n  - `player_pool`\n  - `matches`\n  - `assignments` with rating window and connection scoping\n\n- **Key**: `match[matchId]`\n- **Responsibility**: Runs ranked match phase, score, and winner reporting.\n- **Actions**\n  - `connect`\n  - Gameplay actions\n- **Queues**\n  - None\n- **State**\n  - JSON\n  - `phase`\n  - `players`\n  - `score`\n  - `winner`\n  - `completion payload`\n\n- **Key**: `player[username]`\n- **Responsibility**: Stores canonical player MMR and win\u002Floss profile.\n- **Actions**\n  - `initialize`\n  - `getRating`\n  - `applyMatchResult`\n- **Queues**\n  - None\n- **State**\n  - JSON\n  - `rating`\n  - `wins`\n  - `losses`\n  - `match counters`\n\n- **Key**: `leaderboard[\"main\"]`\n- **Responsibility**: Stores and serves top-ranked players.\n- **Actions**\n  - `updatePlayer`\n- **Queues**\n  - None\n- **State**\n  - SQLite\n  - Leaderboard score rows\n  - Top-list ordering\n\n**Lifecycle**\n\n```mermaid\nsequenceDiagram\n\tparticipant C as Client\n\tparticipant MM as matchmaker\n\tparticipant P as player\n\tparticipant M as match\n\tparticipant LB as leaderboard\n\n\tC->>MM: queueForMatch(username)\n\tMM->>P: initialize\u002FgetRating\n\tP-->>MM: rating\n\tNote over MM: store queue row + retry pairing\n\tMM->>M: create(matchId, assigned players)\n\tMM-->>C: assignmentReady\n\tC->>M: connect(username)\n\tM->>MM: matchCompleted(...)\n\tMM->>P: applyMatchResult(...)\n\tMM->>LB: updatePlayer(...)\n\tNote over MM: remove matches + assignments rows\n```\n\n### Turn-Based\n\n| Topic | Summary |\n| --- | --- |\n| Matchmaking | Async private-invite and public-queue pairing in the same pattern. |\n| Netcode | Server-authoritative (basic logic). Client can draft moves before submit. Server owns turn ownership, committed move log, turn order, and completion state. |\n| Tick Rate | No continuous tick; move submission and turn transitions drive updates. |\n| Physics | Very low intensity; no realtime physics loop, just discrete rules validation. Indexing is optional and mostly for board or query convenience at scale. |\n\n**Actors**\n\n- **Key**: `matchmaker[\"main\"]`\n- **Responsibility**: Handles private invite and public queue pairing for async matches.\n- **Actions**\n  - `createGame`\n  - `joinByCode`\n  - `queueForMatch`\n  - `unqueueForMatch`\n  - `closeMatch`\n- **Queues**\n  - `createGame`\n  - `joinByCode`\n  - `queueForMatch`\n  - `unqueueForMatch`\n  - `closeMatch`\n- **State**\n  - SQLite\n  - `matches`\n  - `player_pool`\n  - `assignments` for invite and queue mapping\n\n- **Key**: `match[matchId]`\n- **Responsibility**: Owns board state, turn order, move validation, and final result.\n- **Actions**\n  - `connect`\n  - `makeMove`\n- **Queues**\n  - None\n- **State**\n  - JSON\n  - `board`\n  - `turns`\n  - `players`\n  - `connection presence`\n  - `result`\n\n**Lifecycle**\n\n### Public Queue\n\n```mermaid\nsequenceDiagram\n\tparticipant A as Client A\n\tparticipant B as Client B\n\tparticipant MM as matchmaker\n\tparticipant M as match\n\n\tA->>MM: queueForMatch()\n\tB->>MM: queueForMatch()\n\tNote over MM: pair first two queued players\n\tMM->>M: create(matchId) + seed X\u002FO players\n\tMM-->>A: assignment\u002Fmatch info\n\tMM-->>B: assignment\u002Fmatch info\n\tA->>M: connect(playerId)\n\tB->>M: connect(playerId)\n\tA->>M: makeMove()\n\tB->>M: makeMove()\n\topt all players disconnected for timeout\n\t\tNote over M: destroy after idle timeout\n\tend\n\tM->>MM: closeMatch(matchId)\n```\n\n### Private Invite\n\n```mermaid\nsequenceDiagram\n\tparticipant A as Client A\n\tparticipant B as Client B\n\tparticipant MM as matchmaker\n\tparticipant M as match\n\n\tA->>MM: createGame()\n\tMM-->>A: {matchId, playerId, inviteCode}\n\tB->>MM: joinByCode(inviteCode)\n\tMM->>M: create(matchId) + seed X\u002FO players\n\tMM-->>A: assignment\u002Fmatch info\n\tMM-->>B: assignment\u002Fmatch info\n\tA->>M: connect(playerId)\n\tB->>M: connect(playerId)\n\tA->>M: makeMove()\n\tB->>M: makeMove()\n\tM->>MM: closeMatch(matchId)\n```\n\n### Idle\n\n| Topic | Summary |\n| --- | --- |\n| Matchmaking | No matchmaker; each player uses a direct per-player actor and a shared leaderboard actor. |\n| Netcode | Server-authoritative (basic logic). Client owns UI and build intent. Server owns resources, production rates, building validation, and leaderboard totals. |\n| Tick Rate | No continuous tick; use `c.schedule.after(...)` for coarse intervals and compute offline catch-up from elapsed wall time. |\n| Physics | None for standard idle loops; transitions are discrete (`build`, `collect`, `upgrade`) and do not need spatial indexing. |\n\n**Actors**\n\n- **Key**: `world[playerId]`\n- **Responsibility**: Owns one player's progression, buildings, production scheduling, and state updates.\n- **Actions**\n  - `initialize`\n  - `build`\n  - `collectProduction`\n- **Queues**\n  - None\n- **State**\n  - JSON\n  - Per-player buildings\n  - `resources`\n  - `timers`\n  - `progression state`\n\n- **Key**: `leaderboard[\"main\"]`\n- **Responsibility**: Stores global scores and serves leaderboard updates.\n- **Actions**\n  - `updateScore`\n- **Queues**\n  - `updateScore`\n- **State**\n  - SQLite\n  - `scores` table keyed by player\n  - Current leaderboard totals\n\n**Lifecycle**\n\n```mermaid\nsequenceDiagram\n\tparticipant C as Client\n\tparticipant W as world\n\tparticipant LB as leaderboard\n\n\tC->>W: getOrCreate(playerId) + initialize()\n\tNote over W: seed state + schedule collection\n\tW-->>C: stateUpdate\n\tloop gameplay loop\n\t\tC->>W: build() \u002F collectProduction()\n\t\tW->>LB: updateScore(...)\n\tNote over LB: upsert scores\n\tLB-->>C: leaderboardUpdate\n\tW-->>C: stateUpdate\n\tend\n```\n\n## Reference Map\n\n### Actors\n\n- [Access Control](reference\u002Factors\u002Faccess-control.md)\n- [Actions](reference\u002Factors\u002Factions.md)\n- [Actor Keys](reference\u002Factors\u002Fkeys.md)\n- [Actor Runtime Socket](reference\u002Factors\u002Factor-runtime-socket.md)\n- [Actor Statuses](reference\u002Factors\u002Fstatuses.md)\n- [Authentication](reference\u002Factors\u002Fauthentication.md)\n- [Cloudflare Workers Quickstart](reference\u002Factors\u002Fquickstart\u002Fcloudflare.md)\n- [Communicating Between Actors](reference\u002Factors\u002Fcommunicating-between-actors.md)\n- [Connections](reference\u002Factors\u002Fconnections.md)\n- [Custom Inspector Tabs](reference\u002Factors\u002Finspector-tabs.md)\n- [Debugging](reference\u002Factors\u002Fdebugging.md)\n- [Design Patterns](reference\u002Factors\u002Fdesign-patterns.md)\n- [Destroying Actors](reference\u002Factors\u002Fdestroy.md)\n- [Effect.ts Quickstart (Beta)](reference\u002Factors\u002Fquickstart\u002Feffect.md)\n- [Errors](reference\u002Factors\u002Ferrors.md)\n- [Fetch and WebSocket Handler](reference\u002Factors\u002Ffetch-and-websocket-handler.md)\n- [Helper Types](reference\u002Factors\u002Fhelper-types.md)\n- [Icons & Names](reference\u002Factors\u002Fappearance.md)\n- [In-Memory State](reference\u002Factors\u002Fstate.md)\n- [Input Parameters](reference\u002Factors\u002Finput.md)\n- [Lifecycle](reference\u002Factors\u002Flifecycle.md)\n- [Limits](reference\u002Factors\u002Flimits.md)\n- [Low-Level HTTP Request Handler](reference\u002Factors\u002Frequest-handler.md)\n- [Low-Level KV Storage](reference\u002Factors\u002Fkv.md)\n- [Low-Level WebSocket Handler](reference\u002Factors\u002Fwebsocket-handler.md)\n- [Metadata](reference\u002Factors\u002Fmetadata.md)\n- [Next.js Quickstart](reference\u002Factors\u002Fquickstart\u002Fnext-js.md)\n- [Node.js & Bun Quickstart](reference\u002Factors\u002Fquickstart\u002Fbackend.md)\n- [Queues & Run Loops](reference\u002Factors\u002Fqueues.md)\n- [React Quickstart](reference\u002Factors\u002Fquickstart\u002Freact.md)\n- [Realtime](reference\u002Factors\u002Fevents.md)\n- [Rust Quickstart (Beta)](reference\u002Factors\u002Fquickstart\u002Frust.md)\n- [Scaling & Concurrency](reference\u002Factors\u002Fscaling.md)\n- [Schedule & Cron](reference\u002Factors\u002Fschedule.md)\n- [Sharing and Joining State](reference\u002Factors\u002Fsharing-and-joining-state.md)\n- [SQLite](reference\u002Factors\u002Fsqlite.md)\n- [SQLite + Drizzle](reference\u002Factors\u002Fsqlite-drizzle.md)\n- [Supabase Functions Quickstart](reference\u002Factors\u002Fquickstart\u002Fsupabase.md)\n- [Testing](reference\u002Factors\u002Ftesting.md)\n- [Troubleshooting](reference\u002Factors\u002Ftroubleshooting.md)\n- [Types](reference\u002Factors\u002Ftypes.md)\n- [Vanilla HTTP API](reference\u002Factors\u002Fhttp-api.md)\n- [Versions & Upgrades](reference\u002Factors\u002Fversions.md)\n- [Workflows](reference\u002Factors\u002Fworkflows.md)\n\n### Cli\n\n- [CLI](reference\u002Fcli.md)\n\n### Clients\n\n- [Node.js & Bun](reference\u002Fclients\u002Fjavascript.md)\n- [React](reference\u002Fclients\u002Freact.md)\n- [Rust (Beta)](reference\u002Fclients\u002Frust.md)\n- [Swift](reference\u002Fclients\u002Fswift.md)\n- [SwiftUI](reference\u002Fclients\u002Fswiftui.md)\n\n### Cookbook\n\n- [AI Agent](reference\u002Fcookbook\u002Fai-agent.md)\n- [Chat Room](reference\u002Fcookbook\u002Fchat-room.md)\n- [Collaborative Text Editor](reference\u002Fcookbook\u002Fcollaborative-text-editor.md)\n- [Cron Jobs and Scheduled Tasks](reference\u002Fcookbook\u002Fcron-jobs.md)\n- [Database per Tenant](reference\u002Fcookbook\u002Fper-tenant-database.md)\n- [Deploying Rivet in a VPC or Air-Gapped Network](reference\u002Fcookbook\u002Fvpc-air-gapped.md)\n- [Live Cursors and Presence](reference\u002Fcookbook\u002Flive-cursors.md)\n- [Multiplayer Game](reference\u002Fcookbook\u002Fmultiplayer-game.md)\n\n### Deploy\n\n- [Container Runner](reference\u002Fdeploy\u002Fcontainer-runner.md)\n- [Deploy To Amazon Web Services Lambda](reference\u002Fdeploy\u002Faws-lambda.md)\n- [Deploying to AWS ECS](reference\u002Fdeploy\u002Faws-ecs.md)\n- [Deploying to Cloudflare Workers](reference\u002Fdeploy\u002Fcloudflare.md)\n- [Deploying to Freestyle](reference\u002Fdeploy\u002Ffreestyle.md)\n- [Deploying to Google Cloud Run](reference\u002Fdeploy\u002Fgcp-cloud-run.md)\n- [Deploying to Hetzner](reference\u002Fdeploy\u002Fhetzner.md)\n- [Deploying to Kubernetes](reference\u002Fdeploy\u002Fkubernetes.md)\n- [Deploying to Railway](reference\u002Fdeploy\u002Frailway.md)\n- [Deploying to Rivet Compute](reference\u002Fdeploy\u002Frivet-compute.md)\n- [Deploying to Supabase Functions](reference\u002Fdeploy\u002Fsupabase.md)\n- [Deploying to Vercel](reference\u002Fdeploy\u002Fvercel.md)\n- [Deploying to VMs & Bare Metal](reference\u002Fdeploy\u002Fvm-and-bare-metal.md)\n\n### General\n\n- [Actor Configuration](reference\u002Fgeneral\u002Factor-configuration.md)\n- [Architecture](reference\u002Fgeneral\u002Farchitecture.md)\n- [Cross-Origin Resource Sharing](reference\u002Fgeneral\u002Fcors.md)\n- [Documentation for LLMs & AI](reference\u002Fgeneral\u002Fdocs-for-llms.md)\n- [Edge Networking](reference\u002Fgeneral\u002Fedge.md)\n- [Endpoints](reference\u002Fgeneral\u002Fendpoints.md)\n- [Environment Variables](reference\u002Fgeneral\u002Fenvironment-variables.md)\n- [HTTP Server](reference\u002Fgeneral\u002Fhttp-server.md)\n- [Logging](reference\u002Fgeneral\u002Flogging.md)\n- [Pool Configuration](reference\u002Fgeneral\u002Fpool-configuration.md)\n- [Production Checklist](reference\u002Fgeneral\u002Fproduction-checklist.md)\n- [Registry Configuration](reference\u002Fgeneral\u002Fregistry-configuration.md)\n- [Runtime Modes](reference\u002Fgeneral\u002Fruntime-modes.md)\n- [WASM vs Native SDK](reference\u002Fgeneral\u002Fwasm-vs-native-sdk.md)\n\n### Self Hosting\n\n- [Configuration](reference\u002Fself-hosting\u002Fconfiguration.md)\n- [Docker Compose](reference\u002Fself-hosting\u002Fdocker-compose.md)\n- [Docker Container](reference\u002Fself-hosting\u002Fdocker-container.md)\n- [File System](reference\u002Fself-hosting\u002Ffilesystem.md)\n- [FoundationDB (Enterprise)](reference\u002Fself-hosting\u002Ffoundationdb.md)\n- [Installing Rivet Engine](reference\u002Fself-hosting\u002Finstall.md)\n- [Kubernetes](reference\u002Fself-hosting\u002Fkubernetes.md)\n- [Multi-Region](reference\u002Fself-hosting\u002Fmulti-region.md)\n- [PostgreSQL](reference\u002Fself-hosting\u002Fpostgres.md)\n- [Production Checklist](reference\u002Fself-hosting\u002Fproduction-checklist.md)\n- [Railway Deployment](reference\u002Fself-hosting\u002Frailway.md)\n- [Render Deployment](reference\u002Fself-hosting\u002Frender.md)\n- [TLS & Certificates](reference\u002Fself-hosting\u002Ftls.md)\n\n",{"data":39,"body":40},{"name":4,"description":6},{"type":41,"children":42},"root",[43,51,70,77,82,99,104,110,124,376,382,389,502,508,513,518,633,639,652,723,729,735,816,822,888,894,907,964,970,975,982,1015,1021,1061,1067,1073,1104,1110,1115,1121,1265,1271,1284,1290,1295,1301,1377,1383,1388,1411,1417,1422,1427,1521,1529,1813,1821,1978,1983,2081,2088,2333,2340,2453,2458,2532,2539,2796,2803,2925,2930,3005,3012,3155,3162,3292,3297,3387,3394,3688,3695,3701,3808,3814,3903,3908,3982,3989,4439,4446,4592,4597,4665,4672,4960,4967,4973,5136,5142,5271,5276,5373,5380,5589,5596,5717,5723,5728,6124,6130,6142,6148,6196,6202,6276,6282,6402,6408,6536,6542,6661],{"type":44,"tag":45,"props":46,"children":47},"element","h1",{"id":4},[48],{"type":49,"value":50},"text","Multiplayer Game",{"type":44,"tag":52,"props":53,"children":54},"p",{},[55],{"type":44,"tag":56,"props":57,"children":58},"strong",{},[59,61,68],{"type":49,"value":60},"IMPORTANT: Before doing anything, you MUST read ",{"type":44,"tag":62,"props":63,"children":65},"code",{"className":64},[],[66],{"type":49,"value":67},"BASE_SKILL.md",{"type":49,"value":69}," in this skill's directory. It contains essential guidance on debugging, error handling, state management, deployment, and project setup. Those rules and patterns apply to all RivetKit work. Everything below assumes you have already read and understood it.",{"type":44,"tag":71,"props":72,"children":74},"h2",{"id":73},"working-examples",[75],{"type":49,"value":76},"Working Examples",{"type":44,"tag":52,"props":78,"children":79},{},[80],{"type":49,"value":81},"If you need a reference implementation, read the raw working example code in these templates:",{"type":44,"tag":83,"props":84,"children":85},"ul",{},[86],{"type":44,"tag":87,"props":88,"children":89},"li",{},[90],{"type":44,"tag":91,"props":92,"children":96},"a",{"href":93,"rel":94},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns",[95],"nofollow",[97],{"type":49,"value":98},"multiplayer-game-patterns",{"type":44,"tag":52,"props":100,"children":101},{},[102],{"type":49,"value":103},"Patterns for building multiplayer games with RivetKit, intended as a practical checklist you can adapt per genre.",{"type":44,"tag":71,"props":105,"children":107},{"id":106},"starter-code",[108],{"type":49,"value":109},"Starter Code",{"type":44,"tag":52,"props":111,"children":112},{},[113,115,122],{"type":49,"value":114},"Start with one of the working examples on ",{"type":44,"tag":91,"props":116,"children":119},{"href":117,"rel":118},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002F",[95],[120],{"type":49,"value":121},"GitHub",{"type":49,"value":123}," and adapt it to your game. Do not start from scratch for matchmaking and lifecycle flows.",{"type":44,"tag":125,"props":126,"children":127},"table",{},[128,151],{"type":44,"tag":129,"props":130,"children":131},"thead",{},[132],{"type":44,"tag":133,"props":134,"children":135},"tr",{},[136,142,146],{"type":44,"tag":137,"props":138,"children":139},"th",{},[140],{"type":49,"value":141},"Game Classification",{"type":44,"tag":137,"props":143,"children":144},{},[145],{"type":49,"value":109},{"type":44,"tag":137,"props":147,"children":148},{},[149],{"type":49,"value":150},"Common Examples",{"type":44,"tag":152,"props":153,"children":154},"tbody",{},[155,178,200,222,244,266,288,310,332,354],{"type":44,"tag":133,"props":156,"children":157},{},[158,164,173],{"type":44,"tag":159,"props":160,"children":161},"td",{},[162],{"type":49,"value":163},"Battle Royale",{"type":44,"tag":159,"props":165,"children":166},{},[167],{"type":44,"tag":91,"props":168,"children":171},{"href":169,"rel":170},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fbattle-royale\u002F",[95],[172],{"type":49,"value":121},{"type":44,"tag":159,"props":174,"children":175},{},[176],{"type":49,"value":177},"Fortnite, Apex Legends, PUBG, Warzone",{"type":44,"tag":133,"props":179,"children":180},{},[181,186,195],{"type":44,"tag":159,"props":182,"children":183},{},[184],{"type":49,"value":185},"Arena",{"type":44,"tag":159,"props":187,"children":188},{},[189],{"type":44,"tag":91,"props":190,"children":193},{"href":191,"rel":192},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Farena\u002F",[95],[194],{"type":49,"value":121},{"type":44,"tag":159,"props":196,"children":197},{},[198],{"type":49,"value":199},"Call of Duty TDM\u002FFFA, Halo Slayer, Counter-Strike casual, VALORANT unrated, Overwatch Quick Play, Rocket League",{"type":44,"tag":133,"props":201,"children":202},{},[203,208,217],{"type":44,"tag":159,"props":204,"children":205},{},[206],{"type":49,"value":207},"IO Style",{"type":44,"tag":159,"props":209,"children":210},{},[211],{"type":44,"tag":91,"props":212,"children":215},{"href":213,"rel":214},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fio-style\u002F",[95],[216],{"type":49,"value":121},{"type":44,"tag":159,"props":218,"children":219},{},[220],{"type":49,"value":221},"Agar.io, Slither.io, surviv.io",{"type":44,"tag":133,"props":223,"children":224},{},[225,230,239],{"type":44,"tag":159,"props":226,"children":227},{},[228],{"type":49,"value":229},"Open World",{"type":44,"tag":159,"props":231,"children":232},{},[233],{"type":44,"tag":91,"props":234,"children":237},{"href":235,"rel":236},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fopen-world\u002F",[95],[238],{"type":49,"value":121},{"type":44,"tag":159,"props":240,"children":241},{},[242],{"type":49,"value":243},"Minecraft survival servers, Rust-like worlds, MMO zone\u002Fchunk worlds",{"type":44,"tag":133,"props":245,"children":246},{},[247,252,261],{"type":44,"tag":159,"props":248,"children":249},{},[250],{"type":49,"value":251},"Party",{"type":44,"tag":159,"props":253,"children":254},{},[255],{"type":44,"tag":91,"props":256,"children":259},{"href":257,"rel":258},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fparty\u002F",[95],[260],{"type":49,"value":121},{"type":44,"tag":159,"props":262,"children":263},{},[264],{"type":49,"value":265},"Fall Guys private lobbies, custom game rooms, social party sessions",{"type":44,"tag":133,"props":267,"children":268},{},[269,274,283],{"type":44,"tag":159,"props":270,"children":271},{},[272],{"type":49,"value":273},"Physics 2D",{"type":44,"tag":159,"props":275,"children":276},{},[277],{"type":44,"tag":91,"props":278,"children":281},{"href":279,"rel":280},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fphysics-2d\u002F",[95],[282],{"type":49,"value":121},{"type":44,"tag":159,"props":284,"children":285},{},[286],{"type":49,"value":287},"Top-down physics brawlers, 2D arena games, platform fighters",{"type":44,"tag":133,"props":289,"children":290},{},[291,296,305],{"type":44,"tag":159,"props":292,"children":293},{},[294],{"type":49,"value":295},"Physics 3D",{"type":44,"tag":159,"props":297,"children":298},{},[299],{"type":44,"tag":91,"props":300,"children":303},{"href":301,"rel":302},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fphysics-3d\u002F",[95],[304],{"type":49,"value":121},{"type":44,"tag":159,"props":306,"children":307},{},[308],{"type":49,"value":309},"Physics sandbox sessions, 3D arena games, movement playgrounds",{"type":44,"tag":133,"props":311,"children":312},{},[313,318,327],{"type":44,"tag":159,"props":314,"children":315},{},[316],{"type":49,"value":317},"Ranked",{"type":44,"tag":159,"props":319,"children":320},{},[321],{"type":44,"tag":91,"props":322,"children":325},{"href":323,"rel":324},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Franked\u002F",[95],[326],{"type":49,"value":121},{"type":44,"tag":159,"props":328,"children":329},{},[330],{"type":49,"value":331},"Chess ladders, competitive card games, duel arena ranked queues",{"type":44,"tag":133,"props":333,"children":334},{},[335,340,349],{"type":44,"tag":159,"props":336,"children":337},{},[338],{"type":49,"value":339},"Turn-Based",{"type":44,"tag":159,"props":341,"children":342},{},[343],{"type":44,"tag":91,"props":344,"children":347},{"href":345,"rel":346},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fturn-based\u002F",[95],[348],{"type":49,"value":121},{"type":44,"tag":159,"props":350,"children":351},{},[352],{"type":49,"value":353},"Chess correspondence, Words With Friends, async board games",{"type":44,"tag":133,"props":355,"children":356},{},[357,362,371],{"type":44,"tag":159,"props":358,"children":359},{},[360],{"type":49,"value":361},"Idle",{"type":44,"tag":159,"props":363,"children":364},{},[365],{"type":44,"tag":91,"props":366,"children":369},{"href":367,"rel":368},"https:\u002F\u002Fgithub.com\u002Frivet-dev\u002Frivet\u002Ftree\u002Fmain\u002Fexamples\u002Fmultiplayer-game-patterns\u002Fsrc\u002Factors\u002Fidle\u002F",[95],[370],{"type":49,"value":121},{"type":44,"tag":159,"props":372,"children":373},{},[374],{"type":49,"value":375},"Cookie Clicker, Idle Miner Tycoon, Adventure Capitalist",{"type":44,"tag":71,"props":377,"children":379},{"id":378},"server-simulation",[380],{"type":49,"value":381},"Server Simulation",{"type":44,"tag":383,"props":384,"children":386},"h3",{"id":385},"game-loop-and-tick-rates",[387],{"type":49,"value":388},"Game Loop And Tick Rates",{"type":44,"tag":125,"props":390,"children":391},{},[392,413],{"type":44,"tag":129,"props":393,"children":394},{},[395],{"type":44,"tag":133,"props":396,"children":397},{},[398,403,408],{"type":44,"tag":137,"props":399,"children":400},{},[401],{"type":49,"value":402},"Pattern",{"type":44,"tag":137,"props":404,"children":405},{},[406],{"type":49,"value":407},"Use When",{"type":44,"tag":137,"props":409,"children":410},{},[411],{"type":49,"value":412},"Implementation Guidance",{"type":44,"tag":152,"props":414,"children":415},{},[416,458,476],{"type":44,"tag":133,"props":417,"children":418},{},[419,424,429],{"type":44,"tag":159,"props":420,"children":421},{},[422],{"type":49,"value":423},"Fixed realtime loop",{"type":44,"tag":159,"props":425,"children":426},{},[427],{"type":49,"value":428},"Battle Royale, Arena, IO Style, Open World, Ranked",{"type":44,"tag":159,"props":430,"children":431},{},[432,434,440,442,448,450,456],{"type":49,"value":433},"Run in ",{"type":44,"tag":62,"props":435,"children":437},{"className":436},[],[438],{"type":49,"value":439},"run",{"type":49,"value":441}," with ",{"type":44,"tag":62,"props":443,"children":445},{"className":444},[],[446],{"type":49,"value":447},"sleep(tickMs)",{"type":49,"value":449}," and exit on ",{"type":44,"tag":62,"props":451,"children":453},{"className":452},[],[454],{"type":49,"value":455},"c.aborted",{"type":49,"value":457},".",{"type":44,"tag":133,"props":459,"children":460},{},[461,466,471],{"type":44,"tag":159,"props":462,"children":463},{},[464],{"type":49,"value":465},"Action-driven updates",{"type":44,"tag":159,"props":467,"children":468},{},[469],{"type":49,"value":470},"Party, Turn-Based",{"type":44,"tag":159,"props":472,"children":473},{},[474],{"type":49,"value":475},"Mutate and broadcast only on actions\u002Fevents rather than scheduled ticks.",{"type":44,"tag":133,"props":477,"children":478},{},[479,484,489],{"type":44,"tag":159,"props":480,"children":481},{},[482],{"type":49,"value":483},"Coarse offline progression",{"type":44,"tag":159,"props":485,"children":486},{},[487],{"type":49,"value":488},"Any mode with idle progression",{"type":44,"tag":159,"props":490,"children":491},{},[492,494,500],{"type":49,"value":493},"Use ",{"type":44,"tag":62,"props":495,"children":497},{"className":496},[],[498],{"type":49,"value":499},"c.schedule.after(...)",{"type":49,"value":501}," with coarse windows (for example 5 to 15 minutes) and apply catch-up from elapsed wall clock time.",{"type":44,"tag":383,"props":503,"children":505},{"id":504},"physics",[506],{"type":49,"value":507},"Physics",{"type":44,"tag":52,"props":509,"children":510},{},[511],{"type":49,"value":512},"Start with custom kinematic logic for simple games. Switch to a full physics engine when you need joints, stacked bodies, high collision density, or complex shapes (rotated polygons, capsules, convex hulls, triangle meshes).",{"type":44,"tag":52,"props":514,"children":515},{},[516],{"type":49,"value":517},"Pick one engine per simulation. Keep frontend-only libs out of backend simulation paths and treat server state as authoritative.",{"type":44,"tag":125,"props":519,"children":520},{},[521,547],{"type":44,"tag":129,"props":522,"children":523},{},[524],{"type":44,"tag":133,"props":525,"children":526},{},[527,532,537,542],{"type":44,"tag":137,"props":528,"children":529},{},[530],{"type":49,"value":531},"Dimension",{"type":44,"tag":137,"props":533,"children":534},{},[535],{"type":49,"value":536},"Primary Engine",{"type":44,"tag":137,"props":538,"children":539},{},[540],{"type":49,"value":541},"Fallback Engines",{"type":44,"tag":137,"props":543,"children":544},{},[545],{"type":49,"value":546},"Example Code",{"type":44,"tag":152,"props":548,"children":549},{},[550,592],{"type":44,"tag":133,"props":551,"children":552},{},[553,558,567,584],{"type":44,"tag":159,"props":554,"children":555},{},[556],{"type":49,"value":557},"2D",{"type":44,"tag":159,"props":559,"children":560},{},[561],{"type":44,"tag":62,"props":562,"children":564},{"className":563},[],[565],{"type":49,"value":566},"@dimforge\u002Frapier2d",{"type":44,"tag":159,"props":568,"children":569},{},[570,576,578],{"type":44,"tag":62,"props":571,"children":573},{"className":572},[],[574],{"type":49,"value":575},"planck-js",{"type":49,"value":577},", ",{"type":44,"tag":62,"props":579,"children":581},{"className":580},[],[582],{"type":49,"value":583},"matter-js",{"type":44,"tag":159,"props":585,"children":586},{},[587],{"type":44,"tag":91,"props":588,"children":590},{"href":279,"rel":589},[95],[591],{"type":49,"value":121},{"type":44,"tag":133,"props":593,"children":594},{},[595,600,609,625],{"type":44,"tag":159,"props":596,"children":597},{},[598],{"type":49,"value":599},"3D",{"type":44,"tag":159,"props":601,"children":602},{},[603],{"type":44,"tag":62,"props":604,"children":606},{"className":605},[],[607],{"type":49,"value":608},"@dimforge\u002Frapier3d",{"type":44,"tag":159,"props":610,"children":611},{},[612,618,619],{"type":44,"tag":62,"props":613,"children":615},{"className":614},[],[616],{"type":49,"value":617},"cannon-es",{"type":49,"value":577},{"type":44,"tag":62,"props":620,"children":622},{"className":621},[],[623],{"type":49,"value":624},"ammo.js",{"type":44,"tag":159,"props":626,"children":627},{},[628],{"type":44,"tag":91,"props":629,"children":631},{"href":301,"rel":630},[95],[632],{"type":49,"value":121},{"type":44,"tag":383,"props":634,"children":636},{"id":635},"spatial-indexing",[637],{"type":49,"value":638},"Spatial Indexing",{"type":44,"tag":52,"props":640,"children":641},{},[642,644,650],{"type":49,"value":643},"For non-physics spatial queries, use a dedicated index instead of naive ",{"type":44,"tag":62,"props":645,"children":647},{"className":646},[],[648],{"type":49,"value":649},"O(n^2)",{"type":49,"value":651}," checks:",{"type":44,"tag":125,"props":653,"children":654},{},[655,671],{"type":44,"tag":129,"props":656,"children":657},{},[658],{"type":44,"tag":133,"props":659,"children":660},{},[661,666],{"type":44,"tag":137,"props":662,"children":663},{},[664],{"type":49,"value":665},"Index Type",{"type":44,"tag":137,"props":667,"children":668},{},[669],{"type":49,"value":670},"Recommendation",{"type":44,"tag":152,"props":672,"children":673},{},[674,703],{"type":44,"tag":133,"props":675,"children":676},{},[677,682],{"type":44,"tag":159,"props":678,"children":679},{},[680],{"type":49,"value":681},"AABB index",{"type":44,"tag":159,"props":683,"children":684},{},[685,687,693,695,701],{"type":49,"value":686},"For AOI, visibility, and non-collider entities, use ",{"type":44,"tag":62,"props":688,"children":690},{"className":689},[],[691],{"type":49,"value":692},"rbush",{"type":49,"value":694}," for dynamic sets or ",{"type":44,"tag":62,"props":696,"children":698},{"className":697},[],[699],{"type":49,"value":700},"flatbush",{"type":49,"value":702}," for static-ish sets.",{"type":44,"tag":133,"props":704,"children":705},{},[706,711],{"type":44,"tag":159,"props":707,"children":708},{},[709],{"type":49,"value":710},"Point index",{"type":44,"tag":159,"props":712,"children":713},{},[714,716,722],{"type":49,"value":715},"For nearest-neighbor or within-radius queries, use ",{"type":44,"tag":62,"props":717,"children":719},{"className":718},[],[720],{"type":49,"value":721},"d3-quadtree",{"type":49,"value":457},{"type":44,"tag":71,"props":724,"children":726},{"id":725},"networking-state-sync",[727],{"type":49,"value":728},"Networking & State Sync",{"type":44,"tag":383,"props":730,"children":732},{"id":731},"netcode",[733],{"type":49,"value":734},"Netcode",{"type":44,"tag":125,"props":736,"children":737},{},[738,759],{"type":44,"tag":129,"props":739,"children":740},{},[741],{"type":44,"tag":133,"props":742,"children":743},{},[744,749,754],{"type":44,"tag":137,"props":745,"children":746},{},[747],{"type":49,"value":748},"Model",{"type":44,"tag":137,"props":750,"children":751},{},[752],{"type":49,"value":753},"When To Use",{"type":44,"tag":137,"props":755,"children":756},{},[757],{"type":49,"value":758},"Implementation",{"type":44,"tag":152,"props":760,"children":761},{},[762,780,798],{"type":44,"tag":133,"props":763,"children":764},{},[765,770,775],{"type":44,"tag":159,"props":766,"children":767},{},[768],{"type":49,"value":769},"Hybrid (client movement, server combat)",{"type":44,"tag":159,"props":771,"children":772},{},[773],{"type":49,"value":774},"Shooters, action sports, ranked duels",{"type":44,"tag":159,"props":776,"children":777},{},[778],{"type":49,"value":779},"Client owns movement and sends capped-rate position updates. Server validates for anti-cheat. Combat (projectiles, hits, damage) is fully server-authoritative.",{"type":44,"tag":133,"props":781,"children":782},{},[783,788,793],{"type":44,"tag":159,"props":784,"children":785},{},[786],{"type":49,"value":787},"Server-authoritative with interpolation",{"type":44,"tag":159,"props":789,"children":790},{},[791],{"type":49,"value":792},"IO Style, persistent worlds",{"type":44,"tag":159,"props":794,"children":795},{},[796],{"type":49,"value":797},"Client sends input commands. Server simulates on fixed ticks and publishes authoritative snapshots. Client interpolates between snapshots.",{"type":44,"tag":133,"props":799,"children":800},{},[801,806,811],{"type":44,"tag":159,"props":802,"children":803},{},[804],{"type":49,"value":805},"Server-authoritative (basic logic)",{"type":44,"tag":159,"props":807,"children":808},{},[809],{"type":49,"value":810},"Turn-based, event-driven",{"type":44,"tag":159,"props":812,"children":813},{},[814],{"type":49,"value":815},"Server validates and applies discrete actions (turns, phase transitions, votes). Client displays confirmed state.",{"type":44,"tag":383,"props":817,"children":819},{"id":818},"realtime-data-model",[820],{"type":49,"value":821},"Realtime Data Model",{"type":44,"tag":83,"props":823,"children":824},{},[825,835,845,863],{"type":44,"tag":87,"props":826,"children":827},{},[828,833],{"type":44,"tag":56,"props":829,"children":830},{},[831],{"type":49,"value":832},"Snapshots and diffs",{"type":49,"value":834},": Publish state as events. Send a full snapshot on join\u002Fresync, then per-tick diffs for regular updates.",{"type":44,"tag":87,"props":836,"children":837},{},[838,843],{"type":44,"tag":56,"props":839,"children":840},{},[841],{"type":49,"value":842},"Batch per tick",{"type":49,"value":844},": Keep events small and typed. Batch high-frequency updates per tick.",{"type":44,"tag":87,"props":846,"children":847},{},[848,853,855,861],{"type":44,"tag":56,"props":849,"children":850},{},[851],{"type":49,"value":852},"Avoid UI framework state for game updates",{"type":49,"value":854},": Use ",{"type":44,"tag":62,"props":856,"children":858},{"className":857},[],[859],{"type":49,"value":860},"requestAnimationFrame",{"type":49,"value":862}," or a Canvas\u002FThree.js loop for simulation, not React state. Reserve UI framework state for menus, HUD, and forms.",{"type":44,"tag":87,"props":864,"children":865},{},[866,871,872,878,880,886],{"type":44,"tag":56,"props":867,"children":868},{},[869],{"type":49,"value":870},"Broadcast vs per-connection",{"type":49,"value":854},{"type":44,"tag":62,"props":873,"children":875},{"className":874},[],[876],{"type":49,"value":877},"c.broadcast(...)",{"type":49,"value":879}," for shared updates and ",{"type":44,"tag":62,"props":881,"children":883},{"className":882},[],[884],{"type":49,"value":885},"conn.send(...)",{"type":49,"value":887}," for private\u002Fper-player data.",{"type":44,"tag":383,"props":889,"children":891},{"id":890},"shared-simulation-logic",[892],{"type":49,"value":893},"Shared Simulation Logic",{"type":44,"tag":52,"props":895,"children":896},{},[897,899,905],{"type":49,"value":898},"Shared simulation logic runs on both the client and the server. For example, an ",{"type":44,"tag":62,"props":900,"children":902},{"className":901},[],[903],{"type":49,"value":904},"applyInput(state, input, dt)",{"type":49,"value":906}," function that integrates velocity and clamps to world bounds can run on the client for prediction and on the server for validation.",{"type":44,"tag":83,"props":908,"children":909},{},[910,920,930,940],{"type":44,"tag":87,"props":911,"children":912},{},[913,918],{"type":44,"tag":56,"props":914,"children":915},{},[916],{"type":49,"value":917},"Hybrid modes",{"type":49,"value":919},": Client runs shared movement as primary authority, server runs it for anti-cheat validation.",{"type":44,"tag":87,"props":921,"children":922},{},[923,928],{"type":44,"tag":56,"props":924,"children":925},{},[926],{"type":49,"value":927},"Server-authoritative modes",{"type":49,"value":929},": Client uses shared logic for interpolation and prediction only.",{"type":44,"tag":87,"props":931,"children":932},{},[933,938],{"type":44,"tag":56,"props":934,"children":935},{},[936],{"type":49,"value":937},"Keep it pure",{"type":49,"value":939},": Movement integration, input transforms, collision helpers, and constants only.",{"type":44,"tag":87,"props":941,"children":942},{},[943,954,956,962],{"type":44,"tag":56,"props":944,"children":945},{},[946,948],{"type":49,"value":947},"Put shared code in ",{"type":44,"tag":62,"props":949,"children":951},{"className":950},[],[952],{"type":49,"value":953},"src\u002Fshared\u002F",{"type":49,"value":955},": Keep deterministic helpers in ",{"type":44,"tag":62,"props":957,"children":959},{"className":958},[],[960],{"type":49,"value":961},"src\u002Fshared\u002Fsim\u002F*",{"type":49,"value":963}," with no side effects.",{"type":44,"tag":383,"props":965,"children":967},{"id":966},"interest-management",[968],{"type":49,"value":969},"Interest Management",{"type":44,"tag":52,"props":971,"children":972},{},[973],{"type":49,"value":974},"Control what each client receives to reduce bandwidth and prevent information leaks.",{"type":44,"tag":976,"props":977,"children":979},"h4",{"id":978},"per-player-replication-filters",[980],{"type":49,"value":981},"Per-Player Replication Filters",{"type":44,"tag":83,"props":983,"children":984},{},[985,995,1005],{"type":44,"tag":87,"props":986,"children":987},{},[988,993],{"type":44,"tag":56,"props":989,"children":990},{},[991],{"type":49,"value":992},"Filter by relevance",{"type":49,"value":994},": Send each client only state relevant to that player (proximity, line-of-sight, team, or game phase).",{"type":44,"tag":87,"props":996,"children":997},{},[998,1003],{"type":44,"tag":56,"props":999,"children":1000},{},[1001],{"type":49,"value":1002},"Shooters and action games",{"type":49,"value":1004},": Limit replication by proximity and optional field-of-view checks.",{"type":44,"tag":87,"props":1006,"children":1007},{},[1008,1013],{"type":44,"tag":56,"props":1009,"children":1010},{},[1011],{"type":49,"value":1012},"Server-side only",{"type":49,"value":1014},": Clients should never receive data they should not see.",{"type":44,"tag":976,"props":1016,"children":1018},{"id":1017},"sharded-worlds",[1019],{"type":49,"value":1020},"Sharded Worlds",{"type":44,"tag":83,"props":1022,"children":1023},{},[1024,1041,1051],{"type":44,"tag":87,"props":1025,"children":1026},{},[1027,1032,1034,1040],{"type":44,"tag":56,"props":1028,"children":1029},{},[1030],{"type":49,"value":1031},"Partition large worlds",{"type":49,"value":1033},": Use chunk actors keyed by ",{"type":44,"tag":62,"props":1035,"children":1037},{"className":1036},[],[1038],{"type":49,"value":1039},"worldId:chunkX:chunkY",{"type":49,"value":457},{"type":44,"tag":87,"props":1042,"children":1043},{},[1044,1049],{"type":44,"tag":56,"props":1045,"children":1046},{},[1047],{"type":49,"value":1048},"Subscribe to nearby chunks",{"type":49,"value":1050},": Clients connect only to nearby partitions (for example a 3x3 chunk window).",{"type":44,"tag":87,"props":1052,"children":1053},{},[1054,1059],{"type":44,"tag":56,"props":1055,"children":1056},{},[1057],{"type":49,"value":1058},"Use sparingly",{"type":49,"value":1060},": Only when the world is large and state-heavy (sandbox builders, MMOs), not as a default for small matches.",{"type":44,"tag":71,"props":1062,"children":1064},{"id":1063},"backend-infrastructure",[1065],{"type":49,"value":1066},"Backend Infrastructure",{"type":44,"tag":383,"props":1068,"children":1070},{"id":1069},"persistence",[1071],{"type":49,"value":1072},"Persistence",{"type":44,"tag":83,"props":1074,"children":1075},{},[1076,1086],{"type":44,"tag":87,"props":1077,"children":1078},{},[1079,1084],{"type":44,"tag":56,"props":1080,"children":1081},{},[1082],{"type":49,"value":1083},"In-memory state",{"type":49,"value":1085},": Best for realtime game state that changes every tick (player positions, inputs, match phase, scores).",{"type":44,"tag":87,"props":1087,"children":1088},{},[1089,1102],{"type":44,"tag":56,"props":1090,"children":1091},{},[1092,1094,1100],{"type":49,"value":1093},"SQLite (",{"type":44,"tag":62,"props":1095,"children":1097},{"className":1096},[],[1098],{"type":49,"value":1099},"rivetkit\u002Fdb",{"type":49,"value":1101},")",{"type":49,"value":1103},": Better for large or table-like state that needs queries, indexes, or long-term persistence (tiles, inventory, matchmaking pools). Serialize DB work through a queue since multiple actions can hit the same actor concurrently.",{"type":44,"tag":383,"props":1105,"children":1107},{"id":1106},"matchmaking-patterns",[1108],{"type":49,"value":1109},"Matchmaking Patterns",{"type":44,"tag":52,"props":1111,"children":1112},{},[1113],{"type":49,"value":1114},"Common building blocks used across the architecture patterns below.",{"type":44,"tag":976,"props":1116,"children":1118},{"id":1117},"actor-topology",[1119],{"type":49,"value":1120},"Actor Topology",{"type":44,"tag":125,"props":1122,"children":1123},{},[1124,1144],{"type":44,"tag":129,"props":1125,"children":1126},{},[1127],{"type":44,"tag":133,"props":1128,"children":1129},{},[1130,1135,1139],{"type":44,"tag":137,"props":1131,"children":1132},{},[1133],{"type":49,"value":1134},"Primitive",{"type":44,"tag":137,"props":1136,"children":1137},{},[1138],{"type":49,"value":407},{"type":44,"tag":137,"props":1140,"children":1141},{},[1142],{"type":49,"value":1143},"Typical Ownership",{"type":44,"tag":152,"props":1145,"children":1146},{},[1147,1177,1199,1221,1243],{"type":44,"tag":133,"props":1148,"children":1149},{},[1150,1167,1172],{"type":44,"tag":159,"props":1151,"children":1152},{},[1153,1159,1161],{"type":44,"tag":62,"props":1154,"children":1156},{"className":1155},[],[1157],{"type":49,"value":1158},"matchmaker[\"main\"]",{"type":49,"value":1160}," + ",{"type":44,"tag":62,"props":1162,"children":1164},{"className":1163},[],[1165],{"type":49,"value":1166},"match[matchId]",{"type":44,"tag":159,"props":1168,"children":1169},{},[1170],{"type":49,"value":1171},"Session-based multiplayer (battle royale, arena, ranked, party, turn-based)",{"type":44,"tag":159,"props":1173,"children":1174},{},[1175],{"type":49,"value":1176},"Matchmaker owns discovery\u002Fassignment. Match owns lifecycle and gameplay state.",{"type":44,"tag":133,"props":1178,"children":1179},{},[1180,1189,1194],{"type":44,"tag":159,"props":1181,"children":1182},{},[1183],{"type":44,"tag":62,"props":1184,"children":1186},{"className":1185},[],[1187],{"type":49,"value":1188},"chunk[worldId,chunkX,chunkY]",{"type":44,"tag":159,"props":1190,"children":1191},{},[1192],{"type":49,"value":1193},"Large continuous worlds that need sharding",{"type":44,"tag":159,"props":1195,"children":1196},{},[1197],{"type":49,"value":1198},"Each chunk owns local players, chunk state, and local simulation.",{"type":44,"tag":133,"props":1200,"children":1201},{},[1202,1211,1216],{"type":44,"tag":159,"props":1203,"children":1204},{},[1205],{"type":44,"tag":62,"props":1206,"children":1208},{"className":1207},[],[1209],{"type":49,"value":1210},"world[playerId]",{"type":44,"tag":159,"props":1212,"children":1213},{},[1214],{"type":49,"value":1215},"Per-player progression loops (idle\u002Fsolo world state)",{"type":44,"tag":159,"props":1217,"children":1218},{},[1219],{"type":49,"value":1220},"Per-player resources, buildings, timers, and progression.",{"type":44,"tag":133,"props":1222,"children":1223},{},[1224,1233,1238],{"type":44,"tag":159,"props":1225,"children":1226},{},[1227],{"type":44,"tag":62,"props":1228,"children":1230},{"className":1229},[],[1231],{"type":49,"value":1232},"player[username]",{"type":44,"tag":159,"props":1234,"children":1235},{},[1236],{"type":49,"value":1237},"Canonical profile\u002Frating reused across matches",{"type":44,"tag":159,"props":1239,"children":1240},{},[1241],{"type":49,"value":1242},"Durable player stats (for example rating and win\u002Floss).",{"type":44,"tag":133,"props":1244,"children":1245},{},[1246,1255,1260],{"type":44,"tag":159,"props":1247,"children":1248},{},[1249],{"type":44,"tag":62,"props":1250,"children":1252},{"className":1251},[],[1253],{"type":49,"value":1254},"leaderboard[\"main\"]",{"type":44,"tag":159,"props":1256,"children":1257},{},[1258],{"type":49,"value":1259},"Shared rankings across many matches\u002Fplayers",{"type":44,"tag":159,"props":1261,"children":1262},{},[1263],{"type":49,"value":1264},"Global ordered score rows and top lists.",{"type":44,"tag":976,"props":1266,"children":1268},{"id":1267},"queueing-strategy",[1269],{"type":49,"value":1270},"Queueing Strategy",{"type":44,"tag":83,"props":1272,"children":1273},{},[1274,1279],{"type":44,"tag":87,"props":1275,"children":1276},{},[1277],{"type":49,"value":1278},"Multiple players can hit the matchmaker at the same time, so actions like find\u002Fcreate, queue\u002Funqueue, and close need to be serialized through actor queues to avoid races.",{"type":44,"tag":87,"props":1280,"children":1281},{},[1282],{"type":49,"value":1283},"Match-local actions (gameplay, scoring) do not need queueing unless they write back to the matchmaker.",{"type":44,"tag":71,"props":1285,"children":1287},{"id":1286},"security-and-anti-cheat",[1288],{"type":49,"value":1289},"Security And Anti-Cheat",{"type":44,"tag":52,"props":1291,"children":1292},{},[1293],{"type":49,"value":1294},"Start with this baseline, then harden further for competitive or high-risk environments.",{"type":44,"tag":383,"props":1296,"children":1298},{"id":1297},"baseline-checklist",[1299],{"type":49,"value":1300},"Baseline Checklist",{"type":44,"tag":83,"props":1302,"children":1303},{},[1304,1337,1347,1357,1367],{"type":44,"tag":87,"props":1305,"children":1306},{},[1307,1312,1313,1319,1321,1327,1329,1335],{"type":44,"tag":56,"props":1308,"children":1309},{},[1310],{"type":49,"value":1311},"Identity",{"type":49,"value":854},{"type":44,"tag":62,"props":1314,"children":1316},{"className":1315},[],[1317],{"type":49,"value":1318},"c.conn.id",{"type":49,"value":1320}," as the authoritative transport identity. Treat ",{"type":44,"tag":62,"props":1322,"children":1324},{"className":1323},[],[1325],{"type":49,"value":1326},"playerId",{"type":49,"value":1328},"\u002F",{"type":44,"tag":62,"props":1330,"children":1332},{"className":1331},[],[1333],{"type":49,"value":1334},"username",{"type":49,"value":1336}," in params as untrusted input and bind through server-issued assignment\u002Fjoin tickets.",{"type":44,"tag":87,"props":1338,"children":1339},{},[1340,1345],{"type":44,"tag":56,"props":1341,"children":1342},{},[1343],{"type":49,"value":1344},"Authorization",{"type":49,"value":1346},": Validate the caller is allowed to mutate the target entity (room membership, turn ownership, host-only actions).",{"type":44,"tag":87,"props":1348,"children":1349},{},[1350,1355],{"type":44,"tag":56,"props":1351,"children":1352},{},[1353],{"type":49,"value":1354},"Input validation",{"type":49,"value":1356},": Clamp sizes\u002Flengths, validate enums, and validate usernames (length, allowed chars, avoid unbounded Unicode).",{"type":44,"tag":87,"props":1358,"children":1359},{},[1360,1365],{"type":44,"tag":56,"props":1361,"children":1362},{},[1363],{"type":49,"value":1364},"Rate limiting",{"type":49,"value":1366},": Per-connection rate limits for spammy actions (chat, join\u002Fleave, fire, movement updates).",{"type":44,"tag":87,"props":1368,"children":1369},{},[1370,1375],{"type":44,"tag":56,"props":1371,"children":1372},{},[1373],{"type":49,"value":1374},"State integrity",{"type":49,"value":1376},": Server recomputes derived state (scores, win conditions, placements). Never allow client-authoritative changes to inventory\u002Fcurrency\u002Fleaderboard totals.",{"type":44,"tag":383,"props":1378,"children":1380},{"id":1379},"movement-validation",[1381],{"type":49,"value":1382},"Movement Validation",{"type":44,"tag":52,"props":1384,"children":1385},{},[1386],{"type":49,"value":1387},"For any mode with client-authoritative movement (hybrid flows), clients may send position\u002Frotation updates for smoothness, but the server must:",{"type":44,"tag":83,"props":1389,"children":1390},{},[1391,1396,1401,1406],{"type":44,"tag":87,"props":1392,"children":1393},{},[1394],{"type":49,"value":1395},"Enforce max delta per update (speed cap) based on elapsed time.",{"type":44,"tag":87,"props":1397,"children":1398},{},[1399],{"type":49,"value":1400},"Reject or clamp teleports.",{"type":44,"tag":87,"props":1402,"children":1403},{},[1404],{"type":49,"value":1405},"Enforce world bounds (and basic collision if applicable).",{"type":44,"tag":87,"props":1407,"children":1408},{},[1409],{"type":49,"value":1410},"Rate limit update frequency (for example 20Hz max).",{"type":44,"tag":71,"props":1412,"children":1414},{"id":1413},"architecture-patterns",[1415],{"type":49,"value":1416},"Architecture Patterns",{"type":44,"tag":52,"props":1418,"children":1419},{},[1420],{"type":49,"value":1421},"Each game type below starts with a quick summary table, then details actors and lifecycle.",{"type":44,"tag":383,"props":1423,"children":1425},{"id":1424},"battle-royale",[1426],{"type":49,"value":163},{"type":44,"tag":125,"props":1428,"children":1429},{},[1430,1446],{"type":44,"tag":129,"props":1431,"children":1432},{},[1433],{"type":44,"tag":133,"props":1434,"children":1435},{},[1436,1441],{"type":44,"tag":137,"props":1437,"children":1438},{},[1439],{"type":49,"value":1440},"Topic",{"type":44,"tag":137,"props":1442,"children":1443},{},[1444],{"type":49,"value":1445},"Summary",{"type":44,"tag":152,"props":1447,"children":1448},{},[1449,1462,1474,1495],{"type":44,"tag":133,"props":1450,"children":1451},{},[1452,1457],{"type":44,"tag":159,"props":1453,"children":1454},{},[1455],{"type":49,"value":1456},"Matchmaking",{"type":44,"tag":159,"props":1458,"children":1459},{},[1460],{"type":49,"value":1461},"Immediate routing to the fullest non-started lobby (oldest tie-break); players wait in lobby until capacity, then the match starts.",{"type":44,"tag":133,"props":1463,"children":1464},{},[1465,1469],{"type":44,"tag":159,"props":1466,"children":1467},{},[1468],{"type":49,"value":734},{"type":44,"tag":159,"props":1470,"children":1471},{},[1472],{"type":49,"value":1473},"Hybrid. Client owns movement, camera, and local prediction. Server owns zone state, projectiles, hit resolution, eliminations, loot, and final placement.",{"type":44,"tag":133,"props":1475,"children":1476},{},[1477,1482],{"type":44,"tag":159,"props":1478,"children":1479},{},[1480],{"type":49,"value":1481},"Tick Rate",{"type":44,"tag":159,"props":1483,"children":1484},{},[1485,1487,1493],{"type":49,"value":1486},"10 ticks\u002Fsec (",{"type":44,"tag":62,"props":1488,"children":1490},{"className":1489},[],[1491],{"type":49,"value":1492},"100ms",{"type":49,"value":1494},") with a fixed loop for zone progression and lifecycle checks.",{"type":44,"tag":133,"props":1496,"children":1497},{},[1498,1502],{"type":44,"tag":159,"props":1499,"children":1500},{},[1501],{"type":49,"value":507},{"type":44,"tag":159,"props":1503,"children":1504},{},[1505,1507,1512,1514,1519],{"type":49,"value":1506},"Client owns movement with server anti-cheat validation; projectiles, hits, and damage are server-authoritative. Use ",{"type":44,"tag":62,"props":1508,"children":1510},{"className":1509},[],[1511],{"type":49,"value":608},{"type":49,"value":1513}," for 3D or ",{"type":44,"tag":62,"props":1515,"children":1517},{"className":1516},[],[1518],{"type":49,"value":566},{"type":49,"value":1520}," for top-down 2D.",{"type":44,"tag":52,"props":1522,"children":1523},{},[1524],{"type":44,"tag":56,"props":1525,"children":1526},{},[1527],{"type":49,"value":1528},"Actors",{"type":44,"tag":83,"props":1530,"children":1531},{},[1532,1547,1557,1604,1647,1692,1705,1714,1738,1753],{"type":44,"tag":87,"props":1533,"children":1534},{},[1535,1540,1542],{"type":44,"tag":56,"props":1536,"children":1537},{},[1538],{"type":49,"value":1539},"Key",{"type":49,"value":1541},": ",{"type":44,"tag":62,"props":1543,"children":1545},{"className":1544},[],[1546],{"type":49,"value":1158},{"type":44,"tag":87,"props":1548,"children":1549},{},[1550,1555],{"type":44,"tag":56,"props":1551,"children":1552},{},[1553],{"type":49,"value":1554},"Responsibility",{"type":49,"value":1556},": Finds or creates lobbies, tracks pending reservations, and maintains occupancy.",{"type":44,"tag":87,"props":1558,"children":1559},{},[1560,1565],{"type":44,"tag":56,"props":1561,"children":1562},{},[1563],{"type":49,"value":1564},"Actions",{"type":44,"tag":83,"props":1566,"children":1567},{},[1568,1577,1586,1595],{"type":44,"tag":87,"props":1569,"children":1570},{},[1571],{"type":44,"tag":62,"props":1572,"children":1574},{"className":1573},[],[1575],{"type":49,"value":1576},"findMatch",{"type":44,"tag":87,"props":1578,"children":1579},{},[1580],{"type":44,"tag":62,"props":1581,"children":1583},{"className":1582},[],[1584],{"type":49,"value":1585},"pendingPlayerConnected",{"type":44,"tag":87,"props":1587,"children":1588},{},[1589],{"type":44,"tag":62,"props":1590,"children":1592},{"className":1591},[],[1593],{"type":49,"value":1594},"updateMatch",{"type":44,"tag":87,"props":1596,"children":1597},{},[1598],{"type":44,"tag":62,"props":1599,"children":1601},{"className":1600},[],[1602],{"type":49,"value":1603},"closeMatch",{"type":44,"tag":87,"props":1605,"children":1606},{},[1607,1612],{"type":44,"tag":56,"props":1608,"children":1609},{},[1610],{"type":49,"value":1611},"Queues",{"type":44,"tag":83,"props":1613,"children":1614},{},[1615,1623,1631,1639],{"type":44,"tag":87,"props":1616,"children":1617},{},[1618],{"type":44,"tag":62,"props":1619,"children":1621},{"className":1620},[],[1622],{"type":49,"value":1576},{"type":44,"tag":87,"props":1624,"children":1625},{},[1626],{"type":44,"tag":62,"props":1627,"children":1629},{"className":1628},[],[1630],{"type":49,"value":1585},{"type":44,"tag":87,"props":1632,"children":1633},{},[1634],{"type":44,"tag":62,"props":1635,"children":1637},{"className":1636},[],[1638],{"type":49,"value":1594},{"type":44,"tag":87,"props":1640,"children":1641},{},[1642],{"type":44,"tag":62,"props":1643,"children":1645},{"className":1644},[],[1646],{"type":49,"value":1603},{"type":44,"tag":87,"props":1648,"children":1649},{},[1650,1655],{"type":44,"tag":56,"props":1651,"children":1652},{},[1653],{"type":49,"value":1654},"State",{"type":44,"tag":83,"props":1656,"children":1657},{},[1658,1663,1672,1681],{"type":44,"tag":87,"props":1659,"children":1660},{},[1661],{"type":49,"value":1662},"SQLite",{"type":44,"tag":87,"props":1664,"children":1665},{},[1666],{"type":44,"tag":62,"props":1667,"children":1669},{"className":1668},[],[1670],{"type":49,"value":1671},"matches",{"type":44,"tag":87,"props":1673,"children":1674},{},[1675],{"type":44,"tag":62,"props":1676,"children":1678},{"className":1677},[],[1679],{"type":49,"value":1680},"pending_players",{"type":44,"tag":87,"props":1682,"children":1683},{},[1684,1690],{"type":44,"tag":62,"props":1685,"children":1687},{"className":1686},[],[1688],{"type":49,"value":1689},"player_count",{"type":49,"value":1691}," includes connected and pending players",{"type":44,"tag":87,"props":1693,"children":1694},{},[1695,1699,1700],{"type":44,"tag":56,"props":1696,"children":1697},{},[1698],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":1701,"children":1703},{"className":1702},[],[1704],{"type":49,"value":1166},{"type":44,"tag":87,"props":1706,"children":1707},{},[1708,1712],{"type":44,"tag":56,"props":1709,"children":1710},{},[1711],{"type":49,"value":1554},{"type":49,"value":1713},": Runs lobby\u002Flive\u002Ffinished phases, owns player state, zone progression, and eliminations.",{"type":44,"tag":87,"props":1715,"children":1716},{},[1717,1721],{"type":44,"tag":56,"props":1718,"children":1719},{},[1720],{"type":49,"value":1564},{"type":44,"tag":83,"props":1722,"children":1723},{},[1724,1733],{"type":44,"tag":87,"props":1725,"children":1726},{},[1727],{"type":44,"tag":62,"props":1728,"children":1730},{"className":1729},[],[1731],{"type":49,"value":1732},"connect",{"type":44,"tag":87,"props":1734,"children":1735},{},[1736],{"type":49,"value":1737},"Movement and combat actions",{"type":44,"tag":87,"props":1739,"children":1740},{},[1741,1745],{"type":44,"tag":56,"props":1742,"children":1743},{},[1744],{"type":49,"value":1611},{"type":44,"tag":83,"props":1746,"children":1747},{},[1748],{"type":44,"tag":87,"props":1749,"children":1750},{},[1751],{"type":49,"value":1752},"None",{"type":44,"tag":87,"props":1754,"children":1755},{},[1756,1760],{"type":44,"tag":56,"props":1757,"children":1758},{},[1759],{"type":49,"value":1654},{"type":44,"tag":83,"props":1761,"children":1762},{},[1763,1768,1777,1786,1795,1804],{"type":44,"tag":87,"props":1764,"children":1765},{},[1766],{"type":49,"value":1767},"JSON",{"type":44,"tag":87,"props":1769,"children":1770},{},[1771],{"type":44,"tag":62,"props":1772,"children":1774},{"className":1773},[],[1775],{"type":49,"value":1776},"phase",{"type":44,"tag":87,"props":1778,"children":1779},{},[1780],{"type":44,"tag":62,"props":1781,"children":1783},{"className":1782},[],[1784],{"type":49,"value":1785},"players",{"type":44,"tag":87,"props":1787,"children":1788},{},[1789],{"type":44,"tag":62,"props":1790,"children":1792},{"className":1791},[],[1793],{"type":49,"value":1794},"zone",{"type":44,"tag":87,"props":1796,"children":1797},{},[1798],{"type":44,"tag":62,"props":1799,"children":1801},{"className":1800},[],[1802],{"type":49,"value":1803},"eliminations",{"type":44,"tag":87,"props":1805,"children":1806},{},[1807],{"type":44,"tag":62,"props":1808,"children":1810},{"className":1809},[],[1811],{"type":49,"value":1812},"snapshot data",{"type":44,"tag":52,"props":1814,"children":1815},{},[1816],{"type":44,"tag":56,"props":1817,"children":1818},{},[1819],{"type":49,"value":1820},"Lifecycle",{"type":44,"tag":1822,"props":1823,"children":1828},"pre",{"className":1824,"code":1825,"language":1826,"meta":1827,"style":1827},"language-mermaid shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","sequenceDiagram\n    participant C as Client\n    participant MM as matchmaker\n    participant M as match\n\n    C->>MM: findMatch()\n    alt no open lobby\n        MM->>M: create(matchId)\n    end\n    MM-->>C: {matchId, playerId}\n    C->>M: connect(playerId)\n    M->>MM: pendingPlayerConnected(matchId, playerId)\n    MM-->>M: accepted\n    Note over M: lobby countdown -> live\n    M-->>C: snapshot + shoot events\n    M->>MM: closeMatch(matchId)\n","mermaid","",[1829],{"type":44,"tag":62,"props":1830,"children":1831},{"__ignoreMap":1827},[1832,1843,1852,1861,1870,1880,1889,1897,1906,1915,1924,1933,1942,1951,1960,1969],{"type":44,"tag":1833,"props":1834,"children":1837},"span",{"class":1835,"line":1836},"line",1,[1838],{"type":44,"tag":1833,"props":1839,"children":1840},{},[1841],{"type":49,"value":1842},"sequenceDiagram\n",{"type":44,"tag":1833,"props":1844,"children":1846},{"class":1835,"line":1845},2,[1847],{"type":44,"tag":1833,"props":1848,"children":1849},{},[1850],{"type":49,"value":1851},"    participant C as Client\n",{"type":44,"tag":1833,"props":1853,"children":1855},{"class":1835,"line":1854},3,[1856],{"type":44,"tag":1833,"props":1857,"children":1858},{},[1859],{"type":49,"value":1860},"    participant MM as matchmaker\n",{"type":44,"tag":1833,"props":1862,"children":1864},{"class":1835,"line":1863},4,[1865],{"type":44,"tag":1833,"props":1866,"children":1867},{},[1868],{"type":49,"value":1869},"    participant M as match\n",{"type":44,"tag":1833,"props":1871,"children":1873},{"class":1835,"line":1872},5,[1874],{"type":44,"tag":1833,"props":1875,"children":1877},{"emptyLinePlaceholder":1876},true,[1878],{"type":49,"value":1879},"\n",{"type":44,"tag":1833,"props":1881,"children":1883},{"class":1835,"line":1882},6,[1884],{"type":44,"tag":1833,"props":1885,"children":1886},{},[1887],{"type":49,"value":1888},"    C->>MM: findMatch()\n",{"type":44,"tag":1833,"props":1890,"children":1891},{"class":1835,"line":31},[1892],{"type":44,"tag":1833,"props":1893,"children":1894},{},[1895],{"type":49,"value":1896},"    alt no open lobby\n",{"type":44,"tag":1833,"props":1898,"children":1900},{"class":1835,"line":1899},8,[1901],{"type":44,"tag":1833,"props":1902,"children":1903},{},[1904],{"type":49,"value":1905},"        MM->>M: create(matchId)\n",{"type":44,"tag":1833,"props":1907,"children":1909},{"class":1835,"line":1908},9,[1910],{"type":44,"tag":1833,"props":1911,"children":1912},{},[1913],{"type":49,"value":1914},"    end\n",{"type":44,"tag":1833,"props":1916,"children":1918},{"class":1835,"line":1917},10,[1919],{"type":44,"tag":1833,"props":1920,"children":1921},{},[1922],{"type":49,"value":1923},"    MM-->>C: {matchId, playerId}\n",{"type":44,"tag":1833,"props":1925,"children":1927},{"class":1835,"line":1926},11,[1928],{"type":44,"tag":1833,"props":1929,"children":1930},{},[1931],{"type":49,"value":1932},"    C->>M: connect(playerId)\n",{"type":44,"tag":1833,"props":1934,"children":1936},{"class":1835,"line":1935},12,[1937],{"type":44,"tag":1833,"props":1938,"children":1939},{},[1940],{"type":49,"value":1941},"    M->>MM: pendingPlayerConnected(matchId, playerId)\n",{"type":44,"tag":1833,"props":1943,"children":1945},{"class":1835,"line":1944},13,[1946],{"type":44,"tag":1833,"props":1947,"children":1948},{},[1949],{"type":49,"value":1950},"    MM-->>M: accepted\n",{"type":44,"tag":1833,"props":1952,"children":1954},{"class":1835,"line":1953},14,[1955],{"type":44,"tag":1833,"props":1956,"children":1957},{},[1958],{"type":49,"value":1959},"    Note over M: lobby countdown -> live\n",{"type":44,"tag":1833,"props":1961,"children":1963},{"class":1835,"line":1962},15,[1964],{"type":44,"tag":1833,"props":1965,"children":1966},{},[1967],{"type":49,"value":1968},"    M-->>C: snapshot + shoot events\n",{"type":44,"tag":1833,"props":1970,"children":1972},{"class":1835,"line":1971},16,[1973],{"type":44,"tag":1833,"props":1974,"children":1975},{},[1976],{"type":49,"value":1977},"    M->>MM: closeMatch(matchId)\n",{"type":44,"tag":383,"props":1979,"children":1981},{"id":1980},"arena",[1982],{"type":49,"value":185},{"type":44,"tag":125,"props":1984,"children":1985},{},[1986,2000],{"type":44,"tag":129,"props":1987,"children":1988},{},[1989],{"type":44,"tag":133,"props":1990,"children":1991},{},[1992,1996],{"type":44,"tag":137,"props":1993,"children":1994},{},[1995],{"type":49,"value":1440},{"type":44,"tag":137,"props":1997,"children":1998},{},[1999],{"type":49,"value":1445},{"type":44,"tag":152,"props":2001,"children":2002},{},[2003,2037,2049,2069],{"type":44,"tag":133,"props":2004,"children":2005},{},[2006,2010],{"type":44,"tag":159,"props":2007,"children":2008},{},[2009],{"type":49,"value":1456},{"type":44,"tag":159,"props":2011,"children":2012},{},[2013,2015,2021,2022,2028,2029,2035],{"type":49,"value":2014},"Mode-based fixed-capacity queues (",{"type":44,"tag":62,"props":2016,"children":2018},{"className":2017},[],[2019],{"type":49,"value":2020},"duo",{"type":49,"value":577},{"type":44,"tag":62,"props":2023,"children":2025},{"className":2024},[],[2026],{"type":49,"value":2027},"squad",{"type":49,"value":577},{"type":44,"tag":62,"props":2030,"children":2032},{"className":2031},[],[2033],{"type":49,"value":2034},"ffa",{"type":49,"value":2036},") that build only full matches and pre-assign teams (except FFA).",{"type":44,"tag":133,"props":2038,"children":2039},{},[2040,2044],{"type":44,"tag":159,"props":2041,"children":2042},{},[2043],{"type":49,"value":734},{"type":44,"tag":159,"props":2045,"children":2046},{},[2047],{"type":49,"value":2048},"Hybrid. Client owns movement plus prediction and smoothing. Server owns team or FFA assignment, projectiles, hit resolution, phase transitions, and scoring.",{"type":44,"tag":133,"props":2050,"children":2051},{},[2052,2056],{"type":44,"tag":159,"props":2053,"children":2054},{},[2055],{"type":49,"value":1481},{"type":44,"tag":159,"props":2057,"children":2058},{},[2059,2061,2067],{"type":49,"value":2060},"20 ticks\u002Fsec (",{"type":44,"tag":62,"props":2062,"children":2064},{"className":2063},[],[2065],{"type":49,"value":2066},"50ms",{"type":49,"value":2068},") with a tighter loop for live team and FFA snapshots.",{"type":44,"tag":133,"props":2070,"children":2071},{},[2072,2076],{"type":44,"tag":159,"props":2073,"children":2074},{},[2075],{"type":49,"value":507},{"type":44,"tag":159,"props":2077,"children":2078},{},[2079],{"type":49,"value":2080},"Medium to high intensity; client movement with server validation and server-authoritative combat\u002Fentities.",{"type":44,"tag":52,"props":2082,"children":2083},{},[2084],{"type":44,"tag":56,"props":2085,"children":2086},{},[2087],{"type":49,"value":1528},{"type":44,"tag":83,"props":2089,"children":2090},{},[2091,2104,2113,2150,2184,2226,2239,2248,2271,2285],{"type":44,"tag":87,"props":2092,"children":2093},{},[2094,2098,2099],{"type":44,"tag":56,"props":2095,"children":2096},{},[2097],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":2100,"children":2102},{"className":2101},[],[2103],{"type":49,"value":1158},{"type":44,"tag":87,"props":2105,"children":2106},{},[2107,2111],{"type":44,"tag":56,"props":2108,"children":2109},{},[2110],{"type":49,"value":1554},{"type":49,"value":2112},": Runs mode queues, builds full matches, assigns teams, and publishes assignments.",{"type":44,"tag":87,"props":2114,"children":2115},{},[2116,2120],{"type":44,"tag":56,"props":2117,"children":2118},{},[2119],{"type":49,"value":1564},{"type":44,"tag":83,"props":2121,"children":2122},{},[2123,2132,2141],{"type":44,"tag":87,"props":2124,"children":2125},{},[2126],{"type":44,"tag":62,"props":2127,"children":2129},{"className":2128},[],[2130],{"type":49,"value":2131},"queueForMatch",{"type":44,"tag":87,"props":2133,"children":2134},{},[2135],{"type":44,"tag":62,"props":2136,"children":2138},{"className":2137},[],[2139],{"type":49,"value":2140},"unqueueForMatch",{"type":44,"tag":87,"props":2142,"children":2143},{},[2144],{"type":44,"tag":62,"props":2145,"children":2147},{"className":2146},[],[2148],{"type":49,"value":2149},"matchCompleted",{"type":44,"tag":87,"props":2151,"children":2152},{},[2153,2157],{"type":44,"tag":56,"props":2154,"children":2155},{},[2156],{"type":49,"value":1611},{"type":44,"tag":83,"props":2158,"children":2159},{},[2160,2168,2176],{"type":44,"tag":87,"props":2161,"children":2162},{},[2163],{"type":44,"tag":62,"props":2164,"children":2166},{"className":2165},[],[2167],{"type":49,"value":2131},{"type":44,"tag":87,"props":2169,"children":2170},{},[2171],{"type":44,"tag":62,"props":2172,"children":2174},{"className":2173},[],[2175],{"type":49,"value":2140},{"type":44,"tag":87,"props":2177,"children":2178},{},[2179],{"type":44,"tag":62,"props":2180,"children":2182},{"className":2181},[],[2183],{"type":49,"value":2149},{"type":44,"tag":87,"props":2185,"children":2186},{},[2187,2191],{"type":44,"tag":56,"props":2188,"children":2189},{},[2190],{"type":49,"value":1654},{"type":44,"tag":83,"props":2192,"children":2193},{},[2194,2198,2207,2215],{"type":44,"tag":87,"props":2195,"children":2196},{},[2197],{"type":49,"value":1662},{"type":44,"tag":87,"props":2199,"children":2200},{},[2201],{"type":44,"tag":62,"props":2202,"children":2204},{"className":2203},[],[2205],{"type":49,"value":2206},"player_pool",{"type":44,"tag":87,"props":2208,"children":2209},{},[2210],{"type":44,"tag":62,"props":2211,"children":2213},{"className":2212},[],[2214],{"type":49,"value":1671},{"type":44,"tag":87,"props":2216,"children":2217},{},[2218,2224],{"type":44,"tag":62,"props":2219,"children":2221},{"className":2220},[],[2222],{"type":49,"value":2223},"assignments",{"type":49,"value":2225}," keyed by connection and player",{"type":44,"tag":87,"props":2227,"children":2228},{},[2229,2233,2234],{"type":44,"tag":56,"props":2230,"children":2231},{},[2232],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":2235,"children":2237},{"className":2236},[],[2238],{"type":49,"value":1166},{"type":44,"tag":87,"props":2240,"children":2241},{},[2242,2246],{"type":44,"tag":56,"props":2243,"children":2244},{},[2245],{"type":49,"value":1554},{"type":49,"value":2247},": Runs match phases and in-match player\u002Fteam state for score and win conditions.",{"type":44,"tag":87,"props":2249,"children":2250},{},[2251,2255],{"type":44,"tag":56,"props":2252,"children":2253},{},[2254],{"type":49,"value":1564},{"type":44,"tag":83,"props":2256,"children":2257},{},[2258,2266],{"type":44,"tag":87,"props":2259,"children":2260},{},[2261],{"type":44,"tag":62,"props":2262,"children":2264},{"className":2263},[],[2265],{"type":49,"value":1732},{"type":44,"tag":87,"props":2267,"children":2268},{},[2269],{"type":49,"value":2270},"Gameplay actions",{"type":44,"tag":87,"props":2272,"children":2273},{},[2274,2278],{"type":44,"tag":56,"props":2275,"children":2276},{},[2277],{"type":49,"value":1611},{"type":44,"tag":83,"props":2279,"children":2280},{},[2281],{"type":44,"tag":87,"props":2282,"children":2283},{},[2284],{"type":49,"value":1752},{"type":44,"tag":87,"props":2286,"children":2287},{},[2288,2292],{"type":44,"tag":56,"props":2289,"children":2290},{},[2291],{"type":49,"value":1654},{"type":44,"tag":83,"props":2293,"children":2294},{},[2295,2299,2307,2315,2324],{"type":44,"tag":87,"props":2296,"children":2297},{},[2298],{"type":49,"value":1767},{"type":44,"tag":87,"props":2300,"children":2301},{},[2302],{"type":44,"tag":62,"props":2303,"children":2305},{"className":2304},[],[2306],{"type":49,"value":1776},{"type":44,"tag":87,"props":2308,"children":2309},{},[2310],{"type":44,"tag":62,"props":2311,"children":2313},{"className":2312},[],[2314],{"type":49,"value":1785},{"type":44,"tag":87,"props":2316,"children":2317},{},[2318],{"type":44,"tag":62,"props":2319,"children":2321},{"className":2320},[],[2322],{"type":49,"value":2323},"team assignments",{"type":44,"tag":87,"props":2325,"children":2326},{},[2327],{"type":44,"tag":62,"props":2328,"children":2330},{"className":2329},[],[2331],{"type":49,"value":2332},"score and win state",{"type":44,"tag":52,"props":2334,"children":2335},{},[2336],{"type":44,"tag":56,"props":2337,"children":2338},{},[2339],{"type":49,"value":1820},{"type":44,"tag":1822,"props":2341,"children":2343},{"className":1824,"code":2342,"language":1826,"meta":1827,"style":1827},"sequenceDiagram\n    participant C as Client\n    participant MM as matchmaker\n    participant M as match\n\n    C->>MM: queueForMatch(mode)\n    Note over MM: enqueue in player_pool\n    Note over MM: fill when capacity reached\n    MM->>M: create(matchId, assignments)\n    Note over MM: persist assignments\n    MM-->>C: assignmentReady\n    C->>M: connect(playerId)\n    Note over M: waiting -> live when all players connect\n    M->>MM: matchCompleted(matchId)\n",[2344],{"type":44,"tag":62,"props":2345,"children":2346},{"__ignoreMap":1827},[2347,2354,2361,2368,2375,2382,2390,2398,2406,2414,2422,2430,2437,2445],{"type":44,"tag":1833,"props":2348,"children":2349},{"class":1835,"line":1836},[2350],{"type":44,"tag":1833,"props":2351,"children":2352},{},[2353],{"type":49,"value":1842},{"type":44,"tag":1833,"props":2355,"children":2356},{"class":1835,"line":1845},[2357],{"type":44,"tag":1833,"props":2358,"children":2359},{},[2360],{"type":49,"value":1851},{"type":44,"tag":1833,"props":2362,"children":2363},{"class":1835,"line":1854},[2364],{"type":44,"tag":1833,"props":2365,"children":2366},{},[2367],{"type":49,"value":1860},{"type":44,"tag":1833,"props":2369,"children":2370},{"class":1835,"line":1863},[2371],{"type":44,"tag":1833,"props":2372,"children":2373},{},[2374],{"type":49,"value":1869},{"type":44,"tag":1833,"props":2376,"children":2377},{"class":1835,"line":1872},[2378],{"type":44,"tag":1833,"props":2379,"children":2380},{"emptyLinePlaceholder":1876},[2381],{"type":49,"value":1879},{"type":44,"tag":1833,"props":2383,"children":2384},{"class":1835,"line":1882},[2385],{"type":44,"tag":1833,"props":2386,"children":2387},{},[2388],{"type":49,"value":2389},"    C->>MM: queueForMatch(mode)\n",{"type":44,"tag":1833,"props":2391,"children":2392},{"class":1835,"line":31},[2393],{"type":44,"tag":1833,"props":2394,"children":2395},{},[2396],{"type":49,"value":2397},"    Note over MM: enqueue in player_pool\n",{"type":44,"tag":1833,"props":2399,"children":2400},{"class":1835,"line":1899},[2401],{"type":44,"tag":1833,"props":2402,"children":2403},{},[2404],{"type":49,"value":2405},"    Note over MM: fill when capacity reached\n",{"type":44,"tag":1833,"props":2407,"children":2408},{"class":1835,"line":1908},[2409],{"type":44,"tag":1833,"props":2410,"children":2411},{},[2412],{"type":49,"value":2413},"    MM->>M: create(matchId, assignments)\n",{"type":44,"tag":1833,"props":2415,"children":2416},{"class":1835,"line":1917},[2417],{"type":44,"tag":1833,"props":2418,"children":2419},{},[2420],{"type":49,"value":2421},"    Note over MM: persist assignments\n",{"type":44,"tag":1833,"props":2423,"children":2424},{"class":1835,"line":1926},[2425],{"type":44,"tag":1833,"props":2426,"children":2427},{},[2428],{"type":49,"value":2429},"    MM-->>C: assignmentReady\n",{"type":44,"tag":1833,"props":2431,"children":2432},{"class":1835,"line":1935},[2433],{"type":44,"tag":1833,"props":2434,"children":2435},{},[2436],{"type":49,"value":1932},{"type":44,"tag":1833,"props":2438,"children":2439},{"class":1835,"line":1944},[2440],{"type":44,"tag":1833,"props":2441,"children":2442},{},[2443],{"type":49,"value":2444},"    Note over M: waiting -> live when all players connect\n",{"type":44,"tag":1833,"props":2446,"children":2447},{"class":1835,"line":1953},[2448],{"type":44,"tag":1833,"props":2449,"children":2450},{},[2451],{"type":49,"value":2452},"    M->>MM: matchCompleted(matchId)\n",{"type":44,"tag":383,"props":2454,"children":2456},{"id":2455},"io-style",[2457],{"type":49,"value":207},{"type":44,"tag":125,"props":2459,"children":2460},{},[2461,2475],{"type":44,"tag":129,"props":2462,"children":2463},{},[2464],{"type":44,"tag":133,"props":2465,"children":2466},{},[2467,2471],{"type":44,"tag":137,"props":2468,"children":2469},{},[2470],{"type":49,"value":1440},{"type":44,"tag":137,"props":2472,"children":2473},{},[2474],{"type":49,"value":1445},{"type":44,"tag":152,"props":2476,"children":2477},{},[2478,2490,2502,2520],{"type":44,"tag":133,"props":2479,"children":2480},{},[2481,2485],{"type":44,"tag":159,"props":2482,"children":2483},{},[2484],{"type":49,"value":1456},{"type":44,"tag":159,"props":2486,"children":2487},{},[2488],{"type":49,"value":2489},"Open-lobby routing to the fullest room below capacity; room counts are heartbeated and new lobbies are auto-created when needed.",{"type":44,"tag":133,"props":2491,"children":2492},{},[2493,2497],{"type":44,"tag":159,"props":2494,"children":2495},{},[2496],{"type":49,"value":734},{"type":44,"tag":159,"props":2498,"children":2499},{},[2500],{"type":49,"value":2501},"Server-authoritative with interpolation. Client sends input intents and interpolates. Server owns movement, bounds, room membership, and canonical snapshots.",{"type":44,"tag":133,"props":2503,"children":2504},{},[2505,2509],{"type":44,"tag":159,"props":2506,"children":2507},{},[2508],{"type":49,"value":1481},{"type":44,"tag":159,"props":2510,"children":2511},{},[2512,2513,2518],{"type":49,"value":1486},{"type":44,"tag":62,"props":2514,"children":2516},{"className":2515},[],[2517],{"type":49,"value":1492},{"type":49,"value":2519},") with lightweight periodic room snapshots.",{"type":44,"tag":133,"props":2521,"children":2522},{},[2523,2527],{"type":44,"tag":159,"props":2524,"children":2525},{},[2526],{"type":49,"value":507},{"type":44,"tag":159,"props":2528,"children":2529},{},[2530],{"type":49,"value":2531},"Low to medium intensity; server-authoritative kinematic movement, escalating to a physics engine only when collisions get complex.",{"type":44,"tag":52,"props":2533,"children":2534},{},[2535],{"type":44,"tag":56,"props":2536,"children":2537},{},[2538],{"type":49,"value":1528},{"type":44,"tag":83,"props":2540,"children":2541},{},[2542,2555,2564,2607,2649,2684,2697,2706,2733,2747],{"type":44,"tag":87,"props":2543,"children":2544},{},[2545,2549,2550],{"type":44,"tag":56,"props":2546,"children":2547},{},[2548],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":2551,"children":2553},{"className":2552},[],[2554],{"type":49,"value":1158},{"type":44,"tag":87,"props":2556,"children":2557},{},[2558,2562],{"type":44,"tag":56,"props":2559,"children":2560},{},[2561],{"type":49,"value":1554},{"type":49,"value":2563},": Routes players into the fullest open lobby and tracks reservations and occupancy.",{"type":44,"tag":87,"props":2565,"children":2566},{},[2567,2571],{"type":44,"tag":56,"props":2568,"children":2569},{},[2570],{"type":49,"value":1564},{"type":44,"tag":83,"props":2572,"children":2573},{},[2574,2583,2591,2599],{"type":44,"tag":87,"props":2575,"children":2576},{},[2577],{"type":44,"tag":62,"props":2578,"children":2580},{"className":2579},[],[2581],{"type":49,"value":2582},"findLobby",{"type":44,"tag":87,"props":2584,"children":2585},{},[2586],{"type":44,"tag":62,"props":2587,"children":2589},{"className":2588},[],[2590],{"type":49,"value":1585},{"type":44,"tag":87,"props":2592,"children":2593},{},[2594],{"type":44,"tag":62,"props":2595,"children":2597},{"className":2596},[],[2598],{"type":49,"value":1594},{"type":44,"tag":87,"props":2600,"children":2601},{},[2602],{"type":44,"tag":62,"props":2603,"children":2605},{"className":2604},[],[2606],{"type":49,"value":1603},{"type":44,"tag":87,"props":2608,"children":2609},{},[2610,2614],{"type":44,"tag":56,"props":2611,"children":2612},{},[2613],{"type":49,"value":1611},{"type":44,"tag":83,"props":2615,"children":2616},{},[2617,2625,2633,2641],{"type":44,"tag":87,"props":2618,"children":2619},{},[2620],{"type":44,"tag":62,"props":2621,"children":2623},{"className":2622},[],[2624],{"type":49,"value":2582},{"type":44,"tag":87,"props":2626,"children":2627},{},[2628],{"type":44,"tag":62,"props":2629,"children":2631},{"className":2630},[],[2632],{"type":49,"value":1585},{"type":44,"tag":87,"props":2634,"children":2635},{},[2636],{"type":44,"tag":62,"props":2637,"children":2639},{"className":2638},[],[2640],{"type":49,"value":1594},{"type":44,"tag":87,"props":2642,"children":2643},{},[2644],{"type":44,"tag":62,"props":2645,"children":2647},{"className":2646},[],[2648],{"type":49,"value":1603},{"type":44,"tag":87,"props":2650,"children":2651},{},[2652,2656],{"type":44,"tag":56,"props":2653,"children":2654},{},[2655],{"type":49,"value":1654},{"type":44,"tag":83,"props":2657,"children":2658},{},[2659,2663,2671,2679],{"type":44,"tag":87,"props":2660,"children":2661},{},[2662],{"type":49,"value":1662},{"type":44,"tag":87,"props":2664,"children":2665},{},[2666],{"type":44,"tag":62,"props":2667,"children":2669},{"className":2668},[],[2670],{"type":49,"value":1671},{"type":44,"tag":87,"props":2672,"children":2673},{},[2674],{"type":44,"tag":62,"props":2675,"children":2677},{"className":2676},[],[2678],{"type":49,"value":1680},{"type":44,"tag":87,"props":2680,"children":2681},{},[2682],{"type":49,"value":2683},"Occupancy includes pending reservations",{"type":44,"tag":87,"props":2685,"children":2686},{},[2687,2691,2692],{"type":44,"tag":56,"props":2688,"children":2689},{},[2690],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":2693,"children":2695},{"className":2694},[],[2696],{"type":49,"value":1166},{"type":44,"tag":87,"props":2698,"children":2699},{},[2700,2704],{"type":44,"tag":56,"props":2701,"children":2702},{},[2703],{"type":49,"value":1554},{"type":49,"value":2705},": Runs per-match movement simulation and broadcasts snapshots.",{"type":44,"tag":87,"props":2707,"children":2708},{},[2709,2713],{"type":44,"tag":56,"props":2710,"children":2711},{},[2712],{"type":49,"value":1564},{"type":44,"tag":83,"props":2714,"children":2715},{},[2716,2724],{"type":44,"tag":87,"props":2717,"children":2718},{},[2719],{"type":44,"tag":62,"props":2720,"children":2722},{"className":2721},[],[2723],{"type":49,"value":1732},{"type":44,"tag":87,"props":2725,"children":2726},{},[2727],{"type":44,"tag":62,"props":2728,"children":2730},{"className":2729},[],[2731],{"type":49,"value":2732},"setInput",{"type":44,"tag":87,"props":2734,"children":2735},{},[2736,2740],{"type":44,"tag":56,"props":2737,"children":2738},{},[2739],{"type":49,"value":1611},{"type":44,"tag":83,"props":2741,"children":2742},{},[2743],{"type":44,"tag":87,"props":2744,"children":2745},{},[2746],{"type":49,"value":1752},{"type":44,"tag":87,"props":2748,"children":2749},{},[2750,2754],{"type":44,"tag":56,"props":2751,"children":2752},{},[2753],{"type":49,"value":1654},{"type":44,"tag":83,"props":2755,"children":2756},{},[2757,2761,2769,2778,2787],{"type":44,"tag":87,"props":2758,"children":2759},{},[2760],{"type":49,"value":1767},{"type":44,"tag":87,"props":2762,"children":2763},{},[2764],{"type":44,"tag":62,"props":2765,"children":2767},{"className":2766},[],[2768],{"type":49,"value":1785},{"type":44,"tag":87,"props":2770,"children":2771},{},[2772],{"type":44,"tag":62,"props":2773,"children":2775},{"className":2774},[],[2776],{"type":49,"value":2777},"inputs",{"type":44,"tag":87,"props":2779,"children":2780},{},[2781],{"type":44,"tag":62,"props":2782,"children":2784},{"className":2783},[],[2785],{"type":49,"value":2786},"movement state",{"type":44,"tag":87,"props":2788,"children":2789},{},[2790],{"type":44,"tag":62,"props":2791,"children":2793},{"className":2792},[],[2794],{"type":49,"value":2795},"snapshot cache",{"type":44,"tag":52,"props":2797,"children":2798},{},[2799],{"type":44,"tag":56,"props":2800,"children":2801},{},[2802],{"type":49,"value":1820},{"type":44,"tag":1822,"props":2804,"children":2806},{"className":1824,"code":2805,"language":1826,"meta":1827,"style":1827},"sequenceDiagram\n    participant C as Client\n    participant MM as matchmaker\n    participant M as match\n\n    C->>MM: findLobby()\n    alt no open lobby\n        MM->>M: create(matchId)\n    end\n    MM-->>C: {matchId, playerId}\n    C->>M: connect(playerId)\n    M->>MM: pendingPlayerConnected(matchId, playerId)\n    MM-->>M: accepted\n    Note over M: fixed tick simulation\n    M-->>C: snapshot events\n    M->>MM: closeMatch(matchId)\n",[2807],{"type":44,"tag":62,"props":2808,"children":2809},{"__ignoreMap":1827},[2810,2817,2824,2831,2838,2845,2853,2860,2867,2874,2881,2888,2895,2902,2910,2918],{"type":44,"tag":1833,"props":2811,"children":2812},{"class":1835,"line":1836},[2813],{"type":44,"tag":1833,"props":2814,"children":2815},{},[2816],{"type":49,"value":1842},{"type":44,"tag":1833,"props":2818,"children":2819},{"class":1835,"line":1845},[2820],{"type":44,"tag":1833,"props":2821,"children":2822},{},[2823],{"type":49,"value":1851},{"type":44,"tag":1833,"props":2825,"children":2826},{"class":1835,"line":1854},[2827],{"type":44,"tag":1833,"props":2828,"children":2829},{},[2830],{"type":49,"value":1860},{"type":44,"tag":1833,"props":2832,"children":2833},{"class":1835,"line":1863},[2834],{"type":44,"tag":1833,"props":2835,"children":2836},{},[2837],{"type":49,"value":1869},{"type":44,"tag":1833,"props":2839,"children":2840},{"class":1835,"line":1872},[2841],{"type":44,"tag":1833,"props":2842,"children":2843},{"emptyLinePlaceholder":1876},[2844],{"type":49,"value":1879},{"type":44,"tag":1833,"props":2846,"children":2847},{"class":1835,"line":1882},[2848],{"type":44,"tag":1833,"props":2849,"children":2850},{},[2851],{"type":49,"value":2852},"    C->>MM: findLobby()\n",{"type":44,"tag":1833,"props":2854,"children":2855},{"class":1835,"line":31},[2856],{"type":44,"tag":1833,"props":2857,"children":2858},{},[2859],{"type":49,"value":1896},{"type":44,"tag":1833,"props":2861,"children":2862},{"class":1835,"line":1899},[2863],{"type":44,"tag":1833,"props":2864,"children":2865},{},[2866],{"type":49,"value":1905},{"type":44,"tag":1833,"props":2868,"children":2869},{"class":1835,"line":1908},[2870],{"type":44,"tag":1833,"props":2871,"children":2872},{},[2873],{"type":49,"value":1914},{"type":44,"tag":1833,"props":2875,"children":2876},{"class":1835,"line":1917},[2877],{"type":44,"tag":1833,"props":2878,"children":2879},{},[2880],{"type":49,"value":1923},{"type":44,"tag":1833,"props":2882,"children":2883},{"class":1835,"line":1926},[2884],{"type":44,"tag":1833,"props":2885,"children":2886},{},[2887],{"type":49,"value":1932},{"type":44,"tag":1833,"props":2889,"children":2890},{"class":1835,"line":1935},[2891],{"type":44,"tag":1833,"props":2892,"children":2893},{},[2894],{"type":49,"value":1941},{"type":44,"tag":1833,"props":2896,"children":2897},{"class":1835,"line":1944},[2898],{"type":44,"tag":1833,"props":2899,"children":2900},{},[2901],{"type":49,"value":1950},{"type":44,"tag":1833,"props":2903,"children":2904},{"class":1835,"line":1953},[2905],{"type":44,"tag":1833,"props":2906,"children":2907},{},[2908],{"type":49,"value":2909},"    Note over M: fixed tick simulation\n",{"type":44,"tag":1833,"props":2911,"children":2912},{"class":1835,"line":1962},[2913],{"type":44,"tag":1833,"props":2914,"children":2915},{},[2916],{"type":49,"value":2917},"    M-->>C: snapshot events\n",{"type":44,"tag":1833,"props":2919,"children":2920},{"class":1835,"line":1971},[2921],{"type":44,"tag":1833,"props":2922,"children":2923},{},[2924],{"type":49,"value":1977},{"type":44,"tag":383,"props":2926,"children":2928},{"id":2927},"open-world",[2929],{"type":49,"value":229},{"type":44,"tag":125,"props":2931,"children":2932},{},[2933,2947],{"type":44,"tag":129,"props":2934,"children":2935},{},[2936],{"type":44,"tag":133,"props":2937,"children":2938},{},[2939,2943],{"type":44,"tag":137,"props":2940,"children":2941},{},[2942],{"type":49,"value":1440},{"type":44,"tag":137,"props":2944,"children":2945},{},[2946],{"type":49,"value":1445},{"type":44,"tag":152,"props":2948,"children":2949},{},[2950,2962,2974,2993],{"type":44,"tag":133,"props":2951,"children":2952},{},[2953,2957],{"type":44,"tag":159,"props":2954,"children":2955},{},[2956],{"type":49,"value":1456},{"type":44,"tag":159,"props":2958,"children":2959},{},[2960],{"type":49,"value":2961},"Client-driven chunk routing from world coordinates, with nearby chunk windows preloaded via adjacent chunk connections.",{"type":44,"tag":133,"props":2963,"children":2964},{},[2965,2969],{"type":44,"tag":159,"props":2966,"children":2967},{},[2968],{"type":49,"value":734},{"type":44,"tag":159,"props":2970,"children":2971},{},[2972],{"type":49,"value":2973},"Hybrid for sandbox (client movement with validation) or server-authoritative for MMO-like flows. Server owns chunk routing, persistence, and canonical world state.",{"type":44,"tag":133,"props":2975,"children":2976},{},[2977,2981],{"type":44,"tag":159,"props":2978,"children":2979},{},[2980],{"type":49,"value":1481},{"type":44,"tag":159,"props":2982,"children":2983},{},[2984,2986,2991],{"type":49,"value":2985},"10 ticks\u002Fsec per chunk actor (",{"type":44,"tag":62,"props":2987,"children":2989},{"className":2988},[],[2990],{"type":49,"value":1492},{"type":49,"value":2992},"), so load scales with active chunks.",{"type":44,"tag":133,"props":2994,"children":2995},{},[2996,3000],{"type":44,"tag":159,"props":2997,"children":2998},{},[2999],{"type":49,"value":507},{"type":44,"tag":159,"props":3001,"children":3002},{},[3003],{"type":49,"value":3004},"Medium to high at scale; chunk-local simulation can be server-authoritative (MMO-like) or client movement with server validation (sandbox-like).",{"type":44,"tag":52,"props":3006,"children":3007},{},[3008],{"type":44,"tag":56,"props":3009,"children":3010},{},[3011],{"type":49,"value":1528},{"type":44,"tag":83,"props":3013,"children":3014},{},[3015,3028,3037,3099,3113],{"type":44,"tag":87,"props":3016,"children":3017},{},[3018,3022,3023],{"type":44,"tag":56,"props":3019,"children":3020},{},[3021],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":3024,"children":3026},{"className":3025},[],[3027],{"type":49,"value":1188},{"type":44,"tag":87,"props":3029,"children":3030},{},[3031,3035],{"type":44,"tag":56,"props":3032,"children":3033},{},[3034],{"type":49,"value":1554},{"type":49,"value":3036},": Owns chunk-local players, blocks, movement tick, and chunk membership.",{"type":44,"tag":87,"props":3038,"children":3039},{},[3040,3044],{"type":44,"tag":56,"props":3041,"children":3042},{},[3043],{"type":49,"value":1564},{"type":44,"tag":83,"props":3045,"children":3046},{},[3047,3055,3064,3073,3081,3090],{"type":44,"tag":87,"props":3048,"children":3049},{},[3050],{"type":44,"tag":62,"props":3051,"children":3053},{"className":3052},[],[3054],{"type":49,"value":1732},{"type":44,"tag":87,"props":3056,"children":3057},{},[3058],{"type":44,"tag":62,"props":3059,"children":3061},{"className":3060},[],[3062],{"type":49,"value":3063},"enterChunk",{"type":44,"tag":87,"props":3065,"children":3066},{},[3067],{"type":44,"tag":62,"props":3068,"children":3070},{"className":3069},[],[3071],{"type":49,"value":3072},"addPlayer",{"type":44,"tag":87,"props":3074,"children":3075},{},[3076],{"type":44,"tag":62,"props":3077,"children":3079},{"className":3078},[],[3080],{"type":49,"value":2732},{"type":44,"tag":87,"props":3082,"children":3083},{},[3084],{"type":44,"tag":62,"props":3085,"children":3087},{"className":3086},[],[3088],{"type":49,"value":3089},"leaveChunk",{"type":44,"tag":87,"props":3091,"children":3092},{},[3093],{"type":44,"tag":62,"props":3094,"children":3096},{"className":3095},[],[3097],{"type":49,"value":3098},"removePlayer",{"type":44,"tag":87,"props":3100,"children":3101},{},[3102,3106],{"type":44,"tag":56,"props":3103,"children":3104},{},[3105],{"type":49,"value":1611},{"type":44,"tag":83,"props":3107,"children":3108},{},[3109],{"type":44,"tag":87,"props":3110,"children":3111},{},[3112],{"type":49,"value":1752},{"type":44,"tag":87,"props":3114,"children":3115},{},[3116,3120],{"type":44,"tag":56,"props":3117,"children":3118},{},[3119],{"type":49,"value":1654},{"type":44,"tag":83,"props":3121,"children":3122},{},[3123,3127,3136,3144],{"type":44,"tag":87,"props":3124,"children":3125},{},[3126],{"type":49,"value":1767},{"type":44,"tag":87,"props":3128,"children":3129},{},[3130],{"type":44,"tag":62,"props":3131,"children":3133},{"className":3132},[],[3134],{"type":49,"value":3135},"connections",{"type":44,"tag":87,"props":3137,"children":3138},{},[3139],{"type":44,"tag":62,"props":3140,"children":3142},{"className":3141},[],[3143],{"type":49,"value":1785},{"type":44,"tag":87,"props":3145,"children":3146},{},[3147,3153],{"type":44,"tag":62,"props":3148,"children":3150},{"className":3149},[],[3151],{"type":49,"value":3152},"blocks",{"type":49,"value":3154}," scoped to one chunk key",{"type":44,"tag":52,"props":3156,"children":3157},{},[3158],{"type":44,"tag":56,"props":3159,"children":3160},{},[3161],{"type":49,"value":1820},{"type":44,"tag":1822,"props":3163,"children":3165},{"className":1824,"code":3164,"language":1826,"meta":1827,"style":1827},"sequenceDiagram\n    participant C as Client\n    participant CH as chunk\n\n    Note over C: resolve chunk keys from world position\n    loop each visible chunk\n        C->>CH: connect(worldId, chunkX, chunkY, playerId)\n        Note over CH: store connection metadata\n    end\n    C->>CH: enterChunk\u002FaddPlayer\n    loop movement updates\n        C->>CH: setInput(...)\n        CH-->>C: snapshot\n    end\n    C->>CH: leaveChunk\u002FremovePlayer or disconnect\n    Note over CH: remove membership and metadata\n",[3166],{"type":44,"tag":62,"props":3167,"children":3168},{"__ignoreMap":1827},[3169,3176,3183,3191,3198,3206,3214,3222,3230,3237,3245,3253,3261,3269,3276,3284],{"type":44,"tag":1833,"props":3170,"children":3171},{"class":1835,"line":1836},[3172],{"type":44,"tag":1833,"props":3173,"children":3174},{},[3175],{"type":49,"value":1842},{"type":44,"tag":1833,"props":3177,"children":3178},{"class":1835,"line":1845},[3179],{"type":44,"tag":1833,"props":3180,"children":3181},{},[3182],{"type":49,"value":1851},{"type":44,"tag":1833,"props":3184,"children":3185},{"class":1835,"line":1854},[3186],{"type":44,"tag":1833,"props":3187,"children":3188},{},[3189],{"type":49,"value":3190},"    participant CH as chunk\n",{"type":44,"tag":1833,"props":3192,"children":3193},{"class":1835,"line":1863},[3194],{"type":44,"tag":1833,"props":3195,"children":3196},{"emptyLinePlaceholder":1876},[3197],{"type":49,"value":1879},{"type":44,"tag":1833,"props":3199,"children":3200},{"class":1835,"line":1872},[3201],{"type":44,"tag":1833,"props":3202,"children":3203},{},[3204],{"type":49,"value":3205},"    Note over C: resolve chunk keys from world position\n",{"type":44,"tag":1833,"props":3207,"children":3208},{"class":1835,"line":1882},[3209],{"type":44,"tag":1833,"props":3210,"children":3211},{},[3212],{"type":49,"value":3213},"    loop each visible chunk\n",{"type":44,"tag":1833,"props":3215,"children":3216},{"class":1835,"line":31},[3217],{"type":44,"tag":1833,"props":3218,"children":3219},{},[3220],{"type":49,"value":3221},"        C->>CH: connect(worldId, chunkX, chunkY, playerId)\n",{"type":44,"tag":1833,"props":3223,"children":3224},{"class":1835,"line":1899},[3225],{"type":44,"tag":1833,"props":3226,"children":3227},{},[3228],{"type":49,"value":3229},"        Note over CH: store connection metadata\n",{"type":44,"tag":1833,"props":3231,"children":3232},{"class":1835,"line":1908},[3233],{"type":44,"tag":1833,"props":3234,"children":3235},{},[3236],{"type":49,"value":1914},{"type":44,"tag":1833,"props":3238,"children":3239},{"class":1835,"line":1917},[3240],{"type":44,"tag":1833,"props":3241,"children":3242},{},[3243],{"type":49,"value":3244},"    C->>CH: enterChunk\u002FaddPlayer\n",{"type":44,"tag":1833,"props":3246,"children":3247},{"class":1835,"line":1926},[3248],{"type":44,"tag":1833,"props":3249,"children":3250},{},[3251],{"type":49,"value":3252},"    loop movement updates\n",{"type":44,"tag":1833,"props":3254,"children":3255},{"class":1835,"line":1935},[3256],{"type":44,"tag":1833,"props":3257,"children":3258},{},[3259],{"type":49,"value":3260},"        C->>CH: setInput(...)\n",{"type":44,"tag":1833,"props":3262,"children":3263},{"class":1835,"line":1944},[3264],{"type":44,"tag":1833,"props":3265,"children":3266},{},[3267],{"type":49,"value":3268},"        CH-->>C: snapshot\n",{"type":44,"tag":1833,"props":3270,"children":3271},{"class":1835,"line":1953},[3272],{"type":44,"tag":1833,"props":3273,"children":3274},{},[3275],{"type":49,"value":1914},{"type":44,"tag":1833,"props":3277,"children":3278},{"class":1835,"line":1962},[3279],{"type":44,"tag":1833,"props":3280,"children":3281},{},[3282],{"type":49,"value":3283},"    C->>CH: leaveChunk\u002FremovePlayer or disconnect\n",{"type":44,"tag":1833,"props":3285,"children":3286},{"class":1835,"line":1971},[3287],{"type":44,"tag":1833,"props":3288,"children":3289},{},[3290],{"type":49,"value":3291},"    Note over CH: remove membership and metadata\n",{"type":44,"tag":383,"props":3293,"children":3295},{"id":3294},"party",[3296],{"type":49,"value":251},{"type":44,"tag":125,"props":3298,"children":3299},{},[3300,3314],{"type":44,"tag":129,"props":3301,"children":3302},{},[3303],{"type":44,"tag":133,"props":3304,"children":3305},{},[3306,3310],{"type":44,"tag":137,"props":3307,"children":3308},{},[3309],{"type":49,"value":1440},{"type":44,"tag":137,"props":3311,"children":3312},{},[3313],{"type":49,"value":1445},{"type":44,"tag":152,"props":3315,"children":3316},{},[3317,3329,3341,3375],{"type":44,"tag":133,"props":3318,"children":3319},{},[3320,3324],{"type":44,"tag":159,"props":3321,"children":3322},{},[3323],{"type":49,"value":1456},{"type":44,"tag":159,"props":3325,"children":3326},{},[3327],{"type":49,"value":3328},"Host-created private party flow using party codes and explicit joins.",{"type":44,"tag":133,"props":3330,"children":3331},{},[3332,3336],{"type":44,"tag":159,"props":3333,"children":3334},{},[3335],{"type":49,"value":734},{"type":44,"tag":159,"props":3337,"children":3338},{},[3339],{"type":49,"value":3340},"Server-authoritative (basic logic). Server owns membership, host permissions, and phase transitions.",{"type":44,"tag":133,"props":3342,"children":3343},{},[3344,3348],{"type":44,"tag":159,"props":3345,"children":3346},{},[3347],{"type":49,"value":1481},{"type":44,"tag":159,"props":3349,"children":3350},{},[3351,3353,3359,3360,3366,3367,3373],{"type":49,"value":3352},"No continuous tick; updates are event-driven (",{"type":44,"tag":62,"props":3354,"children":3356},{"className":3355},[],[3357],{"type":49,"value":3358},"join",{"type":49,"value":577},{"type":44,"tag":62,"props":3361,"children":3363},{"className":3362},[],[3364],{"type":49,"value":3365},"start",{"type":49,"value":577},{"type":44,"tag":62,"props":3368,"children":3370},{"className":3369},[],[3371],{"type":49,"value":3372},"finish",{"type":49,"value":3374},").",{"type":44,"tag":133,"props":3376,"children":3377},{},[3378,3382],{"type":44,"tag":159,"props":3379,"children":3380},{},[3381],{"type":49,"value":507},{"type":44,"tag":159,"props":3383,"children":3384},{},[3385],{"type":49,"value":3386},"Low intensity for lobby-first flows; usually no dedicated physics or indexing unless you add realtime mini-games.",{"type":44,"tag":52,"props":3388,"children":3389},{},[3390],{"type":44,"tag":56,"props":3391,"children":3392},{},[3393],{"type":49,"value":1528},{"type":44,"tag":83,"props":3395,"children":3396},{},[3397,3410,3419,3474,3524,3558,3571,3580,3616,3630],{"type":44,"tag":87,"props":3398,"children":3399},{},[3400,3404,3405],{"type":44,"tag":56,"props":3401,"children":3402},{},[3403],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":3406,"children":3408},{"className":3407},[],[3409],{"type":49,"value":1158},{"type":44,"tag":87,"props":3411,"children":3412},{},[3413,3417],{"type":44,"tag":56,"props":3414,"children":3415},{},[3416],{"type":49,"value":1554},{"type":49,"value":3418},": Handles party create\u002Fjoin flow, validates join tickets, and tracks party size.",{"type":44,"tag":87,"props":3420,"children":3421},{},[3422,3426],{"type":44,"tag":56,"props":3423,"children":3424},{},[3425],{"type":49,"value":1564},{"type":44,"tag":83,"props":3427,"children":3428},{},[3429,3438,3447,3456,3465],{"type":44,"tag":87,"props":3430,"children":3431},{},[3432],{"type":44,"tag":62,"props":3433,"children":3435},{"className":3434},[],[3436],{"type":49,"value":3437},"createParty",{"type":44,"tag":87,"props":3439,"children":3440},{},[3441],{"type":44,"tag":62,"props":3442,"children":3444},{"className":3443},[],[3445],{"type":49,"value":3446},"joinParty",{"type":44,"tag":87,"props":3448,"children":3449},{},[3450],{"type":44,"tag":62,"props":3451,"children":3453},{"className":3452},[],[3454],{"type":49,"value":3455},"verifyJoin",{"type":44,"tag":87,"props":3457,"children":3458},{},[3459],{"type":44,"tag":62,"props":3460,"children":3462},{"className":3461},[],[3463],{"type":49,"value":3464},"updatePartySize",{"type":44,"tag":87,"props":3466,"children":3467},{},[3468],{"type":44,"tag":62,"props":3469,"children":3471},{"className":3470},[],[3472],{"type":49,"value":3473},"closeParty",{"type":44,"tag":87,"props":3475,"children":3476},{},[3477,3481],{"type":44,"tag":56,"props":3478,"children":3479},{},[3480],{"type":49,"value":1611},{"type":44,"tag":83,"props":3482,"children":3483},{},[3484,3492,3500,3508,3516],{"type":44,"tag":87,"props":3485,"children":3486},{},[3487],{"type":44,"tag":62,"props":3488,"children":3490},{"className":3489},[],[3491],{"type":49,"value":3437},{"type":44,"tag":87,"props":3493,"children":3494},{},[3495],{"type":44,"tag":62,"props":3496,"children":3498},{"className":3497},[],[3499],{"type":49,"value":3446},{"type":44,"tag":87,"props":3501,"children":3502},{},[3503],{"type":44,"tag":62,"props":3504,"children":3506},{"className":3505},[],[3507],{"type":49,"value":3455},{"type":44,"tag":87,"props":3509,"children":3510},{},[3511],{"type":44,"tag":62,"props":3512,"children":3514},{"className":3513},[],[3515],{"type":49,"value":3464},{"type":44,"tag":87,"props":3517,"children":3518},{},[3519],{"type":44,"tag":62,"props":3520,"children":3522},{"className":3521},[],[3523],{"type":49,"value":3473},{"type":44,"tag":87,"props":3525,"children":3526},{},[3527,3531],{"type":44,"tag":56,"props":3528,"children":3529},{},[3530],{"type":49,"value":1654},{"type":44,"tag":83,"props":3532,"children":3533},{},[3534,3538,3547],{"type":44,"tag":87,"props":3535,"children":3536},{},[3537],{"type":49,"value":1662},{"type":44,"tag":87,"props":3539,"children":3540},{},[3541],{"type":44,"tag":62,"props":3542,"children":3544},{"className":3543},[],[3545],{"type":49,"value":3546},"parties",{"type":44,"tag":87,"props":3548,"children":3549},{},[3550,3556],{"type":44,"tag":62,"props":3551,"children":3553},{"className":3552},[],[3554],{"type":49,"value":3555},"join_tickets",{"type":49,"value":3557}," for party lookup and join validation",{"type":44,"tag":87,"props":3559,"children":3560},{},[3561,3565,3566],{"type":44,"tag":56,"props":3562,"children":3563},{},[3564],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":3567,"children":3569},{"className":3568},[],[3570],{"type":49,"value":1166},{"type":44,"tag":87,"props":3572,"children":3573},{},[3574,3578],{"type":44,"tag":56,"props":3575,"children":3576},{},[3577],{"type":49,"value":1554},{"type":49,"value":3579},": Owns party members, host role, ready flags, and phase transitions.",{"type":44,"tag":87,"props":3581,"children":3582},{},[3583,3587],{"type":44,"tag":56,"props":3584,"children":3585},{},[3586],{"type":49,"value":1564},{"type":44,"tag":83,"props":3588,"children":3589},{},[3590,3598,3607],{"type":44,"tag":87,"props":3591,"children":3592},{},[3593],{"type":44,"tag":62,"props":3594,"children":3596},{"className":3595},[],[3597],{"type":49,"value":1732},{"type":44,"tag":87,"props":3599,"children":3600},{},[3601],{"type":44,"tag":62,"props":3602,"children":3604},{"className":3603},[],[3605],{"type":49,"value":3606},"startGame",{"type":44,"tag":87,"props":3608,"children":3609},{},[3610],{"type":44,"tag":62,"props":3611,"children":3613},{"className":3612},[],[3614],{"type":49,"value":3615},"finishGame",{"type":44,"tag":87,"props":3617,"children":3618},{},[3619,3623],{"type":44,"tag":56,"props":3620,"children":3621},{},[3622],{"type":49,"value":1611},{"type":44,"tag":83,"props":3624,"children":3625},{},[3626],{"type":44,"tag":87,"props":3627,"children":3628},{},[3629],{"type":49,"value":1752},{"type":44,"tag":87,"props":3631,"children":3632},{},[3633,3637],{"type":44,"tag":56,"props":3634,"children":3635},{},[3636],{"type":49,"value":1654},{"type":44,"tag":83,"props":3638,"children":3639},{},[3640,3644,3653,3662,3671,3679],{"type":44,"tag":87,"props":3641,"children":3642},{},[3643],{"type":49,"value":1767},{"type":44,"tag":87,"props":3645,"children":3646},{},[3647],{"type":44,"tag":62,"props":3648,"children":3650},{"className":3649},[],[3651],{"type":49,"value":3652},"members",{"type":44,"tag":87,"props":3654,"children":3655},{},[3656],{"type":44,"tag":62,"props":3657,"children":3659},{"className":3658},[],[3660],{"type":49,"value":3661},"host",{"type":44,"tag":87,"props":3663,"children":3664},{},[3665],{"type":44,"tag":62,"props":3666,"children":3668},{"className":3667},[],[3669],{"type":49,"value":3670},"ready state",{"type":44,"tag":87,"props":3672,"children":3673},{},[3674],{"type":44,"tag":62,"props":3675,"children":3677},{"className":3676},[],[3678],{"type":49,"value":1776},{"type":44,"tag":87,"props":3680,"children":3681},{},[3682],{"type":44,"tag":62,"props":3683,"children":3685},{"className":3684},[],[3686],{"type":49,"value":3687},"party events",{"type":44,"tag":52,"props":3689,"children":3690},{},[3691],{"type":44,"tag":56,"props":3692,"children":3693},{},[3694],{"type":49,"value":1820},{"type":44,"tag":383,"props":3696,"children":3698},{"id":3697},"host-flow",[3699],{"type":49,"value":3700},"Host Flow",{"type":44,"tag":1822,"props":3702,"children":3704},{"className":1824,"code":3703,"language":1826,"meta":1827,"style":1827},"sequenceDiagram\n    participant H as Host Client\n    participant MM as matchmaker\n    participant M as match\n\n    H->>MM: createParty()\n    MM-->>H: {matchId, partyCode, playerId, joinToken}\n    H->>M: connect(playerId, joinToken)\n    M->>MM: verifyJoin(...)\n    MM-->>M: allowed\n    M->>MM: updatePartySize(playerCount)\n    H->>M: startGame() \u002F finishGame()\n    M->>MM: closeParty(matchId)\n",[3705],{"type":44,"tag":62,"props":3706,"children":3707},{"__ignoreMap":1827},[3708,3715,3723,3730,3737,3744,3752,3760,3768,3776,3784,3792,3800],{"type":44,"tag":1833,"props":3709,"children":3710},{"class":1835,"line":1836},[3711],{"type":44,"tag":1833,"props":3712,"children":3713},{},[3714],{"type":49,"value":1842},{"type":44,"tag":1833,"props":3716,"children":3717},{"class":1835,"line":1845},[3718],{"type":44,"tag":1833,"props":3719,"children":3720},{},[3721],{"type":49,"value":3722},"    participant H as Host Client\n",{"type":44,"tag":1833,"props":3724,"children":3725},{"class":1835,"line":1854},[3726],{"type":44,"tag":1833,"props":3727,"children":3728},{},[3729],{"type":49,"value":1860},{"type":44,"tag":1833,"props":3731,"children":3732},{"class":1835,"line":1863},[3733],{"type":44,"tag":1833,"props":3734,"children":3735},{},[3736],{"type":49,"value":1869},{"type":44,"tag":1833,"props":3738,"children":3739},{"class":1835,"line":1872},[3740],{"type":44,"tag":1833,"props":3741,"children":3742},{"emptyLinePlaceholder":1876},[3743],{"type":49,"value":1879},{"type":44,"tag":1833,"props":3745,"children":3746},{"class":1835,"line":1882},[3747],{"type":44,"tag":1833,"props":3748,"children":3749},{},[3750],{"type":49,"value":3751},"    H->>MM: createParty()\n",{"type":44,"tag":1833,"props":3753,"children":3754},{"class":1835,"line":31},[3755],{"type":44,"tag":1833,"props":3756,"children":3757},{},[3758],{"type":49,"value":3759},"    MM-->>H: {matchId, partyCode, playerId, joinToken}\n",{"type":44,"tag":1833,"props":3761,"children":3762},{"class":1835,"line":1899},[3763],{"type":44,"tag":1833,"props":3764,"children":3765},{},[3766],{"type":49,"value":3767},"    H->>M: connect(playerId, joinToken)\n",{"type":44,"tag":1833,"props":3769,"children":3770},{"class":1835,"line":1908},[3771],{"type":44,"tag":1833,"props":3772,"children":3773},{},[3774],{"type":49,"value":3775},"    M->>MM: verifyJoin(...)\n",{"type":44,"tag":1833,"props":3777,"children":3778},{"class":1835,"line":1917},[3779],{"type":44,"tag":1833,"props":3780,"children":3781},{},[3782],{"type":49,"value":3783},"    MM-->>M: allowed\n",{"type":44,"tag":1833,"props":3785,"children":3786},{"class":1835,"line":1926},[3787],{"type":44,"tag":1833,"props":3788,"children":3789},{},[3790],{"type":49,"value":3791},"    M->>MM: updatePartySize(playerCount)\n",{"type":44,"tag":1833,"props":3793,"children":3794},{"class":1835,"line":1935},[3795],{"type":44,"tag":1833,"props":3796,"children":3797},{},[3798],{"type":49,"value":3799},"    H->>M: startGame() \u002F finishGame()\n",{"type":44,"tag":1833,"props":3801,"children":3802},{"class":1835,"line":1944},[3803],{"type":44,"tag":1833,"props":3804,"children":3805},{},[3806],{"type":49,"value":3807},"    M->>MM: closeParty(matchId)\n",{"type":44,"tag":383,"props":3809,"children":3811},{"id":3810},"joiner-flow",[3812],{"type":49,"value":3813},"Joiner Flow",{"type":44,"tag":1822,"props":3815,"children":3817},{"className":1824,"code":3816,"language":1826,"meta":1827,"style":1827},"sequenceDiagram\n    participant J as Joiner Client\n    participant MM as matchmaker\n    participant M as match\n\n    J->>MM: joinParty(partyCode)\n    MM-->>J: {matchId, playerId, joinToken}\n    J->>M: connect(playerId, joinToken)\n    M->>MM: verifyJoin(...)\n    MM-->>M: allowed \u002F denied\n    M->>MM: updatePartySize(playerCount)\n",[3818],{"type":44,"tag":62,"props":3819,"children":3820},{"__ignoreMap":1827},[3821,3828,3836,3843,3850,3857,3865,3873,3881,3888,3896],{"type":44,"tag":1833,"props":3822,"children":3823},{"class":1835,"line":1836},[3824],{"type":44,"tag":1833,"props":3825,"children":3826},{},[3827],{"type":49,"value":1842},{"type":44,"tag":1833,"props":3829,"children":3830},{"class":1835,"line":1845},[3831],{"type":44,"tag":1833,"props":3832,"children":3833},{},[3834],{"type":49,"value":3835},"    participant J as Joiner Client\n",{"type":44,"tag":1833,"props":3837,"children":3838},{"class":1835,"line":1854},[3839],{"type":44,"tag":1833,"props":3840,"children":3841},{},[3842],{"type":49,"value":1860},{"type":44,"tag":1833,"props":3844,"children":3845},{"class":1835,"line":1863},[3846],{"type":44,"tag":1833,"props":3847,"children":3848},{},[3849],{"type":49,"value":1869},{"type":44,"tag":1833,"props":3851,"children":3852},{"class":1835,"line":1872},[3853],{"type":44,"tag":1833,"props":3854,"children":3855},{"emptyLinePlaceholder":1876},[3856],{"type":49,"value":1879},{"type":44,"tag":1833,"props":3858,"children":3859},{"class":1835,"line":1882},[3860],{"type":44,"tag":1833,"props":3861,"children":3862},{},[3863],{"type":49,"value":3864},"    J->>MM: joinParty(partyCode)\n",{"type":44,"tag":1833,"props":3866,"children":3867},{"class":1835,"line":31},[3868],{"type":44,"tag":1833,"props":3869,"children":3870},{},[3871],{"type":49,"value":3872},"    MM-->>J: {matchId, playerId, joinToken}\n",{"type":44,"tag":1833,"props":3874,"children":3875},{"class":1835,"line":1899},[3876],{"type":44,"tag":1833,"props":3877,"children":3878},{},[3879],{"type":49,"value":3880},"    J->>M: connect(playerId, joinToken)\n",{"type":44,"tag":1833,"props":3882,"children":3883},{"class":1835,"line":1908},[3884],{"type":44,"tag":1833,"props":3885,"children":3886},{},[3887],{"type":49,"value":3775},{"type":44,"tag":1833,"props":3889,"children":3890},{"class":1835,"line":1917},[3891],{"type":44,"tag":1833,"props":3892,"children":3893},{},[3894],{"type":49,"value":3895},"    MM-->>M: allowed \u002F denied\n",{"type":44,"tag":1833,"props":3897,"children":3898},{"class":1835,"line":1926},[3899],{"type":44,"tag":1833,"props":3900,"children":3901},{},[3902],{"type":49,"value":3791},{"type":44,"tag":383,"props":3904,"children":3906},{"id":3905},"ranked",[3907],{"type":49,"value":317},{"type":44,"tag":125,"props":3909,"children":3910},{},[3911,3925],{"type":44,"tag":129,"props":3912,"children":3913},{},[3914],{"type":44,"tag":133,"props":3915,"children":3916},{},[3917,3921],{"type":44,"tag":137,"props":3918,"children":3919},{},[3920],{"type":49,"value":1440},{"type":44,"tag":137,"props":3922,"children":3923},{},[3924],{"type":49,"value":1445},{"type":44,"tag":152,"props":3926,"children":3927},{},[3928,3940,3952,3970],{"type":44,"tag":133,"props":3929,"children":3930},{},[3931,3935],{"type":44,"tag":159,"props":3932,"children":3933},{},[3934],{"type":49,"value":1456},{"type":44,"tag":159,"props":3936,"children":3937},{},[3938],{"type":49,"value":3939},"ELO-based queue pairing with a widening search window as wait time increases.",{"type":44,"tag":133,"props":3941,"children":3942},{},[3943,3947],{"type":44,"tag":159,"props":3944,"children":3945},{},[3946],{"type":49,"value":734},{"type":44,"tag":159,"props":3948,"children":3949},{},[3950],{"type":49,"value":3951},"Hybrid. Client owns movement with local prediction and interpolation. Server owns projectiles, hit resolution, match results, and rating updates.",{"type":44,"tag":133,"props":3953,"children":3954},{},[3955,3959],{"type":44,"tag":159,"props":3956,"children":3957},{},[3958],{"type":49,"value":1481},{"type":44,"tag":159,"props":3960,"children":3961},{},[3962,3963,3968],{"type":49,"value":2060},{"type":44,"tag":62,"props":3964,"children":3966},{"className":3965},[],[3967],{"type":49,"value":2066},{"type":49,"value":3969},") with fixed live ticks for deterministic pacing and broadcast cadence.",{"type":44,"tag":133,"props":3971,"children":3972},{},[3973,3977],{"type":44,"tag":159,"props":3974,"children":3975},{},[3976],{"type":49,"value":507},{"type":44,"tag":159,"props":3978,"children":3979},{},[3980],{"type":49,"value":3981},"Medium to high intensity; client movement with server validation and server-authoritative combat\u002Fhit resolution.",{"type":44,"tag":52,"props":3983,"children":3984},{},[3985],{"type":44,"tag":56,"props":3986,"children":3987},{},[3988],{"type":49,"value":1528},{"type":44,"tag":83,"props":3990,"children":3991},{},[3992,4005,4014,4048,4082,4122,4135,4144,4166,4180,4237,4250,4259,4296,4310,4360,4373,4382,4401,4415],{"type":44,"tag":87,"props":3993,"children":3994},{},[3995,3999,4000],{"type":44,"tag":56,"props":3996,"children":3997},{},[3998],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":4001,"children":4003},{"className":4002},[],[4004],{"type":49,"value":1158},{"type":44,"tag":87,"props":4006,"children":4007},{},[4008,4012],{"type":44,"tag":56,"props":4009,"children":4010},{},[4011],{"type":49,"value":1554},{"type":49,"value":4013},": Runs rating-based queueing, pairing, assignment persistence, and completion fanout.",{"type":44,"tag":87,"props":4015,"children":4016},{},[4017,4021],{"type":44,"tag":56,"props":4018,"children":4019},{},[4020],{"type":49,"value":1564},{"type":44,"tag":83,"props":4022,"children":4023},{},[4024,4032,4040],{"type":44,"tag":87,"props":4025,"children":4026},{},[4027],{"type":44,"tag":62,"props":4028,"children":4030},{"className":4029},[],[4031],{"type":49,"value":2131},{"type":44,"tag":87,"props":4033,"children":4034},{},[4035],{"type":44,"tag":62,"props":4036,"children":4038},{"className":4037},[],[4039],{"type":49,"value":2140},{"type":44,"tag":87,"props":4041,"children":4042},{},[4043],{"type":44,"tag":62,"props":4044,"children":4046},{"className":4045},[],[4047],{"type":49,"value":2149},{"type":44,"tag":87,"props":4049,"children":4050},{},[4051,4055],{"type":44,"tag":56,"props":4052,"children":4053},{},[4054],{"type":49,"value":1611},{"type":44,"tag":83,"props":4056,"children":4057},{},[4058,4066,4074],{"type":44,"tag":87,"props":4059,"children":4060},{},[4061],{"type":44,"tag":62,"props":4062,"children":4064},{"className":4063},[],[4065],{"type":49,"value":2131},{"type":44,"tag":87,"props":4067,"children":4068},{},[4069],{"type":44,"tag":62,"props":4070,"children":4072},{"className":4071},[],[4073],{"type":49,"value":2140},{"type":44,"tag":87,"props":4075,"children":4076},{},[4077],{"type":44,"tag":62,"props":4078,"children":4080},{"className":4079},[],[4081],{"type":49,"value":2149},{"type":44,"tag":87,"props":4083,"children":4084},{},[4085,4089],{"type":44,"tag":56,"props":4086,"children":4087},{},[4088],{"type":49,"value":1654},{"type":44,"tag":83,"props":4090,"children":4091},{},[4092,4096,4104,4112],{"type":44,"tag":87,"props":4093,"children":4094},{},[4095],{"type":49,"value":1662},{"type":44,"tag":87,"props":4097,"children":4098},{},[4099],{"type":44,"tag":62,"props":4100,"children":4102},{"className":4101},[],[4103],{"type":49,"value":2206},{"type":44,"tag":87,"props":4105,"children":4106},{},[4107],{"type":44,"tag":62,"props":4108,"children":4110},{"className":4109},[],[4111],{"type":49,"value":1671},{"type":44,"tag":87,"props":4113,"children":4114},{},[4115,4120],{"type":44,"tag":62,"props":4116,"children":4118},{"className":4117},[],[4119],{"type":49,"value":2223},{"type":49,"value":4121}," with rating window and connection scoping",{"type":44,"tag":87,"props":4123,"children":4124},{},[4125,4129,4130],{"type":44,"tag":56,"props":4126,"children":4127},{},[4128],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":4131,"children":4133},{"className":4132},[],[4134],{"type":49,"value":1166},{"type":44,"tag":87,"props":4136,"children":4137},{},[4138,4142],{"type":44,"tag":56,"props":4139,"children":4140},{},[4141],{"type":49,"value":1554},{"type":49,"value":4143},": Runs ranked match phase, score, and winner reporting.",{"type":44,"tag":87,"props":4145,"children":4146},{},[4147,4151],{"type":44,"tag":56,"props":4148,"children":4149},{},[4150],{"type":49,"value":1564},{"type":44,"tag":83,"props":4152,"children":4153},{},[4154,4162],{"type":44,"tag":87,"props":4155,"children":4156},{},[4157],{"type":44,"tag":62,"props":4158,"children":4160},{"className":4159},[],[4161],{"type":49,"value":1732},{"type":44,"tag":87,"props":4163,"children":4164},{},[4165],{"type":49,"value":2270},{"type":44,"tag":87,"props":4167,"children":4168},{},[4169,4173],{"type":44,"tag":56,"props":4170,"children":4171},{},[4172],{"type":49,"value":1611},{"type":44,"tag":83,"props":4174,"children":4175},{},[4176],{"type":44,"tag":87,"props":4177,"children":4178},{},[4179],{"type":49,"value":1752},{"type":44,"tag":87,"props":4181,"children":4182},{},[4183,4187],{"type":44,"tag":56,"props":4184,"children":4185},{},[4186],{"type":49,"value":1654},{"type":44,"tag":83,"props":4188,"children":4189},{},[4190,4194,4202,4210,4219,4228],{"type":44,"tag":87,"props":4191,"children":4192},{},[4193],{"type":49,"value":1767},{"type":44,"tag":87,"props":4195,"children":4196},{},[4197],{"type":44,"tag":62,"props":4198,"children":4200},{"className":4199},[],[4201],{"type":49,"value":1776},{"type":44,"tag":87,"props":4203,"children":4204},{},[4205],{"type":44,"tag":62,"props":4206,"children":4208},{"className":4207},[],[4209],{"type":49,"value":1785},{"type":44,"tag":87,"props":4211,"children":4212},{},[4213],{"type":44,"tag":62,"props":4214,"children":4216},{"className":4215},[],[4217],{"type":49,"value":4218},"score",{"type":44,"tag":87,"props":4220,"children":4221},{},[4222],{"type":44,"tag":62,"props":4223,"children":4225},{"className":4224},[],[4226],{"type":49,"value":4227},"winner",{"type":44,"tag":87,"props":4229,"children":4230},{},[4231],{"type":44,"tag":62,"props":4232,"children":4234},{"className":4233},[],[4235],{"type":49,"value":4236},"completion payload",{"type":44,"tag":87,"props":4238,"children":4239},{},[4240,4244,4245],{"type":44,"tag":56,"props":4241,"children":4242},{},[4243],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":4246,"children":4248},{"className":4247},[],[4249],{"type":49,"value":1232},{"type":44,"tag":87,"props":4251,"children":4252},{},[4253,4257],{"type":44,"tag":56,"props":4254,"children":4255},{},[4256],{"type":49,"value":1554},{"type":49,"value":4258},": Stores canonical player MMR and win\u002Floss profile.",{"type":44,"tag":87,"props":4260,"children":4261},{},[4262,4266],{"type":44,"tag":56,"props":4263,"children":4264},{},[4265],{"type":49,"value":1564},{"type":44,"tag":83,"props":4267,"children":4268},{},[4269,4278,4287],{"type":44,"tag":87,"props":4270,"children":4271},{},[4272],{"type":44,"tag":62,"props":4273,"children":4275},{"className":4274},[],[4276],{"type":49,"value":4277},"initialize",{"type":44,"tag":87,"props":4279,"children":4280},{},[4281],{"type":44,"tag":62,"props":4282,"children":4284},{"className":4283},[],[4285],{"type":49,"value":4286},"getRating",{"type":44,"tag":87,"props":4288,"children":4289},{},[4290],{"type":44,"tag":62,"props":4291,"children":4293},{"className":4292},[],[4294],{"type":49,"value":4295},"applyMatchResult",{"type":44,"tag":87,"props":4297,"children":4298},{},[4299,4303],{"type":44,"tag":56,"props":4300,"children":4301},{},[4302],{"type":49,"value":1611},{"type":44,"tag":83,"props":4304,"children":4305},{},[4306],{"type":44,"tag":87,"props":4307,"children":4308},{},[4309],{"type":49,"value":1752},{"type":44,"tag":87,"props":4311,"children":4312},{},[4313,4317],{"type":44,"tag":56,"props":4314,"children":4315},{},[4316],{"type":49,"value":1654},{"type":44,"tag":83,"props":4318,"children":4319},{},[4320,4324,4333,4342,4351],{"type":44,"tag":87,"props":4321,"children":4322},{},[4323],{"type":49,"value":1767},{"type":44,"tag":87,"props":4325,"children":4326},{},[4327],{"type":44,"tag":62,"props":4328,"children":4330},{"className":4329},[],[4331],{"type":49,"value":4332},"rating",{"type":44,"tag":87,"props":4334,"children":4335},{},[4336],{"type":44,"tag":62,"props":4337,"children":4339},{"className":4338},[],[4340],{"type":49,"value":4341},"wins",{"type":44,"tag":87,"props":4343,"children":4344},{},[4345],{"type":44,"tag":62,"props":4346,"children":4348},{"className":4347},[],[4349],{"type":49,"value":4350},"losses",{"type":44,"tag":87,"props":4352,"children":4353},{},[4354],{"type":44,"tag":62,"props":4355,"children":4357},{"className":4356},[],[4358],{"type":49,"value":4359},"match counters",{"type":44,"tag":87,"props":4361,"children":4362},{},[4363,4367,4368],{"type":44,"tag":56,"props":4364,"children":4365},{},[4366],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":4369,"children":4371},{"className":4370},[],[4372],{"type":49,"value":1254},{"type":44,"tag":87,"props":4374,"children":4375},{},[4376,4380],{"type":44,"tag":56,"props":4377,"children":4378},{},[4379],{"type":49,"value":1554},{"type":49,"value":4381},": Stores and serves top-ranked players.",{"type":44,"tag":87,"props":4383,"children":4384},{},[4385,4389],{"type":44,"tag":56,"props":4386,"children":4387},{},[4388],{"type":49,"value":1564},{"type":44,"tag":83,"props":4390,"children":4391},{},[4392],{"type":44,"tag":87,"props":4393,"children":4394},{},[4395],{"type":44,"tag":62,"props":4396,"children":4398},{"className":4397},[],[4399],{"type":49,"value":4400},"updatePlayer",{"type":44,"tag":87,"props":4402,"children":4403},{},[4404,4408],{"type":44,"tag":56,"props":4405,"children":4406},{},[4407],{"type":49,"value":1611},{"type":44,"tag":83,"props":4409,"children":4410},{},[4411],{"type":44,"tag":87,"props":4412,"children":4413},{},[4414],{"type":49,"value":1752},{"type":44,"tag":87,"props":4416,"children":4417},{},[4418,4422],{"type":44,"tag":56,"props":4419,"children":4420},{},[4421],{"type":49,"value":1654},{"type":44,"tag":83,"props":4423,"children":4424},{},[4425,4429,4434],{"type":44,"tag":87,"props":4426,"children":4427},{},[4428],{"type":49,"value":1662},{"type":44,"tag":87,"props":4430,"children":4431},{},[4432],{"type":49,"value":4433},"Leaderboard score rows",{"type":44,"tag":87,"props":4435,"children":4436},{},[4437],{"type":49,"value":4438},"Top-list ordering",{"type":44,"tag":52,"props":4440,"children":4441},{},[4442],{"type":44,"tag":56,"props":4443,"children":4444},{},[4445],{"type":49,"value":1820},{"type":44,"tag":1822,"props":4447,"children":4449},{"className":1824,"code":4448,"language":1826,"meta":1827,"style":1827},"sequenceDiagram\n    participant C as Client\n    participant MM as matchmaker\n    participant P as player\n    participant M as match\n    participant LB as leaderboard\n\n    C->>MM: queueForMatch(username)\n    MM->>P: initialize\u002FgetRating\n    P-->>MM: rating\n    Note over MM: store queue row + retry pairing\n    MM->>M: create(matchId, assigned players)\n    MM-->>C: assignmentReady\n    C->>M: connect(username)\n    M->>MM: matchCompleted(...)\n    MM->>P: applyMatchResult(...)\n    MM->>LB: updatePlayer(...)\n    Note over MM: remove matches + assignments rows\n",[4450],{"type":44,"tag":62,"props":4451,"children":4452},{"__ignoreMap":1827},[4453,4460,4467,4474,4482,4489,4497,4504,4512,4520,4528,4536,4544,4551,4559,4567,4575,4583],{"type":44,"tag":1833,"props":4454,"children":4455},{"class":1835,"line":1836},[4456],{"type":44,"tag":1833,"props":4457,"children":4458},{},[4459],{"type":49,"value":1842},{"type":44,"tag":1833,"props":4461,"children":4462},{"class":1835,"line":1845},[4463],{"type":44,"tag":1833,"props":4464,"children":4465},{},[4466],{"type":49,"value":1851},{"type":44,"tag":1833,"props":4468,"children":4469},{"class":1835,"line":1854},[4470],{"type":44,"tag":1833,"props":4471,"children":4472},{},[4473],{"type":49,"value":1860},{"type":44,"tag":1833,"props":4475,"children":4476},{"class":1835,"line":1863},[4477],{"type":44,"tag":1833,"props":4478,"children":4479},{},[4480],{"type":49,"value":4481},"    participant P as player\n",{"type":44,"tag":1833,"props":4483,"children":4484},{"class":1835,"line":1872},[4485],{"type":44,"tag":1833,"props":4486,"children":4487},{},[4488],{"type":49,"value":1869},{"type":44,"tag":1833,"props":4490,"children":4491},{"class":1835,"line":1882},[4492],{"type":44,"tag":1833,"props":4493,"children":4494},{},[4495],{"type":49,"value":4496},"    participant LB as leaderboard\n",{"type":44,"tag":1833,"props":4498,"children":4499},{"class":1835,"line":31},[4500],{"type":44,"tag":1833,"props":4501,"children":4502},{"emptyLinePlaceholder":1876},[4503],{"type":49,"value":1879},{"type":44,"tag":1833,"props":4505,"children":4506},{"class":1835,"line":1899},[4507],{"type":44,"tag":1833,"props":4508,"children":4509},{},[4510],{"type":49,"value":4511},"    C->>MM: queueForMatch(username)\n",{"type":44,"tag":1833,"props":4513,"children":4514},{"class":1835,"line":1908},[4515],{"type":44,"tag":1833,"props":4516,"children":4517},{},[4518],{"type":49,"value":4519},"    MM->>P: initialize\u002FgetRating\n",{"type":44,"tag":1833,"props":4521,"children":4522},{"class":1835,"line":1917},[4523],{"type":44,"tag":1833,"props":4524,"children":4525},{},[4526],{"type":49,"value":4527},"    P-->>MM: rating\n",{"type":44,"tag":1833,"props":4529,"children":4530},{"class":1835,"line":1926},[4531],{"type":44,"tag":1833,"props":4532,"children":4533},{},[4534],{"type":49,"value":4535},"    Note over MM: store queue row + retry pairing\n",{"type":44,"tag":1833,"props":4537,"children":4538},{"class":1835,"line":1935},[4539],{"type":44,"tag":1833,"props":4540,"children":4541},{},[4542],{"type":49,"value":4543},"    MM->>M: create(matchId, assigned players)\n",{"type":44,"tag":1833,"props":4545,"children":4546},{"class":1835,"line":1944},[4547],{"type":44,"tag":1833,"props":4548,"children":4549},{},[4550],{"type":49,"value":2429},{"type":44,"tag":1833,"props":4552,"children":4553},{"class":1835,"line":1953},[4554],{"type":44,"tag":1833,"props":4555,"children":4556},{},[4557],{"type":49,"value":4558},"    C->>M: connect(username)\n",{"type":44,"tag":1833,"props":4560,"children":4561},{"class":1835,"line":1962},[4562],{"type":44,"tag":1833,"props":4563,"children":4564},{},[4565],{"type":49,"value":4566},"    M->>MM: matchCompleted(...)\n",{"type":44,"tag":1833,"props":4568,"children":4569},{"class":1835,"line":1971},[4570],{"type":44,"tag":1833,"props":4571,"children":4572},{},[4573],{"type":49,"value":4574},"    MM->>P: applyMatchResult(...)\n",{"type":44,"tag":1833,"props":4576,"children":4577},{"class":1835,"line":27},[4578],{"type":44,"tag":1833,"props":4579,"children":4580},{},[4581],{"type":49,"value":4582},"    MM->>LB: updatePlayer(...)\n",{"type":44,"tag":1833,"props":4584,"children":4586},{"class":1835,"line":4585},18,[4587],{"type":44,"tag":1833,"props":4588,"children":4589},{},[4590],{"type":49,"value":4591},"    Note over MM: remove matches + assignments rows\n",{"type":44,"tag":383,"props":4593,"children":4595},{"id":4594},"turn-based",[4596],{"type":49,"value":339},{"type":44,"tag":125,"props":4598,"children":4599},{},[4600,4614],{"type":44,"tag":129,"props":4601,"children":4602},{},[4603],{"type":44,"tag":133,"props":4604,"children":4605},{},[4606,4610],{"type":44,"tag":137,"props":4607,"children":4608},{},[4609],{"type":49,"value":1440},{"type":44,"tag":137,"props":4611,"children":4612},{},[4613],{"type":49,"value":1445},{"type":44,"tag":152,"props":4615,"children":4616},{},[4617,4629,4641,4653],{"type":44,"tag":133,"props":4618,"children":4619},{},[4620,4624],{"type":44,"tag":159,"props":4621,"children":4622},{},[4623],{"type":49,"value":1456},{"type":44,"tag":159,"props":4625,"children":4626},{},[4627],{"type":49,"value":4628},"Async private-invite and public-queue pairing in the same pattern.",{"type":44,"tag":133,"props":4630,"children":4631},{},[4632,4636],{"type":44,"tag":159,"props":4633,"children":4634},{},[4635],{"type":49,"value":734},{"type":44,"tag":159,"props":4637,"children":4638},{},[4639],{"type":49,"value":4640},"Server-authoritative (basic logic). Client can draft moves before submit. Server owns turn ownership, committed move log, turn order, and completion state.",{"type":44,"tag":133,"props":4642,"children":4643},{},[4644,4648],{"type":44,"tag":159,"props":4645,"children":4646},{},[4647],{"type":49,"value":1481},{"type":44,"tag":159,"props":4649,"children":4650},{},[4651],{"type":49,"value":4652},"No continuous tick; move submission and turn transitions drive updates.",{"type":44,"tag":133,"props":4654,"children":4655},{},[4656,4660],{"type":44,"tag":159,"props":4657,"children":4658},{},[4659],{"type":49,"value":507},{"type":44,"tag":159,"props":4661,"children":4662},{},[4663],{"type":49,"value":4664},"Very low intensity; no realtime physics loop, just discrete rules validation. Indexing is optional and mostly for board or query convenience at scale.",{"type":44,"tag":52,"props":4666,"children":4667},{},[4668],{"type":44,"tag":56,"props":4669,"children":4670},{},[4671],{"type":49,"value":1528},{"type":44,"tag":83,"props":4673,"children":4674},{},[4675,4688,4697,4749,4799,4839,4852,4861,4888,4902],{"type":44,"tag":87,"props":4676,"children":4677},{},[4678,4682,4683],{"type":44,"tag":56,"props":4679,"children":4680},{},[4681],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":4684,"children":4686},{"className":4685},[],[4687],{"type":49,"value":1158},{"type":44,"tag":87,"props":4689,"children":4690},{},[4691,4695],{"type":44,"tag":56,"props":4692,"children":4693},{},[4694],{"type":49,"value":1554},{"type":49,"value":4696},": Handles private invite and public queue pairing for async matches.",{"type":44,"tag":87,"props":4698,"children":4699},{},[4700,4704],{"type":44,"tag":56,"props":4701,"children":4702},{},[4703],{"type":49,"value":1564},{"type":44,"tag":83,"props":4705,"children":4706},{},[4707,4716,4725,4733,4741],{"type":44,"tag":87,"props":4708,"children":4709},{},[4710],{"type":44,"tag":62,"props":4711,"children":4713},{"className":4712},[],[4714],{"type":49,"value":4715},"createGame",{"type":44,"tag":87,"props":4717,"children":4718},{},[4719],{"type":44,"tag":62,"props":4720,"children":4722},{"className":4721},[],[4723],{"type":49,"value":4724},"joinByCode",{"type":44,"tag":87,"props":4726,"children":4727},{},[4728],{"type":44,"tag":62,"props":4729,"children":4731},{"className":4730},[],[4732],{"type":49,"value":2131},{"type":44,"tag":87,"props":4734,"children":4735},{},[4736],{"type":44,"tag":62,"props":4737,"children":4739},{"className":4738},[],[4740],{"type":49,"value":2140},{"type":44,"tag":87,"props":4742,"children":4743},{},[4744],{"type":44,"tag":62,"props":4745,"children":4747},{"className":4746},[],[4748],{"type":49,"value":1603},{"type":44,"tag":87,"props":4750,"children":4751},{},[4752,4756],{"type":44,"tag":56,"props":4753,"children":4754},{},[4755],{"type":49,"value":1611},{"type":44,"tag":83,"props":4757,"children":4758},{},[4759,4767,4775,4783,4791],{"type":44,"tag":87,"props":4760,"children":4761},{},[4762],{"type":44,"tag":62,"props":4763,"children":4765},{"className":4764},[],[4766],{"type":49,"value":4715},{"type":44,"tag":87,"props":4768,"children":4769},{},[4770],{"type":44,"tag":62,"props":4771,"children":4773},{"className":4772},[],[4774],{"type":49,"value":4724},{"type":44,"tag":87,"props":4776,"children":4777},{},[4778],{"type":44,"tag":62,"props":4779,"children":4781},{"className":4780},[],[4782],{"type":49,"value":2131},{"type":44,"tag":87,"props":4784,"children":4785},{},[4786],{"type":44,"tag":62,"props":4787,"children":4789},{"className":4788},[],[4790],{"type":49,"value":2140},{"type":44,"tag":87,"props":4792,"children":4793},{},[4794],{"type":44,"tag":62,"props":4795,"children":4797},{"className":4796},[],[4798],{"type":49,"value":1603},{"type":44,"tag":87,"props":4800,"children":4801},{},[4802,4806],{"type":44,"tag":56,"props":4803,"children":4804},{},[4805],{"type":49,"value":1654},{"type":44,"tag":83,"props":4807,"children":4808},{},[4809,4813,4821,4829],{"type":44,"tag":87,"props":4810,"children":4811},{},[4812],{"type":49,"value":1662},{"type":44,"tag":87,"props":4814,"children":4815},{},[4816],{"type":44,"tag":62,"props":4817,"children":4819},{"className":4818},[],[4820],{"type":49,"value":1671},{"type":44,"tag":87,"props":4822,"children":4823},{},[4824],{"type":44,"tag":62,"props":4825,"children":4827},{"className":4826},[],[4828],{"type":49,"value":2206},{"type":44,"tag":87,"props":4830,"children":4831},{},[4832,4837],{"type":44,"tag":62,"props":4833,"children":4835},{"className":4834},[],[4836],{"type":49,"value":2223},{"type":49,"value":4838}," for invite and queue mapping",{"type":44,"tag":87,"props":4840,"children":4841},{},[4842,4846,4847],{"type":44,"tag":56,"props":4843,"children":4844},{},[4845],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":4848,"children":4850},{"className":4849},[],[4851],{"type":49,"value":1166},{"type":44,"tag":87,"props":4853,"children":4854},{},[4855,4859],{"type":44,"tag":56,"props":4856,"children":4857},{},[4858],{"type":49,"value":1554},{"type":49,"value":4860},": Owns board state, turn order, move validation, and final result.",{"type":44,"tag":87,"props":4862,"children":4863},{},[4864,4868],{"type":44,"tag":56,"props":4865,"children":4866},{},[4867],{"type":49,"value":1564},{"type":44,"tag":83,"props":4869,"children":4870},{},[4871,4879],{"type":44,"tag":87,"props":4872,"children":4873},{},[4874],{"type":44,"tag":62,"props":4875,"children":4877},{"className":4876},[],[4878],{"type":49,"value":1732},{"type":44,"tag":87,"props":4880,"children":4881},{},[4882],{"type":44,"tag":62,"props":4883,"children":4885},{"className":4884},[],[4886],{"type":49,"value":4887},"makeMove",{"type":44,"tag":87,"props":4889,"children":4890},{},[4891,4895],{"type":44,"tag":56,"props":4892,"children":4893},{},[4894],{"type":49,"value":1611},{"type":44,"tag":83,"props":4896,"children":4897},{},[4898],{"type":44,"tag":87,"props":4899,"children":4900},{},[4901],{"type":49,"value":1752},{"type":44,"tag":87,"props":4903,"children":4904},{},[4905,4909],{"type":44,"tag":56,"props":4906,"children":4907},{},[4908],{"type":49,"value":1654},{"type":44,"tag":83,"props":4910,"children":4911},{},[4912,4916,4925,4934,4942,4951],{"type":44,"tag":87,"props":4913,"children":4914},{},[4915],{"type":49,"value":1767},{"type":44,"tag":87,"props":4917,"children":4918},{},[4919],{"type":44,"tag":62,"props":4920,"children":4922},{"className":4921},[],[4923],{"type":49,"value":4924},"board",{"type":44,"tag":87,"props":4926,"children":4927},{},[4928],{"type":44,"tag":62,"props":4929,"children":4931},{"className":4930},[],[4932],{"type":49,"value":4933},"turns",{"type":44,"tag":87,"props":4935,"children":4936},{},[4937],{"type":44,"tag":62,"props":4938,"children":4940},{"className":4939},[],[4941],{"type":49,"value":1785},{"type":44,"tag":87,"props":4943,"children":4944},{},[4945],{"type":44,"tag":62,"props":4946,"children":4948},{"className":4947},[],[4949],{"type":49,"value":4950},"connection presence",{"type":44,"tag":87,"props":4952,"children":4953},{},[4954],{"type":44,"tag":62,"props":4955,"children":4957},{"className":4956},[],[4958],{"type":49,"value":4959},"result",{"type":44,"tag":52,"props":4961,"children":4962},{},[4963],{"type":44,"tag":56,"props":4964,"children":4965},{},[4966],{"type":49,"value":1820},{"type":44,"tag":383,"props":4968,"children":4970},{"id":4969},"public-queue",[4971],{"type":49,"value":4972},"Public Queue",{"type":44,"tag":1822,"props":4974,"children":4976},{"className":1824,"code":4975,"language":1826,"meta":1827,"style":1827},"sequenceDiagram\n    participant A as Client A\n    participant B as Client B\n    participant MM as matchmaker\n    participant M as match\n\n    A->>MM: queueForMatch()\n    B->>MM: queueForMatch()\n    Note over MM: pair first two queued players\n    MM->>M: create(matchId) + seed X\u002FO players\n    MM-->>A: assignment\u002Fmatch info\n    MM-->>B: assignment\u002Fmatch info\n    A->>M: connect(playerId)\n    B->>M: connect(playerId)\n    A->>M: makeMove()\n    B->>M: makeMove()\n    opt all players disconnected for timeout\n        Note over M: destroy after idle timeout\n    end\n    M->>MM: closeMatch(matchId)\n",[4977],{"type":44,"tag":62,"props":4978,"children":4979},{"__ignoreMap":1827},[4980,4987,4995,5003,5010,5017,5024,5032,5040,5048,5056,5064,5072,5080,5088,5096,5104,5112,5120,5128],{"type":44,"tag":1833,"props":4981,"children":4982},{"class":1835,"line":1836},[4983],{"type":44,"tag":1833,"props":4984,"children":4985},{},[4986],{"type":49,"value":1842},{"type":44,"tag":1833,"props":4988,"children":4989},{"class":1835,"line":1845},[4990],{"type":44,"tag":1833,"props":4991,"children":4992},{},[4993],{"type":49,"value":4994},"    participant A as Client A\n",{"type":44,"tag":1833,"props":4996,"children":4997},{"class":1835,"line":1854},[4998],{"type":44,"tag":1833,"props":4999,"children":5000},{},[5001],{"type":49,"value":5002},"    participant B as Client B\n",{"type":44,"tag":1833,"props":5004,"children":5005},{"class":1835,"line":1863},[5006],{"type":44,"tag":1833,"props":5007,"children":5008},{},[5009],{"type":49,"value":1860},{"type":44,"tag":1833,"props":5011,"children":5012},{"class":1835,"line":1872},[5013],{"type":44,"tag":1833,"props":5014,"children":5015},{},[5016],{"type":49,"value":1869},{"type":44,"tag":1833,"props":5018,"children":5019},{"class":1835,"line":1882},[5020],{"type":44,"tag":1833,"props":5021,"children":5022},{"emptyLinePlaceholder":1876},[5023],{"type":49,"value":1879},{"type":44,"tag":1833,"props":5025,"children":5026},{"class":1835,"line":31},[5027],{"type":44,"tag":1833,"props":5028,"children":5029},{},[5030],{"type":49,"value":5031},"    A->>MM: queueForMatch()\n",{"type":44,"tag":1833,"props":5033,"children":5034},{"class":1835,"line":1899},[5035],{"type":44,"tag":1833,"props":5036,"children":5037},{},[5038],{"type":49,"value":5039},"    B->>MM: queueForMatch()\n",{"type":44,"tag":1833,"props":5041,"children":5042},{"class":1835,"line":1908},[5043],{"type":44,"tag":1833,"props":5044,"children":5045},{},[5046],{"type":49,"value":5047},"    Note over MM: pair first two queued players\n",{"type":44,"tag":1833,"props":5049,"children":5050},{"class":1835,"line":1917},[5051],{"type":44,"tag":1833,"props":5052,"children":5053},{},[5054],{"type":49,"value":5055},"    MM->>M: create(matchId) + seed X\u002FO players\n",{"type":44,"tag":1833,"props":5057,"children":5058},{"class":1835,"line":1926},[5059],{"type":44,"tag":1833,"props":5060,"children":5061},{},[5062],{"type":49,"value":5063},"    MM-->>A: assignment\u002Fmatch info\n",{"type":44,"tag":1833,"props":5065,"children":5066},{"class":1835,"line":1935},[5067],{"type":44,"tag":1833,"props":5068,"children":5069},{},[5070],{"type":49,"value":5071},"    MM-->>B: assignment\u002Fmatch info\n",{"type":44,"tag":1833,"props":5073,"children":5074},{"class":1835,"line":1944},[5075],{"type":44,"tag":1833,"props":5076,"children":5077},{},[5078],{"type":49,"value":5079},"    A->>M: connect(playerId)\n",{"type":44,"tag":1833,"props":5081,"children":5082},{"class":1835,"line":1953},[5083],{"type":44,"tag":1833,"props":5084,"children":5085},{},[5086],{"type":49,"value":5087},"    B->>M: connect(playerId)\n",{"type":44,"tag":1833,"props":5089,"children":5090},{"class":1835,"line":1962},[5091],{"type":44,"tag":1833,"props":5092,"children":5093},{},[5094],{"type":49,"value":5095},"    A->>M: makeMove()\n",{"type":44,"tag":1833,"props":5097,"children":5098},{"class":1835,"line":1971},[5099],{"type":44,"tag":1833,"props":5100,"children":5101},{},[5102],{"type":49,"value":5103},"    B->>M: makeMove()\n",{"type":44,"tag":1833,"props":5105,"children":5106},{"class":1835,"line":27},[5107],{"type":44,"tag":1833,"props":5108,"children":5109},{},[5110],{"type":49,"value":5111},"    opt all players disconnected for timeout\n",{"type":44,"tag":1833,"props":5113,"children":5114},{"class":1835,"line":4585},[5115],{"type":44,"tag":1833,"props":5116,"children":5117},{},[5118],{"type":49,"value":5119},"        Note over M: destroy after idle timeout\n",{"type":44,"tag":1833,"props":5121,"children":5123},{"class":1835,"line":5122},19,[5124],{"type":44,"tag":1833,"props":5125,"children":5126},{},[5127],{"type":49,"value":1914},{"type":44,"tag":1833,"props":5129,"children":5131},{"class":1835,"line":5130},20,[5132],{"type":44,"tag":1833,"props":5133,"children":5134},{},[5135],{"type":49,"value":1977},{"type":44,"tag":383,"props":5137,"children":5139},{"id":5138},"private-invite",[5140],{"type":49,"value":5141},"Private Invite",{"type":44,"tag":1822,"props":5143,"children":5145},{"className":1824,"code":5144,"language":1826,"meta":1827,"style":1827},"sequenceDiagram\n    participant A as Client A\n    participant B as Client B\n    participant MM as matchmaker\n    participant M as match\n\n    A->>MM: createGame()\n    MM-->>A: {matchId, playerId, inviteCode}\n    B->>MM: joinByCode(inviteCode)\n    MM->>M: create(matchId) + seed X\u002FO players\n    MM-->>A: assignment\u002Fmatch info\n    MM-->>B: assignment\u002Fmatch info\n    A->>M: connect(playerId)\n    B->>M: connect(playerId)\n    A->>M: makeMove()\n    B->>M: makeMove()\n    M->>MM: closeMatch(matchId)\n",[5146],{"type":44,"tag":62,"props":5147,"children":5148},{"__ignoreMap":1827},[5149,5156,5163,5170,5177,5184,5191,5199,5207,5215,5222,5229,5236,5243,5250,5257,5264],{"type":44,"tag":1833,"props":5150,"children":5151},{"class":1835,"line":1836},[5152],{"type":44,"tag":1833,"props":5153,"children":5154},{},[5155],{"type":49,"value":1842},{"type":44,"tag":1833,"props":5157,"children":5158},{"class":1835,"line":1845},[5159],{"type":44,"tag":1833,"props":5160,"children":5161},{},[5162],{"type":49,"value":4994},{"type":44,"tag":1833,"props":5164,"children":5165},{"class":1835,"line":1854},[5166],{"type":44,"tag":1833,"props":5167,"children":5168},{},[5169],{"type":49,"value":5002},{"type":44,"tag":1833,"props":5171,"children":5172},{"class":1835,"line":1863},[5173],{"type":44,"tag":1833,"props":5174,"children":5175},{},[5176],{"type":49,"value":1860},{"type":44,"tag":1833,"props":5178,"children":5179},{"class":1835,"line":1872},[5180],{"type":44,"tag":1833,"props":5181,"children":5182},{},[5183],{"type":49,"value":1869},{"type":44,"tag":1833,"props":5185,"children":5186},{"class":1835,"line":1882},[5187],{"type":44,"tag":1833,"props":5188,"children":5189},{"emptyLinePlaceholder":1876},[5190],{"type":49,"value":1879},{"type":44,"tag":1833,"props":5192,"children":5193},{"class":1835,"line":31},[5194],{"type":44,"tag":1833,"props":5195,"children":5196},{},[5197],{"type":49,"value":5198},"    A->>MM: createGame()\n",{"type":44,"tag":1833,"props":5200,"children":5201},{"class":1835,"line":1899},[5202],{"type":44,"tag":1833,"props":5203,"children":5204},{},[5205],{"type":49,"value":5206},"    MM-->>A: {matchId, playerId, inviteCode}\n",{"type":44,"tag":1833,"props":5208,"children":5209},{"class":1835,"line":1908},[5210],{"type":44,"tag":1833,"props":5211,"children":5212},{},[5213],{"type":49,"value":5214},"    B->>MM: joinByCode(inviteCode)\n",{"type":44,"tag":1833,"props":5216,"children":5217},{"class":1835,"line":1917},[5218],{"type":44,"tag":1833,"props":5219,"children":5220},{},[5221],{"type":49,"value":5055},{"type":44,"tag":1833,"props":5223,"children":5224},{"class":1835,"line":1926},[5225],{"type":44,"tag":1833,"props":5226,"children":5227},{},[5228],{"type":49,"value":5063},{"type":44,"tag":1833,"props":5230,"children":5231},{"class":1835,"line":1935},[5232],{"type":44,"tag":1833,"props":5233,"children":5234},{},[5235],{"type":49,"value":5071},{"type":44,"tag":1833,"props":5237,"children":5238},{"class":1835,"line":1944},[5239],{"type":44,"tag":1833,"props":5240,"children":5241},{},[5242],{"type":49,"value":5079},{"type":44,"tag":1833,"props":5244,"children":5245},{"class":1835,"line":1953},[5246],{"type":44,"tag":1833,"props":5247,"children":5248},{},[5249],{"type":49,"value":5087},{"type":44,"tag":1833,"props":5251,"children":5252},{"class":1835,"line":1962},[5253],{"type":44,"tag":1833,"props":5254,"children":5255},{},[5256],{"type":49,"value":5095},{"type":44,"tag":1833,"props":5258,"children":5259},{"class":1835,"line":1971},[5260],{"type":44,"tag":1833,"props":5261,"children":5262},{},[5263],{"type":49,"value":5103},{"type":44,"tag":1833,"props":5265,"children":5266},{"class":1835,"line":27},[5267],{"type":44,"tag":1833,"props":5268,"children":5269},{},[5270],{"type":49,"value":1977},{"type":44,"tag":383,"props":5272,"children":5274},{"id":5273},"idle",[5275],{"type":49,"value":361},{"type":44,"tag":125,"props":5277,"children":5278},{},[5279,5293],{"type":44,"tag":129,"props":5280,"children":5281},{},[5282],{"type":44,"tag":133,"props":5283,"children":5284},{},[5285,5289],{"type":44,"tag":137,"props":5286,"children":5287},{},[5288],{"type":49,"value":1440},{"type":44,"tag":137,"props":5290,"children":5291},{},[5292],{"type":49,"value":1445},{"type":44,"tag":152,"props":5294,"children":5295},{},[5296,5308,5320,5339],{"type":44,"tag":133,"props":5297,"children":5298},{},[5299,5303],{"type":44,"tag":159,"props":5300,"children":5301},{},[5302],{"type":49,"value":1456},{"type":44,"tag":159,"props":5304,"children":5305},{},[5306],{"type":49,"value":5307},"No matchmaker; each player uses a direct per-player actor and a shared leaderboard actor.",{"type":44,"tag":133,"props":5309,"children":5310},{},[5311,5315],{"type":44,"tag":159,"props":5312,"children":5313},{},[5314],{"type":49,"value":734},{"type":44,"tag":159,"props":5316,"children":5317},{},[5318],{"type":49,"value":5319},"Server-authoritative (basic logic). Client owns UI and build intent. Server owns resources, production rates, building validation, and leaderboard totals.",{"type":44,"tag":133,"props":5321,"children":5322},{},[5323,5327],{"type":44,"tag":159,"props":5324,"children":5325},{},[5326],{"type":49,"value":1481},{"type":44,"tag":159,"props":5328,"children":5329},{},[5330,5332,5337],{"type":49,"value":5331},"No continuous tick; use ",{"type":44,"tag":62,"props":5333,"children":5335},{"className":5334},[],[5336],{"type":49,"value":499},{"type":49,"value":5338}," for coarse intervals and compute offline catch-up from elapsed wall time.",{"type":44,"tag":133,"props":5340,"children":5341},{},[5342,5346],{"type":44,"tag":159,"props":5343,"children":5344},{},[5345],{"type":49,"value":507},{"type":44,"tag":159,"props":5347,"children":5348},{},[5349,5351,5357,5358,5364,5365,5371],{"type":49,"value":5350},"None for standard idle loops; transitions are discrete (",{"type":44,"tag":62,"props":5352,"children":5354},{"className":5353},[],[5355],{"type":49,"value":5356},"build",{"type":49,"value":577},{"type":44,"tag":62,"props":5359,"children":5361},{"className":5360},[],[5362],{"type":49,"value":5363},"collect",{"type":49,"value":577},{"type":44,"tag":62,"props":5366,"children":5368},{"className":5367},[],[5369],{"type":49,"value":5370},"upgrade",{"type":49,"value":5372},") and do not need spatial indexing.",{"type":44,"tag":52,"props":5374,"children":5375},{},[5376],{"type":44,"tag":56,"props":5377,"children":5378},{},[5379],{"type":49,"value":1528},{"type":44,"tag":83,"props":5381,"children":5382},{},[5383,5396,5405,5440,5454,5500,5513,5522,5541,5559],{"type":44,"tag":87,"props":5384,"children":5385},{},[5386,5390,5391],{"type":44,"tag":56,"props":5387,"children":5388},{},[5389],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":5392,"children":5394},{"className":5393},[],[5395],{"type":49,"value":1210},{"type":44,"tag":87,"props":5397,"children":5398},{},[5399,5403],{"type":44,"tag":56,"props":5400,"children":5401},{},[5402],{"type":49,"value":1554},{"type":49,"value":5404},": Owns one player's progression, buildings, production scheduling, and state updates.",{"type":44,"tag":87,"props":5406,"children":5407},{},[5408,5412],{"type":44,"tag":56,"props":5409,"children":5410},{},[5411],{"type":49,"value":1564},{"type":44,"tag":83,"props":5413,"children":5414},{},[5415,5423,5431],{"type":44,"tag":87,"props":5416,"children":5417},{},[5418],{"type":44,"tag":62,"props":5419,"children":5421},{"className":5420},[],[5422],{"type":49,"value":4277},{"type":44,"tag":87,"props":5424,"children":5425},{},[5426],{"type":44,"tag":62,"props":5427,"children":5429},{"className":5428},[],[5430],{"type":49,"value":5356},{"type":44,"tag":87,"props":5432,"children":5433},{},[5434],{"type":44,"tag":62,"props":5435,"children":5437},{"className":5436},[],[5438],{"type":49,"value":5439},"collectProduction",{"type":44,"tag":87,"props":5441,"children":5442},{},[5443,5447],{"type":44,"tag":56,"props":5444,"children":5445},{},[5446],{"type":49,"value":1611},{"type":44,"tag":83,"props":5448,"children":5449},{},[5450],{"type":44,"tag":87,"props":5451,"children":5452},{},[5453],{"type":49,"value":1752},{"type":44,"tag":87,"props":5455,"children":5456},{},[5457,5461],{"type":44,"tag":56,"props":5458,"children":5459},{},[5460],{"type":49,"value":1654},{"type":44,"tag":83,"props":5462,"children":5463},{},[5464,5468,5473,5482,5491],{"type":44,"tag":87,"props":5465,"children":5466},{},[5467],{"type":49,"value":1767},{"type":44,"tag":87,"props":5469,"children":5470},{},[5471],{"type":49,"value":5472},"Per-player buildings",{"type":44,"tag":87,"props":5474,"children":5475},{},[5476],{"type":44,"tag":62,"props":5477,"children":5479},{"className":5478},[],[5480],{"type":49,"value":5481},"resources",{"type":44,"tag":87,"props":5483,"children":5484},{},[5485],{"type":44,"tag":62,"props":5486,"children":5488},{"className":5487},[],[5489],{"type":49,"value":5490},"timers",{"type":44,"tag":87,"props":5492,"children":5493},{},[5494],{"type":44,"tag":62,"props":5495,"children":5497},{"className":5496},[],[5498],{"type":49,"value":5499},"progression state",{"type":44,"tag":87,"props":5501,"children":5502},{},[5503,5507,5508],{"type":44,"tag":56,"props":5504,"children":5505},{},[5506],{"type":49,"value":1539},{"type":49,"value":1541},{"type":44,"tag":62,"props":5509,"children":5511},{"className":5510},[],[5512],{"type":49,"value":1254},{"type":44,"tag":87,"props":5514,"children":5515},{},[5516,5520],{"type":44,"tag":56,"props":5517,"children":5518},{},[5519],{"type":49,"value":1554},{"type":49,"value":5521},": Stores global scores and serves leaderboard updates.",{"type":44,"tag":87,"props":5523,"children":5524},{},[5525,5529],{"type":44,"tag":56,"props":5526,"children":5527},{},[5528],{"type":49,"value":1564},{"type":44,"tag":83,"props":5530,"children":5531},{},[5532],{"type":44,"tag":87,"props":5533,"children":5534},{},[5535],{"type":44,"tag":62,"props":5536,"children":5538},{"className":5537},[],[5539],{"type":49,"value":5540},"updateScore",{"type":44,"tag":87,"props":5542,"children":5543},{},[5544,5548],{"type":44,"tag":56,"props":5545,"children":5546},{},[5547],{"type":49,"value":1611},{"type":44,"tag":83,"props":5549,"children":5550},{},[5551],{"type":44,"tag":87,"props":5552,"children":5553},{},[5554],{"type":44,"tag":62,"props":5555,"children":5557},{"className":5556},[],[5558],{"type":49,"value":5540},{"type":44,"tag":87,"props":5560,"children":5561},{},[5562,5566],{"type":44,"tag":56,"props":5563,"children":5564},{},[5565],{"type":49,"value":1654},{"type":44,"tag":83,"props":5567,"children":5568},{},[5569,5573,5584],{"type":44,"tag":87,"props":5570,"children":5571},{},[5572],{"type":49,"value":1662},{"type":44,"tag":87,"props":5574,"children":5575},{},[5576,5582],{"type":44,"tag":62,"props":5577,"children":5579},{"className":5578},[],[5580],{"type":49,"value":5581},"scores",{"type":49,"value":5583}," table keyed by player",{"type":44,"tag":87,"props":5585,"children":5586},{},[5587],{"type":49,"value":5588},"Current leaderboard totals",{"type":44,"tag":52,"props":5590,"children":5591},{},[5592],{"type":44,"tag":56,"props":5593,"children":5594},{},[5595],{"type":49,"value":1820},{"type":44,"tag":1822,"props":5597,"children":5599},{"className":1824,"code":5598,"language":1826,"meta":1827,"style":1827},"sequenceDiagram\n    participant C as Client\n    participant W as world\n    participant LB as leaderboard\n\n    C->>W: getOrCreate(playerId) + initialize()\n    Note over W: seed state + schedule collection\n    W-->>C: stateUpdate\n    loop gameplay loop\n        C->>W: build() \u002F collectProduction()\n        W->>LB: updateScore(...)\n    Note over LB: upsert scores\n    LB-->>C: leaderboardUpdate\n    W-->>C: stateUpdate\n    end\n",[5600],{"type":44,"tag":62,"props":5601,"children":5602},{"__ignoreMap":1827},[5603,5610,5617,5625,5632,5639,5647,5655,5663,5671,5679,5687,5695,5703,5710],{"type":44,"tag":1833,"props":5604,"children":5605},{"class":1835,"line":1836},[5606],{"type":44,"tag":1833,"props":5607,"children":5608},{},[5609],{"type":49,"value":1842},{"type":44,"tag":1833,"props":5611,"children":5612},{"class":1835,"line":1845},[5613],{"type":44,"tag":1833,"props":5614,"children":5615},{},[5616],{"type":49,"value":1851},{"type":44,"tag":1833,"props":5618,"children":5619},{"class":1835,"line":1854},[5620],{"type":44,"tag":1833,"props":5621,"children":5622},{},[5623],{"type":49,"value":5624},"    participant W as world\n",{"type":44,"tag":1833,"props":5626,"children":5627},{"class":1835,"line":1863},[5628],{"type":44,"tag":1833,"props":5629,"children":5630},{},[5631],{"type":49,"value":4496},{"type":44,"tag":1833,"props":5633,"children":5634},{"class":1835,"line":1872},[5635],{"type":44,"tag":1833,"props":5636,"children":5637},{"emptyLinePlaceholder":1876},[5638],{"type":49,"value":1879},{"type":44,"tag":1833,"props":5640,"children":5641},{"class":1835,"line":1882},[5642],{"type":44,"tag":1833,"props":5643,"children":5644},{},[5645],{"type":49,"value":5646},"    C->>W: getOrCreate(playerId) + initialize()\n",{"type":44,"tag":1833,"props":5648,"children":5649},{"class":1835,"line":31},[5650],{"type":44,"tag":1833,"props":5651,"children":5652},{},[5653],{"type":49,"value":5654},"    Note over W: seed state + schedule collection\n",{"type":44,"tag":1833,"props":5656,"children":5657},{"class":1835,"line":1899},[5658],{"type":44,"tag":1833,"props":5659,"children":5660},{},[5661],{"type":49,"value":5662},"    W-->>C: stateUpdate\n",{"type":44,"tag":1833,"props":5664,"children":5665},{"class":1835,"line":1908},[5666],{"type":44,"tag":1833,"props":5667,"children":5668},{},[5669],{"type":49,"value":5670},"    loop gameplay loop\n",{"type":44,"tag":1833,"props":5672,"children":5673},{"class":1835,"line":1917},[5674],{"type":44,"tag":1833,"props":5675,"children":5676},{},[5677],{"type":49,"value":5678},"        C->>W: build() \u002F collectProduction()\n",{"type":44,"tag":1833,"props":5680,"children":5681},{"class":1835,"line":1926},[5682],{"type":44,"tag":1833,"props":5683,"children":5684},{},[5685],{"type":49,"value":5686},"        W->>LB: updateScore(...)\n",{"type":44,"tag":1833,"props":5688,"children":5689},{"class":1835,"line":1935},[5690],{"type":44,"tag":1833,"props":5691,"children":5692},{},[5693],{"type":49,"value":5694},"    Note over LB: upsert scores\n",{"type":44,"tag":1833,"props":5696,"children":5697},{"class":1835,"line":1944},[5698],{"type":44,"tag":1833,"props":5699,"children":5700},{},[5701],{"type":49,"value":5702},"    LB-->>C: leaderboardUpdate\n",{"type":44,"tag":1833,"props":5704,"children":5705},{"class":1835,"line":1953},[5706],{"type":44,"tag":1833,"props":5707,"children":5708},{},[5709],{"type":49,"value":5662},{"type":44,"tag":1833,"props":5711,"children":5712},{"class":1835,"line":1962},[5713],{"type":44,"tag":1833,"props":5714,"children":5715},{},[5716],{"type":49,"value":1914},{"type":44,"tag":71,"props":5718,"children":5720},{"id":5719},"reference-map",[5721],{"type":49,"value":5722},"Reference Map",{"type":44,"tag":383,"props":5724,"children":5726},{"id":5725},"actors",[5727],{"type":49,"value":1528},{"type":44,"tag":83,"props":5729,"children":5730},{},[5731,5740,5748,5757,5766,5775,5784,5793,5802,5811,5820,5829,5838,5847,5856,5865,5874,5883,5892,5901,5910,5918,5927,5936,5945,5954,5963,5972,5981,5990,5999,6008,6017,6026,6035,6044,6052,6061,6070,6079,6088,6097,6106,6115],{"type":44,"tag":87,"props":5732,"children":5733},{},[5734],{"type":44,"tag":91,"props":5735,"children":5737},{"href":5736},"reference\u002Factors\u002Faccess-control.md",[5738],{"type":49,"value":5739},"Access Control",{"type":44,"tag":87,"props":5741,"children":5742},{},[5743],{"type":44,"tag":91,"props":5744,"children":5746},{"href":5745},"reference\u002Factors\u002Factions.md",[5747],{"type":49,"value":1564},{"type":44,"tag":87,"props":5749,"children":5750},{},[5751],{"type":44,"tag":91,"props":5752,"children":5754},{"href":5753},"reference\u002Factors\u002Fkeys.md",[5755],{"type":49,"value":5756},"Actor Keys",{"type":44,"tag":87,"props":5758,"children":5759},{},[5760],{"type":44,"tag":91,"props":5761,"children":5763},{"href":5762},"reference\u002Factors\u002Factor-runtime-socket.md",[5764],{"type":49,"value":5765},"Actor Runtime Socket",{"type":44,"tag":87,"props":5767,"children":5768},{},[5769],{"type":44,"tag":91,"props":5770,"children":5772},{"href":5771},"reference\u002Factors\u002Fstatuses.md",[5773],{"type":49,"value":5774},"Actor Statuses",{"type":44,"tag":87,"props":5776,"children":5777},{},[5778],{"type":44,"tag":91,"props":5779,"children":5781},{"href":5780},"reference\u002Factors\u002Fauthentication.md",[5782],{"type":49,"value":5783},"Authentication",{"type":44,"tag":87,"props":5785,"children":5786},{},[5787],{"type":44,"tag":91,"props":5788,"children":5790},{"href":5789},"reference\u002Factors\u002Fquickstart\u002Fcloudflare.md",[5791],{"type":49,"value":5792},"Cloudflare Workers Quickstart",{"type":44,"tag":87,"props":5794,"children":5795},{},[5796],{"type":44,"tag":91,"props":5797,"children":5799},{"href":5798},"reference\u002Factors\u002Fcommunicating-between-actors.md",[5800],{"type":49,"value":5801},"Communicating Between Actors",{"type":44,"tag":87,"props":5803,"children":5804},{},[5805],{"type":44,"tag":91,"props":5806,"children":5808},{"href":5807},"reference\u002Factors\u002Fconnections.md",[5809],{"type":49,"value":5810},"Connections",{"type":44,"tag":87,"props":5812,"children":5813},{},[5814],{"type":44,"tag":91,"props":5815,"children":5817},{"href":5816},"reference\u002Factors\u002Finspector-tabs.md",[5818],{"type":49,"value":5819},"Custom Inspector Tabs",{"type":44,"tag":87,"props":5821,"children":5822},{},[5823],{"type":44,"tag":91,"props":5824,"children":5826},{"href":5825},"reference\u002Factors\u002Fdebugging.md",[5827],{"type":49,"value":5828},"Debugging",{"type":44,"tag":87,"props":5830,"children":5831},{},[5832],{"type":44,"tag":91,"props":5833,"children":5835},{"href":5834},"reference\u002Factors\u002Fdesign-patterns.md",[5836],{"type":49,"value":5837},"Design Patterns",{"type":44,"tag":87,"props":5839,"children":5840},{},[5841],{"type":44,"tag":91,"props":5842,"children":5844},{"href":5843},"reference\u002Factors\u002Fdestroy.md",[5845],{"type":49,"value":5846},"Destroying Actors",{"type":44,"tag":87,"props":5848,"children":5849},{},[5850],{"type":44,"tag":91,"props":5851,"children":5853},{"href":5852},"reference\u002Factors\u002Fquickstart\u002Feffect.md",[5854],{"type":49,"value":5855},"Effect.ts Quickstart (Beta)",{"type":44,"tag":87,"props":5857,"children":5858},{},[5859],{"type":44,"tag":91,"props":5860,"children":5862},{"href":5861},"reference\u002Factors\u002Ferrors.md",[5863],{"type":49,"value":5864},"Errors",{"type":44,"tag":87,"props":5866,"children":5867},{},[5868],{"type":44,"tag":91,"props":5869,"children":5871},{"href":5870},"reference\u002Factors\u002Ffetch-and-websocket-handler.md",[5872],{"type":49,"value":5873},"Fetch and WebSocket Handler",{"type":44,"tag":87,"props":5875,"children":5876},{},[5877],{"type":44,"tag":91,"props":5878,"children":5880},{"href":5879},"reference\u002Factors\u002Fhelper-types.md",[5881],{"type":49,"value":5882},"Helper Types",{"type":44,"tag":87,"props":5884,"children":5885},{},[5886],{"type":44,"tag":91,"props":5887,"children":5889},{"href":5888},"reference\u002Factors\u002Fappearance.md",[5890],{"type":49,"value":5891},"Icons & Names",{"type":44,"tag":87,"props":5893,"children":5894},{},[5895],{"type":44,"tag":91,"props":5896,"children":5898},{"href":5897},"reference\u002Factors\u002Fstate.md",[5899],{"type":49,"value":5900},"In-Memory State",{"type":44,"tag":87,"props":5902,"children":5903},{},[5904],{"type":44,"tag":91,"props":5905,"children":5907},{"href":5906},"reference\u002Factors\u002Finput.md",[5908],{"type":49,"value":5909},"Input Parameters",{"type":44,"tag":87,"props":5911,"children":5912},{},[5913],{"type":44,"tag":91,"props":5914,"children":5916},{"href":5915},"reference\u002Factors\u002Flifecycle.md",[5917],{"type":49,"value":1820},{"type":44,"tag":87,"props":5919,"children":5920},{},[5921],{"type":44,"tag":91,"props":5922,"children":5924},{"href":5923},"reference\u002Factors\u002Flimits.md",[5925],{"type":49,"value":5926},"Limits",{"type":44,"tag":87,"props":5928,"children":5929},{},[5930],{"type":44,"tag":91,"props":5931,"children":5933},{"href":5932},"reference\u002Factors\u002Frequest-handler.md",[5934],{"type":49,"value":5935},"Low-Level HTTP Request Handler",{"type":44,"tag":87,"props":5937,"children":5938},{},[5939],{"type":44,"tag":91,"props":5940,"children":5942},{"href":5941},"reference\u002Factors\u002Fkv.md",[5943],{"type":49,"value":5944},"Low-Level KV Storage",{"type":44,"tag":87,"props":5946,"children":5947},{},[5948],{"type":44,"tag":91,"props":5949,"children":5951},{"href":5950},"reference\u002Factors\u002Fwebsocket-handler.md",[5952],{"type":49,"value":5953},"Low-Level WebSocket Handler",{"type":44,"tag":87,"props":5955,"children":5956},{},[5957],{"type":44,"tag":91,"props":5958,"children":5960},{"href":5959},"reference\u002Factors\u002Fmetadata.md",[5961],{"type":49,"value":5962},"Metadata",{"type":44,"tag":87,"props":5964,"children":5965},{},[5966],{"type":44,"tag":91,"props":5967,"children":5969},{"href":5968},"reference\u002Factors\u002Fquickstart\u002Fnext-js.md",[5970],{"type":49,"value":5971},"Next.js Quickstart",{"type":44,"tag":87,"props":5973,"children":5974},{},[5975],{"type":44,"tag":91,"props":5976,"children":5978},{"href":5977},"reference\u002Factors\u002Fquickstart\u002Fbackend.md",[5979],{"type":49,"value":5980},"Node.js & Bun Quickstart",{"type":44,"tag":87,"props":5982,"children":5983},{},[5984],{"type":44,"tag":91,"props":5985,"children":5987},{"href":5986},"reference\u002Factors\u002Fqueues.md",[5988],{"type":49,"value":5989},"Queues & Run Loops",{"type":44,"tag":87,"props":5991,"children":5992},{},[5993],{"type":44,"tag":91,"props":5994,"children":5996},{"href":5995},"reference\u002Factors\u002Fquickstart\u002Freact.md",[5997],{"type":49,"value":5998},"React Quickstart",{"type":44,"tag":87,"props":6000,"children":6001},{},[6002],{"type":44,"tag":91,"props":6003,"children":6005},{"href":6004},"reference\u002Factors\u002Fevents.md",[6006],{"type":49,"value":6007},"Realtime",{"type":44,"tag":87,"props":6009,"children":6010},{},[6011],{"type":44,"tag":91,"props":6012,"children":6014},{"href":6013},"reference\u002Factors\u002Fquickstart\u002Frust.md",[6015],{"type":49,"value":6016},"Rust Quickstart (Beta)",{"type":44,"tag":87,"props":6018,"children":6019},{},[6020],{"type":44,"tag":91,"props":6021,"children":6023},{"href":6022},"reference\u002Factors\u002Fscaling.md",[6024],{"type":49,"value":6025},"Scaling & Concurrency",{"type":44,"tag":87,"props":6027,"children":6028},{},[6029],{"type":44,"tag":91,"props":6030,"children":6032},{"href":6031},"reference\u002Factors\u002Fschedule.md",[6033],{"type":49,"value":6034},"Schedule & Cron",{"type":44,"tag":87,"props":6036,"children":6037},{},[6038],{"type":44,"tag":91,"props":6039,"children":6041},{"href":6040},"reference\u002Factors\u002Fsharing-and-joining-state.md",[6042],{"type":49,"value":6043},"Sharing and Joining State",{"type":44,"tag":87,"props":6045,"children":6046},{},[6047],{"type":44,"tag":91,"props":6048,"children":6050},{"href":6049},"reference\u002Factors\u002Fsqlite.md",[6051],{"type":49,"value":1662},{"type":44,"tag":87,"props":6053,"children":6054},{},[6055],{"type":44,"tag":91,"props":6056,"children":6058},{"href":6057},"reference\u002Factors\u002Fsqlite-drizzle.md",[6059],{"type":49,"value":6060},"SQLite + Drizzle",{"type":44,"tag":87,"props":6062,"children":6063},{},[6064],{"type":44,"tag":91,"props":6065,"children":6067},{"href":6066},"reference\u002Factors\u002Fquickstart\u002Fsupabase.md",[6068],{"type":49,"value":6069},"Supabase Functions Quickstart",{"type":44,"tag":87,"props":6071,"children":6072},{},[6073],{"type":44,"tag":91,"props":6074,"children":6076},{"href":6075},"reference\u002Factors\u002Ftesting.md",[6077],{"type":49,"value":6078},"Testing",{"type":44,"tag":87,"props":6080,"children":6081},{},[6082],{"type":44,"tag":91,"props":6083,"children":6085},{"href":6084},"reference\u002Factors\u002Ftroubleshooting.md",[6086],{"type":49,"value":6087},"Troubleshooting",{"type":44,"tag":87,"props":6089,"children":6090},{},[6091],{"type":44,"tag":91,"props":6092,"children":6094},{"href":6093},"reference\u002Factors\u002Ftypes.md",[6095],{"type":49,"value":6096},"Types",{"type":44,"tag":87,"props":6098,"children":6099},{},[6100],{"type":44,"tag":91,"props":6101,"children":6103},{"href":6102},"reference\u002Factors\u002Fhttp-api.md",[6104],{"type":49,"value":6105},"Vanilla HTTP API",{"type":44,"tag":87,"props":6107,"children":6108},{},[6109],{"type":44,"tag":91,"props":6110,"children":6112},{"href":6111},"reference\u002Factors\u002Fversions.md",[6113],{"type":49,"value":6114},"Versions & Upgrades",{"type":44,"tag":87,"props":6116,"children":6117},{},[6118],{"type":44,"tag":91,"props":6119,"children":6121},{"href":6120},"reference\u002Factors\u002Fworkflows.md",[6122],{"type":49,"value":6123},"Workflows",{"type":44,"tag":383,"props":6125,"children":6127},{"id":6126},"cli",[6128],{"type":49,"value":6129},"Cli",{"type":44,"tag":83,"props":6131,"children":6132},{},[6133],{"type":44,"tag":87,"props":6134,"children":6135},{},[6136],{"type":44,"tag":91,"props":6137,"children":6139},{"href":6138},"reference\u002Fcli.md",[6140],{"type":49,"value":6141},"CLI",{"type":44,"tag":383,"props":6143,"children":6145},{"id":6144},"clients",[6146],{"type":49,"value":6147},"Clients",{"type":44,"tag":83,"props":6149,"children":6150},{},[6151,6160,6169,6178,6187],{"type":44,"tag":87,"props":6152,"children":6153},{},[6154],{"type":44,"tag":91,"props":6155,"children":6157},{"href":6156},"reference\u002Fclients\u002Fjavascript.md",[6158],{"type":49,"value":6159},"Node.js & Bun",{"type":44,"tag":87,"props":6161,"children":6162},{},[6163],{"type":44,"tag":91,"props":6164,"children":6166},{"href":6165},"reference\u002Fclients\u002Freact.md",[6167],{"type":49,"value":6168},"React",{"type":44,"tag":87,"props":6170,"children":6171},{},[6172],{"type":44,"tag":91,"props":6173,"children":6175},{"href":6174},"reference\u002Fclients\u002Frust.md",[6176],{"type":49,"value":6177},"Rust (Beta)",{"type":44,"tag":87,"props":6179,"children":6180},{},[6181],{"type":44,"tag":91,"props":6182,"children":6184},{"href":6183},"reference\u002Fclients\u002Fswift.md",[6185],{"type":49,"value":6186},"Swift",{"type":44,"tag":87,"props":6188,"children":6189},{},[6190],{"type":44,"tag":91,"props":6191,"children":6193},{"href":6192},"reference\u002Fclients\u002Fswiftui.md",[6194],{"type":49,"value":6195},"SwiftUI",{"type":44,"tag":383,"props":6197,"children":6199},{"id":6198},"cookbook",[6200],{"type":49,"value":6201},"Cookbook",{"type":44,"tag":83,"props":6203,"children":6204},{},[6205,6214,6223,6232,6241,6250,6259,6268],{"type":44,"tag":87,"props":6206,"children":6207},{},[6208],{"type":44,"tag":91,"props":6209,"children":6211},{"href":6210},"reference\u002Fcookbook\u002Fai-agent.md",[6212],{"type":49,"value":6213},"AI Agent",{"type":44,"tag":87,"props":6215,"children":6216},{},[6217],{"type":44,"tag":91,"props":6218,"children":6220},{"href":6219},"reference\u002Fcookbook\u002Fchat-room.md",[6221],{"type":49,"value":6222},"Chat Room",{"type":44,"tag":87,"props":6224,"children":6225},{},[6226],{"type":44,"tag":91,"props":6227,"children":6229},{"href":6228},"reference\u002Fcookbook\u002Fcollaborative-text-editor.md",[6230],{"type":49,"value":6231},"Collaborative Text Editor",{"type":44,"tag":87,"props":6233,"children":6234},{},[6235],{"type":44,"tag":91,"props":6236,"children":6238},{"href":6237},"reference\u002Fcookbook\u002Fcron-jobs.md",[6239],{"type":49,"value":6240},"Cron Jobs and Scheduled Tasks",{"type":44,"tag":87,"props":6242,"children":6243},{},[6244],{"type":44,"tag":91,"props":6245,"children":6247},{"href":6246},"reference\u002Fcookbook\u002Fper-tenant-database.md",[6248],{"type":49,"value":6249},"Database per Tenant",{"type":44,"tag":87,"props":6251,"children":6252},{},[6253],{"type":44,"tag":91,"props":6254,"children":6256},{"href":6255},"reference\u002Fcookbook\u002Fvpc-air-gapped.md",[6257],{"type":49,"value":6258},"Deploying Rivet in a VPC or Air-Gapped Network",{"type":44,"tag":87,"props":6260,"children":6261},{},[6262],{"type":44,"tag":91,"props":6263,"children":6265},{"href":6264},"reference\u002Fcookbook\u002Flive-cursors.md",[6266],{"type":49,"value":6267},"Live Cursors and Presence",{"type":44,"tag":87,"props":6269,"children":6270},{},[6271],{"type":44,"tag":91,"props":6272,"children":6274},{"href":6273},"reference\u002Fcookbook\u002Fmultiplayer-game.md",[6275],{"type":49,"value":50},{"type":44,"tag":383,"props":6277,"children":6279},{"id":6278},"deploy",[6280],{"type":49,"value":6281},"Deploy",{"type":44,"tag":83,"props":6283,"children":6284},{},[6285,6294,6303,6312,6321,6330,6339,6348,6357,6366,6375,6384,6393],{"type":44,"tag":87,"props":6286,"children":6287},{},[6288],{"type":44,"tag":91,"props":6289,"children":6291},{"href":6290},"reference\u002Fdeploy\u002Fcontainer-runner.md",[6292],{"type":49,"value":6293},"Container Runner",{"type":44,"tag":87,"props":6295,"children":6296},{},[6297],{"type":44,"tag":91,"props":6298,"children":6300},{"href":6299},"reference\u002Fdeploy\u002Faws-lambda.md",[6301],{"type":49,"value":6302},"Deploy To Amazon Web Services Lambda",{"type":44,"tag":87,"props":6304,"children":6305},{},[6306],{"type":44,"tag":91,"props":6307,"children":6309},{"href":6308},"reference\u002Fdeploy\u002Faws-ecs.md",[6310],{"type":49,"value":6311},"Deploying to AWS ECS",{"type":44,"tag":87,"props":6313,"children":6314},{},[6315],{"type":44,"tag":91,"props":6316,"children":6318},{"href":6317},"reference\u002Fdeploy\u002Fcloudflare.md",[6319],{"type":49,"value":6320},"Deploying to Cloudflare Workers",{"type":44,"tag":87,"props":6322,"children":6323},{},[6324],{"type":44,"tag":91,"props":6325,"children":6327},{"href":6326},"reference\u002Fdeploy\u002Ffreestyle.md",[6328],{"type":49,"value":6329},"Deploying to Freestyle",{"type":44,"tag":87,"props":6331,"children":6332},{},[6333],{"type":44,"tag":91,"props":6334,"children":6336},{"href":6335},"reference\u002Fdeploy\u002Fgcp-cloud-run.md",[6337],{"type":49,"value":6338},"Deploying to Google Cloud Run",{"type":44,"tag":87,"props":6340,"children":6341},{},[6342],{"type":44,"tag":91,"props":6343,"children":6345},{"href":6344},"reference\u002Fdeploy\u002Fhetzner.md",[6346],{"type":49,"value":6347},"Deploying to Hetzner",{"type":44,"tag":87,"props":6349,"children":6350},{},[6351],{"type":44,"tag":91,"props":6352,"children":6354},{"href":6353},"reference\u002Fdeploy\u002Fkubernetes.md",[6355],{"type":49,"value":6356},"Deploying to Kubernetes",{"type":44,"tag":87,"props":6358,"children":6359},{},[6360],{"type":44,"tag":91,"props":6361,"children":6363},{"href":6362},"reference\u002Fdeploy\u002Frailway.md",[6364],{"type":49,"value":6365},"Deploying to Railway",{"type":44,"tag":87,"props":6367,"children":6368},{},[6369],{"type":44,"tag":91,"props":6370,"children":6372},{"href":6371},"reference\u002Fdeploy\u002Frivet-compute.md",[6373],{"type":49,"value":6374},"Deploying to Rivet Compute",{"type":44,"tag":87,"props":6376,"children":6377},{},[6378],{"type":44,"tag":91,"props":6379,"children":6381},{"href":6380},"reference\u002Fdeploy\u002Fsupabase.md",[6382],{"type":49,"value":6383},"Deploying to Supabase Functions",{"type":44,"tag":87,"props":6385,"children":6386},{},[6387],{"type":44,"tag":91,"props":6388,"children":6390},{"href":6389},"reference\u002Fdeploy\u002Fvercel.md",[6391],{"type":49,"value":6392},"Deploying to Vercel",{"type":44,"tag":87,"props":6394,"children":6395},{},[6396],{"type":44,"tag":91,"props":6397,"children":6399},{"href":6398},"reference\u002Fdeploy\u002Fvm-and-bare-metal.md",[6400],{"type":49,"value":6401},"Deploying to VMs & Bare Metal",{"type":44,"tag":383,"props":6403,"children":6405},{"id":6404},"general",[6406],{"type":49,"value":6407},"General",{"type":44,"tag":83,"props":6409,"children":6410},{},[6411,6420,6428,6437,6446,6455,6464,6473,6482,6491,6500,6509,6518,6527],{"type":44,"tag":87,"props":6412,"children":6413},{},[6414],{"type":44,"tag":91,"props":6415,"children":6417},{"href":6416},"reference\u002Fgeneral\u002Factor-configuration.md",[6418],{"type":49,"value":6419},"Actor Configuration",{"type":44,"tag":87,"props":6421,"children":6422},{},[6423],{"type":44,"tag":91,"props":6424,"children":6426},{"href":6425},"reference\u002Fgeneral\u002Farchitecture.md",[6427],{"type":49,"value":16},{"type":44,"tag":87,"props":6429,"children":6430},{},[6431],{"type":44,"tag":91,"props":6432,"children":6434},{"href":6433},"reference\u002Fgeneral\u002Fcors.md",[6435],{"type":49,"value":6436},"Cross-Origin Resource Sharing",{"type":44,"tag":87,"props":6438,"children":6439},{},[6440],{"type":44,"tag":91,"props":6441,"children":6443},{"href":6442},"reference\u002Fgeneral\u002Fdocs-for-llms.md",[6444],{"type":49,"value":6445},"Documentation for LLMs & AI",{"type":44,"tag":87,"props":6447,"children":6448},{},[6449],{"type":44,"tag":91,"props":6450,"children":6452},{"href":6451},"reference\u002Fgeneral\u002Fedge.md",[6453],{"type":49,"value":6454},"Edge Networking",{"type":44,"tag":87,"props":6456,"children":6457},{},[6458],{"type":44,"tag":91,"props":6459,"children":6461},{"href":6460},"reference\u002Fgeneral\u002Fendpoints.md",[6462],{"type":49,"value":6463},"Endpoints",{"type":44,"tag":87,"props":6465,"children":6466},{},[6467],{"type":44,"tag":91,"props":6468,"children":6470},{"href":6469},"reference\u002Fgeneral\u002Fenvironment-variables.md",[6471],{"type":49,"value":6472},"Environment Variables",{"type":44,"tag":87,"props":6474,"children":6475},{},[6476],{"type":44,"tag":91,"props":6477,"children":6479},{"href":6478},"reference\u002Fgeneral\u002Fhttp-server.md",[6480],{"type":49,"value":6481},"HTTP Server",{"type":44,"tag":87,"props":6483,"children":6484},{},[6485],{"type":44,"tag":91,"props":6486,"children":6488},{"href":6487},"reference\u002Fgeneral\u002Flogging.md",[6489],{"type":49,"value":6490},"Logging",{"type":44,"tag":87,"props":6492,"children":6493},{},[6494],{"type":44,"tag":91,"props":6495,"children":6497},{"href":6496},"reference\u002Fgeneral\u002Fpool-configuration.md",[6498],{"type":49,"value":6499},"Pool Configuration",{"type":44,"tag":87,"props":6501,"children":6502},{},[6503],{"type":44,"tag":91,"props":6504,"children":6506},{"href":6505},"reference\u002Fgeneral\u002Fproduction-checklist.md",[6507],{"type":49,"value":6508},"Production Checklist",{"type":44,"tag":87,"props":6510,"children":6511},{},[6512],{"type":44,"tag":91,"props":6513,"children":6515},{"href":6514},"reference\u002Fgeneral\u002Fregistry-configuration.md",[6516],{"type":49,"value":6517},"Registry Configuration",{"type":44,"tag":87,"props":6519,"children":6520},{},[6521],{"type":44,"tag":91,"props":6522,"children":6524},{"href":6523},"reference\u002Fgeneral\u002Fruntime-modes.md",[6525],{"type":49,"value":6526},"Runtime Modes",{"type":44,"tag":87,"props":6528,"children":6529},{},[6530],{"type":44,"tag":91,"props":6531,"children":6533},{"href":6532},"reference\u002Fgeneral\u002Fwasm-vs-native-sdk.md",[6534],{"type":49,"value":6535},"WASM vs Native SDK",{"type":44,"tag":383,"props":6537,"children":6539},{"id":6538},"self-hosting",[6540],{"type":49,"value":6541},"Self Hosting",{"type":44,"tag":83,"props":6543,"children":6544},{},[6545,6554,6563,6572,6581,6590,6599,6608,6617,6626,6634,6643,6652],{"type":44,"tag":87,"props":6546,"children":6547},{},[6548],{"type":44,"tag":91,"props":6549,"children":6551},{"href":6550},"reference\u002Fself-hosting\u002Fconfiguration.md",[6552],{"type":49,"value":6553},"Configuration",{"type":44,"tag":87,"props":6555,"children":6556},{},[6557],{"type":44,"tag":91,"props":6558,"children":6560},{"href":6559},"reference\u002Fself-hosting\u002Fdocker-compose.md",[6561],{"type":49,"value":6562},"Docker Compose",{"type":44,"tag":87,"props":6564,"children":6565},{},[6566],{"type":44,"tag":91,"props":6567,"children":6569},{"href":6568},"reference\u002Fself-hosting\u002Fdocker-container.md",[6570],{"type":49,"value":6571},"Docker Container",{"type":44,"tag":87,"props":6573,"children":6574},{},[6575],{"type":44,"tag":91,"props":6576,"children":6578},{"href":6577},"reference\u002Fself-hosting\u002Ffilesystem.md",[6579],{"type":49,"value":6580},"File System",{"type":44,"tag":87,"props":6582,"children":6583},{},[6584],{"type":44,"tag":91,"props":6585,"children":6587},{"href":6586},"reference\u002Fself-hosting\u002Ffoundationdb.md",[6588],{"type":49,"value":6589},"FoundationDB (Enterprise)",{"type":44,"tag":87,"props":6591,"children":6592},{},[6593],{"type":44,"tag":91,"props":6594,"children":6596},{"href":6595},"reference\u002Fself-hosting\u002Finstall.md",[6597],{"type":49,"value":6598},"Installing Rivet Engine",{"type":44,"tag":87,"props":6600,"children":6601},{},[6602],{"type":44,"tag":91,"props":6603,"children":6605},{"href":6604},"reference\u002Fself-hosting\u002Fkubernetes.md",[6606],{"type":49,"value":6607},"Kubernetes",{"type":44,"tag":87,"props":6609,"children":6610},{},[6611],{"type":44,"tag":91,"props":6612,"children":6614},{"href":6613},"reference\u002Fself-hosting\u002Fmulti-region.md",[6615],{"type":49,"value":6616},"Multi-Region",{"type":44,"tag":87,"props":6618,"children":6619},{},[6620],{"type":44,"tag":91,"props":6621,"children":6623},{"href":6622},"reference\u002Fself-hosting\u002Fpostgres.md",[6624],{"type":49,"value":6625},"PostgreSQL",{"type":44,"tag":87,"props":6627,"children":6628},{},[6629],{"type":44,"tag":91,"props":6630,"children":6632},{"href":6631},"reference\u002Fself-hosting\u002Fproduction-checklist.md",[6633],{"type":49,"value":6508},{"type":44,"tag":87,"props":6635,"children":6636},{},[6637],{"type":44,"tag":91,"props":6638,"children":6640},{"href":6639},"reference\u002Fself-hosting\u002Frailway.md",[6641],{"type":49,"value":6642},"Railway Deployment",{"type":44,"tag":87,"props":6644,"children":6645},{},[6646],{"type":44,"tag":91,"props":6647,"children":6649},{"href":6648},"reference\u002Fself-hosting\u002Frender.md",[6650],{"type":49,"value":6651},"Render Deployment",{"type":44,"tag":87,"props":6653,"children":6654},{},[6655],{"type":44,"tag":91,"props":6656,"children":6658},{"href":6657},"reference\u002Fself-hosting\u002Ftls.md",[6659],{"type":49,"value":6660},"TLS & Certificates",{"type":44,"tag":6662,"props":6663,"children":6664},"style",{},[6665],{"type":49,"value":6666},"html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"items":6668,"total":1971},[6669,6690,6708,6727,6743,6759,6776],{"slug":6670,"name":6670,"fn":6671,"description":6672,"org":6673,"tags":6674,"stars":27,"repoUrl":28,"updatedAt":6689},"ai-agent","build AI agent backends with Rivet","Build an AI agent backend with persistent memory: one Rivet Actor per conversation, queued message handling, and streaming LLM responses as realtime events.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6675,6678,6681,6684,6687,6688],{"name":6676,"slug":6677,"type":14},"Agents","agents",{"name":6679,"slug":6680,"type":14},"Backend","backend",{"name":6682,"slug":6683,"type":14},"LLM","llm",{"name":6685,"slug":6686,"type":14},"Memory","memory",{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},"2026-07-21T05:37:45.411803",{"slug":6691,"name":6691,"fn":6692,"description":6693,"org":6694,"tags":6695,"stars":27,"repoUrl":28,"updatedAt":6707},"ai-agent-workspace","create persistent workspaces for AI agents","Give every AI agent its own computer: a persistent workspace with a filesystem, processes, shells, networking, and agent sessions on a lightweight in-process OS.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6696,6697,6700,6703,6704],{"name":6676,"slug":6677,"type":14},{"name":6698,"slug":6699,"type":14},"File Storage","file-storage",{"name":6701,"slug":6702,"type":14},"Infrastructure","infrastructure",{"name":9,"slug":8,"type":14},{"name":6705,"slug":6706,"type":14},"Sandboxing","sandboxing","2026-06-14T08:06:57.274844",{"slug":6709,"name":6709,"fn":6710,"description":6711,"org":6712,"tags":6713,"stars":27,"repoUrl":28,"updatedAt":6726},"chat-room","build realtime chat rooms with Rivet","Build a realtime chat room backend with Rivet Actors: one actor per room, SQLite-backed message history, and WebSocket broadcast to every connected client.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6714,6715,6718,6719,6720,6723],{"name":6679,"slug":6680,"type":14},{"name":6716,"slug":6717,"type":14},"Messaging","messaging",{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},{"name":6721,"slug":6722,"type":14},"SQL","sql",{"name":6724,"slug":6725,"type":14},"WebSockets","websockets","2026-07-21T05:37:48.403494",{"slug":6728,"name":6728,"fn":6729,"description":6730,"org":6731,"tags":6732,"stars":27,"repoUrl":28,"updatedAt":6742},"collaborative-text-editor","build collaborative text editors with Rivet","Build a collaborative text editor backend with Yjs CRDTs and Rivet Actors: per-document actors relay sync and awareness updates and persist snapshots.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6733,6734,6737,6740,6741],{"name":6679,"slug":6680,"type":14},{"name":6735,"slug":6736,"type":14},"Collaboration","collaboration",{"name":6738,"slug":6739,"type":14},"Documents","documents",{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},"2026-07-21T05:37:49.412829",{"slug":6744,"name":6744,"fn":6745,"description":6746,"org":6747,"tags":6748,"stars":27,"repoUrl":28,"updatedAt":6758},"cron-jobs","schedule durable cron jobs with Rivet","Patterns for durable one-shot, calendar, and fixed-interval work on Rivet Actors.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6749,6752,6753,6754,6755],{"name":6750,"slug":6751,"type":14},"Automation","automation",{"name":6679,"slug":6680,"type":14},{"name":6701,"slug":6702,"type":14},{"name":9,"slug":8,"type":14},{"name":6756,"slug":6757,"type":14},"Scheduling","scheduling","2026-07-21T05:37:43.395911",{"slug":6760,"name":6760,"fn":6761,"description":6762,"org":6763,"tags":6764,"stars":27,"repoUrl":28,"updatedAt":6775},"live-cursors","implement live cursors and multiplayer presence","Live cursors and multiplayer presence with Rivet Actors: per-connection cursor state, realtime updates over events or raw WebSockets, and throttling.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6765,6766,6769,6770,6771,6774],{"name":6735,"slug":6736,"type":14},{"name":6767,"slug":6768,"type":14},"Frontend","frontend",{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},{"name":6772,"slug":6773,"type":14},"UX Design","ux-design",{"name":6724,"slug":6725,"type":14},"2026-07-21T05:37:47.391088",{"slug":4,"name":4,"fn":5,"description":6,"org":6777,"tags":6778,"stars":27,"repoUrl":28,"updatedAt":29},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6779,6780,6781,6782,6783],{"name":16,"slug":17,"type":14},{"name":22,"slug":23,"type":14},{"name":19,"slug":20,"type":14},{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},{"items":6785,"total":27},[6786,6795,6803,6812,6820,6828,6837,6845,6863,6878,6894,6909],{"slug":6670,"name":6670,"fn":6671,"description":6672,"org":6787,"tags":6788,"stars":27,"repoUrl":28,"updatedAt":6689},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6789,6790,6791,6792,6793,6794],{"name":6676,"slug":6677,"type":14},{"name":6679,"slug":6680,"type":14},{"name":6682,"slug":6683,"type":14},{"name":6685,"slug":6686,"type":14},{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},{"slug":6691,"name":6691,"fn":6692,"description":6693,"org":6796,"tags":6797,"stars":27,"repoUrl":28,"updatedAt":6707},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6798,6799,6800,6801,6802],{"name":6676,"slug":6677,"type":14},{"name":6698,"slug":6699,"type":14},{"name":6701,"slug":6702,"type":14},{"name":9,"slug":8,"type":14},{"name":6705,"slug":6706,"type":14},{"slug":6709,"name":6709,"fn":6710,"description":6711,"org":6804,"tags":6805,"stars":27,"repoUrl":28,"updatedAt":6726},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6806,6807,6808,6809,6810,6811],{"name":6679,"slug":6680,"type":14},{"name":6716,"slug":6717,"type":14},{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},{"name":6721,"slug":6722,"type":14},{"name":6724,"slug":6725,"type":14},{"slug":6728,"name":6728,"fn":6729,"description":6730,"org":6813,"tags":6814,"stars":27,"repoUrl":28,"updatedAt":6742},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6815,6816,6817,6818,6819],{"name":6679,"slug":6680,"type":14},{"name":6735,"slug":6736,"type":14},{"name":6738,"slug":6739,"type":14},{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},{"slug":6744,"name":6744,"fn":6745,"description":6746,"org":6821,"tags":6822,"stars":27,"repoUrl":28,"updatedAt":6758},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6823,6824,6825,6826,6827],{"name":6750,"slug":6751,"type":14},{"name":6679,"slug":6680,"type":14},{"name":6701,"slug":6702,"type":14},{"name":9,"slug":8,"type":14},{"name":6756,"slug":6757,"type":14},{"slug":6760,"name":6760,"fn":6761,"description":6762,"org":6829,"tags":6830,"stars":27,"repoUrl":28,"updatedAt":6775},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6831,6832,6833,6834,6835,6836],{"name":6735,"slug":6736,"type":14},{"name":6767,"slug":6768,"type":14},{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},{"name":6772,"slug":6773,"type":14},{"name":6724,"slug":6725,"type":14},{"slug":4,"name":4,"fn":5,"description":6,"org":6838,"tags":6839,"stars":27,"repoUrl":28,"updatedAt":29},{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6840,6841,6842,6843,6844],{"name":16,"slug":17,"type":14},{"name":22,"slug":23,"type":14},{"name":19,"slug":20,"type":14},{"name":25,"slug":26,"type":14},{"name":9,"slug":8,"type":14},{"slug":6846,"name":6846,"fn":6847,"description":6848,"org":6849,"tags":6850,"stars":27,"repoUrl":28,"updatedAt":6862},"per-tenant-database","implement multi-tenant data isolation with Rivet","Multi-tenant data isolation with one Rivet Actor per tenant: the actor key is the tenant id, so each tenant gets its own isolated dataset and migrations.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6851,6852,6855,6858,6861],{"name":16,"slug":17,"type":14},{"name":6853,"slug":6854,"type":14},"Database","database",{"name":6856,"slug":6857,"type":14},"Migration","migration",{"name":6859,"slug":6860,"type":14},"Multi-Tenant","multi-tenant",{"name":9,"slug":8,"type":14},"2026-07-21T05:37:46.414425",{"slug":6864,"name":6864,"fn":6865,"description":6866,"org":6867,"tags":6868,"stars":27,"repoUrl":28,"updatedAt":6877},"rivetkit","build and debug Rivet Actors","RivetKit backend and Rivet Actor runtime guidance. Use for building, modifying, debugging, or testing Rivet Actors, registries, serverless\u002Frunner modes, deployment, or actor-based workflows.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6869,6870,6871,6873,6876],{"name":6676,"slug":6677,"type":14},{"name":6679,"slug":6680,"type":14},{"name":5828,"slug":6872,"type":14},"debugging",{"name":6874,"slug":6875,"type":14},"Deployment","deployment",{"name":9,"slug":8,"type":14},"2026-07-24T05:38:58.10133",{"slug":6879,"name":6879,"fn":6880,"description":6881,"org":6882,"tags":6883,"stars":27,"repoUrl":28,"updatedAt":6893},"rivetkit-client-javascript","use RivetKit JavaScript client","RivetKit JavaScript client guidance. Use for browser, Node.js, or Bun clients that connect to Rivet Actors with rivetkit\u002Fclient, create clients, call actions, or manage connections.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6884,6885,6886,6889,6890],{"name":6679,"slug":6680,"type":14},{"name":6767,"slug":6768,"type":14},{"name":6887,"slug":6888,"type":14},"JavaScript","javascript",{"name":9,"slug":8,"type":14},{"name":6891,"slug":6892,"type":14},"SDK","sdk","2026-07-30T05:31:37.725576",{"slug":6895,"name":6895,"fn":6896,"description":6897,"org":6898,"tags":6899,"stars":27,"repoUrl":28,"updatedAt":6908},"rivetkit-client-react","use RivetKit React client","RivetKit React client guidance. Use for React apps that connect to Rivet Actors with @rivetkit\u002Freact, create hooks with createRivetKit, or manage realtime state with useActor.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6900,6901,6903,6904,6905],{"name":6767,"slug":6768,"type":14},{"name":6168,"slug":6902,"type":14},"react",{"name":9,"slug":8,"type":14},{"name":6891,"slug":6892,"type":14},{"name":6906,"slug":6907,"type":14},"State Management","state-management","2026-07-30T05:31:36.618873",{"slug":6910,"name":6910,"fn":6911,"description":6912,"org":6913,"tags":6914,"stars":27,"repoUrl":28,"updatedAt":6922},"rivetkit-client-rust","build RivetKit Rust clients","RivetKit Rust client guidance. Use for Rust clients and backends that connect to Rivet Actors with rivetkit::client, create typed actor handles, call actions, or manage connections.",{"slug":8,"name":9,"logoUrl":10,"githubOrg":11},[6915,6918,6919],{"name":6916,"slug":6917,"type":14},"API Development","api-development",{"name":6679,"slug":6680,"type":14},{"name":6920,"slug":6921,"type":14},"Rust","rust","2026-07-24T05:39:02.105888"]