Mega UI

Getting started

What you need installed, and the shortest path from nothing to an app on the store computer.

What you need

ThingWhich one
GameMegastore Simulator
LoaderBepInEx 5 (Mono) — not 6
LibraryMegaUI.dll in BepInEx/plugins/
SDK.NET SDK 6 or newer, targeting netstandard2.1
BepInEx 5, not 6

Megastore is a Mono game; Supermarket Simulator is IL2CPP. Installing the wrong loader makes every mod stay silent, which looks exactly like a broken mod. If you have modded Supermarket before, this is the difference that catches you.

1 · Reference the library

Two references and nothing else. Note what is missing: no UnityEngine.UI, no TextMeshPro. A mod that draws a whole screen with Mega UI does not reference a single UI assembly.

xml
<Reference Include="MegaUI">
  <HintPath>C:\...\BepInEx\plugins\rodopoulos\MegaUI.dll</HintPath>
  <Private>false</Private>
</Reference>

<Reference Include="BepInEx">
  <HintPath>C:\...\BepInEx\core\BepInEx.dll</HintPath>
  <Private>false</Private>
</Reference>
Private=false is not optional

Without it MSBuild copies MegaUI.dll into your output, and whoever ships that folder puts a second Mega UI into BepInEx/plugins. BepInEx then drops one of the two by duplicate guid, and which copy survives is not your choice.

2 · Declare the dependency

csharp
[BepInPlugin(Guid, "My Mod", "1.0.0")]
[BepInDependency(MegaUiApi.ModGuid, BepInDependency.DependencyFlags.HardDependency)]
public sealed class Plugin : BaseUnityPlugin
{
    public const string Guid = "MyMod";
}

Use Hard when your mod is only a screen: BepInEx then refuses to load your plugin at all if the library is missing, which gives one clear line in the log instead of a TypeLoadException halfway through Awake.

Use Soft if your mod does other things too, and check MegaUiApi.IsRegistered before touching the API.

3 · Register and describe

csharp
private void Awake()
{
    var app = MegaUiApi.Register(Guid, new AppDefinition
    {
        Title = "Stock Report",
        Icon  = UiIcon.Builtin("package"),
    });

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

    app.Build(ui =>
    {
        ui.Header("Warehouse");

        ui.Row(r =>
        {
            r.Label("Boxes in storage");
            r.Spacer();
            r.Value(() => Warehouse.Count.ToString());
        });

        ui.Button("Order more", Warehouse.Order);
    });
}

That is the whole mod. Build it, drop the dll in BepInEx/plugins/, open the store computer, and your icon is on the desktop.

Why Build takes a lambda

Your Awake runs long before there is a store computer in the scene. Mega UI keeps your recipe and cooks it when the window actually exists — and again if the desktop is rebuilt, which happens more than once per session.

The good consequence

You never hold a reference to anything on screen. No field for a label you have to keep updating, nothing to null-check after a scene change, nothing to dispose.

Where to go next