Mega UI

The app

Everything Mega UI needs to put your app on the desktop: what it is called, what its icon looks like, and where it sits.

AppDefinition

FieldTypeWhat it does
TitlestringThe label under the icon and on the taskbar tab. Trimmed to 18 characters.
IconUiIconA built-in icon or your own PNG. See Icons.
SortOrderintWhere you sit in the desktop column, low first. Ties break by plugin guid.
OnOpenedActionCalled right after your window becomes visible.
OnClosedActionCalled when it is minimized or closed, including on walking away from the computer.

Title

Keep it short. The game's own labels are Shopping, Management and Statistics, and a long one overflows the icon rather than wrapping. Anything past 18 characters is cut. An empty title falls back to your plugin guid, so an app is never nameless.

SortOrder, and why to leave it alone

Apps are ordered by SortOrder first, then by plugin guid. Not by the order they registered in — BepInEx loads plugins in file order, which changes when the player installs, removes or renames a mod. Icons that shuffle around on their own are worse than icons in an order you did not choose.

The default of 0 is the right answer for almost every mod

If everybody picks a big number to be near the top, the field stops meaning anything and we are back to arbitrary order — only now it is arbitrary and everyone thinks they won.

OnOpened and OnClosed

For work you only want to do while someone is looking: recalculating a summary, starting a poll, subscribing to an event.

csharp
new AppDefinition
{
    Title = "Stock Report",
    Icon  = UiIcon.Builtin("package"),

    OnOpened = () => Report.Recalculate(),
    OnClosed = () => Report.StopWatching(),
}
You do not need OnOpened to refresh numbers

Anything you passed as a Func — a Value, a Toggle getter, a Stepper getter — is read again on every open by itself.

Registering

csharp
var app = MegaUiApi.Register(Guid, definition);

Register never throws and never returns null. A bad definition comes back as a handle whose Ok is false and whose Problem says why, so a typo in your mod cannot take down somebody else's app.

csharp
if (!app.Ok)
{
    Logger.LogError($"Mega UI refused this app: {app.Problem}");
    return;
}

Calling Register twice with the same guid updates your app instead of adding a second icon. That is deliberate: registering again after a save loads is a natural thing to write, and it should not cost the player a duplicate.

Unregistering

csharp
MegaUiApi.Unregister(Guid);

Rarely needed. When an app leaves, the ones below it move up to close the gap.