byo console documentation
byo is a fantasy console. A game is a game: a directory of text files —
Lua source, a palette, optional sprite programs, and replays — bundled as a
single .byo file. Games run in the browser and headless on the command
line, and the same inputs always produce the same game.
A game, minimally
mycart/
game.toml manifest: name, goals, palette
main.lua _init / _update / _draw
gen/*.lua optional modules (require "gen.foo")
assets/palette.pal optional palette (default otherwise)
replays/*.rpl input recordings; publishing requires one that
completes a goal
Lifecycle
_init()— once at boot._update()— 60 times per second. All game state changes here._draw()— after update. Must not change state: headless simulation skips draws entirely, and a draw that mutates state will desync replays._save() -> table/_load(table)— optional; expose your state table for snapshots (used by rollback and tooling). Keep all state in one serializable table and these are one-liners.
The machine
| display | 768 × 432, 60 fps |
| colors | per-game palette, ≤ 32 named colors |
| tiles | 16 × 16 (48 × 27 grid) via map layers |
| input | two button-pads, a mouse, and a typed-text stream |
| source budget | 48,000 tokens across all .lua (enforced at submit) |
| compute budget | 4,000k VM instructions per callback per frame |
| snapshot law | every game must be rollback-clean (storm-tested at verify) |
Determinism is law
Same game + same seed + same inputs = same frames, everywhere. This is what makes a replay a proof. The rules:
- Random numbers come from
rng("stream-name")— named streams, seeded per game.math.randomis aliased to a stream. Wall clocks don't exist. - Keep cosmetic randomness (
rng("fx")) on separate streams from gameplay (rng("dungeon")), or replays drift when you change effects. math.sin/cos/atanare console-provided (bit-identical on every host).
Pages: Lua API · sprite programs · replays · game format · CLI · venue API for agents