Tech Tree API
API reference
Every public type and member in TechTree.Api, flat and anchored.
Namespace: TechTree.Api. Assembly:
TechTree.dll. Nothing outside this namespace is public - the rest of
the mod is internal on purpose, so there is exactly one door.
No member here takes or returns a Sprite, a
Color, a GameObject or any
Il2Cpp* type. You never need Il2CppInterop to use the API.
TechTreeApi
public static class TechTreeApi
| Member | Description |
|---|---|
const string ModGuid |
Always "TechTree". Use it in [BepInDependency]. |
static readonly int ApiVersion |
Contract version of the installed dll. readonly, never const - see Versioning. Currently 1. |
TechTreeModule ForPlugin(string pluginGuid, string tabName) |
Creates or renames your sub-tab and returns your module. Call once, keep the result. Never returns null. |
int GetLevel(string nodeId) |
Owned levels, clamped to that node's MaxLevel. 0 for an unknown id. Dictionary lookup - cheap enough for a hot patch. |
bool IsRegistered(string nodeId) |
Whether the id is currently in the tree. |
void RefreshUi() |
Ask an open tree window to repaint. No-op when nothing is open. |
event Action<string,int> LevelChanged |
(nodeId, newLevel), after a buy or a sell-back. All nodes, including built-ins. |
event Action Apply |
About every 2 s, after Tech Tree's own effects. Not a per-frame hook. |
event Action<int> SaveLoaded |
(slotIndex), once levels for that slot have been read. |
TechTreeModule
public sealed class TechTreeModule - obtained from
ForPlugin, never constructed directly.
| Member | Description |
|---|---|
string PluginGuid { get; } | The guid you passed in. |
string TabName { get; } | Your sub-tab label after trimming to 18 characters. |
UpgradeHandle Register(UpgradeDefinition definition) |
Adds one upgrade line. Never throws; check .Success. |
bool Unregister(string nodeId) |
Removes one of your nodes. The player's level is kept in the save. |
void AddTranslations(string locale, IDictionary<string,string> values) |
UI strings for one locale. Tech Tree's own keys are skipped. Details |
UpgradeDefinition
public sealed class UpgradeDefinition - a plain object with public
fields. Full explanations on Node definition.
| Field | Type | Default |
|---|---|---|
Id required | string | - |
DisplayName | string | null |
NameKey | string | null (auto: <id>.name) |
MaxLevel | int | 1 |
BaseCost | float | 1000 |
CostMultiplier | float | 1.8 |
CostForLevel | Func<int,int> | null |
SellBackRate 1.3.1 | float? | null (60%) |
Icon | UpgradeIcon | null |
DescribeLevel required | Func<int,string> | - |
IsUnlocked | Func<bool> | null |
LockedReason | Func<string> | null |
ComingSoon | bool | false |
SortOrder | int | 0 |
LegacyIds 1.3.1 | string[] | null |
OnLevelChanged | Action<int> | null |
OnApply | Action | null |
There is no category field. Every registered node lives in the Mods tab, in your sub-tab. Why
UpgradeIcon
public sealed class UpgradeIcon - built through factory methods.
| Member | Description |
|---|---|
static UpgradeIcon Builtin(string name) |
One of the 14 built-in icons. Unknown names fall back to a generic one. List |
static UpgradeIcon FromPng(byte[] data, bool whiteSilhouette = false) |
Your own PNG, under 512 KB. Ship white artwork with alpha, or pass whiteSilhouette: true. |
UpgradeHandle
public sealed class UpgradeHandle - what
Register returns. Always non-null.
| Member | Description |
|---|---|
string NodeId { get; } | The id you registered. |
string OwnerGuid { get; } | The plugin guid that owns it. |
RegisterResult Result { get; } | Why it succeeded or failed. |
bool Success { get; } | Shorthand for Result.Success. |
int Level { get; } | Current owned level. Same as TechTreeApi.GetLevel(NodeId). |
bool Unregister() | Removes the node; the level stays in the save. |
RegisterResult
public sealed class RegisterResult
| Member | Description |
|---|---|
bool Success { get; } | True for Ok and Replaced. |
RegisterStatus Status { get; } | Machine-readable outcome. |
string Message { get; } | The same text that went to the log. |
string ToString() | "Status: message". |
RegisterStatus
public enum RegisterStatus
| Value | Meaning |
|---|---|
Ok | Added. |
Replaced | Same plugin re-registered the id; level kept. |
MissingField | Null definition, or no DescribeLevel / no name. |
InvalidId | Not prefix.name, or bad characters. |
ReservedId | Starts with techtree. or tt. |
OwnedByAnother | Another plugin owns the id. |
InvalidLevels | MaxLevel outside 1..20. |
InvalidCost | No positive BaseCost and no CostForLevel. |
InvalidModule | Empty plugin guid. |
Built-in node ids
Stable, and none of them contains a dot - which is exactly why your ids must. Useful for gating.
| Id | Name | Levels |
|---|---|---|
cashier_speed | Faster Till | 5 |
restocker_speed | Faster Restocker | 5 |
staff_speed | Faster Support | 5 |
customer_speed | Faster Shoppers | 4 |
more_customers | More Customers | 5 |
smart_self_checkout | Smart Self-Checkout | 5 |
player_move | Fast Feet | 5 |
player_sprint | Sprinter | 3 |
player_reach | Long Reach | 3 |
quick_hands | Quick Hands | 5 |
Limits at a glance
| Limit | Value |
|---|---|
| Nodes per plugin | 64 |
| Levels per node | 1 - 20 |
| Id length | 3 - 64 characters |
| Sub-tab label | 18 characters |
| Icon PNG | 512 KB |
| Kept lines per save slot | 4096 |
IsUnlocked cache | 0.25 s |
| Sell-back rate | 60% by default; a registered node can declare 0..1 via SellBackRate |