The launcher from v0lumehi's PR #62 (Launcher.swift, SwiftUI: the game's icon, name and version, Play, and the settings), built as their issue #64 proposes: dm/games/settings.tsv declares each player-facing setting once (the environment variable it sets, its kind: choice, range or toggle, its default and the condition under which a game offers it). build_ipa.sh runs dm/games/settings.py, which keeps the rows that hold for the game and fills in its defaults: the host's own from game_profile.h (DM_GAME_FPS_TARGET, DM_GAME_OPMODE), the build's (DM_LANG, DM_SHOW_FPS), the game's languages from its control data, and the render scale only for a build with the rewriter's render-scale stub, which patch_nso.py now records in main's table (RENDER_SCALE: Breath of the Wild 1.9.0, Tears of the Kingdom 1.4.3). The result goes into the app as dm/launcher.json, and the launcher draws one row per setting from it, so a new setting is one table row. Diagnostic switches stay environment-only. Breath of the Wild offers frame rate, render scale, console mode, 15 languages, the frame-rate counter and Apple's performance HUD.
Differences from the PR's launcher:
- The host's loading still starts at app launch. Only the loader read the frame rate and the render scale that early; it now just maps the frame step state page, and dm_fps_state_apply (main.c, when the game starts) writes both, so a boot is no slower with the launcher (the PR started all loading when Play was tapped). The game view, the pad and the frame-rate counter are made after Play, since they read the launcher's switches.
- The language choice applies: main.m sets the packed language as a default before the launcher runs, which the PR then took for a setting from env.txt and kept. main.m now lists the variables an env file set (DM_ENV_FILE_KEYS); only those are kept, and the launcher shows them greyed out.
- No new profile key for render scale (the rewriter's table tells), and the scale stops at 100 % (the above-1080p part is not in main). No Mac launcher.
The choices are kept in UserDefaults; DM_LAUNCHER=0 in Documents/env.txt skips the screen, as does an app without launcher.json. README: the settings screen in the Play section; dm/games/README.md and docs/development.md describe the table.
Checked: Launcher.swift type-checks against the iOS SDK and the Breath of the Wild IPA builds with it (launcher.json and RENDER_SCALE inside); the Mac host applies DM_FPS_TARGET=30 from the first present and DM_RENDER_SCALE=0.75 when the game starts. Not yet run on an iPhone.
Co-authored-by: v0lumehi <34629096+v0lumehi@users.noreply.github.com>