Skip to content

Instantly share code, notes, and snippets.

@RillonDodgers
Created April 19, 2025 03:09
Show Gist options
  • Save RillonDodgers/98a75a77a79f1e260ec3ea1b5dc4b307 to your computer and use it in GitHub Desktop.
Save RillonDodgers/98a75a77a79f1e260ec3ea1b5dc4b307 to your computer and use it in GitHub Desktop.
Schedule 1 Modding - Quick Guide

🧩 Modding Schedule I with MelonLoader + dnSpy

This guide shows how to mod Schedule One, a Unity game that uses IL2CPP, by leveraging the beta Mono version available on Steam, along with dnSpy and MelonLoader. We'll walk through how to inspect and patch game logic like the OfferDealValid method.

🛠️ Prerequisites

  • Steam version of Schedule One
  • MelonLoader (latest version)
  • dnSpy (for exploring .NET assemblies)
  • Basic knowledge of C# and Harmony patching
  • [optional] A local clone of SellAgain mod

🧪 Setup Steps

  1. Install the game via Steam

    • Install the standard Schedule One release.
    • Copy the installed game directory somewhere safe.
    • Uninstall
  2. Install the Mono version

    • Right-click on Schedule One in your Steam Library
    • Click Properties > Betas
    • Select alternate from the dropdown to download the Mono version.
  3. Browse to the Mono Assembly DLLs

    Open this in dnSpy to explore methods that would normally be unavailable in IL2CPP builds. Schedule 1/Managed/Assembly-CSharp.dll


🔍 Finding the Method You Want to Patch

In this example, we want to patch the method OfferDealValid, which looks like this in the Mono version:

protected virtual bool OfferDealValid(out string invalidReason)
{
  invalidReason = string.Empty;
  if (this.TimeSinceLastDealCompleted < 360)
  {
    invalidReason = "Customer recently completed a deal";
    return false;
  }
  if (this.OfferedContractInfo != null)
  {
    invalidReason = "Customer already has a pending offer";
    return false;
  }
  if (this.TimeSinceInstantDealOffered < 360 && !this.pendingInstantDeal)
  {
    invalidReason = "Already recently offered";
    return false;
  }
  return true;
}

💥 Patching It With Harmony

In your mod project (e.g., SellAgain), create a patch using Harmony

[HarmonyPatch(typeof(Customer), "OfferDealValid")]
public static class OfferDealValidPatch {
    [HarmonyPrefix]
    public static bool Prefix(ref string invalidReason, ref bool __result) {
        invalidReason = string.Empty;
        __result = true; // Force the method to always return true
        return false;    // Skip the original method
    }
}

This patch effectively disables all original guard clauses in OfferDealValid.

🧩 Building & Running Your Mod

Create a C# project that targets .NET Framework 6.0 Reference:

  • MelonLoader.dll
  • Assembly-CSharp.dll
  • UnityEngine.dll

Build your mod .dll and place it in: Schedule I/Mods/

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