Scripts often modify preferences to control how KoLmafia behaves. Sometimes this is because the user's existing preferences are unsuitable, and sometimes because the script needs different behavior temporarily (eg, autoscend or garbo)
Normally this works, but many of these changes are not meant to be permanent. They only need to apply while the script is running.
If a script exits unexpectedly or the process is killed before script cleanup, the user can be left with modified preferences they did not intend to keep.
An idea to address this, was adding support for temporary preferences overrides.
This would set a memory-only preference stored separately from persistent preferences, and not written to disk.
The function
Calling
For example, if a parent script temporarily clears
As for the scope and lifetime of temporary preferences, two possible ideas.
1. Script scope
Temporary preferences exist only for the current script runtime.
Each runtime can set their own temporary values.
The newest value is the active value, what's returned by
When the runtime is no longer running, it falls through to the next oldest value.
Picture it as
2. Session scope
Temporary preferences persist in memory until preferences are loaded or unloaded, at which point they are cleared.
They will persist even when no scripts are active. There's only a single global
The downside of a session scope, is that the user may be surprised when a script fails to clean up after itself, and may have headaches trying to figure out why things are working weirdly. It would also mean more care would need to be taken to ensure that the user is aware when a temporary setting is active, whereas with a script runtime, normally it would finish before the user's input is considered.
Eg, the commands
As a final note, could also be worth introducing a new preference
Thoughts?
Normally this works, but many of these changes are not meant to be permanent. They only need to apply while the script is running.
If a script exits unexpectedly or the process is killed before script cleanup, the user can be left with modified preferences they did not intend to keep.
An idea to address this, was adding support for temporary preferences overrides.
set_temporary_property(string preference, string value)This would set a memory-only preference stored separately from persistent preferences, and not written to disk.
temporary_property_exists(string preference)remove_temporary_property(string preference)get_actual_property(string preference)The function
get_property would return the temporary preference if set, otherwise the actual preference.Calling
set_property sets the actual preference and removes any temporary overrides.For example, if a parent script temporarily clears
afterAdventureScript and a child script later calls set_property, the child's change is saved to disk and the parent script now sees the updated value. If neither script restores the original value, it is permanently changed. It's up to the scripts to handle that.As for the scope and lifetime of temporary preferences, two possible ideas.
1. Script scope
Temporary preferences exist only for the current script runtime.
Each runtime can set their own temporary values.
The newest value is the active value, what's returned by
get_propertyWhen the runtime is no longer running, it falls through to the next oldest value.
Picture it as
Code:
get_property(string preference) {
List temporarySettings;
temporarySettings.removeIf( ! setting.runtime.isRunning())
if (temporarySettings.isEmpty()) return actualSetting;
temporarySettings.sort(setting.timestamp)
return temporarySettings.newest()
}
Code:
set_temporary_property(ScriptRuntime runtime, string preference, string value) {
List temporarySettings = map.get(preference);
setting = new Setting(scriptRuntime, timestamp, value);
temporarySettings.add(setting)
}
Code:
set_property(string preference, string value) {
// This is being saved to file, remove all temporary settings.
temporarySettings.get(preference).clear();
// Normal code
}
2. Session scope
Temporary preferences persist in memory until preferences are loaded or unloaded, at which point they are cleared.
They will persist even when no scripts are active. There's only a single global
Map<string, string> temporaryPreferences = new Map();The downside of a session scope, is that the user may be surprised when a script fails to clean up after itself, and may have headaches trying to figure out why things are working weirdly. It would also mean more care would need to be taken to ensure that the user is aware when a temporary setting is active, whereas with a script runtime, normally it would finish before the user's input is considered.
Eg, the commands
choice, prefref and getAs a final note, could also be worth introducing a new preference
logTemporaryPreferenceChange that acts as logPreferenceChange does. And "prefref" and "get" commands would likely need to be updated to show both the actual, and the temporary preferences for assistance in debugging.Thoughts?