byo.games

Replays

A replay is a text file: a seed plus an input timeline. Because the console is deterministic, replaying it reproduces the exact game — which makes a replay simultaneously a regression test, a proof of completion, and a watchable recording.

Format

game: my-game
seed: 0
goal: reach the end
-- timeline: "<frame> <buttons…>", held until the next line
0 right
40 right a
120 -
  • Frames are absolute and ascending. Buttons: up down left right a b x y l r start select. - = nothing held.
  • The listed state is held until the next line changes it.
  • N players: | separates seat columns — column i is seat i (12 right a | left | - | a). A line updates only the columns it lists; omitted trailing columns keep their held state, and - explicitly clears one.
  • Pointer: a p:x,y,buttons token (held until the next p: token): 30 a p:384,216,1. Text typed on exactly that frame: t:<hex utf-8>. Device tokens live in column 1.
  • goal: names the game.toml goal this replay claims to complete.

Verification

byo verify replays/win.rpl --game mygame

re-simulates the replay; the declared goal must fire (byo.complete) before the timeline ends (+60 frames of grace), and the game must pass the snapshot test (save, simulate garbage, restore — the future must be bit-identical). A game is publishable only while at least one bundled replay verifies. The site re-runs this on its own servers for every published version.

Recording

  • The right way is a bot (below): the sim records what it presses.
  • The browser watch pages replay any bundled .rpl — the replay drives every seat, keyboard and touch off.

Bots — authoring replays closed-loop

Hand-computing frame timings is the hard way. Write a controller instead — sandboxed, one per seat, reading a view, never the globals:

-- bots/seek.lua: _input(view) returns the buttons to hold next frame.
-- view = what this seat may know: the game's _view(seat) if defined,
-- else the game's save (its state as one data table).
function _input(view)
  if view.G.player.x < view.G.sword.x then return "right" end
  return ""
end

Bots live in the reserved bots/ directory (bundled with the game, outside the source budget). Run one per seat inside the real sim:

byo sim --bot bots/seek.lua --record replays/win.rpl
byo sim --bot 1:bots/hero.lua --bot 2:bots/rival.lua --record replays/vs.rpl

(or the bot tool over the API, with bots: [{seat, path | source}]). The sim records every seat's presses as a normal N-column replay; if a goal completes, the header is written and the replay verifies as-is. Replays authored by sandboxed bots against a game-defined _view carry a fair: seat N stamp — provenance that the run played by the same information rules a person would. --god (debug only) loads a bot inside the game env; god recordings never earn the stamp.

Bots run only during authoring — verification re-runs the recorded inputs without the bots, so a bot that mutates game state produces a replay that fails. Read the view, return buttons, nothing else.

The verify horizon

Verification simulates to the last input frame + 60. A two-line replay ends after ~60 frames even if the game needed thousands — pad the end (2400 -) to extend the run.