Mega Tree API

API reference

Every public type and member in MegaTree.Api, flat and anchored.

Namespace: MegaTree.Api. Assembly: MegaTree.dll. Nothing outside this namespace is public - the rest of the mod is internal on purpose, so there is exactly one door.

Every member here takes or returns plain objects and delegates. Nothing in the surface is a Sprite, a Color or a GameObject, so a mod can use the API without referencing a single Unity UI assembly.

MegaTreeApi

public static class MegaTreeApi

MemberDescription
const string ModGuid Always "MegaTree". Use it in [BepInDependency].
static readonly int ApiVersion Contract version of the installed dll. readonly, never const - see Versioning. Currently 1.
MegaTreeModule 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, and it only marks the view stale - calling it in a loop costs one redraw.
event Action<string,int> LevelChanged (nodeId, newLevel), after a buy or a sell-back. All nodes, including built-ins. Does not fire for a level restored on registration.
event Action Apply About twice a second, after Mega Tree's own effects. Not a per-frame hook.
event Action<int> SaveLoaded (slotIndex), once levels for that slot have been read.

MegaTreeModule

public sealed class MegaTreeModule - obtained from ForPlugin, never constructed directly.

MemberDescription
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 language. Accepts "pt-BR" or "Portuguese". Mega Tree's own keys are skipped. Details

UpgradeDefinition

public sealed class UpgradeDefinition - a plain object with public fields. Full explanations on Node definition.

FieldTypeDefault
Id requiredstring-
DisplayNamestringnull
NameKeystringnull (auto: <id>.name)
MaxLevelint1
BaseCostfloat1000
CostMultiplierfloat1.8
CostForLevelFunc<int,int>null
SellBackRatefloat?null (50%)
IconUpgradeIconnull
DescribeLevel requiredFunc<int,string>-
IsUnlockedFunc<bool>null
LockedReasonFunc<string>null
RequiredStoreLevelFunc<int,int>null
ComingSoonboolfalse
SortOrderint0
LegacyIdsstring[]null
OnLevelChangedAction<int>null
OnApplyActionnull

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.

MemberDescription
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. Ship white artwork with alpha, or pass whiteSilhouette: true.

UpgradeHandle

public sealed class UpgradeHandle - what Register returns. Always non-null.

MemberDescription
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 MegaTreeApi.GetLevel(NodeId).
bool Unregister()Removes the node; the level stays in the save.

RegisterResult

public sealed class RegisterResult

MemberDescription
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

ValueMeaning
OkAdded.
ReplacedSame plugin re-registered the id; level kept.
MissingFieldNull definition, or no DescribeLevel / no name.
InvalidIdNot prefix.name, or bad characters.
ReservedIdStarts with megatree. or mt.
OwnedByAnotherAnother plugin owns the id.
InvalidLevelsMaxLevel outside 1..20.
InvalidCostNo positive BaseCost and no CostForLevel.
InvalidModuleEmpty plugin guid.

Built-in node ids

Stable, and none of them contains a dot - which is exactly why your ids must. Useful for gating.

IdNameTabLevels
walkWalking SpeedYou5
sprintSprint SpeedYou5
reachLong ReachYou4
pushPush ThroughYou4
cashierFast CashierStaff5
fulldayFull Day ShiftStaff1
trainingStaff TrainingStaff1 soon
mv_cashierCashier LegsStaff5 soon
mv_restockerRestocker LegsStaff5 soon
mv_unloaderUnloader LegsStaff5 soon
mv_bakerBaker LegsStaff5 soon
mv_butcherButcher LegsStaff5 soon
mv_seafoodSeafood LegsStaff5 soon

The ones marked soon are drawn and unbuyable. GetLevel returns 0 for them and will keep doing so until they ship - do not gate anything on them.

Limits at a glance

LimitValue
Nodes per plugin64
Levels per node1 - 20
Id length3 - 64 characters
Sub-tab label18 characters
Sub-tabs per page5, then arrows
Kept lines per save slot4096
IsUnlocked cache0.25 s
Sell-back rate50% by default; a registered node can declare 0..1 via SellBackRate

Differences from the Tech Tree API

The surface is the same, name for name. What differs is the platform and a few numbers:

Tech TreeMega Tree
NamespaceTechTree.ApiMegaTree.Api
Entry classTechTreeApiMegaTreeApi
Module typeTechTreeModuleMegaTreeModule
Reserved prefixestechtree. tt.megatree. mt.
Default sell-back60%50%
Apply period~2 s~0.5 s
Locale argumentBCP-47 (pt-BR)BCP-47 or the game's name (Portuguese)
Plugin baseBasePlugin / Load()BaseUnityPlugin / Awake()