MAME: The Complete Arcade Cabinet Build Guide

An arcade cabinet is a dedicated cyber-physical system designed to provide a stable, deterministic environment for retro game reproduction. The Multiple Arcade Machine Emulator (MAME) is the foundational software for these builds, but its extensive feature set and complex file structure can lead to configuration conflicts, fragile input mappings, and silent failures. To prevent these issues, the Sentinel AI governance system operates as a protective layer alongside MAME.

Beginning: Stable Infrastructure

Core Directory Architecture

MAME must be installed to a clean directory with simple paths — C:mame on Windows. Never install inside Program Files. MAME's command-line parser is highly sensitive to whitespace, and folder paths with spaces cause launch failures, broken asset paths, and configuration errors. Run mame -cc from the terminal to create a default mame.ini in the root directory — your baseline configuration.

ROM Set Architecture: Split, Merged, and Non-Merged

There are three distinct ROM set types. Split sets (~76 GB) store only files that differ from the parent, requiring parent ZIPs alongside clones — avoid for cabinets. Merged sets (~73 GB) combine parent and clone into one archive — complex to manage. Non-Merged sets (~137 GB) are fully self-contained per ZIP — every game includes its own parent and BIOS files internally. Non-Merged is the only recommended format for cabinet builds: if one game breaks, you replace one file.

The Parent, Clone, and BIOS Dependency System

Arcade games were built on physical PCBs containing multiple chips. MAME uses a Parent/Clone relationship to save storage: the Parent Set is the primary fully-dumped version (e.g., sf2.zip), Clone Sets contain only files that differ from the parent (e.g., sf2ce.zip), and BIOS ROMs are hardware system software required by multi-game systems (e.g., neogeo.zip for Neo Geo, cps3.zip for CPS3). With Non-Merged sets, all dependencies are embedded — no separate parent or BIOS ZIPs needed.

Sentinel Pre-Flight Validation

Sentinel Law 7 (No Silent Failure) prevents MAME from launching and crashing silently. Before each launch: identify game ID and parent/clone relationship, scan roms for the primary ROM archive, verify parent ROM if a clone is selected, check for required hardware BIOS, verify CHD folder if the game requires disc data. If any check fails, Sentinel blocks launch and identifies the missing files by name.

Intermediate: Configuration Precision

The 9-Layer Configuration Precedence System

MAME loads configuration files in strict sequential order, with each file overriding all previous values. From lowest to highest priority: (1) mame.ini global baseline, (2) debug.ini, (3) vertical.ini or horizont.ini for screen orientation, (4) arcade.ini or console.ini for machine type, (5) monitor chassis ini, (6) source file ini for hardware platform (e.g., cps1.ini), (7) BIOS name ini, (8) parent name ini, (9) game name ini — highest priority. Sentinel Law 2: always edit at the narrowest scope.

Input Safety and Keyboard Encoder Mappings

Physical arcade controls are routed through a keyboard encoder such as the Ultimarc I-PAC series. Default I-PAC mappings: Player 1 Start = key 1, Player 2 Start = key 2, Coin gates = keys 5 and 6, joystick directions = arrow keys, buttons = Left Ctrl, Left Alt, Space, Left Shift. When controls are changed in the MAME UI, settings are saved to cfg/default.cfg. If a USB controller disconnects at launch, MAME may overwrite this file with null values. Fix: use a ctrlr/ profile (read-only template) or set cfg/default.cfg to Read-Only in OS file properties. Sentinel Law 3: a reliable exit command must always be mapped.

