`content` in horizon-client's reply, from the constants the build checks content against: content mods' manifest api lines (APIS without the removed WebAssembly 0.1), native mods' hooks level and that they need a rebuild, the shader schema and the line it draws, the resource and data pack formats, the modpack format and the index schema. A launcher offers only what works. The generated reference shows the hooks level as a placeholder, since it rises with every hook. Part of #10562. Co-Authored-By: Claude Opus 5.5 <[email protected]>
7.0 KiB
Launch API
What another launcher (Prism Launcher, MultiMC, ATLauncher, Modrinth App, HMCL or your own) needs to start Horizon:
the options horizon-client takes, how it hands over an account, and how it ends. horizon-launcher is the
reference implementation. Proposed in horizon-rust/horizon#3545.
Overview
| Version | 0.1.0, printed by horizon-client --launch-api and horizon-prepare --launch-api |
| Level | experimental (stability.md): preview once preparing and the guide are covered too |
| Covers | starting horizon-client: its options, the session JSON, the exit codes, the crash report's path; preparing with horizon-prepare: --launch-api, --output, --check, --complete, --progress json |
| Not yet | finding a build (see Not there yet) |
Guide
The whole way, from picking a build to playing: launch-guide.md. In short:
-
Start Horizon only for a player signed in with a Microsoft account that owns Minecraft: Java Edition, and hand over that account's session (
--session-stdin, or--session-file), never on the command line. This is the same owner gatehorizon-launcherapplies before every start. Horizon never downloads Mojang's files; a launcher that does downloads them only for that owner. -
Ask the build what it takes:
horizon-client --launch-apiprints JSON withlaunch_api(the version),optionsandcontent(which mods, shader packs and packs it loads). Pass only options it lists: any other is refused with exit code 2. -
Start it with a folder per instance:
horizon-client --resources PREPARED --game-dir INSTANCE --home INSTANCE --width 1280 --height 720 --session-stdin -
Watch the exit code. On 2, stderr names the refused option (
Horizon: --width: …). On 1 or 101, the last line on stderr names the crash report.
Reference
launch-reference.md, generated from crates/horizon-client/src/game/launch_api.rs: every
option, the --launch-api reply and the exit codes.
The session JSON
The account the game joins online-mode servers with (microsoft-account.md):
{"name": "Alex", "uuid": "069a79f444e94726a5befca90e38aaf5", "access_token": "…", "user_type": "msa", "xuid": "…"}
name,uuid(with or without dashes) andaccess_tokenare required;user_type, when present, ismsa;xuidis optional.--session-stdin: write the JSON to the game's standard input and close it.--session-file PATH: a file the game reads once and deletes at once. On Unix its mode must be 0600; a file older than two minutes is refused (and deleted).- A session the game can't read is reported on stderr (
Horizon: not signed in: …), and online-mode servers will refuse the player.
Preparing
horizon-prepare turns the player's own Minecraft files into the resources horizon-client --resources reads. It
downloads nothing: it reads the files of a Minecraft the player owns (Guide, step 1) and checks each against the
pins in research-lock.json.
horizon-prepare --launch-api
horizon-prepare --prepare --output PREPARED --complete --progress json
horizon-prepare --check --output PREPARED
--launch-api: prints one JSON object on stdout and exits 0 (1, with anerror:line, when there is noresearch-lock.jsonbeside it or at--root).launch_apiis the version, the same ashorizon-client --launch-api's;horizonis the preparer's own;minecraftandjava_majorare the pins it prepares for (the game files it needs, and the Java--java-homemust give);schemaandoutput_versionare the layout and contents of the resources it writes, the ones--checkcompares;optionslists the options above and below as{"name", "value"}(valueis the placeholder, null for a flag) andexit_codesits exit codes. Pass only options it lists; readers ignore fields they don't know.--output DIR: where the resources go; the preparer's scratch files stay in its own.local/. One preparation at a time writes to a folder; a second one waits.--check: exit 0 when the resources are complete and current for this preparer. Otherwise exit 1, with each gap on stdout and the command that fills it, or anerror:line on stderr when it can't check. It tests which files are there and the versions they were made for, not their contents: a launcher that suspects damage prepares again. A folder being prepared, or whose preparation stopped, is not current.--checkrefuses--progressand--complete(exit 2): they apply to preparing.--complete: after preparing, copies the sounds and fails unless--checkwould pass.--version-json,--client-jar,--libraries-dir(Maven layout),--assets-dir(indexes/andobjects/): for a launcher whose files aren't laid out like the official launcher's, each names what--minecraft-dirwould give. Every file is still checked against the pins. When an earlier import beside the preparer is still verified, it is reused and these files aren't read.--server-jar PATH: the first--prepareneeds the server jar, which no launcher keeps. Horizon never downloads it; a launcher downloads it (the version JSON'sdownloads.server) only for a signed-in account that owns Java Edition, ashorizon-launcherdoes.--java-home PATH: a Java of the pinned version that the launcher manages, tried afterJAVA_HOMEand thePATH, before the official launcher's runtimes.- Exit codes: 0 done, 1 failed or gaps found, 2 a refused command line.
--progress json
- Every line on stdout is one JSON object; stderr is human text.
{"message": string}: a log line, for the player to read.{"fraction": number}: how far the work is, from 0 to 1, never decreasing.{"error": string}: why it failed. It is the last line, and the exit code is 1.- Readers ignore keys they don't know, and lines with no key they know. A new key comes with a patch of the Launch API; a key whose meaning changes starts the next line (stability.md).
Examples
horizon-client --launch-api
printf '%s' "$SESSION_JSON" | horizon-client --resources ~/horizon/prepared --game-dir ~/instances/a --session-stdin --fullscreen
Stability
Experimental: the options in the reference, the session JSON, the exit codes and the crash report line may still change before preview. From preview on, they change only as stability.md says, and the reference's test keeps the contract and the code together.
Not there yet
- Finding a build: a signed release index and builds kept longer than seven days.
Changelog
- 0.1.0 (not released yet, so still one version):
horizon-client's--game-dir,--home,--player-dir,--fullscreen,--session-stdin,--launch-api(withcontent), exit code 2 for a refused command line;horizon-prepare's--launch-api,--output,--check,--complete,--progress json,--version-json,--client-jar,--libraries-dir,--assets-dirand--java-home.