# Chip8
A component script.
# Nes
A component script.
# RetroConsole
An arcade cabinet on one entity: one screen, one cartridge list spanning every
installed console, at most one machine running. Drop it on a flat panel
carrying `console_screen_mat` and every `emulatorCore` asset in the world
appears in its loader.
- **Pick a cartridge** (or upload / fetch by URL) and it routes to its console
by extension, boots that core, and tears down whatever ran before — ten
installed consoles cost one machine's frame time.
- **Controls engage on pick; Esc releases them.** While released the cabinet
keeps running in attract mode and the keyboard belongs to the player.
- The active core letterboxes into the shared 256×240 screen texture at
integer scale.
- Battery saves and the player's uploaded cartridges persist per console in
runtime data, exactly like the standalone console components.
## Quick start
```lua
local id = tools.use("primitives", "cube", "arcade", 0, 2, 0)
local e = entity.find("arcade")
e.localScale = { 3.2, 3.0, 0.05 }
e.component.get("Model").material = asset.resolve("console_screen_mat", "material")
e.component.add("RetroConsole", {})
```
## Adding a console
Publish a `<name>_core.emulatorCore` asset (in any package) with the spec
contract documented in `emulatorCore.assetType` — the cabinet discovers it
live. Name core assets so their identity does not collide with the machine
module (`nes_core.emulatorCore` beside `nes.module`).
# chip8 (emulatorCore)
CHIP-8 console spec for the RetroConsole cabinet: 128×64 phosphor display,
`.ch8` cartridges, the standard 1234/QWER/ASDF/ZXCV hex pad, and a single
beeper voice. The machine core is `retro.chip8`.
# chip8_screen_mat
Unlit screen surface for the CHIP-8 kiosk panel. Binds the committed
`chip8_screen` texture; the Chip8 component blits the live framebuffer into
that texture's GPU identity every frame.
# console_screen_mat
Unlit screen surface for the RetroConsole arcade cabinet. Binds the committed
`console_screen` texture; the cabinet letterboxes whichever console is active
into that texture's GPU identity every frame.
# emulatorCore (asset type)
A pluggable console emulator: the machine spec the `RetroConsole` cabinet
discovers and boots. Publishing a new `<name>.emulatorCore` asset (in any
package) makes that console appear in every cabinet in the world — the cabinet
enumerates `asset.list("emulatorCore")` live, so cores install like any other
content, with no cabinet changes.
## Instance shape
`<name>.emulatorCore/init.luau` returns the core spec:
```luau
return {
id = "nes", -- stable key: save/store namespaces derive from it
name = "NES", -- select-screen label
cover = "cover_nes", -- optional: texture reference shown on the select screen
extensions = { "nes" }, -- cartridge extensions, lowercase, first = default
width = 256, -- native framebuffer size
height = 240,
fps = 60.0988, -- hardware frame rate
romsDir = "/zero/source/nes_roms",
storePrefix = "nes_roms/", -- runtime-data cartridge library namespace
savesPrefix = "nes_saves/", -- battery-save namespace; omit if the console has none
make = function(bytes) ... end, -- romBytes -> machine; raises on a bad ROM
validate = function(bytes) ... end, -- ok, err — gate for uploads/URL fetches
framebuffer = function(m) ... end, -- machine -> RGBA8 buffer (width*height*4)
applyInput = function(m) ... end, -- read the keyboard, set machine input
neutralInput = function(m) ... end, -- release every button (called on disengage)
voices = function(m) ... end, -- optional: { {active, hz, vol, noise} } for MIDI
statusFor = function(m) ... end,-- optional one-line status; defaults to m.title
ram = { -- optional battery accessors
isDirty = function(m) ... end,
clearDirty = function(m) ... end,
get = function(m) ... end,
set = function(m, bytes) ... end,
},
}
```
The machine contract behind `make` is the `retro.host` one: `m:runFrame()`
advances one video frame; `m.title` keys battery saves and the status line.
## Reading a spec
`asset.resolve("<name>", "emulatorCore"):spec()` loads and caches the spec
(the type's `behavior.luau` provides `:spec()` on every reference).
# nes (emulatorCore)
NES console spec for the RetroConsole cabinet: 256×240 display, `.nes` (iNES)
cartridges, controller 1 on arrows/WASD + Z/X + Enter + RShift, four MIDI
voices from the APU model, and battery PRG-RAM persistence. The machine core
is `retro.nes` (6502 + PPU + APU + mappers NROM/MMC1/UNROM/CNROM).
# nes_screen_mat
Unlit screen surface for the NES kiosk panel. Binds the committed
`nes_screen` texture; the Nes component blits the live 256×240 framebuffer
into that texture's GPU identity every frame.
# pressstart2p
Press Start 2P — the bitmap-arcade display face the cabinet UI uses for
headings and console names (`fontFamily = "pressstart2p"`). SIL Open Font
License; © The Press Start 2P Project Authors.
# vt323
VT323 — the CRT-terminal text face the cabinet UI uses for cartridge lists and
body text (`fontFamily = "vt323"`). SIL Open Font License; © The VT323 Project
Authors.