Skip to content

Latest commit

 

History

539 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Zwick

Play Zwick — a fast-paced, real-time multiplayer card game. Everyone plays at once: clear your Main pile first, call Zwick, and race to 75 points.

Zwick is an open-source Gleam application built on the BEAM. It is deliberately small enough to study, while still using OTP supervision, WebSockets, server-authoritative game state, and graceful recovery.

Play

Open zwick.fly.dev, choose Quick Play or create a private room, and share its link. Games have four seats; after a short wait, bots can fill vacant seats so a game can begin.

Technology

  • Gleam for the application and game rules
  • Erlang/OTP for isolated actors, dynamic workers, and supervision
  • Mist for HTTP and WebSockets
  • Lustre for server-rendered UI
  • Fly.io for the deployed service and persistent game snapshots

Supervision tree

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#dbeafe', 'primaryTextColor': '#1e3a5f', 'primaryBorderColor': '#3b82f6', 'lineColor': '#64748b', 'secondaryColor': '#f1f5f9', 'tertiaryColor': '#e0f2fe', 'background': '#ffffff', 'mainBkg': '#dbeafe', 'nodeBorder': '#2563eb', 'clusterBkg': '#eff6ff', 'clusterBorder': '#bfdbfe', 'titleColor': '#1e3a5f', 'edgeLabelBackground': '#f8fafc'}}}%%
flowchart TD
    Root[Root supervisor] --> Core[Core supervisor]
    Root --> Bots[Bot factory]
    Root --> Metrics[Metrics actor]
    Root --> Sessions[Session registry]
    Root --> Snapshots[Snapshot manager]
    Root --> Server[Mist server]

    subgraph CoreGroup[Rest-for-one core]
        Factory[Game factory] --> Matchmaker[Matchmaker]
    end

    Core --> Factory
    Factory --> Games[Game servers]
    Bots --> BotPlayers[Bot players]
    Matchmaker --> Games
    Matchmaker --> BotPlayers
    Server --> Matchmaker
    Server --> Sessions
    Server --> Metrics
    Snapshots -. save and restore .-> Sessions
Loading

The root supervisor keeps the service available; the core group restarts the matchmaker when its game-factory dependency restarts, while game servers and bot players are created dynamically for each match.

Game request flow

%%{init: {'theme': 'base', 'themeVariables': {'primaryColor': '#dbeafe', 'primaryTextColor': '#1e3a5f', 'primaryBorderColor': '#3b82f6', 'lineColor': '#64748b', 'secondaryColor': '#f1f5f9', 'tertiaryColor': '#e0f2fe', 'background': '#ffffff', 'mainBkg': '#dbeafe', 'nodeBorder': '#2563eb', 'clusterBkg': '#eff6ff', 'clusterBorder': '#bfdbfe', 'titleColor': '#1e3a5f', 'edgeLabelBackground': '#f8fafc'}}}%%
flowchart LR
    Player[/Player browser/] --> Router[HTTP and WebSocket]
    Router --> Matchmaker[Matchmaker]
    Matchmaker --> Factory[Game factory]
    Factory --> Game[Game server]
    Game --> Router
    Router --> Player
    Router --> Registry[Session registry]
    Router --> Metrics[Metrics actor]
Loading

The browser keeps a WebSocket to the Mist server; the matchmaker forms four-player games, and each game server owns and broadcasts its authoritative state.

Reliability and operations

  • Game isolation: each match runs in its own actor, so failures are contained to that match rather than shared game state.
  • Graceful restarts: on SIGTERM, the snapshot manager serializes active games and browser sessions to SNAPSHOT_DIR (the Fly volume mounted at /data), then restores them at startup.
  • Capacity: SERVER_CAP defaults to 200 and counts queued players plus active games. Fly is configured for 200 soft / 250 hard concurrent connections.
  • Metrics: GET /admin/metrics returns JSON with active-game and active-player counts.

Run locally

Install Gleam, then:

gleam deps download
gleam run
gleam test
gleam format --check src test

The server listens on http://localhost:3000 by default. Set PORT to choose another port; SERVER_CAP controls the admission limit; and SNAPSHOT_DIR chooses where graceful-restart snapshots are written.

Project layout

Path Purpose
src/domain/ Pure game rules and card-domain types
src/internal/ OTP actors, matchmaking, bots, snapshots, and metrics
src/web/ HTTP routes, WebSockets, and server-rendered UI
test/ Unit, integration, WebSocket, and snapshot tests
fly.toml Fly.io runtime and volume configuration
deploy/fly-topology.env Versioned Fly Machine regions and desired per-region count
docs/deployment.md Deployment topology, regional data behavior, and drift checks

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages