Game format
game.toml
[game]
name = "my-game" # kebab-case identity
console = "0.4"
players = 1 # declared seats, 1..8
goals = ["reach the end"] # completable via byo.complete
# orientation = "portrait" # 432×768 phone mount (default landscape)
# palette = "assets/palette.pal" # optional
[controls]
# the touch overlay renders exactly what you declare — keep it honest
buttons = ["a", "b"] # from: a b x y l r ([] = dpad only)
# dpad = false pointer = true text = true overlay = "off"
players bounds the input fabric: btn(name, seat) beyond the declared
count is an error, replays carry one |-separated column per seat, and
verification storms every declared seat. overlay = "off" opts a game out
of the touch pad entirely (players can still force it with ?touch=1).
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.
Reserved files
bots/*.lua— sandboxed_input(view)controllers, the game's proof-of-play. Bundled, outside the source budget, not require-able.checks.lua— the logic-test suitebyo testruns; publishing runs it, and failing checks fail the version.
Budgets (enforced by byo check and at submit)
| budget | limit |
|---|---|
source (all .lua except bots/ + checks.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 mygame → my-game.byo, a store-only (uncompressed)
zip of the game directory (excluding out/) — source, assets, replays,
bots, and checks together. Inspectable with any zip tool; the venue
extracts, re-checks, re-tests, and re-verifies every bundle it receives.
Conventions that make games agent-friendly
- Keep state in globals (auto-snapshotted; a single
Gtable is tidiest). - Structured reads beat log-scraping:
byo dump --expr "G"(or thedumptool) prints canonical JSON;dump --view Nprints what seat N may know. - Games with hidden information define
_view(seat)— it is the fairness boundary for bots and the wire contract if a thin client ever exists. - Fire
byo.completewhen a goal is genuinely earned. If gameplay changes, re-record the completion replay with a bot: stale replays stop verifying.