1# Chapter 28: nix, the Mesen launcher 2 3`flake.nix` at the top of the repository is the devshell: every tool at an 4exact version. This folder holds the Nix expressions it calls, and today 5there is one: the wrapper that launches Mesen. 6 7[Mesen 2](https://github.com/SourMesen/Mesen2) is a well-regarded emulator 8the devshell carries as a second opinion. When our core and the game seem to 9disagree about a RAM address or a picture, Mesen running the same ROM 10settles it. Jev never plays in it. 11 12Mesen keeps all its settings in one `settings.json` of about 220 KB, and 13rewrites the whole file on startup and exit. So the file cannot be a 14read-only file Nix puts in place. What can be declared is the handful of 15keys this project depends on, merged into the file before every launch, 16leaving the rest of it Mesen's: 17 18- `Video.UseSoftwareRenderer = true`. Mesen reads it before it parses the 19 command line, so no switch can set it. The GPU renderer shows a black game 20 surface (with working sound) whenever Mesa falls back to software 21 rendering, which an ordinary WSLg session does; the software renderer 22 works either way. 23- `Debug.ScriptWindow.AllowIoOsAccess` and `AllowNetworkAccess = true`, 24 which gate LuaSocket and have no switch at all. 25 26If there is no settings file yet, it writes a seed instead: those keys plus 27`ConfigUpgrade = 1`, the one value for which Mesen fills in controller 28mappings (a bare `{}` leaves every port unmapped), and whose existence 29suppresses the first-run wizard, which would otherwise hang `--testRunner`. 30 31> **Aside: the invisible byte.** Mesen writes `settings.json` with a UTF-8 32> byte-order mark, which `jq` rejects. The wrapper strips it with `sed` 33> before merging. A test against a hand-made seed would never notice, which 34> is why changes here are tested against a copy of a file Mesen really wrote. 35 36> **Try it.** `nix develop -c sh -c 'cat "$(command -v Mesen)"'` prints the 37> wrapper script itself. Inside the devshell, `Mesen` is the only Mesen on 38> `PATH`: the wrapper takes the upstream binary's name so that there is no 39> unwrapped one to start by mistake. 40 41## For the people who maintain it 42 43### In this folder 44 45| File | What | 46| --- | --- | 47| [mesen.nix](mesen.nix) | The `Mesen` launcher: merges the `enforce` attrset (set in `../flake.nix`) into Mesen's settings.json, seeds a missing one, then execs the real emulator. Its header comment is the full rationale, with file and line citations into the Mesen source. | 48| [README.md](README.md) | This chapter. | 49| [CLAUDE.md](CLAUDE.md) | How to test a wrapper change, for agents. | 50 51← Previous: [Chapter 27, hotpatch/](../tools/hotpatch/) · Up: [jevsnes](../) · Next: [Chapter 29, toolchains/](../toolchains/) →