Skip to Content
DevelopersShared configs

Shared configs

Players share their setup as a code like myriad_JS3k4d: modules with their settings, control panels, the theme. As an addon author, you have one job: mark private settings. The API also lets you build and take in shares from code.

Private settings: protect()

Any setting whose value is private to the player has to be protected. Its value then never leaves their computer in a share: the share (and the website) only says the setting exists. Taking a share in never changes it either.

private final StringSetting webhook = sgGeneral.string("Webhook") .description("Discord webhook for finds.") .protect() .build(); private final IntSetting centerX = sgGeneral.intSetting("Center X").range(-30_000_000, 30_000_000) .protect() // coordinates in plain numbers: protect them too .build();

Protect anything that is, or could be:

  • a URL with a token in it (webhooks, API keys), a password, an account name;
  • coordinates, a server address, a player’s name the player chose to track;
  • a file path (it can name the player’s home folder);
  • free text the player types that could hold any of these.

BlockPosSetting and FileSetting are protected unless you call .protect(false). Myriad’s macro commands are protected. When in doubt, protect it: a player can always share a value by hand, but a leaked one can’t be taken back.

Protection is decided by your code, not the player. Shares are public to anyone with the code.

Building a share

Myriad.shares().builder() puts one together, from any mix of things:

ConfigShare share = Myriad.shares().builder() .title("Highway setup") .module(elytraFly) // one module .addonCategory("myriad-essentials", Categories.MOVEMENT) // one of the menu's windows .addon("my-addon") // every module of an addon .controlPanel(highway) // a control panel, with what it saves .theme() // the active theme's look .binds(false) // keybinds stay out unless true .build();

Then:

Myriad.shares().publish(share).thenAccept(p -> Async.onRenderThread(() -> Myriad.notifications().info("Shared", p.code() + " (" + p.url() + ")"))); Myriad.shares().fetch("myriad_JS3k4d").thenAccept(s -> Async.onRenderThread(() -> { ConfigShares.Applied result = Myriad.shares().apply(s, ConfigShares.Apply.AS_CONTROL_PANEL); if (!result.missing().isEmpty()) Myriad.notifications().warn("Missing", String.join(", ", result.missing())); }));
publish(share)uploads it; the code arrives with the future. Kept, with the key that deletes it, in published()
fetch(codeOrLink)downloads a share
apply(share, Apply.REPLACE)its settings become the player’s (protected ones excepted), modules on or off as shared
apply(share, Apply.AS_CONTROL_PANEL)a new control panel of its modules and settings, layered over the player’s
unpublish(code)deletes a share published from this computer
ConfigShares.isCode(text)whether text is a share code

Futures complete off the render thread: hop back with Async.onRenderThread before touching the game.

The format

A share is JSON (ConfigShare.FORMAT 1). Each module carries its settings (only values that differ from the defaults, no protected ones) and a view: how it looked in the sharer’s menu (name, category with icon and colour, each setting’s kind and shown value), so the website can draw it without knowing your addon.

{ "format": 1, "title": "Highway setup", "made": { "core": "0.3.4", "minecraft": "26.2" }, "addons": [{ "id": "myriad-essentials", "name": "Myriad Essentials", "version": "0.3.2" }], "modules": [{ "id": "myriad-essentials:elytra_fly", "enabled": true, "settings": { "general": { "type": "Recast" } }, "view": { "name": "Elytra Fly", "category": { "name": "Movement", "icon": "", "color": "#89B4FAFF" }, "groups": [{ "name": "General", "settings": [ { "name": "Type", "kind": "choice", "shown": "Recast", "options": ["Recast", "Altitude"] }, { "name": "Webhook", "kind": "text", "protected": true } ] }] } }], "controlPanels": [{ "name": "Highway", "members": ["myriad-essentials:elytra_fly"], "settings": { } }], "theme": { "name": "Myriad", "settings": { } } }

Shares live on Myriad’s API (https://api.myriadclient.dev/v1/configs), which also refuses to store a value for any setting marked protected, and the website shows them at https://myriadclient.dev/config/<code>.