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>
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>
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>
A mod can now turn on the game's distant terrain (LOD) with
render.set-far-terrain: a distance of 64 to 1024 chunks and Far Detail's
Reduced. The game builds and draws the tiles as it does for the LOD
Distance setting, which wins while it is on. One far terrain shows at a
time, the first loaded mod's. API level 4.
mods/official/far-view is the official mod on it: Distance (256 chunks by
default) and Far detail on its settings page, kept in its storage.
As the creative inventory does: a count over the item's stack size (64, 16
or 1) is cut to it, so a mod can ask for a full stack without knowing it.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
recipes.place(book-id, all) is the recipe book's click: in the open
inventory's or crafting table's grid it sends ServerboundPlaceRecipePacket
on a server, or places it in this world, refused as handlePlaceRecipe
refuses it (no crafting screen, a recipe the player's book doesn't hold, an
impossible one); a recipe missing items shows as a ghost. recipes.give(stack)
gives a creative player the stack as the creative inventory does; a server
hears it as SetCreativeModeSlot through the inventory's sync. Both answer at
once from the tick's snapshot (placing, creative, known) and take at most 36
calls a hook call.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mod gives the recipes to show (a layout: crafting grid, cooking, single
input, smithing or brewing; the slots, each cycling through its stacks;
the results; a note; and an optional action button, enabled or greyed)
under a title; an empty list shows the items again. The game pages them
and sends the slot-clicked, action, page and back events.
At most 256 recipes, 9 slots each and 64 stacks a slot. Same level as the
rest of browser (5): none of it has shipped yet.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A new interface under capability ui. browser.set-items lists the items of
a panel the game shows right of the inventory and container screens (an
empty list hides it); browser.poll returns what the player did since the
last poll: a click on an item, the search text, or one of the mod's own
keys pressed over an item (a slot's or the panel's), with that stack. The
slot-clicked, action, page and back events are there now for the recipe
pages to come, since adding variant cases later would break mods.
At most 8192 items and 256 waiting events. The game side is the next PR.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: merged main to resolve a conflict in game/remote.rs (main's boss-overlay reset beside this PR's QuietCommands event; both kept). Clippy with mods on is clean. Requeued at the new head.
#2171 takes level 3 (command.run-quiet), so the world interface's functions
take level 4. The workspace members keep main's horizon-hdr and this branch's
beacons example.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
playhorizon.dev now deploys from the private ludovic111/horizon-site, which holds website/'s history. The files
its build still reads from here move out of website/:
- the design tokens to crates/horizon-theme/tokens.css (xtask tokens writes them, tokens_css_is_up_to_date checks them);
- the roadmap's JSON to roadmap/roadmap.json (tools/roadmap.py build);
- the benchmark fixtures to crates/horizon-telemetry-server/tests/fixtures/benchmarks/ (the site keeps a copy);
- the web icons to docs/media/brand/web/ (xtask icons).
pr_ready loses its website area and the tokens special case; rust_changes, the roadmap's links and every doc
that pointed into website/ follow.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
recipes.items() lists every item in registry order, with its name in the
player's language and its tags. recipes.all() lists every recipe: crafting
and furnace ones from the recipe book's own entries (vanilla's displays and
display ids), then campfire, stonecutting, smithing and brewing (display
only). Stacks point into the item table by index. recipes.known() gives the
book ids the player's recipe book holds, from the client book in every mode,
so on a server it follows the server's book.
The game builds the tables once, the first time a running mod reads them.
Experimental, new functions only. Smithing::Transform now keeps its recipe
id.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: merged main (aec52c85e). pr_ready --quick passes (1308 horizon-client tests, clippy, 507 LOC). The welcome server mod e2e passes 35/35 in every mode: in-frame, server thread, LAN host in-frame and on its thread with a guest, dedicated with a guest. Verify is green; parity now runs on main (parity-scope). Queued.
The registry's publish job (ludovic111/horizon-mods#7) writes each
project's `downloads` into index.json, summed from GitHub's counts of its
release assets every hour. `index::Project` reads it (absent: 0, never
written when 0, so older readers and the schema are unchanged).
The launcher's Horizon results show "12.3k downloads" like Modrinth's, and
list the most downloaded first.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A mod hands `run-quiet` a list of lines (at most 256 a call). In single
player they run as the player typing them would, with the player's source
made silent; on a Horizon server (it announces horizon:quiet_commands) they
go as one payload that the server runs the same way; on any other server
they fall back to chat commands, whose feedback shows. command.run is
unchanged.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: verified: pr_ready --quick green at this head, 33/33 affected harnesses pass locally, CI verify green, A/B shows no frame cost without a pack. A Horizon shader pack's material stage now colours terrain in the game.