Mega Tree API
Registration
When to call, what comes back, the rules ids must follow, and what happens when two mods want the same one.
When to call
Register from your plugin's Awake(). That is early - before any scene
exists - and it is fine, because registration only records data. Nothing touches Unity until the
player opens the tree window.
You can also register later: mid-game, after a config reload, after the player unlocks something. A node that appears while the window is open shows up on the next repaint, and if the player already owned levels on that id from a previous session, those levels come back with it (see Persistence).
The API never throws
Register is called from inside your
Awake(). If it threw, the exception would abort your plugin, not Mega
Tree - which is a terrible failure mode for a mistake as small as a typo in an id. So it does
not throw. Every failure comes back as a result and is written to the log with your guid.
UpgradeHandle handle = tree.Register(new UpgradeDefinition { /* ... */ });
if (!handle.Success)
{
// handle.Result.Status -> RegisterStatus enum
// handle.Result.Message -> the same text that went to the log
Logger.LogError($"Mega Tree refused the node: {handle.Result}");
return;
}
int owned = handle.Level; // 0 on a fresh saveRegisterStatus
| Status | Meaning |
|---|---|
Ok | The node was added. |
Replaced | You re-registered your own id. The definition was swapped and the owned level kept. |
MissingField | No DescribeLevel, no name, or a null definition. |
InvalidId | The id is not prefix.name, or uses characters outside a-z 0-9 _ - . |
ReservedId | The id starts with megatree. or mt. |
OwnedByAnother | Another plugin got there first. The first registration is untouched. |
InvalidLevels | MaxLevel is outside 1..20. |
InvalidCost | No positive BaseCost and no CostForLevel. |
InvalidModule | You passed an empty plugin guid to ForPlugin. |
Id rules
An id registered through the API must be in prefix.name
form:
- lower case only, plus digits,
_,-and dots - at least one dot, not at the start or the end, never two in a row
- 3 to 64 characters
- not starting with
megatree.ormt.
| Id | Verdict |
|---|---|
bigboxes.capacity | ok |
night_owl.open-late | ok |
capacity | no dot |
BigBoxes.Capacity | upper case |
bigboxes..capacity | double dot |
mt.capacity | reserved prefix |
cashier | no dot (and it is a built-in id) |
None of Mega Tree's own ids contain a
dot - they are walk, cashier,
mv_restocker and so on. Requiring a dot from everyone else means a
third-party mod cannot collide with or hijack a built-in node by construction. No
renaming, no save migration, and the rule is one line to remember.
Renaming it normally costs your
players their levels, because the id is the save key. LegacyIds carries
the level over to the new name. How it works
Duplicate ids
| Situation | What happens |
|---|---|
| Same plugin, same id, twice | The definition is replaced and the owned level is kept. This is what makes hot-reload work. |
| Different plugin, same id | Rejected with OwnedByAnother, naming both guids in the log. The first registration is untouched and neither mod breaks. |
| Same prefix, different plugins | Allowed, with a warning. Mod suites legitimately share a prefix. |
Limits
| Limit | Value |
|---|---|
| Nodes per plugin | 64 |
| Levels per node | 1 to 20 |
| Sub-tab label | 18 characters |
| Icon PNG | 512 KB |
Removing a node
Unregister takes a node out of the tree. It does not
delete the player's level - that stays in the save file and comes back if you register the id
again. Use it for config toggles, not as a cleanup step on shutdown.
// Via the handle...
handle.Unregister();
// ...or by id, from the module.
tree.Unregister("bigboxes.capacity");A sub-tab with no nodes is not drawn, and if yours was the only mod registered, the whole Mods tab disappears too - it does not exist at all until something is registered. If that happens while the window is open, the view falls back to the You tab instead of going blank.