Integrate in under an hour.

The whole mandatory contract is two messages you send and five you react to. Playlists, voting, controllers, transitions β€” that's the daemon's problem, not yours.

The entire integration β€” Godot 4
func _ready() -> void:
    GameNight.prepared.connect(_on_prepared)
    GameNight.started.connect(_on_started)
    GameNight.disposed.connect(_on_disposed)

func _on_prepared(session, seats, players) -> void:
    load_arena(seats)          # one pawn per occupied seat
    GameNight.notify_ready(session)   # show nothing yet!

func _on_started(_session) -> void:
    start_match()              # gameplay within a second

func _match_over() -> void:
    GameNight.notify_finished(session)
    # keep rendering the scoreboard until `disposed`

Same shape in Rust, or in 60 lines of dependency-free JavaScript β€” it's a WebSocket and seven JSON messages. The protocol is the product; SDKs are convenience.

Prove it β€” one command
$ gamenight-certify my-game -- ./my-game
─────────────────────────────────────
 GameNight conformance Β· my-game
─────────────────────────────────────
 βœ” process connects and says hello  (487 ms)
 βœ” prepare β†’ ready β†’ instant start  (warm in 42 ms)
 βœ” match ends with a single `finished`
 βœ” replay vote β†’ fresh session, same process
 βœ” pause and resume tolerated mid-match
 βœ” mid-match skips: dispose, re-prepare, stay resident
 βœ” process resident for the whole night
─────────────────────────────────────
 7/7 passed β€” my-game is party-ready πŸŽ‰

A scripted night runs against your real build β€” launch handshake, warm-up, replay, five mid-match skips. Exit 0 = party-ready, so it drops straight into your CI.

The full guide

Everything below is rendered live from docs/integrating-your-game.md β€” the same file that ships in the repo. One source of truth.

Loading the guide…