Commit Graph

657 Commits

Author SHA1 Message Date
Ludovic Marie f7170d6b9f Merge pull request #2045 from ESHAYAT102/fix/creative-tool-block-breaking
🤖 Agent: Gate check by Ludovic's AI agent (Claude). Item.canDestroyBlock in creative (swords, maces and tridents can't break blocks) matches the 26.3 bytecode, on the player's prediction and on the server. On the integration tree, `lan_e2e --check creative_tools` passes in-frame and on the server thread, and the new `creative_mining` harness passes against its oracle. I merged main into the branch twice; the second time, lan_e2e.py and the probe list keep both sides, every def checked against its source branch, and client_probe and the bins compile. Fixes #2035 is right. Thanks @ESHAYAT102!
2026-10-26 17:09:09 +01:00
Ludovic Marie 7ace1e9e8f Merge pull request #2076 from RoyalPixelsDE/fix/structure-starts-2-templates
🤖 Agent: Gate check by Ludovic's AI agent (Claude). Template pieces now save as vanilla's TemplateStructurePiece does. Checked with a vanilla save of a generated world (overworld, Nether, End) taken through Horizon and back to vanilla 26.3 on the server thread and in-frame. On an integration tree with the whole stack, `save_roundtrip`, `world_reopen`, `chunk_generation`, `structure_start_nbt`, `structure_blocks`, `structure_layout`, `trial_spawner` and `vault` all pass. Thanks @FusselTV!
2026-10-26 16:48:38 +01:00
Ludovic Marie 402b8dc01e Merge main (lan_e2e.py and the probe list keep both checks and probes)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:39:28 +01:00
Ludovic Marie 625c4c559e Merge main into the creative tool mining fix
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 16:10:15 +01:00
Ludovic Marie 9540734e29 Merge main into fix/cushion-placement
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 14:50:57 +01:00
Ludovic Marie 6ee319c607 Merge pull request #2018 from rdbtCVS/fix/peaceful-mob-despawn-1942
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @rdbtCVS!
2026-10-26 13:55:47 +01:00
Ludovic Marie fc5cd8060d Merge pull request #2007 from rdbtCVS/fix/1962-passenger-animation
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @rdbtCVS!
2026-10-26 13:55:12 +01:00
Ludovic Marie 9feb4da17c Merge pull request #2003 from rdbtCVS/fix/bat-wing-animation-2000
🤖 Agent: contrib-gate-17 verified this head (26.3 sources, integration tree build, clippy, tests, parity; details in the PR comment). Thanks @rdbtCVS!
2026-10-26 13:51:59 +01:00
Ludovic Marie 6a7951e150 mob_ai oracle: create a Peaceful scenario's hostile mobs past canSpawn
EntityType.create returns null for a type that isn't allowedInPeaceful once
the difficulty is Peaceful, so the peaceful_* scenarios threw in the oracle.
Their mobs stand for ones already in the world when the difficulty changed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 13:09:28 +01:00
Ludovic Marie 5d04a5bee8 Merge remote-tracking branch 'origin/main' into fix/harness-await-flakes 2026-10-26 12:04:32 +01:00
Ludovic Marie c048292f3f Merge pull request #1909 from rdbtCVS/t3/server-thread-integration-clean
🤖 Agent: gate verified on e3e08911b (main merged). fmt, clippy -D warnings and horizon-client tests pass. lan_e2e with the server-thread host: 131/133, and cursor/falling pass on rerun in both modes. 14 in-frame checks pass. agent_control_e2e: only manage fails, and it fails the same way on main. 82 of the 83 affected harnesses pass. lan_integration flakes under load and is now named-only (nightly). Queued.
2026-10-26 11:47:59 +01:00
Ludovic Marie 34d8d94022 parity: server harnesses wait on the server's clock and replies, not on sleeps
server_knockback, locator_bar, server_dimension_players and their one-player users now end a step by the server's
game clock (a sync round trip, N ticks, a last sync) the way server_player_targets does, so a server that stalls
under load still gets all its ticks inside the step. server_knockback's frozen section waits for the stepped tick,
the stopped clock and the landed hit; dedicated_server waits for the player's leaving before /list.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-26 11:06:02 +01:00
FusselTV c776d6586e Structures: save jigsaw starts as StructureStart.createTag does
Horizon kept no saveable form of its structure starts, so its saves carry
an empty structures.starts and every structure it generates is invisible
to vanilla and Paper (locate, structure spawns, location predicates,
advancements) and cannot be continued past the generated area.

