# 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.

URL: https://xichil.dev/docs/xis-mvui/v1/guides/game-options/ · Updated: 2026-11-06 · Applies to: Fabric, Quilt, Legacy Fabric, Forge, NeoForge, MC 1.7.10 - 26.3

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](https://xichil.dev/javadoc/xis-mvui/v1/dev/xichil/mvui/GameBridge.html), 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](https://xichil.dev/javadoc/xis-mvui/v1/dev/xichil/mvui/ReloadResult.html). | 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:

```java
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:

```java
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:

```java
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 `true` if a backend took the request; `false` if 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:

```java
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](https://xichil.dev/docs/xis-mvui/v1/guides/async-work/index.md): the `runAsync` rules used above.
