Why Cosmictron for Games?

⚡ Sub-millisecond Latency

0.8ms average response time. Game logic runs inside the database—no network hops.

🎯 Deterministic Reducers

ACID transactions ensure game state consistency. No race conditions or desync.

👥 10K+ Concurrent Players

Scale to thousands of players on a single $20 server. Horizontal scaling ready.

🔄 Real-time Sync

Player positions, scores, and game state sync instantly to all clients.

Example: Simple Arena Game

Schema

Rust
#[table(name = "players")]
pub struct Player {
  #[primary_key] pub id: u64,
  #[index] pub session_id: String,
  pub x: f32,
  pub y: f32,
  pub health: i32,
  pub score: u32,
  #[index] pub last_update: u64,
}

#[table(name = "game_state")]
pub struct GameState {
  #[primary_key] pub id: u32, // always 0 for singleton
  pub status: String, // "waiting" | "playing" | "ended"
  pub started_at: Option,
}

Game Logic

Rust
// Player joins the game
#[reducer]
pub fn join_game(session_id: String) -> Player {
  let player = Player {
    id: 0,
    session_id,
    x: rand::random::() * 100.0,
    y: rand::random::() * 100.0,
    health: 100,
    score: 0,
    last_update: ctx.timestamp(),
  };
  ctx.db.players().insert(&player);
  player
}

// Update player position
#[reducer]
pub fn move_player(player_id: u64, x: f32, y: f32) {
  // Verify ownership
  let player = ctx.db.players().id().find(player_id)
    .expect("Player not found");
  
  assert_eq!(player.session_id, ctx.sender().to_string());
  
  // Update position
  ctx.db.players().id().update(player_id, Player {
    x, y,
    last_update: ctx.timestamp(),
    ..player
  });
}

// Handle player hit
#[reducer]
pub fn player_hit(target_id: u64, damage: i32) {
  let target = ctx.db.players().id().find(target_id)
    .expect("Target not found");
  
  let new_health = (target.health - damage).max(0);
  
  if new_health == 0 {
    // Player died - update scores
    ctx.db.players().id().delete(target_id);
    
    // Award kill to attacker
    let attacker = ctx.db.players()
      .session_id().find(ctx.sender().to_string())
      .expect("Attacker not found");
    ctx.db.players().session_id().update(
      ctx.sender().to_string(),
      Player { score: attacker.score + 1, ..attacker }
    );
  } else {
    ctx.db.players().id().update(target_id, Player {
      health: new_health,
      ..target
    });
  }
}

Client Subscription

Clients subscribe to game state and receive real-time updates:

TypeScript
// Subscribe to all player positions
const playersSub = await client.subscribe(
  'SELECT id, x, y, health, score FROM players',
  (delta) => {
    delta.inserts.forEach(player => game.addPlayer(player));
    delta.updates.forEach(player => game.updatePlayer(player));
    delta.deletes.forEach(player => game.removePlayer(player.id));
  }
);

// Send player movement
function onPlayerMove(x: number, y: number) {
  client.callReducer('game', 'move_player', {
    player_id: myPlayerId,
    x, y
  });
}

Performance at Scale

BitCraft, an MMORPG built on similar technology, handles:

Cosmictron's DBSP engine and zero-latency architecture make similar scale achievable for small teams.

Get the Code

Check out the complete example in our repository:

Bash
git clone https://github.com/cosmictron/cosmictron.git
cd cosmictron/examples/gameserver

The example includes:

Build Your Game

Start building multiplayer games with sub-millisecond latency.

Read the Docs → View on GitHub