Skip to content

v1.3 - Fix 64-bit fields in PS4 conversions

Choose a tag to compare

@NeverCookFirst NeverCookFirst released this 28 Aug 09:47
· 5 commits to main since this release

⚠ No guarantee — back up first

This tool comes with no guarantee that the saves it produces are stable or free of corruption. Use it at your own risk, and always keep a backup of any save you care about before touching it. Convert into a spare slot, never over your only copy.

The save format was reverse-engineered rather than documented. It is verified as far as it can be, but the game's field types are only known for the parts that real saves happened to exercise — and a bad conversion can look fine for hours of play before something turns out to be missing.


The PS4 fix

Anything converted to or from the PS4 before this release was wrong, even though it loaded.

The save payload is fixed little-endian on every platform, but a 64-bit field is written as two little-endian halves in the console's own word order — low half first on the PS4, high half first on the PowerPC consoles. So 0x00000000726DE363 is stored as:

Xbox 360 / PS3 / Wii U:   00 00 00 00 63 e3 6d 72
PS4:                      63 e3 6d 72 00 00 00 00

The converter used to copy the payload across unchanged, which left every 64-bit value byte-reversed. The game does not reject such a file — it loads it and reads those fields as garbage. The save looked like it worked while the progress stored in them was silently gone: right level, right stud count, but the hub shown as never completed and every red brick locked.

Fixing it meant working out the save's record grammar — [u32 key][u32 size][body][u32 key], the key repeated as a terminator, bodies being either nested records or arrays of 24-byte { id, tag, u64, u64 } entries — and swapping the halves of the 64-bit slots.

Two guards keep the swap from doing harm:

  • a slot is only swapped when exactly one half is zero, which is what a 64-bit value below 2^32 looks like, so opaque byte arrays whose length happens to be a multiple of 24 are never touched;
  • entry id 0EEB6A85 — the total stud counter — holds a 32-bit value where every other id holds a 64-bit one. Swapping it multiplied the player's studs by 2^32 (two million became nine quadrillion), so it is excluded.

Also fixed

  • GAME is now written as a slice of the finished main file rather than rebuilt from the payload; a rebuild walks a truncated record stream and picks a different set of 64-bit fields. In a real save GAME is the exact byte prefix of V2GAME.
  • ZOPTS is recognised as the PS4 spelling of OPTS, so it is no longer converted when options files are meant to be skipped. Options files are raw native-endian structs and are now skipped outright across a byte-order boundary rather than scrambling the target's settings.

Two things that will bite you if you skip them

  1. Convert the whole save, with every DLC file, and copy all of the results across. Progress is spread over them — each DLC file is one world.
  2. The target slot must already contain a save the game itself made. Do not drop the converted folder in as a new slot. Create a save in a spare slot in-game, quit, then replace the files inside it. Per-slot metadata (the .header file on Xbox 360, PARAM.SFO on PS3, sce_sys\ on PS4, meta\ on Wii U) is never written by this tool.

Full instructions are in READ ME FIRST.txt inside the download.

Verified

  • A real Xbox 360 save run through Xbox 360 → PS4 → Xbox 360 comes back bit-identical, all 32 files.
  • Round trip PS4 → Xbox 360 → PS4: likewise bit-identical.
  • A PS4 save converted to Xbox 360 matches a real xenia save byte for byte on nine DLC files, the rest differing only by the two players' actual progress.
  • That converted save was loaded and played under xenia: correct level, hub progress, red bricks and stud total.