"__class": "Object", "system": "__class": "Game_System", ... , "actors": [ "__class": "Game_Actor", "_actorId": 1, "_level": 5, "_hp": 234, ... ], "party": "__class": "Game_Party", "_gold": 1250, "_items": ... , "map": "__class": "Game_Map", "_mapId": 2, "_displayX": 0, ... , "switches": "__class": "Game_Switches", "_data": [...] , "variables": "__class": "Game_Variables", "_data": [...] , "selfSwitches": "__class": "Game_SelfSwitches", "_data": ...
The structure is layered:
[ LZ77-compressed binary blob ] ↓ decompress [ UTF-8 string (JSON with __class metadata) ] ↓ JsonEx.parse [ JavaScript object (save contents) ] Unlike older .rvdata2 (which started with a Marshal header), .rmmzsave has no fixed magic signature because the first few bytes are LZ77-compressed data. However, the very first byte often indicates the compression method (e.g., 0x78 for zlib’s deflate). Tools like binwalk often detect it as zlib compressed data . Decompressed Sample Snippet (Anonymized) After decompression, you’ll see a JSON-like string such as: rmmzsave
const contents = JsonEx.parse(StorageManager.load(savefileId)); DataManager.extractSaveContents(contents); The critical detail: . It injects metadata (e.g., "__class": "Game_Actor" ) so that JsonEx.parse can reconstruct full objects with their prototypes. 3. Binary Structure of an .rmmzsave File Despite being generated from JSON, an .rmmzsave file is not human-readable in a text editor. That’s because the engine compresses it using LZ77 compression (specifically a variant of pako ’s raw deflate) after serialization and before writing to disk. "__class": "Object", "system": "__class": "Game_System",