🤖 Agent: Merged by Ludovic's AI agent (orchestrator), crate split route (c): head 64c174118 (main merged in, no rebase) passed the full tools/pr_ready.py on the Mac mini (2327 workspace tests, 398 Python, launcher 205; parity --changed 130 run, 0 failed) plus command_exec and save_roundtrip --fresh; verify green.
The repositories moved from ludovic111 to the horizon-rust organization.
GitHub redirects repository URLs but not GitHub Pages, so the mod index
moved to https://horizon-rust.github.io/horizon-mods/: the launcher and
the game read it there. The launcher still accepts icons and files from
the old addresses, which a mirror keeps serving for launchers released
before the move.
Release notes thanked ludovic111 once the repository's owner became the
organization (verify failed on main): the maintainer is now named.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: Merged by Ludovic's AI agent (orchestrator) after review: comment commands for the trusted reviewers (/close, /reopen, /label, /unlabel), from main's code only, same list and pause as /nightly.
🤖 Agent: Merged by Ludovic's AI agent (orchestrator). The full pr_ready ran on this exact merge with main: clippy -D warnings, 2325 workspace tests, 365 Python tests, launcher 197, and 116 affected harnesses (114 passed, 0 failed). Verify is green here. rdbtCVS approved. Crate split, priority 1.
With the owner gate in place, a signed-in owner no longer needs another
launcher first (brief mc-download-1, Ludovic 2026-10-27).
- The Play page's Resources row offers an owner "Download and prepare"
and "From my install"; without an owner it asks to sign in first.
- `horizon-launcher prepare --download` does the same.
- Every file from Mojang must have the size and sha1 Mojang lists.
- The download shows its progress and has Cancel; files already whole
are kept, so the next try goes on where it stopped.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A player without an account that owns Minecraft: Java Edition sees one
screen when the launcher opens (once) and whenever Play is refused: why
Horizon needs the account, like other launchers, that worlds, offline
names and settings stay where they are, and Sign in, which runs the
device-code sign-in on the same screen. Not now closes it; Home keeps
its Sign in row, which now opens this screen.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ludovic's decision (2026-10-27). `nightly.py prune-builds` runs in the
scheduled `pick` only, with main's code, and lists each deletion in the run
summary. It deletes only branches named nightly/build-<date>-<n> older than
7 days, never the newest build, and never one a published `nightly` or
nightly-<date> release points to. nightly-state and every other branch are
left alone. tests/test_nightly.py pins it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Like other launchers, the launcher now starts the game only while an
account in it owns Java Edition (Ludovic's decision, 2026-10-27).
- account::launch is the owner gate: it asks the Minecraft services
again (entitlements and profile, after the token renewal), the
selected account first, until one owns the game. Each answer is kept
in the keychain item beside the tokens. No answer (no network) keeps
the last one; "doesn't own" blocks at once.
- Every Play goes through it: the window (Home, instances, packs),
`horizon-launcher play` and `modpack play`, the MCP's play.
- Offline names are added and played only beside an owner; signing the
last owner out keeps them, unplayable.
- Home shows "Sign in with a Microsoft account that owns Minecraft:
Java Edition to play" with Sign in; the "coming soon" sign-in strings
are gone.
- The game binary, harnesses, CI and the servers are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ludovic asked for his top three contributors by merged pull requests: kacpherek, rdbtCVS and Online5277.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: playhorizon's CI runner now skips the harnesses its host entry excludes (remote_fireball, remote_fireworks fail there on bare main from CPU starvation); pr_ready clean, unit test added.
Credential Manager takes at most 2560 bytes per item. The secrets of a
Microsoft sign-in (the refresh token and the Minecraft token) are longer,
so saving them failed on Windows with "password encoded as UTF-16 is
longer than platform limit of 2560 chars" and the sign-in did not finish.
On macOS and Windows a secret is now split over the items `<uuid>`,
`<uuid>.1`, `<uuid>.2`... of at most 1000 UTF-8 bytes each (under 2560
bytes of UTF-16). Reads join the pieces, a write removes the leftovers
of a longer secret, and sign-out removes all of them. Existing single
items keep working.
Co-Authored-By: Claude Haiku 5.5 <noreply@anthropic.com>
Orchestrator's review of #2859: a nightly can hold pull requests nobody
reviewed yet, and their build scripts run in `build`. game-build.yml gets a
`trusted` input, true only from release.yml:
- the Rust cache (GitHub-hosted Linux and Windows): its own key for an
untrusted build (`nightly-<name>`), never saved; a release restores only
what a release saved;
- macOS: an untrusted build's exporters and build jobs run on the runner
that already runs pull requests' parity jobs (macOS + horizon-game), never
the release runner (MAC_RUNNER) nor parity-main's;
- a trusted build doesn't read the machine's shared sccache, which pull
requests' jobs write (runner-env.sh: HORIZON_NO_SCCACHE).
tests/test_nightly.py pins all three.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Ludovic's decision (2026-10-27, from kacpherek's proposal under #2779): the
Nightly is where contributors test pull requests before the gate.
kacpherek, rdbtCVS and levzzz5154 (.github/nightly-reviewers.txt) and
Ludovic pick them with `/nightly 2640 2642`, `add`, `remove`, `clear`,
`status` or `dry-run` in any issue or pull request.
- nightly-command.yml (issue_comment, main's copy): checks who asked, saves
the set on nightly-state, starts `nightly build`, answers "🤖 Nightly: …".
It never checks out or merges a pull request.
- nightly-build.yml: `pick` builds main + the set (newest heads and merged or
closed ones dropped at the scheduled run), pushes it as
nightly/build-<date>-<n>, records it in builds.jsonl; build, sign and
publish are unchanged; `answer` tells the thread how it ended.
- Notes say a Nightly can include pull requests not reviewed yet, picked by
trusted reviewers, and list each with its author and who picked it.
- docs/release-flow.md: who can pick, how, how Ludovic removes or pauses them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
playhorizon's runner fails remote_fireball and remote_fireworks even alone and
at bare main (3b19c386c: 2 of 2 runs and the retry), while the Mac mini passes
them; every fork PR whose parity lands there stopped on them. The host's
exclude list only kept harnesses off workers sent there, not off the runner's
own jobs: platform_skips now adds the local host's exclude, skipped with its
reason unless named. The two harnesses join playhorizon's list; the Mac
mini's runner and the nightly audit (macOS) keep running them.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: Merged by hand by Ludovic's AI agent (orchestrator) after reading the workflows: the union build runs without secrets, a separate job only hashes and signs with a channel-tagged message (release launchers refuse nightly signatures, #2792), and the workflows always run from main. The release dry run on this head (40504185084) is green on every job.
nightly-build.yml builds, once a night, the newest union/<agent>-<name> branch on origin when it is newer than
main and holds something main lacks (else main), and publishes it as the `nightly` pre-release; the previous one
stays a week as nightly-<date> (tools/ci/nightly.py pick/rotate/prune). Launchers ignore it until a player turns
Nightly on (next PR).
The release builds move unchanged into game-build.yml, a reusable workflow both release.yml and the nightly call
from main's copy. The nightly builds with no secrets and the macOS keychain locked; only the sign job holds the
key, and it runs nothing but main's sign_release.sh over the archives, for the message "horizon release nightly".
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The sidebar showed Sculk's wide banner shrunk to 228 px, and its baked-in text could not be read.
It now shows a card made for the sidebar: Sculk's characters and logo cropped from its banner, and
the headline, "Ready in under a minute", a "Get my server" button and the HORIZON15 code drawn by
the launcher, so they stay sharp and follow its language (French and Russian added). Where the
window is too short for the tall card, a compact one puts the characters beside the text. The
Partner label, the 180 s before Hide, the link and the hover lift stay; the Servers page keeps
the wide banner.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: Merged by hand by Ludovic's AI agent (orchestrator) after the contribution gate. rdbtCVS's change request is addressed at this head (checked against the head by contrib-gate-20). Re-review was asked about 07:30Z with no new objection. Proven in wave 5's union run (main + 54 PRs, 332/332 selected harnesses; lan_e2e 18/18 in-frame and on the server thread). Thank you!
packs/pattern.rs is self-contained; atlas_sources reached into packs for it,
one of the edges that keep the client lib in a single cycle. It moves to
horizon-client-core and packs re-exports it under its old path. No
behaviour change.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: Merged by Ludovic's AI agent (Claude, contrib-gate-19). Thanks @kacpherek: mods can now turn on the game's own distant terrain, and Far View is an official mod. I merged main into the branch. render.set-far-terrain is now API level 7, because main added levels 4 to 6 (world, recipes, browser) in the meantime. The horizon-mods sandbox tests (32), the far-view wasm build, and clippy with the mods feature all pass. Without the mods feature, the LOD path is unchanged.
🤖 Agent: verified by Ludovic's AI agent (contrib gate 20): HDR output builds and validates; HDR stays off by default (no HDR display here to see it). It passed in this wave's union with main on the Mac mini: the selected parity harnesses (332/332, then 122/122 on the final union), clippy -D warnings and the tests, and lan_e2e with the host on its server thread and in-frame (18/18 each). Thanks @senjinthedragon!
Key bindings and names, toggle keys, mouse options, controller settings,
the clipboard and window options move to their own crate, re-exported under
their old paths. Their unit tests now rebuild in about a second after an
edit instead of rebuilding the client lib's test binary.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
render.set-far-terrain moves to API level 7: main added levels 4 to 6
(world, recipes, browser) since this branch started.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On playhorizon's runner (CPUs 4-7, 4 harness slots, frames drawn on the CPU)
remote_fireworks still failed in #2215's job after #2589 and #2629: a
screenshot took ~1.5 s (58 ticks for two) beside three other harnesses. The
harnesses in parity_hosts.json's new solo list run alone there, after the
others; bigger machines are unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>