Skip to Content
DevelopersThe addon and its context

The addon and its context

Your entrypoint implements MyriadAddon. Myriad calls its phases for every addon in turn:

PhaseWhenUse it for
registerCategories(ctx)first, for every addonyour own categories, so other addons can use them too
initialize(ctx)then, for every addoneverything else: modules, commands, windows, hooks
(config load)Myriad loads the player’s profile: your modules’ settings and states come in
postInitialize(ctx)lastlooking for optional integrations (other mods, other addons)

If any phase throws, your addon is marked failed, everything it registered is removed, and the game carries on. The Addons window shows the error.

public final class MyAddon implements MyriadAddon { private Category automation; @Override public void registerCategories(AddonContext ctx) { automation = ctx.registerCategory("Automation", "", SettingColor.role(SettingColor.Mode.CYAN)); } @Override public void initialize(AddonContext ctx) { // Shared state: made here, passed to whatever needs it. Not in static fields. WaypointStore waypoints = new WaypointStore(ctx.storage()); waypoints.load(); ctx.registerModules(new Waypoints(waypoints), new AutoFarm(automation)); // menu order ctx.registerCommand(new WaypointCommand(waypoints)); PanelType window = ctx.registerPanel("Waypoints", "", () -> new WaypointsPanel(waypoints)); ctx.registerHud("Nearest Waypoint", "", () -> new NearestWaypointHud(waypoints)); ctx.registerKeyAction("Open Waypoints", Keybind.NONE, () -> Myriad.ui().openPanel(window)); ctx.events().subscribe(new SessionStats()); // always-on listener } @Override public void postInitialize(AddonContext ctx) { if (FabricLoader.getInstance().isModLoaded("baritone")) ctx.logger().info("Baritone found"); } }

What the context registers

MethodRegisters
registerModules(Module...)modules, in menu order
registerCategory(name, icon, color)a category (in registerCategories)
registerCommand(Command)a chat command
registerPanel(name, icon, factory) / registerPanel(PanelType)a window
registerHud(name, icon, factory[, anchor, x, y])a HUD element
registerBarWidget(BarWidget)something in the menu’s top bar
registerLayout(Layout)a workspace layout
registerTheme(Theme)a theme preset
registerKeyAction(name, defaultBind, action)a global key, rebindable in the Keybinds window
registerControlPanel(ControlPreset)a ready-made control panel
hook(Hook) / replace(Service)a hook or service replacement
settings(name)settings of the addon itself, shown in the Addons window, saved per profile
settingWidgets()the editor for a custom setting type
events()the event bus (listeners you subscribe through it are attributed to your addon)
storage()your own folder for saved data
logger(), namespace(), id(path)your logger, your mod id, and an id in your namespace

Everything registered through the context is owned by your addon: shown with its name in the menu, and removed if it fails.

Registering later

An addon that bridges another mod may only be able to register its modules once that mod is up. That’s allowed: the menu picks them up the next time it opens. Those modules missed the config load, so they should mirror state kept elsewhere: return true from Module.isMirror() and Myriad neither saves them nor toggles them on their keybind, and setEnabledSilently(...) follows the other side without chat feedback.

Reach Myriad from anywhere with the static Myriad class: Myriad.modules(), Myriad.rotations(), Myriad.ui(), Myriad.notifications()… Myriad.isReady() says whether it has started.