Skip to content

Instantly share code, notes, and snippets.

@jh0ker
Last active June 19, 2025 04:08
Show Gist options
  • Save jh0ker/1b8dd16f113b7ddc7b90e617ac0851c4 to your computer and use it in GitHub Desktop.
Save jh0ker/1b8dd16f113b7ddc7b90e617ac0851c4 to your computer and use it in GitHub Desktop.
Max attributes and skills in SCUM game single player (+ unlock developer commands)

README

This script manipulates the SCUM database for the single player mode to increase the level of all skills and attributes to max (or the value of your choice) for a given prisoner. This script does not work for multiplayer characters.

You can edit the configuration settings SET_ATTRIBUTES and SET_SKILLS at the start of the script below to change the target values for the skills and attributes. Default is maxed out.

Tested with SCUM Build 0.9.605.85940

How do I use it?

You need to have Python installed on your computer. The script was tested with Python 3.13 - older versions may work, newer versions should be fine.

Download Python from python.org and install it. I recommend you tick the option "Add to PATH" during the install if there is one.

Now, scroll down on this page to the 01_max_prisoner.py script file and download it by right-clicking on the Raw button in its title bar and selecting "Save link as...". Save it somewhere you can easily find it.

Make sure you are not currently in a single player game (being in the main menu should be fine). Now, you should be able to run the script by simply double-clicking it in Windows. If this does not work, right click the file and select "Open with" -> "Python".

The script will automatically create a backup of your current DB and ask you which prisoner/character to work on. If everything works out correctly, it will look something like this:

image

Inspired by https://gist.github.com/quonic/279da005187df6e611b1b31859d91eeb

Other scripts

02_elevate_user.py

This script was contributed by @Vortox14 (see this comment) and allows you to use developer commands. You will need your Steam ID 64 – you can use a website like https://www.steamidfinder.com/ to find it. The following commands are available after elevating your user account:

  • #SetInfiniteAmmo <true | false>
  • #SetInfiniteOxygen <true | false>
  • #SetInfiniteStamina <true | false>
  • #SetImmortality <true | false>
  • #SetMetabolismSimulationSpeed <Multiplier>
  • #SetAttributes <Str [1-8]> <Con [1-5]> <Dex [1-5]> <Int [1-5]>
  • #SetSkillLevel <SkillName> <SkillLevel [0-4]>

03_repair_placed_items.py

I made this variant of the script for @MrAndrsn21 to help with testing different strategies. It simply restores the durability of all placed items and building elements. See this comment for further info.

"""
This script manipulates the SCUM database for the single player mode to
increase the level of all skills and attributes to max (or the value of
your choice).
Edit the constants below to change the target values for the skills and
attributes. Default is maxed out.
Tested with Python 3.13 on December 28th, 2024 with SCUM Build 0.9.605.85940
"""
from dataclasses import dataclass
import datetime as dt
from pathlib import Path
import shutil
import sqlite3
import struct
import traceback
from typing import Literal
#### Configuration ####
## Main attributes ##
SET_ATTRIBUTES = {
"BaseStrength": 8.0, # 1.0 to 8.0
"BaseConstitution": 5.0, # 1.0 to 5.0
"BaseDexterity": 5.0, # 1.0 to 5.0
"BaseIntelligence": 8.0, # 1.0 to 8.0
}
## Skills ##
"""
You can remove skills from the list below and they will not be changed.
If a new skill is added to the game, you can add it to the list below.
The first number in each line is the skill level (0 - 3)
The second number is the skill experience (0 - 10000000)
"""
SET_SKILLS = {
"BoxingSkill": (3, 10000000),
"AwarenessSkill": (3, 10000000),
"RiflesSkill": (3, 10000000),
"SnipingSkill": (3, 10000000),
"CamouflageSkill": (3, 10000000),
"SurvivalSkill": (3, 10000000),
"MeleeWeaponsSkill": (3, 10000000),
"HandgunSkill": (3, 10000000),
"RunningSkill": (3, 10000000),
"EnduranceSkill": (3, 10000000),
"TacticsSkill": (3, 10000000),
"CookingSkill": (3, 10000000),
"ThieverySkill": (3, 10000000),
"ArcherySkill": (3, 10000000),
"DrivingSkill": (3, 10000000),
"EngineeringSkill": (3, 10000000),
"DemolitionSkill": (3, 10000000),
"MedicalSkill": (3, 10000000),
"MotorcycleSkill": (3, 10000000),
"StealthSkill": (3, 10000000),
"AviationSkill": (3, 10000000),
"ResistanceSkill": (3, 10000000),
"FarmingSkill": (3, 10000000),
}
# Other constants
DB_PATH = Path.home() / "AppData/Local/SCUM/Saved/SaveFiles/SCUM.db"
BODY_SIM_KEY_PADDING = 5
BODY_SIM_VALUE_PADDING = 10
@dataclass
class PropertyType:
"""Just a small class to define property types as they occur in the body simulation blob."""
name: bytes
width: int # in bytes
# Used for converting with Python types
struct_type: Literal["<d", "<f", "<?"]
DoubleProperty = PropertyType(name=b"DoubleProperty", width=8, struct_type="<d")
FloatProperty = PropertyType(name=b"FloatProperty", width=4, struct_type="<f")
BoolProperty = PropertyType(name=b"BoolProperty", width=1, struct_type="<?")
def load_prisoner(con: sqlite3.Connection, id: int):
"""Load prisoner from database."""
cur = con.execute("SELECT * FROM prisoner WHERE id = ?", (id,))
result = {desc[0]: val for desc, val in zip(cur.description, cur.fetchone())}
return result
def save_prisoner(con: sqlite3.Connection, prisoner: dict):
"""Updates prisoner in database. Currently only sets body_simulation."""
return con.execute(
"UPDATE prisoner SET body_simulation = ? WHERE id = ?",
(prisoner["body_simulation"], prisoner["id"]),
)
def update_body_sim(
body_sim: bytearray,
key: bytes,
value: float,
property_type: PropertyType,
):
# Find the key in the body simulation blob
key_offset = body_sim.index(key)
# Make sure we are using the correct property type
property_type_offset = key_offset + len(key) + BODY_SIM_KEY_PADDING
assert (
body_sim[property_type_offset : property_type_offset + len(property_type.name)]
== property_type.name
)
# Calculate offset of actual value
value_offset = (
key_offset
+ len(key)
+ BODY_SIM_KEY_PADDING
+ len(property_type.name)
+ BODY_SIM_VALUE_PADDING
)
# Convert value to bytes
value_bytes = struct.pack(property_type.struct_type, value)
# Update value in body sim blob
body_sim[value_offset : value_offset + property_type.width] = value_bytes
def update_skills(con: sqlite3.Connection, prisoner: dict):
"""Sets all skills to max level in the database."""
for (name,) in con.execute(
"SELECT name FROM prisoner_skill WHERE prisoner_id = ?", (prisoner["id"],)
):
if name not in SET_SKILLS:
continue
new_level, new_experience = SET_SKILLS[name]
# Finally, update the XML and other fields in the database
con.execute(
"UPDATE prisoner_skill SET level = ?, experience = ? WHERE prisoner_id = ? AND name = ?",
(new_level, new_experience, prisoner["id"], name),
)
def choose_prisoner(con: sqlite3.Connection):
"""Choose prisoner to update."""
cur = con.execute(
"SELECT prisoner.id, user_profile.name FROM prisoner LEFT JOIN user_profile ON prisoner.user_profile_id = user_profile.id WHERE user_profile.authority_name is ?",
(None,),
)
prisoners = {id: name for (id, name) in cur}
if not prisoners:
print("No prisoners found in local single player.")
return None
print("\nFound prisoners in local single player:\n")
for id, name in prisoners.items():
print(f'"{name}" with ID {id}')
selected_id = input("\nEnter prisoner ID: ")
try:
selected_id = int(selected_id)
except ValueError:
print("Invalid input.")
return None
if selected_id not in prisoners:
print("Please enter a valid prisoner ID.")
return None
return selected_id
def create_backup(db_path: Path):
"""Creates a backup of the database."""
filename_safe_iso = dt.datetime.now().isoformat().replace(":", "-")
backup_path = db_path.with_name(f"SCUM-bak-{filename_safe_iso}.db")
shutil.copy(db_path, backup_path)
return backup_path
def main():
if not DB_PATH.exists():
print(f"Database file {DB_PATH} not found.")
input("Press enter to exit.")
return
print("Creating backup... ")
backup_path = create_backup(DB_PATH)
print(f"Backed up to: {backup_path}")
print("\nConnecting to database...")
con = sqlite3.connect(DB_PATH)
# Choose prisoner interactively
prisoner_id = choose_prisoner(con)
if not prisoner_id:
input("Prisoner selection failed. Press enter to exit.")
return
print(f"Loading prisoner with ID {prisoner_id}...")
prisoner = load_prisoner(con, prisoner_id)
print("\nUpdating attributes... ", end="")
body_sim = bytearray(prisoner["body_simulation"])
for attribute, value in SET_ATTRIBUTES.items():
update_body_sim(
body_sim,
attribute.encode("ascii"),
value,
DoubleProperty,
)
prisoner["body_simulation"] = bytes(body_sim)
save_prisoner(con, prisoner)
print("Success!")
print("Updating skills... ", end="")
update_skills(con, prisoner)
print("Success!")
con.commit()
input("\nAll done! Press enter to exit.")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\nExiting...")
except Exception:
print("\n\nSomething went wrong...\n\n")
traceback.print_exc()
input("\n\nPress enter to exit.")
"""
This script manipulates the SCUM database for the single player mode to
unlock developer commands.
Tested with Python 3.13 on December 28th, 2024 with SCUM Build 0.9.605.85940
"""
import shutil
import sqlite3
from pathlib import Path
import datetime as dt
import traceback
DB_PATH = Path.home() / "AppData/Local/SCUM/Saved/SaveFiles/SCUM.db"
def add_elevated_user(steam_id: str):
"""
Adds a SteamID64 to the elevated_users list.
Parameters:
steam_id (str): SteamID64 of the user to elevate.
Returns:
None
"""
# Connect to the database
with sqlite3.connect(DB_PATH) as con:
cursor = con.cursor()
# Insert the SteamID64 into the existing table
cursor.execute(
"""
INSERT INTO elevated_users (user_id)
VALUES (?)
""",
(steam_id,),
)
# Commit the changes
con.commit()
print(f"SteamID64 {steam_id} successfully added to elevated_users.")
def create_backup(db_path: Path):
"""Creates a backup of the database."""
filename_safe_iso = dt.datetime.now().isoformat().replace(":", "-")
backup_path = db_path.with_name(f"SCUM-bak-{filename_safe_iso}.db")
shutil.copy(db_path, backup_path)
return backup_path
def main():
print("Creating backup... ")
backup_path = create_backup(DB_PATH)
print(f"Backed up to: {backup_path}")
# Prompt user for SteamID64
steam_id = input("Enter the SteamID64 to elevate: ").strip()
# Validate SteamID64
if len(steam_id) == 17 and steam_id.isdigit():
add_elevated_user(steam_id)
else:
print("Invalid SteamID64. Please ensure it is a 17-digit numeric ID.")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\nExiting...")
except Exception:
print("\n\nSomething went wrong...\n\n")
traceback.print_exc()
input("\n\nPress enter to exit.")
"""
This script manipulates the SCUM database for the single player mode to
repair placed items by the chosen player.
Tested with Python 3.10 on September 15, 2022 with SCUM Build 0.7.162.51364
"""
import datetime as dt
import os
import shutil
import sqlite3
import traceback
import xml.etree.ElementTree as ET
from pathlib import Path
from typing import Tuple
#### Configuration ####
# No configuration :)
# Other constants
DB_PATH = Path.home() / "AppData/Local/SCUM/Saved/SaveFiles/SCUM.db"
def repair_base_element(con: sqlite3.Connection, prisoner_id: int):
"""Reset health of base elements like walls, foundations and some other stuff."""
con.execute(
"UPDATE base_element SET element_health = ? WHERE creator_prisoner_id = ?",
(1.0, prisoner_id),
)
def repair_virtualized_item(con: sqlite3.Connection, user_profile_id: int):
"""Reset health of other buildings and dropped items."""
for item_id, xml in con.execute(
"SELECT id, item_xml FROM virtualized_item WHERE user_profile_id = ?",
(user_profile_id,),
):
# Parse XML, modify health and max health, and convert back to XML
string_terminator = "\x0a\x00"
root = ET.fromstring(xml.rstrip(string_terminator))
root.set("_health", "1")
root.set("_maxHealth", "1")
new_xml = ET.tostring(root, encoding="unicode") + string_terminator
# Finally, update the XML and other fields in the database
con.execute(
"UPDATE virtualized_item SET item_xml = ? WHERE id = ?",
(new_xml, item_id),
)
def choose_prisoner(con: sqlite3.Connection) -> Tuple[int, int]:
"""Choose prisoner to update. Returns a tuple (prisoner_id, user_profile_id)."""
cur = con.execute(
"SELECT prisoner.id, user_profile.name, user_profile.id FROM prisoner LEFT JOIN user_profile ON prisoner.user_profile_id = user_profile.id WHERE user_profile.authority_name is ?",
(None,),
)
prisoners = {
prisoner_id: {"name": name, "user_profile_id": user_profile_id}
for (prisoner_id, name, user_profile_id) in cur
}
print("\nFound prisoners in local single player:\n")
for prisoner_id, data in prisoners.items():
print(f'"{data["name"]}" with ID {prisoner_id}')
chosen_prisoner_id = int(input("\nEnter prisoner ID: "))
if chosen_prisoner_id not in prisoners:
raise ValueError(f"Prisoner ID {chosen_prisoner_id} not found!")
return (chosen_prisoner_id, prisoners[chosen_prisoner_id]["user_profile_id"])
def main():
print("Backing up database... ")
filename_safe_iso = dt.datetime.now().isoformat().replace(":", "-")
backup_path = DB_PATH.with_name(f"SCUM-bak-{filename_safe_iso}.db")
shutil.copy(DB_PATH, backup_path)
print(f"Backed up to: {backup_path}")
print("\nConnecting to database...")
con = sqlite3.connect(DB_PATH)
# Choose prisoner interactively
prisoner_id, user_profile_id = choose_prisoner(con)
print('Repairing items in table "base_element"... ', end="")
repair_base_element(con, prisoner_id)
print("Success!")
print('Repairing items in table "virtualized_item"... ', end="")
repair_virtualized_item(con, user_profile_id)
print("Success!")
con.commit()
input("\nAll done! Press enter to exit.")
if __name__ == "__main__":
try:
main()
except KeyboardInterrupt:
print("\nExiting...")
except Exception:
print("\n\nSomething went wrong...\n\n")
traceback.print_exc()
input("\n\nPress enter to exit.")
@bakedbeangaming
Copy link

@bakedbeangaming Hmm... if it did run successfully, that's strange. Have you tried shutting off your game completely before running the script? Maybe the changes got overwritten by something in the game. Did you make any modifications to the script? If yes, try re-downloading the original. If it still doesn't work, maybe you could send me your save game and I'll take a look if there's anything different with that. You can send it to me on Discord if you want, my username there is the same as here, jh0ker

hi iv sent you a friend request on discord as it would not let me inbox you or send save file

@jh0ker
Copy link
Author

jh0ker commented Dec 23, 2023

Hey @bakedbeangaming I don't see any friend requests on my end, not sure why

@bakedbeangaming
Copy link

@jh0ker just like to say a big thank you to jh0ker for all your time in helping me much love and again thank you all sorted

@itsnotmesebas
Copy link

itsnotmesebas commented Oct 1, 2024

@jh0ker
hi! i have an issue:
Something went wrong...

Traceback (most recent call last):
File "C:\Users\yoels\AppData\Local\SCUM\Saved\SaveFiles\max_prisioner.py", line 208, in
main()
File "C:\Users\yoels\AppData\Local\SCUM\Saved\SaveFiles\max_prisioner.py", line 183, in main
body_sim = bytearray(prisoner["body_simulation"])
~~~~~~~~^^^^^^^^^^^^^^^^^^^
KeyError: 'body_simulation'

Press enter to exit.
what i can do?

@jh0ker
Copy link
Author

jh0ker commented Oct 2, 2024

Hey @itsnotmesebas

I'm unsure what might cause this, it doesn't seem to happen on my end with the latest version. Does this happen on all your single player prisoners? Perhaps you could send me your save file on Discord (I'm @jh0ker on there as well) and I'll take a look at it.

@Vortox14
Copy link

Vortox14 commented Dec 24, 2024

HOLY SH!! I got the "Elevated" Commands to work!!!

Elevated_User.py | This allows access to Elevated User commands.

#SetUnlimitedAmmo true (Heh Heh, No need for WeMod for this now.)
#SetUnlimitedOxygen true (WeMod doesn't even have this)
#SetUnlimitedStamina true (WeMod's variant sucks.)
#SetImmortality true (Can't die 😄!! Still take injuries though....)
#SetMetabolismSimulationSpeed 0 (This is a nice one, if you have perfect stats already.... Else breaks the metabolic system. (Can't eat/drink and so on..)
#SetAttributes 8 5 5 5 (Str Con Dex Int || Int can be set to 8 with the max_prisoner.py script but with not the in-game commands!)
#SetSkillLevel <SkillLevel [0-4]>

import sqlite3
from pathlib import Path

def add_elevated_user(steam_id):
    """
    Adds a SteamID64 to the elevated_users list.

    Parameters:
        steam_id (str): SteamID64 of the user to elevate.

    Returns:
        None
    """
    db_path = Path.home() / "AppData/Local/SCUM/Saved/SaveFiles/SCUM.db"

    try:
        # Connect to the database
        with sqlite3.connect(db_path) as con:
            cursor = con.cursor()

            # Insert the SteamID64 into the existing table
            cursor.execute("""
                INSERT INTO elevated_users (user_id)
                VALUES (?)
            """, (steam_id,))

            # Commit the changes
            con.commit()
            print(f"SteamID64 {steam_id} successfully added to elevated_users.")

    except sqlite3.Error as e:
        print(f"Database error: {e}")

    except Exception as e:
        print(f"Unexpected error: {e}")

if __name__ == "__main__":
    # Prompt user for SteamID64
    steam_id = input("Enter the SteamID64 to elevate: ").strip()

    # Validate SteamID64
    if len(steam_id) == 17 and steam_id.isdigit():
        add_elevated_user(steam_id)
    else:
        print("Invalid SteamID64. Please ensure it is a 17-digit numeric ID.")

I also have a modified script for max_prisoner.py, for I ran into issues as well with the original script.

@Luxcatz
Copy link

Luxcatz commented Jun 13, 2025

Thank you so much this still work.

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