0.7.0 · RETROPIE · FORGE

Relics

One file. One game. Capability-secured.

Sigil Forge packages ROMs, BIOS, and save states into a single verified container — a Relic. The launcher verifies before play; the emulator core sees only what it's allowed to see. No loose files, no ambient authority, no trust by default.

What is a Relic?

A Relic is a complete, playable game in a single file — ROM + BIOS (if the system needs one) + optional embedded save state + metadata. Forge packs them; the launcher verifies them; the emulator core plays them. Relics are the native game format for sigilOS Forge.

A Relic is self-describing — the file extension encodes the target system, the header encodes section layout, and the CRC32 covers the ROM section for integrity. Move it, copy it, archive it — everything travels with the file.


Why Relics?

Self-contained
No loose BIOS files, no side-car saves, no metadata JSON. One Relic = one game. Everything travels with it.
Verified before play
forgery_verify.sg checks magic, structure, and CRC32 of the ROM section before rp_launch issues any capability. A corrupted or tampered Relic never reaches the emulator.
Capability-minimal
The emulator core holds a read-only sub-range cap to the ROM section only. It cannot read metadata, BIOS directly, or any other file on the system.
Typed per system
.ness, .sfcs, .zips — the extension encodes the target system. The launcher knows which emulator to load from the extension alone.
Embeddable saves
--embed-save snapshots the current savestate into the Relic's SAVE section. Carry your save anywhere the Relic goes.

Creating a Relic

Use forgery_pack.sg to create a Relic from a ROM file:

forgery_pack.sg <rom_path> [options] [key=value ...]

Options:
  --bios <path>          Embed a system BIOS file
  --embed-save <path>    Embed a save state snapshot
  --out <path>           Output path (default: derived from ROM name + system extension)

Examples

# Pack a NES ROM into a Relic
forgery_pack.sg mario.nes title="Super Mario Bros" region="US" year="1985"
# Output: mario.ness

# Pack a SNES ROM with embedded save
forgery_pack.sg zelda.sfc --embed-save zelda.sav title="Zelda: A Link to the Past" region="US"
# Output: zelda.sfcs

# Pack with BIOS (systems that require it)
forgery_pack.sg game.bin --bios bios.bin --out my_game.zips title="My Game" sys="zxspectrum"

Metadata keys

Key Required Description
title Yes Human-readable game title
sys Yes Target system identifier (e.g. nes, snes, zxspectrum)
forge_version Yes Relic format version (auto-filled by forgery_pack.sg)
region No Region code (US, EU, JP)
crc32 Auto CRC32 of ROM section (computed at pack time)
hash_sha256 No SHA-256 of ROM section for additional verification
year No Original release year

File extensions

The file extension is the authoritative system selector — it determines which emulator core launches the game.

Extension System ROM format
.ness NES iNES / NES 2.0
.sfcs SNES SFC (headerless or headered; SMC header stripped at pack time)
.zips ZX Spectrum .z80 / .tap snapshot

Additional extensions for the full 75-system Forge fleet will be added as cores ship.


Lifecycle: Create, Verify, Launch

1. Create
forgery_pack.sg reads the ROM, optional BIOS, optional save state. Computes CRC32 of ROM data. Writes the 16-byte header, section table, and section data into a single Relic file.
2. Verify
Before launch, the launcher calls forgery_verify.sg. It checks the magic bytes (FORG), version, section layout coherence, file size, and recomputes the CRC32 of the ROM section against the stored value. Returns FORG_OK or an error code.
3. Launch
On FORG_OK, forgery_unpack.sg derives a read-only sub-range cap for the ROM section and hands it to the emulator core via rp_launch. The core receives only the byte ranges it needs — nothing else.

Capability model

Every section in a Relic maps to a distinct capability. The emulator core never receives more authority than it needs to run the game.

ROM section cap
Read-only sub-range. Issued to the emulator core. Covers only the ROM section bytes — not the header, not META, not BIOS, not SAVE.
BIOS section cap
Read-only sub-range. Derived separately if a BIOS section exists. Handed to the core's BIOS loader, not to the main ROM execution path.
META section
Launcher only. The emulator core holds no cap to META — it cannot read title, region, or any other metadata.
SAVE section
Savestate ABI only. The emulator core cannot write to the Relic file directly. Saves are committed by the launcher on explicit savestate calls.
Host filesystem
No cap issued. The emulator core has zero visibility of the host FS — it cannot enumerate the ROM library, read other Relics, or access any path outside its granted section ranges.

Binary format

Header (16 bytes)

Offset Size Field Value
0x00 4 B Magic FORG (0x46 0x4F 0x52 0x47)
0x04 1 B Version 0x01
0x05 2 B SYS_ID LE u16 — Forge system catalog ID
0x07 1 B SECTION_COUNT 1–16 sections
0x08 4 B TOTAL_SIZE LE u32 — file size including header
0x0C 4 B Reserved Must be 0x00000000

Section table (starts at 0x10)

Each entry is 12 bytes. Sections are ordered by offset ascending.

Offset Size Field
+0x00 1 B SECT_TYPE
+0x01 3 B Reserved (zero)
+0x04 4 B SECT_OFFSET (LE u32, from file start)
+0x08 4 B SECT_SIZE (LE u32)

Section types

Type ID Required Description
ROM 0x01 Yes Raw ROM image. Sub-range cap issued to emulator core.
BIOS 0x02 No System BIOS data. Separate cap if core requires it.
SAVE 0x03 No Embedded save state. Loaded via core_load_state().
META 0x04 Yes UTF-8 key=value pairs, one per line.

Verification error codes

Code Name Meaning
0 FORG_OK Relic is valid — proceed to launch
-1 FORG_ERR_MAGIC Magic bytes do not equal FORG
-2 FORG_ERR_SIZE TOTAL_SIZE exceeds actual file size (truncated file)
-3 FORG_ERR_CRC CRC32 of ROM section does not match stored value
-4 FORG_ERR_LAYOUT Section overlap or section extends past TOTAL_SIZE
-5 FORG_WARN_UNKNOWN_SECT Unknown section type (warning, not rejection)

Tools

forgery_pack.sg
Pack — create a Relic from a ROM + optional BIOS + optional save + metadata key-value pairs. Computes CRC32, writes header + section table + data. Strips SMC header for SNES ROMs automatically.
forgery_unpack.sg
Unpack — validate and derive capabilities. Returns read-only ROM cap, optional BIOS cap, and META key-value map. Does not extract to disk — caps are derived in-place over the Relic's byte ranges.
forgery_verify.sg
Verify — validate only (no extraction). Checks magic, version, layout, CRC32. Returns FORG_OK or error code. This is the launch gate — if it fails, no capability is issued and the game does not launch.

Supported systems

Relics support the full 75-system sigilOS Forge fleet — every system from Fairchild Channel F (1976) to Nintendo Switch (2017). System-specific extensions are defined per core; the three shipped extensions are:

Additional extensions will be added as cores ship. The SYS_ID field in the header maps to the full 73-system catalog regardless of extension availability.