🤖 Agent: Gate check by Ludovic's AI agent (Claude). I checked CushionItem.useOn and Cushion.interact against the 26.3 bytecode with rea_vanilla and pushed three leftovers. (1) An occupied cushion now returns PASS, as Cushion.interact does. (2) A cushion placed in fire burns at once (destroyIfInFire). (3) Placing always posts the entity_place game event before consuming the item. I also merged main into the branch (lan_e2e.py). The suffocation check matches vanilla's block definitions except closed shulker boxes, which are approximated as always suffocating (noted in a comment). Integration tree: `lan_e2e --check cushions` passes in-frame and on the server thread, and the `cushion_placement` and suffocation harnesses pass. Thanks @ESHAYAT102!
🤖 Agent: Gate check by Ludovic's AI agent (Claude). The launcher contacts no new host: the existing requests (releases, Mojang files, Modrinth, CurseForge, the mod registry, pictures, Microsoft sign-in, Tailscale's API, modpack jars) now go through the player's HTTP proxy, or HTTPS_PROXY/HTTP_PROXY/ALL_PROXY when unset. Loopback and NO_PROXY hosts stay direct, and the Servers page's local API never uses the proxy. Tokens (Microsoft, Tailscale) only cross the proxy inside TLS (CONNECT), so the proxy can't read them, and none are logged. rdbt's NO_PROXY review is addressed: `horizon-port-pack`'s agents apply the same rules (`no_proxy_lists_hosts_and_their_subdomains`). On Linux at da54f988d: launcher lib tests 132 passed, `cargo clippy --all-targets -D warnings` clean, `horizon-port-pack` 68 tests passed and clippy clean. Labelled feature. One small note for later: an unusable proxy address is printed to stderr as typed, so a `user:pass@` in it would show in the log. Thanks @zhykowo!
🤖 Agent: Gate check by Ludovic's AI agent (Claude). `tools/bundle_tooltip_e2e.py` passes in-frame. On the server thread (what players run) it showed every bundle full, holding more bundles, so I pushed two commits: (1) BundleContents' stream codec (component 52, a list of ItemStackTemplate, checked with javap) plus sending it to clients in `network_stack`; (2) `Hub::stack` gave every stack inside an item the outer item's id, which also turned a crossbow's charged projectiles into crossbows on clients. It is fixed now: each inner stack looks up its own id. With both commits the e2e passes on the server thread and in-frame (306 px tooltip frame; main shows 117 px and fails). The screenshot shows 32 stone with a half-full bar, as in vanilla. Unit tests: `bundle_contents_are_item_stack_templates` and `a_bundle_keeps_its_contents_across_the_wire`. Thanks @levzzz5154!
🤖 Agent: Gate check by Ludovic's AI agent (Claude). I checked the loot functions against vanilla 26.3 directly. A vanilla server placed 48 chests with fixed LootTableSeed values: 16 tables (end city, stronghold library, ancient city, mansion, dungeon, trial chamber rewards and more) times 3 seeds, then rolled them. Horizon then opened the same world. Every chest got the same items, counts, slots and enchantments as vanilla, enchant_randomly and enchant_with_levels included: 48/48 on the server thread and 48/48 in-frame. The only difference is the order of keys inside the enchantments map, which vanilla doesn't read. EnchantRandomly and EnchantWithLevels match the bytecode, and rdbt's single-level review point is covered by `a_single_level_enchantment_draws_no_level`. It is also built and run in an integration tree with the other open PRs. Thanks @levzzz5154!
Hub::stack resolved every item id of a stack to the outer item's, so a
bundle's contents and a crossbow's charged projectiles reached a server's
clients as more bundles and crossbows. The tooltip then drew a bundle of
bundles, full. Each stack inside now looks its own id up.
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.
linux-runner.sh takes its packages from apt where there is no Nix, the
registration token from RUNNER_TOKEN (a machine where gh must not be logged
in), and RUNNER_CPUS / RUNNER_MEMORY for a machine that does nothing else.
playhorizon, a partner's 8-thread server, joins parity_hosts.json.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: Gate check by Ludovic's AI agent (Claude). The server fix in this PR landed first in #1779 (levzzz's PR, same change to `hub.rs` and `agent.rs`, with the same `lan_bot` test). I merged main into the branch and kept main's side, so what this PR now adds is its two unit tests: `sprint::tests::sprint_survives_releasing_the_key_through_a_jump` (the client sprint state survives the key coming up on the jump tick) and `living_motion::tests::sprint_jump_adds_look_direction_impulse` (LivingEntity.jumpFromGround's 0.2 impulse along the look, and none for a walk). Both pass, and `lan_e2e --check sprint-fov` passes in-frame and on the server thread in the integration tree. Labelled skip-release, because players see no change. Thanks @mc070309 for tracking the cause down and for the tests.
🤖 Agent: Merging. verify and parity passed; the new unit test covers the merge of both key forms, and save_roundtrip no longer sees duplicate RecipesUsed keys.
bf81ae635 started saving recipes_used, but Horizon's recipe ids lack the
minecraft: namespace, so a furnace could hold both forms of one id and
vanilla refused it with "Duplicate entry for key" (save_roundtrip).
recipe_used_key gives the full id; loading merges the two forms from saves
written in between.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: Merging. verify passed, along with launcher tests (11 registry tests), the horizon-theme icon test and clippy -D warnings. #2173, which it was stacked on, is merged.
🤖 Agent: Merging. verify and mod-registry passed, and pr_ready --quick passed (clippy, horizon-mods and launcher tests). The index's downloads field is optional, so the schema doesn't change.
🤖 Agent: Merging. verify passed and the website tests (44) pass. Ratings appear once #2167's service is live; until then the pages show downloads only.
🤖 Agent: verify and parity pass (109 harnesses affected; parity green). The dedicated-server e2e (tools/quiet_commands_e2e.py) passes 7/7. Queued. #2171 (the mod API, stacked on it) follows once this lands.
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @lazy-importer!
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @levzzz5154!
Horizon results and project pages show a project's rating from the
registry service (GET playhorizon.dev/api/mods/ratings, fetched with the
results, kept ten minutes): five pixel stars, the mean and how many, or
"No ratings yet". Nothing shows when the service doesn't answer.
The launcher has no GitHub account, so a project's page offers "Sign in
with GitHub to rate": it opens the site's sign-in, which comes back to the
project's page and its stars (one rating per GitHub account).
HORIZON_MOD_RATINGS (a file or https:// address) points a test registry at
its own ratings. The star icon is drawn for Horizon on the icons' grid.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @Domanffe!
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @Domanffe!
Main's #1779 already keeps the sprint through PlayerInput (hub.rs, agent.rs)
and has the same lan_bot test, so this keeps main's side: what the branch adds
is the two unit tests.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @Domanffe!
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>
Checked against the 26.3 bytecode (tools/rea_vanilla.py):
- Cushion.interact passes (PASS) when the cushion already has a rider;
CONSUME is only for a startRiding that fails.
- CushionItem.useOn calls destroyIfInFire right after addFreshEntity, and
posts GameEvent.ENTITY_PLACE from the player.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @Domanffe!
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @levzzz5154!
- The list shows each project's rating (stars, mean and count) and its
downloads ("12.3k downloads"), ordered by downloads by default; an Order
menu also sorts by rating or name (?sort= too).
- A project's page shows the same, then a rating control: five stars when
signed in (the account's own rating lit), "Sign in with GitHub to rate"
(coming back to the page) when not, a note for its owners.
- Ratings come from the registry service's GET /api/mods/ratings; a rating
is POSTed with the session's CSRF token. Until the service answers, the
pages show downloads only.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @Domanffe!
BundleContents had no stream codec here: the host never sent what a bundle
holds, so on the server thread, LAN and a dedicated server the new tooltip
showed every bundle empty, and a vanilla server's bundle made its packet
undecodable. Its STREAM_CODEC is a list of ItemStackTemplate, the same as
ChargedProjectiles' (component 52).
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @kacpherek!
The registry service keeps players' ratings of published projects in one
SQLite file on a volume (REGISTRY_DB, /data on Railway):
- GET /api/mods/ratings: every rated project's average and count, cached a
minute; never who rated.
- GET /api/mods/{id}/rating: the signed-in account's own rating.
- POST /api/mods/{id}/rating: sets or changes it, checked like a submission
(origin, session, CSRF token), 30 per account and 600 in all per hour, only
for projects on the registry's main, never by their owners.
- The sign-in takes ?back=/mods/<id> to come back to a project's page.
The image hands the volume to nobody before running as nobody.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @nirajkhetre!
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @Domanffe!
Twice today (runs 40301239508, 40311712302) mob_ai failed in parity-main, passed when bisect ran it again at
the same HEAD, and the run still ended red, so no game release could follow main for three hours. The
harness step now continues on error and the bisect step gives the verdict: 0 when every failed harness
passes again at HEAD, 1 when they fail at the base too or a merge is named.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @vlesmentie!
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @Domanffe!
🤖 Agent: pr_ready passed (horizon-world and client tests, affected harnesses), lan_e2e passed in-frame and on the server thread. GeneratorData::load on the ThinkPad 0.64 → 0.45 s warm. Queued for merge.
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @Domanffe!
🤖 Agent: contrib-gate-17 verified this head (integration tree build, clippy, tests, parity; details in the PR comment). Re-opened from kohad1ck's PR; thanks to kohad1ck.
🤖 Agent: contrib-gate-17 verified this head (integration tree build, clippy, tests, parity; details in the PR comment). Re-opened from kohad1ck's PR; thanks to kohad1ck.
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @levzzz5154!