# 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).
# retro
A pluggable multi-console emulation system: the `RetroConsole` arcade cabinet,
the `emulatorCore` asset type consoles plug into, the shared host machinery,
and two machine cores (CHIP-8, NES). Install this package, drop the cabinet on
a panel, and every emulator core installed in the world shows up in one
cartridge loader — one screen, one machine running at a time.
## What installs
- **`RetroConsole.component`** — the cabinet. One screen, one loader spanning
every installed console, engage/release controls (Esc), letterboxed display,
per-console battery saves and cartridge libraries. See its README for the
drop-on-a-panel quick start.
- **`emulatorCore.assetType`** — the console plug. A core is an asset carrying
its spec (extensions, resolution, fps, `make`, input map, battery
accessors); publishing one in any package adds that console to every cabinet
in the world. The contract is documented in the type's README.
- **`chip8_core.emulatorCore` / `nes_core.emulatorCore`** — the shipped
consoles (the Game Boy core registers from `gameboy.package` as
`gameboy_core.emulatorCore`).
- **`chip8.module`** — CHIP-8 machine: 35 opcodes, configurable quirks,
128×64 phosphor framebuffer, beeper voice.
- **`nes.module`** — NES machine: cycle-exact 6502 (nestest golden log),
scanline PPU with loopy scroll + sprite-0 hit, APU voice model, controllers,
mappers NROM/MMC1/UNROM/CNROM, battery PRG-RAM.
- **`host.module`** — the shared machinery (`require("retro.host")`): the
cabinet engine (`Console`), the core registry, and the units both the
cabinet and standalone console components compose — `Display`,
`RomLibrary`, `Pacer`, `Saves`, `MidiVoices`, `LoaderUi`, `Host`.
- **`console_screen.texture` / `console_screen_mat.material`** — the cabinet's
screen surface.
## Machine contract
A core's `make(romBytes)` returns a machine with `m:runFrame()` advancing one
video frame and `m.title` naming it for saves/status; the spec's
`framebuffer(m)` exposes the RGBA8 buffer the cabinet blits. The
`emulatorCore.assetType` README documents the full spec table.