Eight Cabinet Killer Traps

  1. Installing MAME in Program Files — UAC silently blocks config writes. Fix: install to C:mame.
  2. Editing mame.ini while a game is running — edits are silently discarded. Fix: always close MAME first.
  3. Using Split or Merged ROM sets on a cabinet — clones silently break when parents move. Fix: use Non-Merged sets exclusively.
  4. No input exit path mapped — you get trapped inside a game with no escape. Fix: map P1 Start + Button 1 = Escape on the I-PAC first.
  5. Sending 31.5 kHz signal to a 15 kHz CRT — physically damages the monitor flyback transformer. Fix: install CRT Emudriver before connecting any CRT.
  6. Overwriting cfg/default.cfg on USB disconnect — entire input mapping is lost. Fix: use ctrlr/ profile or set default.cfg to Read-Only.
  7. Applying global settings instead of scoped overrides — fixing one game breaks all others. Fix: create ini/vertical.ini or game-specific ini files.
  8. Ignoring the GUI Retention Bug — settings from the first game bleed into subsequent launches. Fix: use a frontend that launches MAME as a fresh process per game.

Advanced: Hardware Integration and Cabinet Orchestration

High-Definition Graphics via BGFX Shaders

MAME includes the BGFX rendering framework to simulate CRT visual characteristics on flat-panel displays. Key mame.ini settings: video = bgfx, bgfx_backend = d3d11, bgfx_screen_chains = crt-geom-deluxe. Direct3D 11 significantly outperforms Vulkan under Windows: D3D11 averages 2264% emulation speed vs Vulkan's 1458%. Save custom shader configurations as unique files (e.g., bgfx/chains/crt-cabinet-custom.json) to prevent MAME updates from overwriting them.

Native 15 kHz CRT Output

Standard PC graphics cards output a minimum 31.5 kHz horizontal sync. Sending this to a legacy 15 kHz CRT physically damages the monitor's analog chassis and flyback transformer. To output native 15 kHz: install CRT Emudriver on a compatible AMD Radeon GPU, then use GroovyMAME with the SwitchRes engine. SwitchRes reads the exact video specifications of the emulated game and outputs those native timings directly — no scaling artifacts.

SwitchRes and CRT Range Configuration

GroovyMAME uses Super Resolutions to prevent horizontal scaling issues — padding the horizontal axis to a standard width like 2560 (e.g., 2560x240@60Hz). Define the physical CRT limits in mame.ini using a crt_range line: monitor = custom, crt_range0 = 15625-16200, 49.50-65.00, 2.000, 4.700, 8.000, 0.064, 0.192, 1.024, 0, 0, 192, 288, 448, 576. Parameters define horizontal sync range, vertical sync range, horizontal timing, vertical timing, sync polarities, and progressive/interlaced line limits.

LEDBlinky and ServoStik Hardware Orchestration

LEDBlinky reads MAME's active outputs to illuminate only the controls used for the active game. For motorized joystick gates, the Ultimarc ServoStik uses a physical restrictor gate driven by a servo motor. LEDBlinky identifies whether a game is 4-way (e.g., Pac-Man) or 8-way and commands the servo to rotate the gate accordingly — automatically switching between modes per game launch.

Sentinel AI Governance Standard Operating Flow

Every automated cabinet modification follows Sentinel's execution sequence: (1) Identify scope and narrowest config file to edit. (2) Validate all ROMs, BIOS files, CHDs, and input exit path. (3) Classify the change category. (4) Propose minimal single-parameter change. (5) Establish verification criteria. (6) Specify rollback files. Failure taxonomy: Classification 1 = Normal Exit; Classification 2 = Soft-Lock (force-terminate, revert input config); Classification 3 = Config-Induced Failure (delete game config, revert to baseline); Classification 4 = Asset Failure (block launch, notify with filenames); Classification 5 = Hard Crash (log, restore baseline, attempt one relaunch).

Quick Reference: 5 Rules to Remember

  1. Install MAME to C:mame — never inside Program Files or paths with spaces.
  2. Use Non-Merged ROM sets exclusively on cabinets — every ZIP is self-contained.
  3. Edit at the narrowest INI scope — game-specific ini before vertical.ini before mame.ini.
  4. Map your exit combo before anything else — P1 Start + Button 1 = Escape.
  5. Never connect a CRT monitor without CRT Emudriver installed first.