webstation-broker
DeveloperPython referenceemulators

emulators.retroarch_cores

The libretro core catalog, core tiers and per-platform core profiles.

The libretro core catalog, core tiers and per-platform core profiles.

RetroArch boots one core per platform, and the platform table in retroarch_platforms.json names the best-tested one. This module answers the question an operator's core: override raises: is that core known, is it built for this machine, how well tested is it, and what profile (library name, save handling, extensions) should the launch use.

It never imports retroarch.py; the platform table is passed in, so the launcher can import this module without a cycle.

attributelog
= logging.getLogger(__name__)
attributeCORE_NAME_RE
= re.compile('^[a-z0-9_]+$')

A libretro core name as the buildbot spells it, which is also what core: accepts.

attributeBUNDLED_ZIP
= _HERE / 'retroarch_core_info.zip'

libretro's info.zip, byte for byte, bundled so the catalog works offline.

attributeBUNDLED_SOURCE
= _HERE / 'retroarch_core_info.source.json'

Where BUNDLED_ZIP came from, its sha256 and the x86_64 build list at that time.

attributeINFO_MEMBER_CAP
= 64 * 1024

Largest decompressed .info member read from a core-info zip, 64 KiB.

The zip cap (ZIP_CAP) bounds the compressed download only; a hostile member can inflate far past it. The largest bundled .info is under 14 KiB, so a member over this cap is not a real core-info file and is skipped.

attributeLIBRARY_NAME_FIXESMapping[str, str]
= MappingProxyType({'dolphin': 'dolphin-emu', 'vecx': 'VecX', 'freeintv': 'freeintv', 'same_cdi': 'SAME_CDI'})

Cores whose real library_name (from their own source) differs from core-info's corename.

attributeCORE_OWNED_FIELDS
= frozenset({'save_subtrees', 'core_options', 'core_option_seeds', 'core_source', 'assets', 'save_links', 'resume_settle', 'state_confirm_wait', 'savestate', 'extra_extensions'})

Profile fields that belong to a core, so an alternate never inherits them from the default.

attributeTIERS_FILE
= _HERE / 'retroarch_core_tiers.json'

Tier of every non-default core that is not untested.

attributeTIERSMapping[str, TierEntry]
= MappingProxyType(load_tiers(json.loads(TIERS_FILE.read_text())))

The loaded tiers file.

attributeProfile
= Mapping[str, Any]

A resolved, read-only platform profile: the platform entry's keys plus tier and display_name.

attributeREPORT_URL
= 'https://github.com/romm-streaming/romm-broker/issues/new?template=core-report.yml'

Where players report how a core works.

attributeZIP_CAP
= 5 * 1024 * 1024

Largest core-info zip a refresh accepts, 5 MiB.

attributeINDEX_CAP
= 256 * 1024

Largest buildbot index a refresh accepts, 256 KiB.

attributeREFRESH_EVERY
= 7 * 24 * 3600

Seconds between background refreshes, 7 days.

attributeREFRESH_RETRY
= 3600

Seconds before a failed background refresh is tried again, 1 hour.

attributeCACHE_ZIP
= 'core_info_cache.zip'

File name the refreshed core-info zip is cached under, in RA_DATA_DIR.

attributeCACHE_INDEX
= 'core_info_cache.index'

File name the refreshed buildbot index is cached under, in RA_DATA_DIR.

attributeFETCH_DEADLINE
= 120

Total seconds a single fetch may take. timeout=60 below is a per-read timeout, so without this a server that trickles a byte every 59 seconds would otherwise never finish.