PlayGo Scenarios Supported by SharpEmu: Complete PS4/5 Content Download Emulation

SharpEmu implements 14 PlayGo scenarios through the libScePlayGo system library, exposing Sony PlayStation 4/5 content-download functions via the static PlayGoExports class to emulate chunk-based game installation without requiring actual PlayStation Network infrastructure.

SharpEmu is an open-source emulator for PlayStation 4 and 5 software that replicates the libScePlayGo system library to support games utilizing PlayGo content delivery. The PlayGo scenarios supported by SharpEmu cover the full lifecycle of chunk-based downloads, from initialization and handle management to progress queries and language masking. These scenarios are implemented as a stub backend in SharpEmu.Libs.PlayGo.PlayGoExports, allowing games to execute their download logic while the emulator provides synthetic metadata and state responses.

Complete List of PlayGo Scenarios in SharpEmu

The emulator exposes all core PlayGo functionality through the PlayGoExports static class in src/SharpEmu.Libs/PlayGo/PlayGoExports.cs. Each scenario maps directly to a Sony system call that games invoke to manage on-demand content installation.

Session Lifecycle Management

  • scePlayGoInitialize: Initializes the PlayGo subsystem and parses the game's play-go.xml metadata via LoadPlayGoMetadata. This validates the chunk configuration and prepares the internal _metadata structure.
  • scePlayGoOpen: Opens a PlayGo handle, returning 1 as the valid handle value to the caller. The emulator tracks a single global handle.
  • scePlayGoClose: Closes the active PlayGo handle and resets session-specific state.
  • scePlayGoTerminate: Shuts down the PlayGo subsystem entirely, clearing all internal metadata and configuration.

Content Chunk Queries

  • scePlayGoGetChunkId: Retrieves available chunk IDs from the parsed metadata stored in _metadata.ChunkIds.
  • scePlayGoGetLocus: Reports the download status (locus) of each chunk, indicating whether content is local, on disc, or needs downloading.
  • scePlayGoGetToDoList: Returns the list of chunks awaiting download.
  • scePlayGoPrefetch: Ensures specified chunks are at a specific locus, simulating the prefetching behavior.

Download Progress and Speed Control

  • scePlayGoGetEta: Returns the estimated time of arrival for downloads (currently stubbed to return 0).
  • scePlayGoGetProgress: Queries the current download progress percentage.
  • scePlayGoGetInstallSpeed: Retrieves the current installation speed setting.
  • scePlayGoSetInstallSpeed: Modifies the installation speed (e.g., setting to full speed).

Language and Localization

  • scePlayGoGetLanguageMask: Retrieves the current language mask for content filtering.
  • scePlayGoSetLanguageMask: Sets the language mask to filter which language-specific chunks should be prioritized.

Architecture and Implementation Details

All PlayGo scenarios share a common implementation pattern in PlayGoExports.cs designed to ensure thread safety and state consistency.

Handle Validation: Every function first invokes ValidateHandle to verify the caller is using the single valid handle (PlayGoHandle == 1). This mimics the real PlayGo API's handle-based access control.

Thread-Safe State Management: Static fields including _metadata, _installSpeed, and _languageMask are guarded by the _stateGate lock object. This ensures concurrent emulated threads accessing PlayGo functions receive consistent state without race conditions.

Metadata Parsing: During initialization, the emulator parses the game's play-go.xml file to populate _metadata.ChunkIds and determine the Available flag. This metadata drives the responses to chunk query functions, determining which IDs the game can legitimately request.

Stub Implementation: Because SharpEmu provides a stub PlayGo backend, many functions return success codes while performing minimal work. For example, scePlayGoGetEta always returns 0 and scePlayGoPrefetch returns immediately without actual network operations. This design allows games to progress through their download logic without requiring a real PlayStation Network connection.

Practical Example: Calling PlayGo Functions

When emulating a game, the runtime invokes these exports through the system ABI. Below is a C# example demonstrating a typical PlayGo workflow using SharpEmuRuntime:

// Initialize PlayGo - parses play-go.xml and prepares the subsystem
int initResult = runtime.InvokeExport("scePlayGoInitialize", cpuContext);
Console.WriteLine($"Init result: {initResult}");

// Open a handle - returns 1 as the valid handle
int openResult = runtime.InvokeExport("scePlayGoOpen", cpuContext);
Console.WriteLine($"Open result: {openResult}");

// Query available chunk IDs
int chunkResult = runtime.InvokeExport("scePlayGoGetChunkId", cpuContext);
Console.WriteLine($"GetChunkId result: {chunkResult}");

// Check current download speed
int speedResult = runtime.InvokeExport("scePlayGoGetInstallSpeed", cpuContext);
Console.WriteLine($"Current speed: {speedResult}");

// Set install speed to full
int setSpeedResult = runtime.InvokeExport("scePlayGoSetInstallSpeed", cpuContext);

// Query download progress
int progressResult = runtime.InvokeExport("scePlayGoGetProgress", cpuContext);

// Close the handle when complete
int closeResult = runtime.InvokeExport("scePlayGoClose", cpuContext);

The InvokeExport method (implemented in SharpEmu.Core.Runtime.SharpEmuRuntime) maps these string names to the corresponding static methods in PlayGoExports, passing the CpuContext parameter for memory access. Each exported method is annotated with SysAbiExportAttribute to define its NID and library association.

Summary

  • SharpEmu supports 14 PlayGo scenarios covering initialization, chunk queries, progress monitoring, and language configuration.
  • All scenarios are implemented in SharpEmu.Libs.PlayGo.PlayGoExports as a stub backend that simulates PlayStation 4/5 content download behavior.
  • The emulator uses a single handle (PlayGoHandle == 1) validated through ValidateHandle across all functions.
  • Thread safety is enforced via the _stateGate lock protecting shared state fields.
  • Games must provide a play-go.xml file which the emulator parses during scePlayGoInitialize to define available chunks.

Frequently Asked Questions

What is PlayGo and why does SharpEmu need to support it?

PlayGo is Sony's system for progressive downloading of game content on PlayStation 4 and 5, allowing games to start before all data is installed. SharpEmu implements these scenarios to prevent games that rely on PlayGo APIs from crashing or stalling during boot sequences that check download status.

Does SharpEmu perform actual downloads or is it just a stub?

SharpEmu provides a stub implementation. Functions like scePlayGoPrefetch and scePlayGoGetEta return success codes without performing network operations. The emulator assumes all content is locally available while maintaining the API contract that games expect.

How does SharpEmu handle PlayGo metadata?

During scePlayGoInitialize, the emulator calls LoadPlayGoMetadata to parse the game's play-go.xml file. This XML defines the chunk layout, which the emulator stores in _metadata.ChunkIds to service subsequent queries about available content.

Are all PlayGo functions fully implemented?

While all 14 major scenarios are present, many are minimally implemented. Critical path functions like opening handles and querying chunk IDs return valid data parsed from the XML, while time-dependent functions like scePlayGoGetEta return static values. This balance allows games to boot without requiring a full PlayStation Network stack.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →