Probably Stolen Modding Basics

How to make a Probably Stolen mod: the official C# API, manifest.xml, build setup, hook points, dev console and Workshop publishing.

Last Updated: 2026-11-02
Probably Stolen Modding Basics — Probably Stolen gameplay

Probably Stolen Modding Guide: Manifest, DLL and Hooks

Quick answer

Probably Stolen has an official C# modding API. You need the game, the .NET SDK 6.0 or later, and the game's managed DLLs. A mod is a folder in Mods/ with a manifest.xml and at least one DLL. Start from the developer's GitHub guide, use the create-mod.bat shortcut, and test with the F8 console.

This is a beginner's map, not a replacement for the official documentation. The developer maintains a detailed guide at github.com/dragonpan2/probably-stolen-modding; read it before you write code. This page explains the moving parts and the order to set them up.

What the API supports

The official guide divides features into supported and unsupported.

Supported:

  • New items with custom sprites.
  • Customer generation hooks.
  • Loot table edits, from code or JSON.
  • Custom UI windows.
  • Paper books (in-game guides, cards, sheets).
  • Machine windows, game options, Wild's Network upgrades.
  • Starting scenarios and perks.
  • Difficulties.
  • Afterhour locations and events.
  • Appraisal items.
  • Mod configuration and per-run mod data.

Not supported:

  • New customer sprites or new client factions.
  • Changing existing UI screens.
  • Changing the store's layout or core loop.
  • Overhaul-style mods that touch many systems.
  • New Underground Exchange deals.
  • New inspectable items (appraisal items have their own API).

You can still attempt unsupported changes with Harmony patches, but you maintain them yourself after every game update. The guide recommends hook points over Harmony because hooks are faster and less likely to break.

Requirements

  • A legal copy of Probably Stolen (for the DLLs).
  • C# knowledge.
  • .NET SDK 6.0 or later.
  • A code editor or IDE.
  • Windows for the create-mod.bat shortcut; other systems can follow the manual steps.

The game uses Harmony for patching and exposes hook points for common events. The project targets netstandard2.1.

Folder layout

The game install folder contains Probably Stolen.exe. Inside it:

Probably Stolen/
├── Probably Stolen.exe
├── Mods/
│   └── TestMod/
│       ├── manifest.xml
│       └── TestMod.dll
└── Modding/
    └── TestMod/
        ├── TestMod.cs
        └── TestMod.csproj

Mods/ is what the game loads. Modding/ is your workspace. Keep them separate so a build does not overwrite your source.

Step 1: create the project

In the Modding folder:

dotnet new classlib -n TestMod --framework netstandard2.1
cd TestMod

Replace the .csproj with references to the game's managed DLLs:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netstandard2.1</TargetFramework>
    <LangVersion>latest</LangVersion>
  </PropertyGroup>
  <ItemGroup>
    <Reference Include="Assembly-CSharp">
      <HintPath>..\..\Probably Stolen_Data\Managed\Assembly-CSharp.dll</HintPath>
      <Private>false</Private>
    </Reference>
    <Reference Include="UnityEngine">
      <HintPath>..\..\Probably Stolen_Data\Managed\UnityEngine.dll</HintPath>
      <Private>false</Private>
    </Reference>
    <Reference Include="UnityEngine.CoreModule">
      <HintPath>..\..\Probably Stolen_Data\Managed\UnityEngine.CoreModule.dll</HintPath>
      <Private>false</Private>
    </Reference>
    <Reference Include="0Harmony">
      <HintPath>..\..\Probably Stolen_Data\Managed\0Harmony.dll</HintPath>
      <Private>false</Private>
    </Reference>
  </ItemGroup>
</Project>

The Private=false is important: the game already ships those assemblies, and copying them into your mod can cause version conflicts.

Step 2: write manifest.xml

The manifest is mandatory. A folder without it is skipped. A minimal manifest:

<?xml version="1.0" encoding="utf-8"?>
<Manifest>
  <ID>test_mod</ID>
  <Name>Test Mod</Name>
  <Author>YourName</Author>
  <ModVersion>1.0</ModVersion>
  <Description>A test mod.</Description>
  <GameVersions>
    <Version>1.0.0.6</Version>
  </GameVersions>
  <Prerequisites />
  <Assemblies>
    <Assembly>TestMod.dll</Assembly>
  </Assemblies>
  <Capabilities />
</Manifest>

Field rules from the official guide:

  • ID — unique, lowercase, ASCII letters/digits/_/-/., not starting with ., at most 64 characters. It names files and folders, so an invalid ID makes the manifest invalid.
  • Name — the display name in the Mods menu.
  • Author — your name.
  • ModVersion — your mod's version.
  • Description — a short description.
  • GameVersions — one <Version> per supported game version.
  • Prerequisites — IDs of mods that must load first; empty if none.
  • Assemblies — every DLL to load, relative to the mod folder, in load order. A DLL not listed is not loaded; an unexpected DLL can block activation.
  • Capabilities — required, usually empty. Declares files, network, process, dynamic-code, native, reflection-external. The scanner refuses activation if you use an undeclared capability.

Check your mod with the F8 console command mod-scan <id> before publishing.

Step 3: write the mod class

A minimal mod implements IMod:

using UnityEngine;

namespace TestMod
{
    public class ModEntry : IMod
    {
        private ModLog log;

        public void Init(ModManifest manifest)
        {
            log = new ModLog(manifest);
            log.Log("Test Mod loaded.");
        }

        public void OnEnable()
        {
            ModHook.OnShutterOpenedEarly += OnShutterOpened;
        }

        public void OnDisable()
        {
            ModHook.OnShutterOpenedEarly -= OnShutterOpened;
        }

        private void OnShutterOpened()
        {
            log.Log("The store opened.");
        }
    }
}

The lifecycle:

  • Init(ModManifest manifest) — once, at game start, at the main menu. Store the manifest, create the logger, cache references. Do not touch save data or managers; they do not exist yet.
  • OnEnable() — right after Init. Subscribe to hooks, register debug buttons, prepare state.
  • OnDisable() — when the game shuts down. Unsubscribe and undo what OnEnable set up.

Deactivating a mod in the Mods menu only takes effect at the next start. OnDisable is not called for a live deactivation.

Step 4: build and install

dotnet build -c Release

The DLL lands in bin/Release/netstandard2.1/. Copy it and manifest.xml into:

Mods/TestMod/

Launch the game, open the Mods menu, activate the mod, and restart when prompted. The F8 console should show your log line.

Hook points

Hooks are C# events on the static ModHook class. Subscribe in OnEnable, unsubscribe in OnDisable. They fire during gameplay, when the game's systems exist.

Useful hooks:

  • OnModItemDirectoryInit — register new items.
  • OnGenerateCustomer* — alter a customer as it is generated.
  • OnGameLoaded* — a save finished loading.
  • OnShutterOpened* / OnShutterClosed* — store open/close.
  • OnGoingSleep* / OnWakingUp* — sleep cycle.
  • OnHandlingNightlyServices* — nightly upkeep.
  • OnCreateTooltip* — append lines to an item tooltip.
  • OnLootRolled — override a loot result.
  • OnNewGameStarted — a new run began.
  • OnDifficultyApplied — a run started or loaded with a difficulty.
  • OnAfterhourArrive* / OnAfterhourLeave* — after-hour locations.

Many hooks have ordering tiers (VeryEarly, Early, Normal, Late, VeryLate). Use Normal unless you need to run before or after another mod.

Prefer hooks over Harmony. Harmony is for things the hooks do not cover, and it breaks more often on game updates.

Adding an item

Register a factory in OnModItemDirectoryInit:

void RegisterItems(ModItemDirectory dir)
{
    dir.Add("health_pack", () =>
    {
        GameItem item = ItemDirectory.CreateEmptyItem("health_pack");
        item.name = "Health Pack";
        item.shortDescription = "Restores a little health.";
        item.SetSpriteAndShapeFromMod("test_mod", "health_pack");
        return item;
    });
}