StructureStart::save and Piece::save write the tag vanilla writes. This
covers the pieces of jigsaw pools (villages, pillager outposts, ancient
cities, trail ruins, trial chambers, abandoned camps, bastions) with
their pool element, junctions and liquid settings. Junctions keep
delta_y and dest_proj, pool elements their processors as written.
LegacyPiece::save defaults to None; a start with such a piece is not
saved, as before.

test_structure_start_nbt_parity compares the tags with the pinned
server's own for one site of every jigsaw structure kind.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 09:33:34 +01:00
Ludovic Marie 6c3473c6e0 Official mod: Minimap
The minimap extra as a mod (mods/official/minimap): the extra's five
options on its settings page, kept in its storage with the extra's values
(corner, size, shape, zoom, rotate), and the map drawn by the game
through render.set-minimap, so it looks and costs the same.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 08:40:03 +01:00
Eshayat Al-Wasiu f4b04218f1 Implement cushion placement and synchronize placed cushions
Add cushion entities, shape-based placement and support checks, colored rendering, server tracking, sitting, destruction and save/load support. Compare placement rules against vanilla and exercise host/guest interactions.

Co-Authored-By: OpenAI GPT-6.1 Sol <noreply@openai.com>
2026-10-26 13:29:16 +06:00
Eshayat Al-Wasiu d422564ab3 Respect tool restrictions on Creative block destruction
Check the tool component before server destruction, local mining and remote prediction. Cover vanilla item defaults, overrides and mode-switch cancellation.

Co-Authored-By: OpenAI GPT-6.1 Sol <noreply@openai.com>
2026-10-26 13:16:45 +06:00
Ludovic Marie c8d75a7892 Merge main into feat/official-zoom-mod
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 07:24:16 +01:00
Ludovic Marie 8fdb27f949 Zoom: the game lists its key on the settings page, as "Zoom key: Z"
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 05:47:15 +01:00
rdbtCVS 03a3c48a71 Fix Peaceful removal of existing hostile mobs
Apply the vanilla Mob.checkDespawn Peaceful gate before persistence and player distance checks. Extend the mob AI parity harness with difficulty, persistence, name-tag and NoAI regressions and allowed-type controls.

Fixes #1942

Co-Authored-By: OpenAI Codex (GPT-6.1 Sol) <noreply@openai.com>
2026-10-26 04:18:54 +00:00
Ludovic Marie 0cb1d46393 Merge main into feat/official-hud-mods
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 05:09:45 +01:00
Ludovic Marie 53289d3565 Official mod: Zoom, the zoom extra as a mod
mods/official/zoom: hold the key (Z) to zoom in at the starting zoom,
the wheel changes it while held (x1.25 a step, 1.25 to 10), smooth
easing and slower turning as options. Same settings page as the extra,
with the key widget for the key. Built on render.set-zoom,
input.claim-wheel and ui's key widget.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 05:08:36 +01:00
Ludovic Marie ab92ab346c Merge remote-tracking branch 'origin/main' into cg15/1909 2026-10-26 05:06:59 +01:00
Ludovic Marie 980c619b81 Merge feat/mod-api-extras (with main) into feat/official-hud-mods
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 03:20:09 +01:00
rdbtCVS 4cc134d08a Fix passenger walk animation in shared render state
Zero passenger walk position and speed like vanilla LivingEntityRenderer, covering local and remote riders. Extend entity model parity with moving passenger and on-foot render-state cases.

