Files
AnyPS5/docs/dev/debt/libScePlayGo.md
T
JJenkxandClaude Opus 5.5 0bf6a77e8f fix(libScePlayGo): answer ids past the listed scenario chunks as unlisted
A dump with sce_sys/playgo-scenario.json and no chunk table lists chunks 0
to 999 through scePlayGoGetChunkId, but every other id was still reported as
installed. Destruction AllStars (PPSA02630) asks for chunk ids from 0 up until
one is rejected; because no id ever was, the walk wrapped the 16-bit id and
grew an array of 16-byte entries until a 5.18 GiB allocation failed about one
second into startup ("Ran out of memory allocating 5565054976 bytes").

An id outside the listed 0 to 999 is now answered like an unlisted id of a
dump without any playgo file: APS5_PLAYGO_UNLISTED_CHUNKS=installed or
=absent answers it, and without an answer the call throws naming the missing
chunk table.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-10-21 18:26:40 -04:00

3.9 KiB

libScePlayGo technical debt

Unknown function info

  • scePlayGoRequestNextChunk, scePlayGoSnapshot (libScePlayGo) - their names and NIDs are in the PS5 3.20 export inventory, but no credible prototypes were found. They are declared without parameters solely to resolve known imports; this is not an ABI claim
  • scePlayGoSetLanguageMask (libScePlayGo) - stores the mask that scePlayGoGetLanguageMask then reports, and returns SCE_PLAYGO_ERROR_BAD_HANDLE for another handle, as shadPS4 does on the PS4. shadPS4 also returns SCE_PLAYGO_ERROR_NOT_INITIALIZED before scePlayGoInitialize and starts from the system language's mask; here the mask starts with every language and initialization is not tracked. Not measured on a PS5
  • libScePlayGo - the chunk set comes from playgo-chunkdefs.xml (every listed chunk plus chunks 0 through the default chunk), otherwise from sce_sys/playgo-chunk.dat, whose plgx header is read as holding the chunk count as a 16-bit value at offset 0x0A and ids 0 to count - 1 are taken as valid. The field was identified on four dumps, where exactly that many 0x20-byte entries follow from offset 0x100 (RIDE 4 PPSA01599: 35, Persona 5 Royal PPSA05110: 25, LEGO Horizon Adventures PPSA14632 and Kena PPSA01802: 1); the rest of the format is not decoded and ids are assumed to be contiguous. Every listed chunk is reported as installed (LOCAL_FAST). Without either file, a package with sce_sys/playgo-scenario.json (PPSA01748, whose dump lists no chunks) accepts ids 0 to 999 as installed, and scePlayGoGetChunkId lists the same ids. A title that builds its set of installed chunks from that list skips any chunk it does not see. The console's chunk limit is not known here, so an id from 1000 up is answered like an unlisted id of a package with no playgo-* file: it throws unless APS5_PLAYGO_UNLISTED_CHUNKS answers it (=absent ends PPSA02630's id walk, which otherwise asks for every id until one is rejected and wraps the 16-bit id). A package with no playgo-* file in sce_sys (PPSA03001, PPSA03490 and PPSA01285 here) accepts chunk 0; querying any other id throws with a message naming the missing playgo-chunk.dat and playgo-scenario.json, since the incomplete dump cannot establish whether that id exists; APS5_PLAYGO_UNLISTED_CHUNKS=installed answers every such id as installed (LOCAL_FAST, which PPSA15388 needs to load its saves) and =absent answers SCE_PLAYGO_ERROR_BAD_CHUNK_ID (which ends PPSA03001's id walk), as the user's choice for that dump. A sce_sys that holds other playgo-* files (playgo-ficm.dat, playgo-hash-table.dat) without playgo-chunk.dat or playgo-scenario.json, or a playgo-chunk.dat without a plgx header and a nonzero count, throws naming the file, because no such dump is known. These answers are unverified on a console, as is the console's answer for an id outside a package's chunk table.
  • libScePlayGo - scePlayGoGetSupportedOptionalChunk and scePlayGoGetOptionalChunk report every bit set for type 0, 1 or 2, i.e. every optional chunk (language pack) supported and installed, like scePlayGoGetLanguageMask. Native requests confirm types 0 through 2 and an eight-byte result; their meanings and bit layout are still determined by the external service, not this module; PPSA01748 calls both with type 0 and hides every text language listed in playgo-scenario.json chunkSupportedLanguages when the bitmask is 0. The console's answer for a package that ships no optional chunks is unverified.