Put the sprite in Textures/Items/health_pack.png. The sprite's transparent pixels define the inventory shape. The mod ID in SetSpriteAndShapeFromMod is the manifest ID, not the folder name.

Assets

Drop assets into named folders; the loader picks them up:

  • Textures/ — general textures.
  • Textures/Items/ — item sprites.
  • Textures/Paper/ — paper book art.
  • Sounds/ — .wav, .ogg, .mp3.
  • Localization/ — en.csv, fr.csv, and so on.
  • LootTables/ — JSON loot edits.
  • Books/ — JSON paper books.

Folder names are exact, and scanning is not recursive. A PNG in a nested subfolder is ignored. Supported image formats are .png and .jpg.

Testing tools

The game ships with two developer tools, disabled by default:

  • F8 — debug console (Quantum Console). Shows logs, warnings, errors and commands.
  • F9 — dev menu. Spawn items, trigger events, change state.

To enable them, create an empty file named dev.txt next to Probably Stolen.exe and restart the game. The log gets a [DevTools] line saying whether they are enabled. Delete the file to disable them. Never ship dev.txt with a mod.

Useful console commands:

  • help, man <command>.
  • mod-scan <id> — scanner findings and version fingerprint.
  • loot-list <id> — table entries and effective odds.
  • loot-roll <id> [count] — test rolls.
  • paper-list, paper-open <id> — paper books.

The dev menu can change the current save permanently. Test on a save you do not mind breaking.

Publishing to the Workshop

Before you publish:

  1. Test on a clean save. Load, play a day, save, reload, disable, re-enable.
  2. Check the manifest. Game versions, assemblies, capabilities.
  3. Run mod-scan. Fix any undeclared capability.
  4. Write a clear description. State what the mod changes, its dependencies and its save impact.
  5. Include a preview image. preview.png in the mod folder, or the Workshop preview.
  6. Version it. A semantic version such as 1.0.0 is easier to support than final.
  7. State the uninstall path. If the mod adds items, tell players what happens to those items when it is removed.

The Workshop upload flow is in the game's mod menu. Do not upload another author's DLLs or assets. The 1.0.0.6 security update scans capabilities and shows them to players before activation; a mod that hides what it does will be refused.

Common beginner mistakes

  • No manifest.xml. The folder is skipped with no useful error.
  • Wrong target framework. Use netstandard2.1.
  • Copying game DLLs into the mod. Use Private=false.
  • Touching managers in Init. They do not exist at the main menu; use a gameplay hook.
  • Forgetting to unsubscribe. A disabled mod can still receive events if OnDisable does not remove its handlers.
  • Hardcoding item IDs that another mod also adds. Prefix your IDs with your mod ID.
  • Publishing without a version. Players cannot tell which build they have.

Where to go next

  • Read the official guide: github.com/dragonpan2/probably-stolen-modding.
  • Use create-mod.bat for a working skeleton.
  • Read the best mods guide to see what the current Workshop does.
  • Read the save editor guide before you touch save data.
  • Keep a clean test save; modding is iterative.

A mod configuration screen. Manifest, assemblies and capabilities are checked before load.
A mod configuration screen. Manifest, assemblies and capabilities are checked before load.

A mod configuration screen. Manifest, assemblies and capabilities are checked before load.

FAQ

What do I need to make a mod?

.NET SDK 6.0+, the game DLLs and the official modding guide.

Where do I start?

Clone the official template, build the DLL, add manifest.xml, then test with the F8 console.

How do I publish a mod?

Use the Workshop uploader or the documented folder structure, and declare capabilities in the manifest.

Sources and version notes

  • Official modding documentation: github.com/dragonpan2/probably-stolen-modding (README and ModdingGuide.md), checked 2 November 2026.
  • Manifest fields, capabilities, hook points and dev tools from that guide.
  • 1.0.0.6 modding security update from the Steam patch notes.
  • Build 1.0.0.6.

Official source: modding guide ↗ · Steam store ↗ · Workshop ↗, checked 2 November 2026.

More Probably Stolen Guides