Fixes #1962

Co-Authored-By: Codex GPT-6.1 Sol <noreply@openai.com>
2026-10-26 02:13:12 +00:00
rdbtCVS 15d99a6856 Start bat animation clocks on server clients
Fixes #2000.

Co-Authored-By: OpenCode GPT-6.1 Sol <noreply@openai.com>
2026-10-26 02:11:48 +00:00
Ludovic Marie dd1581c062 Merge remote-tracking branch 'origin/main' into cg15/1965
# Conflicts:
#	crates/horizon-prepare/src/lib.rs
2026-10-26 02:44:23 +01:00
rdbtCVS f45e3f1237 Optimize launcher preparation with precompiled, batched exporters
Compile and validate original exporter bundles during release builds, cache development compilation, and reuse initialized JVMs and collision data during preparation. Keep legacy preparers compatible while current releases need only a Java runtime.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-25 23:11:23 +00:00
Ludovic Marie fbd6bee3e3 Official mods: FPS Counter and Keystrokes, the first extras as mods
The FPS counter and keystrokes extras rewritten as mods on the public API
(render, input, ui, storage), in mods/official/, with the extras' options
on their settings pages and the extras' look: the same boxes, colours and
text positions, pixel for pixel. They are workspace members, so clippy and
pr_ready cover them; a maintainer publishes them in horizon-mods. The
built-in extras stay until the removal PR, which installs these for the
players who had them on.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-26 00:08:55 +01:00
rdbtCVS 0b49da2466 Fix lead drops when leashed mobs die
Follow Leashable.tickLeash for dying mobs and cover trader/player-held llama leads through the death animation.

Co-Authored-By: Codex <noreply@openai.com>
2026-10-25 22:07:58 +00:00
Ludovic Marie 31e9e2da97 Merge origin/main into fix/item-lore-tooltips
In stack_tooltip keep #1806's translate through `display_get` and this
PR's `push` helper for the styled tooltip lines.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-25 22:26:10 +01:00
rdbtCVS bd09f8b03e Migrate player integration coverage to server-thread hosting
Co-Authored-By: OpenAI Codex GPT-6.1 <noreply@openai.com>
2026-10-25 19:36:11 +00:00
Joansitoh 90eda915d5 Add a lore tooltip harness against ItemLore.addToTooltip.
The styled lines have to keep matching vanilla, including an explicit non-italic span and a lore component hidden by tooltip_display.
2026-10-25 18:58:52 +01:00
Ludovic Marie 75951a769a Merge #1847 into #1849: LocatorBarClient's respawn and use commands, the harness scaffold
The three harnesses add commands to the same LocatorBarClient lines;
this branch now builds on #1847 (itself on #1843), keeps all three
commands, and test_cursor_death_parity.py runs through
locator.one_player.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 17:27:31 +01:00
Kacpherek 5bfc649edd Drop the cursor stack of a dead player
A stack held on the inventory cursor at death stayed there through the
respawn, even with keep_inventory off. In vanilla the dead player is
removed 20 ticks after dying (or when it respawns sooner), and
Player.remove's inventoryMenu.removed drops what the cursor held where
the player died. Do the same for server players and the in-frame
player, and add a harness that dies with a cursor stack on a dedicated
server and compares with vanilla.
2026-10-25 16:09:09 +01:00
Kacpherek 10efca9e6c Discard a dead player's ender pearl when the rule says so
With ender_pearls_vanish_on_death on, a pearl thrown just before death
kept flying and pulled the respawned player back to it. Vanilla's
ThrownEnderpearl.tick discards the pearl instead of ticking it while
its owner is dead. Add a harness that throws a pearl, dies and respawns
on a dedicated server and compares the teleports with vanilla's.
2026-10-25 16:05:52 +01:00
Ludovic Marie 6a32ee68d4 Merge pull request #1725 from RVZO6/feature/text-display-rendering
Client: render server text displays and lobby labels
2026-10-25 09:07:59 +01:00
Ludovic Marie 0e73edceff Merge pull request #1718 from RVZO6/feature/text-display-state
Client: model text-display metadata against the Java wire codec
2026-10-25 09:07:02 +01:00
Ludovic Marie b149a0ec3f Merge main into fix/stop-sound-packet: keep both sides' appended checks
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>

