Add an Emulator Platform
Use this workflow for a new emulated system or libretro core. A game integration only adds data under stable_retro/data/ and should follow docs/integration.md instead.
Gather requirements
Before editing, establish:
- Stable Retro platform identifier and game-directory suffix.
- Core directory slug and expected libretro library basename.
- Upstream repository, pinned revision, license, and redistribution terms.
- ROM extensions, libretro joypad layout, RAM regions, serialization behavior, and BIOS needs.
- Supported host matrix: Linux, Windows, macOS x86_64, and macOS arm64.
- A legally redistributable smoke-test ROM, or a documented manual-test substitute.
Compare one nearby simple platform manifest and one platform with similar rendering, BIOS, or architecture constraints. Do not assume a core's standalone defaults are suitable for deterministic, headless reinforcement learning.
Implement the platform
Vendor the pinned core under
cores/<platform>/. Preserve upstream licensing and avoid unrelated source edits.Ensure the core's Makefile produces
<core_name>_libretrowith the host shared-library suffix. The top-leveladd_corefunction expects this exact name.Copy the manifest template to
cores/<platform>.jsonand adapt it. The top-level key is the public platform identifier;libis<core_name>from CMake.Keep
buttonsandkeybindsaligned to libretro joypad IDs. Usenullfor unsupported positions and list only valid button names inactions.Validate the manifest before compiling:
python .github/skills/add-emulator-platform/scripts/validate_manifest.py cores/<platform>.jsonAdd
add_core(<platform> <core_name>)inCMakeLists.txt. Guard it when host support or system libraries are conditional.Add only required deterministic core options to
s_envVariablesinsrc/emulator.cpp. Prefer software rendering unless the core truly requiresENABLE_HW_RENDER.Add the platform suffix to
setup.pyonly when packaged game integrations use that suffix. Core JSON and shared-library packaging is already generic.Update
tests/emulator.cppwith manifest loading and an emulator smoke parameter when a redistributable fixture exists. Otherwise add lower-level mapping coverage and record manual load, frame, audio, reset, and serialization evidence.Update
docs/supported_emulators.mdand, when users can import games for the system, the supported ROM types indocs/integration.md.
Validate incrementally
Build the new core first:
cmake -DCMAKE_DISABLE_FIND_PACKAGE_CapnProto=TRUE .
cmake --build . --target <platform> -- -j2
Then run the native suite:
CMAKE_BUILD_PARALLEL_LEVEL=2 scripts/test-cpp.sh
Run relevant Python tests and repository checks:
scripts/test-python.sh
python -m pre_commit run --files <changed-files>
Use the completion checklist before finishing. Clearly report any host platform or hardware path that was not tested.