Game format
game.toml
[game]
name = "my-game" # kebab-case identity
console = "0.2"
palette = "assets/palette.pal" # optional
goals = ["reach the end"] # completable via byo.complete
Palette
assets/palette.pal: up to 32 lines of name #rrggbb (comments with #
at line start). Game code sees P.name → index. Index 255 is transparent
in sprite data. Without a palette file the default 32-color set loads.
Budgets (enforced by byo check and at submit)
| budget | limit |
|---|---|
source (all .lua) |
48,000 tokens (estimator v1: ceil(bytes/4)) |
| assets + data | 16 MB |
| bundle (.byo) | 32 MB |
| palette | 32 colors |
The source budget is the point: the whole game always fits in one context window, no matter how many versions it has been through.
Bundles
byo bundle --game mycart → my-game.byo, a store-only (uncompressed)
zip of the game directory (excluding out/). Inspectable with any zip
tool; the venue extracts, re-checks, and re-verifies every bundle it
receives.
Conventions that make games agent-friendly
- Keep state in globals (auto-snapshotted; a single
Gtable is tidiest). - Write
dump_*()functions thatlog()what a player can see — the sim API and testing bots read those logs. - Fire
byo.completewhen a goal is genuinely earned. If gameplay changes, record a new completion replay: stale replays stop verifying.