# Conflicts:
#	tools/lan_e2e.py
2026-10-25 08:51:09 +01:00
Ludovic Marie 6b88291009 Merge pull request #1631 from some-du6e/fix/item-components 2026-10-25 08:21:58 +01:00
Ludovic Marie 6acf7fb6ab server_player_targets harness: end each step by the server's clock
Each step waited a fixed 2.5 s. When the machine is loaded the vanilla server stalls for longer than that (CI on
#1571 and #1585: after Bob's trip to the Nether, vanilla's `tp Bob 4.5 -60 0.5` from the console ran a step late),
so its packets were filed under the next step and the transcripts differed although both servers sent the same.

A step now ends once the server has done its work:
- the console's own `time query gametime` comes back, so the step's console commands have run (the console runs
  its queue in order);
- LocatorBarClient's new `sync NAME` runs `time query gametime` as that player and waits for the reply (not
  recorded), so that player's commands have run and every packet sent before the reply is recorded;
- the server's game time has advanced STEP_TICKS (40) more ticks, then each player sends its position reminder
  and syncs once more.

game_time() moves out of settle() in test_dedicated_server_parity.py so both use it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-25 05:46:22 +01:00
RVZO6 07519df062 Handle server stop-sound packets through the existing sound engine
Decode source/event selection flags, including 26.3 UI source 10, and route them to Audio.stop_sounds. Compare all 36 native Java codec selections and round-trip their bytes; reject invalid sources and truncated packets.

Co-Authored-By: Codex (gpt-6.1-sol) <noreply@openai.com>
2026-10-24 23:23:59 -04:00
RVZO6 792ac58f46 Render server text displays with billboard transforms and styled glyphs
Apply metadata, lifetime and position/transform interpolation; render wrapped/aligned text, background, opacity, shadows, brightness and see-through flags. Upload dynamic font glyphs and expose actual emitted vertices for end-to-end checks. Verify 108 matrices with the native client renderer and exercise a real Java-server/Rust-client fixture.

Co-Authored-By: Codex (gpt-6.1-sol) <noreply@openai.com>
2026-10-24 23:10:47 -04:00
RVZO6 dc1e16f472 Model every text-display metadata field against the Java wire codec
Add a native Java oracle for the actual Display/TextDisplay accessors and encoded metadata, with 513 combinations of flags, opacity, billboard mode and transforms. Preserve styled text and partial updates.

Co-Authored-By: Codex (gpt-6.1-sol) <noreply@openai.com>
2026-10-24 22:52:51 -04:00
some-du6e 9223b401e7 Decode every item data component a server sends
Horizon decoded 25 of 26.3's 122 data component types. Item data has no
length prefix, so a stack with any other component (an armour trim,
banner patterns, pot sherds, a stew's effects, a plugin's item) made the
whole packet undecodable and it was dropped: on a Paper server the
inventory arrived empty until each slot was clicked, the advancements
screen said "There doesn't seem to be anything here..." and the recipe
book was empty.

Every other component is now read to its end with its vanilla
StreamCodec (item/skip.rs) and kept as its bytes, written back as they
came; components without a network codec go as their NBT. The client
leaves them out of the item's components, so the item keeps its
prototype's values for them.

tools/test_item_wire_parity.py checks it against vanilla: the oracle
encodes 374 stacks with ItemStack.OPTIONAL_STREAM_CODEC (every default
component value of every item, SNBT fixtures for the rest, direct
holders and removals built in Java), covering all 122 component types,
and the Rust probe must consume every byte, find the same component ids
and encode the read-past ones back to the same bytes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 12:20:45 -06:00
Ludovic Marie ccb827282b Merge remote-tracking branch 'origin/main' into pa1/gate-1558
# Conflicts:
#	docs/vulkan.md
#	mods/horizon/src/main/java/dev/horizonlab/client/HorizonClient.java
#	mods/horizon/src/test/java/dev/horizonlab/client/DistantTerrainSettingsTest.java
#	mods/horizon/src/test/java/dev/horizonlab/metrics/ClientGraphicsIntegration.java
#	packs/START-HERE.txt
#	packs/mods.lock.json
#	tests/test_fixtures.py
#	tests/test_packs.py
#	tools/Compare-Benchmarks.html
#	tools/build_pack.py
#	tools/compare_benchmarks.py
#	tools/test_client_graphics.py
2026-10-24 18:47:57 +02:00
Ludovic Marie 71292d2ed7 Merge pull request #1562 from ludovic111/feat/server-pack-status 2026-10-24 18:12:16 +02:00
Ludovic Marie ab8b379097 Dedicated server: offer server.properties' resource pack as vanilla does
ServerResourcePackConfigurationTask: after the tags, the configuration phase
sends the pack (id from the URL when none is given, hash, required, prompt)
and waits for a final answer, with keepalives every 15 s. A declined required
pack disconnects with multiplayer.requiredTexturePrompt.disconnect, in
configuration or in play, with vanilla's log lines.

tools/test_server_resource_pack_parity.py drives a vanilla 26.3 server and
Horizon's with the same five players (declines, accepts then declines in
play, fails the download, answers after 20 s, declines an optional pack) and
compares what each one receives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:21:53 +02:00
Ludovic Marie 4e7c25bb55 Remove shader packs
A developer of Iris showed that Horizon's shader pack code was written from
Iris's source. This removes it: the horizon-shaderpack crate, Java pack
loading and its render stages, Horizon's own WGSL packs and the example
packs, the Shader Packs screen and its option, the launcher's shader pack
browsing and installing, and the docs about them. Shader packs may come
back later as a clean-room rewrite.

The vanilla renderer and its post-processing (resolution scale, FXAA) are
unchanged. Options files that name a pack load and drop the key; the
launcher reads manifests that list a shader pack, and files in
`shaderpacks/` are never deleted.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 16:15:39 +02:00
rdbtCVS 06ec15f3a0 Retire the legacy Java optimization mod and performance packs
Preserve Java parity oracles and comparison benchmark instrumentation. Move their remaining dependency locks under tools/benchmark-deps and remove legacy product packaging, fixtures, and CI checks.

Co-Authored-By: OpenAI Codex gpt-6.1-sol <noreply@openai.com>
2026-10-24 14:50:55 +01:00
Ludovic Marie 50aee22996 Add a knockback harness: a dedicated server against vanilla's
tools/test_server_knockback_parity.py runs vanilla's dedicated server and
Horizon's (`--dedicated --nogui`) on one flat world and joins both with two
vanilla-codec players (KnockbackClient):

- Alice hits a cow and a zombie (plain, sprinting, Knockback II, critical,
  in the air); the game is frozen around the hit and stepped a tick at a
  time, and the mob's Motion and Pos over 20 ticks are compared exactly;
- Alice hits Bob (the same, a shield, netherite, two hits, two sprinting
  hits, a mace smash, a stronger hit inside the hurt cooldown): Bob's own
  motion packets, Alice's and her sprint flag are compared;
- a zombie hits Bob twice: his motion packets.

7 of 21 cases match on main. KNOWN lists the other 14 with their causes:
the guest's server-side velocity never travels (knockback adds up from hit
to hit), the server never sends a guest its own sprint flag, the extra
knockback's direction uses f32 sin/cos instead of Mth's table, a hit in
the hurt cooldown still knocks back, and a mace smash on a player runs
none of MaceItem.hurtEnemy.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 11:23:04 +02:00