Tech Tree API
Getting started
What you need installed, and the shortest path from an empty project to a node on screen.
Prerequisites
| You need | Why |
|---|---|
| .NET SDK 6.0 or newer | The mod targets net6.0, same as Tech Tree. |
| BepInEx 6 (IL2CPP build) | Supermarket Simulator is an IL2CPP game. The Mono build of BepInEx will not load. |
| Tech Tree 1.3.0 or newer | The API does not exist in 1.2.0 and below. |
| A working BepInEx plugin | This page assumes your plugin already loads and logs something. |
If your plugin inherits from
BaseUnityPlugin you are on the Mono template and it will never load.
For IL2CPP the base class is BasePlugin and the entry point is
Load(), not Awake().
Four steps
1. Add TechTree.dll to the references you already have
This is one extra reference on top of a normal IL2CPP plugin project, not a
replacement for them. You still need BepInEx.Core,
BepInEx.Unity.IL2CPP, 0Harmony,
Il2CppInterop.Runtime, Il2Cppmscorlib,
Assembly-CSharp and whichever
UnityEngine.*Module assemblies your code touches.
Project setup has the complete, working csproj.
Download the Tech Tree zip from Nexus, take TechTree.dll out of
BepInEx/plugins/rodopoulos/, and add it with
Private=false:
<!-- IN ADDITION to your usual BepInEx / Harmony / Assembly-CSharp references. -->
<Reference Include="TechTree">
<HintPath>C:\...\BepInEx\plugins\rodopoulos\TechTree.dll</HintPath>
<Private>false</Private>
</Reference>2. Declare the dependency
Without this attribute BepInEx may load your plugin before Tech Tree, and your registration call would hit a type that has not initialised yet.
[BepInPlugin("BigBoxes", "Big Boxes", "1.0.0")]
[BepInDependency(TechTreeApi.ModGuid)]
public sealed class Plugin : BasePlugin { }3. Get your module and register
ForPlugin creates your sub-tab inside the Mods tab.
The second argument is the label on that sub-tab, and it is the only thing you ever say about
where your nodes appear.
public override void Load()
{
var tree = TechTreeApi.ForPlugin("BigBoxes", "Big Boxes");
var handle = tree.Register(new UpgradeDefinition
{
Id = "bigboxes.capacity",
DisplayName = "Bigger Boxes",
MaxLevel = 3,
BaseCost = 1500,
Icon = UpgradeIcon.Builtin("package"),
DescribeLevel = lvl => $"+{lvl * 2} items per box",
});
// Register never throws. Check the handle instead.
if (!handle.Success) Log.LogError(handle.Result.ToString());
}4. Implement the effect
Tech Tree stores the level. Making it mean something is your job. Read the level with
TechTreeApi.GetLevel wherever the game asks the question:
[HarmonyPatch(typeof(SomeGameClass), "get_BoxCapacity")]
internal static class BoxCapacityPatch
{
private static void Postfix(ref int __result)
{
int lvl = TechTreeApi.GetLevel("bigboxes.capacity");
if (lvl > 0) __result += lvl * 2;
}
}Check it worked
- Close the game. BepInEx locks the dll while it runs, so a copy over a running game silently fails.
- Copy your dll into
BepInEx/plugins/. - Start the game, load a save, sit at the store computer and open Tech Tree.
- A Mods tab should be there, with your sub-tab inside it.
If it is not, the log will say why. Open
BepInEx/LogOutput.log and search for
[api] - every rejection is written there with your plugin guid and the
reason.
An empty sub-tab is never drawn. If every one of your registrations failed, the Mods tab does not appear either - which looks exactly like Tech Tree ignoring you. Check the log before assuming the API is broken.
Common first-run mistakes
| Symptom | Cause |
|---|---|
[api] registration of 'X' ... refused - id must be in 'prefix.name' form |
Ids must contain a dot and be lower case. See Registration. |
| Two Tech Tree versions load | You shipped TechTree.dll with your mod. Set Private=false. |
TypeLoadException on your plugin |
The installed Tech Tree is older than 1.3.0. |
| Node shows but does nothing | You registered it but never wrote the effect. That part is always yours. |