Client library
Vendor umm_client.js into your mod if you would rather call
UMM.register({ ..., onChange }) than write inline bus code. It speaks the same
umm:1 protocol as the snippet.
Where it earns its keep is the bookkeeping. The snippet makes you guard group
and descend into checks yourself in the default loop; the library does both,
so onChange only ever sees real values.
Vendoring it
Section titled “Vendoring it”Download umm_client.js,
put it in your mod’s src/panorama/scripts/, and include it from your layout
ahead of your own script:
<scripts> <include src="s2r://panorama/scripts/umm_client.vjs_c" /> <include src="s2r://panorama/scripts/your_mod.vjs_c" /></scripts>var settings = UMM.register({ id: "your_mod", // stable; namespaces your stored values name: "Your Mod", // shown as the tab title settings: [ { id: "enabled", type: "toggle", label: "Enabled", default: true, description: "Optional. Shown as a tooltip when the row is hovered." }, { id: "opacity", type: "slider", label: "Opacity", min: 20, max: 100, step: 5, default: 90, unit: "%" }, { id: "corner", type: "select", label: "Corner", default: "tl", options: [ { value: "tl", label: "Top Left" }, { value: "tr", label: "Top Right" } ] } ], onChange: function (key, value, all) { /* apply it */ }});
settings.get("opacity"); // current value, or the declared defaultsettings.all(); // every value, keyed by setting idregister() fires onChange once per setting straight away, carrying your
declared default, so your mod runs on its defaults whether or not UMM is
installed. If UMM is there, it answers the announce with a set per setting a
moment later and onChange fires again for every value that differs from the
default. As with the snippet’s applySetting, that leaves exactly one code path
to write, and it has to be idempotent for the same reason.
It never fires for a group, and a checks row arrives as one call per option
id rather than one for the row, matching how those values are stored. So the
key you receive is always something you can switch on.
onChange is called inside a try/catch: a throw is logged with a [UMM]
prefix and swallowed, so one bad setting cannot take down the rest of your mod.
Seeing it against a real mod
Section titled “Seeing it against a real mod”The worked example walks through a shipping mod’s integration and ends by rewriting it against this library, so you can read the same settings both ways and judge which suits you.