#1024·windhawk

Settings: allow `$options` to be populated at runtime

Author: mazanyCreated Jul 28, 2026Updated Sep 6, 2026
Labelsenhancement

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:

  1. Free-text patch ids. Typo-prone, and the mod can only report a mismatch to a log the user isn't reading.
  2. Bake $options into the source. Adding a patch then means editing and reinstalling the mod, which defeats the point of a file-driven registry.
  3. 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:

cpp
// 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.