Summary
$options combobox values are declared in the mod source and fixed at install
time. That means a mod can't offer a picker over anything it discovers on the
machine. I'd like a way for a mod to supply options at runtime — for example an
optional export the settings UI calls, Wh_GetSettingOptions(name).
Filing this as the ambitious one of a small batch. It is clearly larger than
the others and I'd understand it being declined or deferred; the ones alongside
it stand on their own.
Why
$options is the right control whenever a value must be one of a known set.
But "known" currently means "known when the mod was written", which excludes
everything interesting about the machine the mod is running on:
- installed applications a mod can target
- files in a folder the mod reads
- connected monitors, audio devices, profiles
- window classes or processes discovered at runtime
For those, authors fall back to a free-text field the user must type exactly,
which trades a discoverable, unmistakable control for one that silently does
nothing when misspelled. The mod usually can't even validate it well, because
by the time it reads the setting it isn't in a position to tell the user.
Evidence
I'm building toward a small patch registry: CSS patches live as files, and the
user picks which to apply per application. The natural control is a checkbox
list or a multi-select of the patches present on disk — which is precisely what
can't be expressed, since the patch set changes whenever a file is added.
The workarounds available today, and why each falls short:
- Free-text patch ids. Typo-prone, and the mod can only report a
mismatch to a log the user isn't reading.
- Bake
$options into the source. Adding a patch then means editing and
reinstalling the mod, which defeats the point of a file-driven registry.
- A directory convention — apply everything in a folder, disable by
renaming with a leading _.
I shipped (3). It works and needs no engine change, but the enable/disable
affordance is now "rename a file in Explorer" rather than a checkbox in the
settings UI, which is a real step down for anyone who isn't the author.
Note that alpha.2's relaxation of settings-array indices (undeclared rows are
now writable — thank you, that was the other half of this problem) makes the
storage side flexible. It is now only the presentation side that is fixed at
install time.
Suggested shape
An optional export the settings UI calls when rendering, mirroring how mods
already expose lifecycle functions:
// Called by the settings UI. Return NULL / do nothing to keep static $options.
BOOL Wh_GetSettingOptions(PCWSTR settingName, WH_SETTING_OPTIONS* out);
Open questions I don't have a good answer to, and which may well make this
not worth it:
- Where does it run? The settings UI is not inside a target process. Calling
into a mod outside its injection context is the hard part of this request, and
possibly the disqualifying one.
- What if it's slow or hangs? Needs a timeout and a fallback to static
options.
- Refresh semantics. Once when the settings page opens is probably enough.
A cheaper alternative that captures much of the value: let a mod write a
candidate list to a known location, and let $options reference it —
$optionsFrom: "%LOCALAPPDATA%\\my-mod\\options.json". No cross-process call,
no lifetime questions, and the mod controls the contents. If the full version is
too invasive, this variant would still turn (1) and (3) above into a real
picker.
Tested on 2.0.0-alpha.2.
Summary
$optionscombobox values are declared in the mod source and fixed at installtime. That means a mod can't offer a picker over anything it discovers on the
machine. I'd like a way for a mod to supply options at runtime — for example an
optional export the settings UI calls,
Wh_GetSettingOptions(name).Filing this as the ambitious one of a small batch. It is clearly larger than
the others and I'd understand it being declined or deferred; the ones alongside
it stand on their own.
Why
$optionsis the right control whenever a value must be one of a known set.But "known" currently means "known when the mod was written", which excludes
everything interesting about the machine the mod is running on:
For those, authors fall back to a free-text field the user must type exactly,
which trades a discoverable, unmistakable control for one that silently does
nothing when misspelled. The mod usually can't even validate it well, because
by the time it reads the setting it isn't in a position to tell the user.
Evidence
I'm building toward a small patch registry: CSS patches live as files, and the
user picks which to apply per application. The natural control is a checkbox
list or a multi-select of the patches present on disk — which is precisely what
can't be expressed, since the patch set changes whenever a file is added.
The workarounds available today, and why each falls short:
mismatch to a log the user isn't reading.
$optionsinto the source. Adding a patch then means editing andreinstalling the mod, which defeats the point of a file-driven registry.
renaming with a leading
_.I shipped (3). It works and needs no engine change, but the enable/disable
affordance is now "rename a file in Explorer" rather than a checkbox in the
settings UI, which is a real step down for anyone who isn't the author.
Note that alpha.2's relaxation of settings-array indices (undeclared rows are
now writable — thank you, that was the other half of this problem) makes the
storage side flexible. It is now only the presentation side that is fixed at
install time.
Suggested shape
An optional export the settings UI calls when rendering, mirroring how mods
already expose lifecycle functions:
Open questions I don't have a good answer to, and which may well make this
not worth it:
into a mod outside its injection context is the hard part of this request, and
possibly the disqualifying one.
options.
A cheaper alternative that captures much of the value: let a mod write a
candidate list to a known location, and let
$optionsreference it —$optionsFrom: "%LOCALAPPDATA%\\my-mod\\options.json". No cross-process call,no lifetime questions, and the mod controls the contents. If the full version is
too invasive, this variant would still turn (1) and (3) above into a real
picker.
Tested on 2.0.0-alpha.2.