A camera shown only as the screen's own view was never prepared: the note
required a non-empty picture list. Two runs picking the same local id both
claimed the screen's frame, though only the first one's camera was drawn
from it. The client now notes whether the frame was a world frame and the
(run, camera id) the screen's world was drawn from, so the main-view
milestone belongs to the run whose selection the screen used, and a title
or loading frame reports the path off without erasing earlier milestones.
A world transition clears the submission, the main-view selection and the
milestones: another world's cameras are not drawn. A camera given to
set-main-view drops its picture target, so its milestone starts over until
a frame is drawn from it. prepared stays a host-side encoding milestone,
not target registration, not a GPU fence, not a visible pixel.
Also gate the client's note on the `mods` feature: without it the default
horizon-client build did not compile.
Verified: horizon-mods 37 unit, 44 sandbox (1 ignored; real Wasmtime
guests, the two-run test shows each id 7 follows only its own pictures and
selection) and 4 api_reference; client checks and build with and without
`mods`; gfx lib tests.
Co-Authored-By: Kimi Code <noreply@moonshot.cn>
API 30 adds render.camera-status: availability, the last noted frame's
mod-camera picture path, the calling run's accepted set-views submission
for this world generation, and per-camera prepared flags. A camera is
prepared when the renderer encoded its picture into the texture target
in a real frame of this generation, or a world frame rendered from it as
the set-main-view selection: a host-side encoding milestone, not target
registration, not a GPU fence, not a visible pixel. An empty set-views
clears the request; a resubmission, world transition or mod reload waits
for a new frame. The renderer reports the pictures it drew each frame;
the game notes the frame after a successful render. Verified with two
real Wasmtime guests sharing local camera id 7: each run's readiness
follows only its own submission and main-view choice, and a world
transition resets both.
Co-Authored-By: Kimi Code <noreply@moonshot.cn>
Preserve AirDef replay lighting and acoustic commands while retaining upstream shadow and HDR fixes. Give the two entity shadow shaders distinct entry points.
Co-Authored-By: Codex <noreply@openai.com>
🤖 Agent: read the diff at 5096b4110: launcher offline names: Forget also deletes the name's skin and cape files, async skin picks bail if the name was forgotten meanwhile, account rows load-mutate-save, and "New name" rolls a fresh PlayerNNNNN into every game home. Tests included. verify and launcher green; no harness reaches launcher code. Queued for the merger, which waits for this head's parity run.
A server thread (single player's, a LAN host's, a dedicated server's) ran
`streaming.update` once a tick, and `schedule_generation` keeps at most
three load or generate jobs per worker in flight. Joining a world was
capped at about six columns a tick (120 a second with two workers) while
the workers idled most of each tick. Vanilla's server runs its chunk
tasks while it waits for the next tick (`MinecraftServer.waitUntilNextTick`).
`pump_pregen`, now `pump_chunks`, already did that for a /pregen task and
force-loaded chunks; it now also pumps while the players' chunks are in
flight, except while the server is paused or a respawn search waits for
a chunk (its area is only asked for by the tick's own update).
Mac mini, --profile fast, offscreen, seed 1234, RD 12, server thread,
medians of 3, all 637 view columns in and meshed once:
2 workers: create 8.05 -> 3.57 s, reload 3.72 -> 1.42 s
4 workers: create 4.97 -> 2.16 s, reload 2.23 -> 1.27 s
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: proven with a real launcher GUI run in isolated dirs (Settings → Native mods row, red warning naming veinminer 0.3.0, trust → cached build reused, status line); launcher clippy and 265 tests green; #3194 merged and this now targets main with only its own 5 files. Verify green at 505de825.
🤖 Agent: proven with a real launcher run in isolated dirs: registry install of Veinminer's .hnmod into an instance, native-build of that instance's enabled native mods, instance pinned to the build; launcher clippy and tests green after merging main (#3140 and #3189 merged). Verify green at 1f6511d0.
The Team tests fixes on the Nightly and hit the cap of 6 builds a day
(Ludovic, 2026-10-28: raise it to 12).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: merging: native-build compiles horizon-mixins bundles on their pinned Nightly with the launcher's own Rust; proven by building levzzz's Veinminer .hnmod on 83f15fa (580 s cold, 2m46s warm) and /veinminer answering in the built game.
- native-mod entries (levzzz5154's #3140) are listed as mods and install as
horizon-native-mods/<id>.hnmod (the folder #3112's inventory reads), turned on in
horizon-mods.txt, after the .hnmod is checked as the registry checks it.
- native-build with no folder builds the native mods turned on in the instance, and that
instance then plays the build (the game's own home builds into the Native mods instance).
- Every registry project says who made it; a project not made by Horizon says it is not made
or endorsed by the Horizon project, with the mod policy's link (playhorizon.dev/mods/policy).
A native mod says it runs with full access to the computer and which Horizon it builds on.
- Pruning keeps every native build an instance plays.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: merging: nightly publishes horizon-source.tar.gz (signed) and tags its commit nightly-source/<date>-<short>; proven by a full dry run of the workflow (run 40686585965) and tests/test_nightly.py.
horizon-launcher native-build FOLDER --trust-native-code compiles mixin bundles (a folder with a
horizon-mixin.toml, or an unpacked .hnmod from the registry) into a game of their own:
- the Horizon commit the mods pin (all must agree; else the installed version's), its source from
GitHub by commit (Nightlies keep theirs as nightly-source/ tags);
- horizon-mixins at the commit the mods were tested with, built once with the launcher's Rust;
- horizon-mixins apply, then the release's cargo build, with the portable toolchain;
- installed as native-<commit>-<key>, played by the Native mods instance.
Based on native-mixins-1's unmerged work; docs/native-mods.md describes it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Native mods compile the game on the player's computer (levzzz5154: many native mods per build). The
launcher now downloads the official rustc, cargo and rust-std components of Rust 1.99.1 (plus
rust-mingw on Windows, the windows-gnu host that needs no Visual Studio) from static.rust-lang.org,
each pinned by SHA-256, into <launcher data>/rust/, and runs them with its own CARGO_HOME. No rustup,
nothing installed on the system. `horizon-launcher rust status|install|remove`.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The nightly release names its commit, and now also attaches horizon-source.tar.gz (git archive of that
commit, made from git objects in pick and signed with the builds) and tags the commit
nightly-source/<date>-<short>. The dated release and the nightly/build-* branch are pruned after 7 days;
the tag is not, so native mods pinned to a Nightly's commit keep building.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The Horizon Team merges ordinary pull requests once verify and parity pass; saves, network, world generation,
launcher updates, the harnesses and big changes wait for a local proof. Also names the licence holder with the
contributors.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep main's owner check (play_as takes the store, Sign out updates
the owner state) with the branch's load-mutate-save and skin cleanup.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 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.