Skip to content

Instantly share code, notes, and snippets.

@widberg
Created June 7, 2025 18:05
Show Gist options
  • Select an option

  • Save widberg/12260304d8aa52370dafa46a4bf2c40f to your computer and use it in GitHub Desktop.

Select an option

Save widberg/12260304d8aa52370dafa46a4bf2c40f to your computer and use it in GitHub Desktop.
#!/usr/bin/env python3
# A Little To The Left Save Editor
# Usage: python3 a_little_to_the_left_save_editor.py decrypt save1.json save1_decrypted.json
# Usage: python3 a_little_to_the_left_save_editor.py encrypt save1_decrypted.json save1.json
# See https://www.pcgamingwiki.com/wiki/A_Little_to_the_Left for save file locations
# Backup your save file before using this script
import argparse
import json
SHIFT = 11
def obfuscate(data, shift):
return bytes([(shift + x) % 0xFFFF for x in data])
def decrypt(args):
# WTF were they doing
with open(args.encrypted_file, "r", encoding="utf-8") as f:
data = f.read().encode("latin1")
data = obfuscate(data, -SHIFT)
j = json.loads(data)
with open(args.decrypted_file, "w", encoding="utf-8") as f:
json.dump(j, f, indent=4)
def encrypt(args):
with open(args.decrypted_file, "r", encoding="utf-8") as f:
j = json.load(f)
s = json.dumps(j, separators=(",", ":"))
data = obfuscate(s.encode("latin1"), SHIFT)
with open(args.encrypted_file, "w", encoding="utf-8") as f:
f.write(data.decode("latin1"))
def main():
parser = argparse.ArgumentParser(description="A Little To The Left Save Editor")
subparsers = parser.add_subparsers(dest="command", required=True)
parser_decrypt = subparsers.add_parser("decrypt")
parser_decrypt.add_argument("encrypted_file", type=str)
parser_decrypt.add_argument("decrypted_file", type=str)
parser_decrypt.set_defaults(func=decrypt)
parser_encrypt = subparsers.add_parser("encrypt")
parser_encrypt.add_argument("decrypted_file", type=str)
parser_encrypt.add_argument("encrypted_file", type=str)
parser_encrypt.set_defaults(func=encrypt)
args = parser.parse_args()
args.func(args)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment