Read and write options.txt
Use GameBridge to flush, reload and apply the game's options.txt from a menu, and report the options that need a restart.
Most menus never touch the game's own settings. A mod that saves or restores options.txt, such as a settings
profile mod, uses GameBridge, which every menu gets from host.game().
What it offers#
| Method | Does | If the backend fails |
|---|---|---|
flushOptions() |
Makes the game write its in-memory options to options.txt now, so a copy made afterwards has the newest values. |
the file stays as the game last wrote it |
reloadOptions() |
Re-reads options.txt and applies what it can in the running game (graphics, sound, controls, language…). Returns a ReloadResult. |
returns a result saying options.txt needs a restart |
isInWorld() |
Whether a single- or multiplayer world is loaded, for example to warn before loading options. | false |
Call them on the main thread, which is where actions run. None of them throws on a registered menu's host.
Save a copy#
Flush first, then copy the file off the main thread:
Button.builder("save")
.label(Text.translatable("mymod.save", "Save profile"))
.onPress(() -> {
host.game().flushOptions();
host.runAsync(() -> {
store.copyFrom(optionsFile);
return null;
}, (ignored, error) -> status.show(
error == null ? StatusLine.Kind.SUCCESS : StatusLine.Kind.ERROR,
error == null ? Text.translatable("mymod.saved", "Saved")
: Text.translatable("mymod.save.failed", "Couldn't save")));
})
.build();
Load a copy and apply it#
Write the file off the main thread, then apply it in onDone and report what needs a restart:
host.runAsync(() -> {
store.copyTo(optionsFile);
return null;
}, (ignored, error) -> {
if (error != null) {
status.show(StatusLine.Kind.ERROR, Text.translatable("mymod.load.failed", "Couldn't load"));
return;
}
ReloadResult r = host.game().reloadOptions();
if (r.needsRestart()) {
status.show(StatusLine.Kind.WARNING, Text.translatable("mymod.restart", "Restart to apply: %s",
String.join(", ", r.restartOptions())));
} else {
status.show(StatusLine.Kind.SUCCESS, Text.translatable("mymod.loaded", "Loaded"));
}
});
ReloadResult.restartOptions() is a set of options.txt keys, such as fullscreenResolution. When nothing
could be applied, it holds options.txt itself.
Outside a menu#
To make the game re-read options.txt from anywhere, for example a mod that restores options at startup, use
the static call:
boolean taken = MultiversionUi.reloadGameOptions();
- Safe on any thread. The backend moves the work to the main thread itself, so it may not have happened yet when the call returns.
- Returns
trueif a backend took the request;falseif there is no backend (the game then applies the file on its next launch) or the backend failed. - Never throws. It doesn't report which options need a restart; inside a menu, prefer
host.game().reloadOptions().
Test it#
dev.xichil.mvui.fake.FakeGame, from the API's test fixtures, is the GameBridge of FakeHost. It counts calls and lets
you choose what they return:
FakeGame game = new FakeGame()
.inWorld(true)
.reloadResult(ReloadResult.needsRestart("fullscreenResolution"));
FakeHost host = new FakeHost(game);
host.open(menu.create(host));
host.click("load");
assertEquals(1, game.reloads());
Next steps#
- Slow work: files and network: the
runAsyncrules used above.