Game Patterns
Watchtower gives you primitives. Here's how to build common game types.
Every multiplayer game follows a pattern for syncing state. Pick the one that fits your game:
Patterns
Cursor Party
Everyone broadcasts their position. Simple, real-time, no authority needed. Great for: collaborative tools, .io games, social experiences.
Turn-Based
Host controls game state, validates moves. Players send requests. Great for: chess, card games, board games, strategy.
Action Game
Frequent position updates with client-side smoothing. Great for: shooters, platformers, racing, fighting games.
Chat Room
Simple message passing with presence. Great for: social apps, lobbies, party games.
Choosing a Pattern
| Pattern | Authority | Update Rate | Complexity |
|---|---|---|---|
| Cursor Party | None (peer-to-peer) | High (20-60Hz) | ⭐ |
| Turn-Based | Host | Low (on action) | ⭐⭐ |
| Action Game | None or Host | High (20Hz) | ⭐⭐⭐ |
| Chat Room | None | Low (on message) | ⭐ |
Common Concepts
Host Authority
In turn-based and some action games, the host (first player to join) controls the "true" game state. Other players send requests, and the host validates and broadcasts the result.
if (room.isHost) {
// I control the game state
room.broadcast({ type: 'state', ...gameState })
}Client-Side Smoothing
For action games, you'll want to smooth movement between network updates. The simplest approach is lerping:
const LERP = 0.15
function update() {
for (const p of Object.values(players)) {
p.x += (p.targetX - p.x) * LERP
p.y += (p.targetY - p.y) * LERP
}
}Message Timestamps
Every message includes meta.serverTime and meta.tick. Use these for ordering messages or building more sophisticated interpolation.