Skip to content

Instantly share code, notes, and snippets.

Created March 21, 2021 20:55
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save Z1ni/7a8c1927343dd5570fff0d015f425cca to your computer and use it in GitHub Desktop.
Yakuza save game "converter" for Xbox Game Pass for PC
import os
import struct
import sys
import uuid
import zipfile
# Yakuza 0 save "converter" (Xbox Game Pass for PC -> Steam)
# Might work for other Yakuza games available with the Game Pass if the app name is changed.
# Running: Just run the script with Python 3 to create a ZIP file that contains the save files
# Thanks to @snoozbuster for figuring out the container format at
xgp_app = "SEGAofAmericaInc.Yakuza0PC_s751p9cej88mt"
save_zip_path = ""
def read_utf16_str(f):
str_len = struct.unpack("<i",[0]
return * 2).decode("utf-16")
def get_file_paths():
# Find Yakuza save dir
wgs_dir = os.path.expandvars(f"%LOCALAPPDATA%\\Packages\\{xgp_app}\\SystemAppData\\wgs")
# Get the correct user directory
dirs = [d for d in os.listdir(wgs_dir) if d != "t"]
dir_count = len(dirs)
if dir_count != 1:
raise Exception(f"Expected one user directory in wgs directory, found {dir_count}")
containers_dir = os.path.join(wgs_dir, dirs[0])
containers_idx_path = os.path.join(containers_dir, "containers.index")
save_files = []
# Read the index file
with open(containers_idx_path, "rb") as f:
# Unknown
file_count = struct.unpack("<i",[0]
# Unknown
store_pkg_name = read_utf16_str(f)
# Unknown
# Unknown
for _ in range(file_count):
# File name
fname = read_utf16_str(f)
# Duplicate of the file name
# Unknown quoted hex number
# Container number
container_num = struct.unpack("B",[0]
# Unknown
# Read container (folder) GUID
container_guid = uuid.UUID(
# Unknown
# Read the container file in the file directory
with open(os.path.join(containers_dir, container_guid.hex.upper(), f"container.{container_num}"), "rb") as cf:
# Unknown
# Read file GUID
file_guid = uuid.UUID(
save_files.append((fname, os.path.join(containers_dir, container_guid.hex.upper(), file_guid.hex.upper())))
return save_files
def main():
# Get save file paths with correct names
save_files = get_file_paths()
# Store the save files into a zip
with zipfile.ZipFile(save_zip_path, "x") as save_zip:
for info in save_files:
orig_fname, container_fname = info
save_zip.write(container_fname, arcname=orig_fname)
except FileExistsError:
print(f"Save file container ZIP \"{save_zip_path}\" already exists.")
print(f"Save files stored to \"{save_zip_path}\"")
if __name__ == "__main__":
Copy link

monodop commented Jun 29, 2021

Thanks for building this! I was able to modify it to work with Snowrunner

Copy link

Z1ni commented Jul 2, 2021


Thanks for building this! I was able to modify it to work with Snowrunner

Cool! I've modified this Gist after publishing to support more games and be a bit more extensible and I just pushed that to a separate repo at, so if you'd like to make (mostly the same) contributions there, feel free to do so!

Copy link

revanmj commented Dec 23, 2021

This script also worked for extracting Final Fantasy XV saves (I only changed package name to "39EA002F.FINALFANTASYXVforPC_n746a19ndrrjg").

Copy link

Would be wonderful to see something like that for MH Rise

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment