Commit Graph

891 Commits

Author SHA1 Message Date
Ludovic Marie e508a5ce1d Merge pull request #751 from LookImEcho-Rick/codex/issue-582-settings-search
🤖 Agent: Merged. CI parity passed 94 of 95. The one miss, tooltip_display, passes locally on main with this branch, and so does options. Thanks LookImEcho-Rick!
2026-10-18 12:04:59 +02:00
Ludovic Marie f0c7df2000 Merge pull request #836 from LookImEcho-Rick/codex/falling-block-collision-parity
🤖 Agent: Merged. Reviewed against vanilla: landing comes from Entity.move's vertical collision, the landing position is blockPosition(), velocity is zeroed per axis, and placement goes through Level.isUnobstructed with the collision shape. Locally on this head, fmt and clippy are clean, and contextual_collision, level_place, placement, powder_snow_collision and world_movement all PASS. Thanks LookImEcho-Rick!
2026-10-18 11:16:57 +02:00
Ludovic Marie 9dd896bfc3 tooltip_display harness: write the case flags in lowercase
Rust's bool parser takes only true/false, so the fixture failed on Python's
True/False; Java's Boolean.parseBoolean ignores case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 10:10:57 +02:00
LookImEcho-Rick 7ddb4ddae5 Fix falling block collisions with partial blocks 2026-10-18 03:02:55 -05:00
Ludovic Marie c1b4ccd571 Merge pull request #824 from ludovic111/perf/chunk-light-sync
🤖 Agent: merged: LAN guests and the server-thread game keep each chunk's light and get vanilla light updates (travel CPU −17%, light_chunk −35%; lan_e2e light PASS with and without --server-thread).
2026-10-18 09:46:11 +02:00
Ludovic Marie 5177fb3601 Merge pull request #828 from ludovic111/perf/brewing-ticker
🤖 Agent: merged: brewing stands tick in the level's single ticker list, in vanilla's order. perf-ticks-7's four PRs together on main d85a3603: clippy, 861 client + world tests, 19 harnesses (light, lan, dedicated_server, save_roundtrip, world_reopen, disk, datafix ×6, world, server_world_gen, block_entity ×4, chunk_stage) PASS.
2026-10-18 09:45:24 +02:00
Ludovic Marie e93c99a4c7 Merge remote-tracking branch 'origin/main' into fix/pr751-merge
# Conflicts:
#	crates/horizon-client/src/options_horizon.rs
2026-10-18 09:44:42 +02:00
Ludovic Marie 817a71ffa5 Clients keep the light the server sends; the server sends light updates
A remote client (a LAN guest, or the game on its server thread) threw away
the light in each LevelChunkWithLight and relit the column and its
neighbours itself. It now applies the sky and block layers as
ClientPacketListener.applyLightData does, and relights only block changes,
as vanilla's client does.

The hub now sends ClientboundLightUpdatePacket for the light sections that
changed in a column to the players for whom it is on the tracked border
(ChunkHolder.broadcastChanges), so light from blocks a guest doesn't track
reaches it.

horizon-ctl gains 'light X1 Y1 Z1 X2 Y2 Z2', and lan_e2e a 'light' check
comparing the guest's light with the host's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 09:39:50 +02:00
Ludovic Marie eb3f2b94ca Merge pull request #831 from ludovic111/feat/secure-chat
🤖 Agent: merged secure chat as vanilla 26.3's server (chat sessions, signed chat and commands, enforce-secure-profile; secure_chat harness identical to vanilla offline and online; 7 server harnesses pass).
2026-10-18 08:40:05 +02:00
Ludovic Marie a2363a3bf6 fix(server-thread): the integrated server follows the render distance, past 32 too
IntegratedServer.tickServer: the server takes the window's render and
simulation distances when they change ("Changing view distance to N, from
M"), tells every player (SetChunkCacheRadius, SetSimulationDistance), and
each player's chunks follow, up to what they asked for. The integrated
server no longer clamps the view distance to 32, and a remote client sends
its render distance again when it changes (Options.broadcastOptions),
past 32 too. Fixes #804.

lan_e2e: a distance check (--server-thread), and the guest is found by
name in lan status, where the server thread lists the owner too: the
hazards check read the owner's food (the "no hunger from moving" gap).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 08:09:49 +02:00
Ludovic Marie 454b3842bb feat(server): secure chat, as vanilla 26.3's server
Chat session updates with their profile key checked against the services'
keys, signed chat and the message chain, last-seen acknowledgements, the
signature cache, signed say/me/msg, enforce-secure-profile, and vanilla's
log lines. Offline servers and players without a chat session chat
unsigned, as on vanilla. tools/test_secure_chat_parity.py compares both
servers with test keys and a mock services server.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 07:52:46 +02:00
Ludovic Marie b540ccb642 Brewing stands tick in the level's block entity ticker list
Brewing stands were the last server ticker with a pass of its own over the
whole block entity map every tick. They now tick in their place in
Level.blockEntityTickers, as BrewingStandBlock.getTicker makes them: in
list order, only in block-ticking range and inside the world border, with
their bottle states written as each one ticks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 07:17:44 +02:00
Ludovic Marie c2f3d01ee4 Merge remote-tracking branch 'pr/779' into integ/mp-sh
# Conflicts:
#	mods/horizon/src/test/java/dev/horizonlab/parity/LocatorBarClient.java
2026-10-18 06:35:13 +02:00
Ludovic Marie 6e7b34d5b8 Merge remote-tracking branch 'pr/790' into integ/mp-sh 2026-10-18 06:34:57 +02:00
Ludovic Marie 1541086b21 Merge remote-tracking branch 'pr/767' into integ/mp-sh 2026-10-18 06:34:56 +02:00
Ludovic Marie 6829da90f2 Merge remote-tracking branch 'pr/769' into integ/mp-sh
# Conflicts:
#	tools/lan_e2e.py
2026-10-18 06:34:56 +02:00
Ludovic Marie 4029475397 Merge remote-tracking branch 'pr/766' into integ/mp-sh 2026-10-18 06:34:38 +02:00
Ludovic Marie daa8b2f528 Merge remote-tracking branch 'pr/760' into integ/mp-sh
# Conflicts:
#	tools/lan_e2e.py
2026-10-18 06:34:26 +02:00
Ludovic Marie e6f0384dda Merge remote-tracking branch 'pr/759' into integ/mp-sh 2026-10-18 06:34:07 +02:00
Ludovic Marie 8d0ec947a3 Merge remote-tracking branch 'pr/755' into integ/mp-sh 2026-10-18 06:34:03 +02:00
Ludovic Marie 2e2f4a6581 Merge pull request #809 from ludovic111/fix/ask-server-suggestions
🤖 Agent: merged: ask_server suggestions. Combined check of main + perf-ticks-6's six: clippy, tests, 8 harnesses PASS.
2026-10-18 06:33:41 +02:00
Ludovic Marie 0436c9470d Merge pull request #808 from ludovic111/fix/server-titles
🤖 Agent: merged: /title reaches guests and the server thread. Combined check of main + perf-ticks-6's six: clippy, tests, 8 harnesses PASS.
2026-10-18 06:33:36 +02:00
Ludovic Marie ff6e01de03 Command suggestions: ask the server for nodes the tree marks ask_server
A remote client's chat now sends ServerboundCommandSuggestionPacket for an
argument node whose provider is minecraft:ask_server (bossbar ids, data
storage, datapacks, team names, functions...), as ClientSuggestionProvider.customSuggestion
does. The suggestions are done when ClientboundCommandSuggestionsPacket
answers that id; its completions join the local ones (Suggestions.merge).
Replies to older requests are dropped.

The remote tree takes each node's provider from the packet only: a local
provider the server didn't send stood in for the server's before.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:57:29 +02:00
Ludovic Marie c12f5cf41a Server titles: /title reaches the guest, and its HUD shows and clears them
TitleCommand sends the targeted player ClientboundSetTitleText,
SetSubtitleText, SetActionBarText, SetTitlesAnimation and ClearTitles. A
guest's /title (the window's own player on the server thread too) only
changed the server's HUD; it is now sent to the guest. The remote client
showed titles and action bars as a bare line and ignored subtitles, times
and clearing; it now feeds the HUD's titles as ClientPacketListener does
(the action bar of a SystemChat overlay too) and ticks them (Gui.tick).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:00:48 +02:00
Ludovic Marie 65d5a35cd2 Server: a dead guest is sent its health of 0, as ServerPlayer.doTick does
The hub held SetHealth back once a guest died, so the guest's health
stayed at its last positive value under the death screen. ServerPlayer
sends it every tick it changes, dead or not, and only when the health or
the food level changes or the saturation reaches or leaves zero: the hub
sent it on every change of saturation too.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 04:00:24 +02:00
Ludovic Marie d223b383ee Merge pull request #798 from ludovic111/perf/block-entity-tickers
🤖 Agent: merged vanilla-order block entity ticking (new harness: 21,590/21,590 ticks match vanilla; block-entity share of the tick 19.5%→9.6% with 50 bots; 90/90 harnesses locally).
2026-10-18 03:59:14 +02:00
Ludovic Marie 50daf6ecfc Merge pull request #792 from LookImEcho-Rick/codex/tooltip-display-parity
🤖 Agent: merged LookImEcho-Rick's tooltip_display parity, with its Java oracle and Rust probe.
2026-10-18 03:33:38 +02:00
Ludovic Marie 209b898c02 The console's and players' command feedback reaches the operators
CommandSourceStack.broadcastToAdmins beyond a guest on a dedicated server:

- The dedicated server's console tells every operator what its commands
  did, as `[Server: ...]`, when `broadcast-console-to-ops` is on
  (DedicatedServer.shouldInformAdmins). This covers the game's commands
  and the dedicated-only ones vanilla broadcasts (op, deop, ban, pardon,
  kick, whitelist, save-all, save-on/off, stop).
- In a world open to LAN, the host, an operator when commands are
  allowed, hears of its guests' commands, and op guests hear of the
  host's.
- A player's name in the line is their display name, with the `/tell`
  suggestion, the entity hover and the insertion (Player.getDisplayName).

New harness test_server_ops_feedback_parity: two vanilla-codec
operators' system chat while the console and one of them run commands,
deop and op, toggle send_command_feedback and save, with
broadcast-console-to-ops on and off. LocatorBarClient can record system
chat (`chat on`). lan_e2e's feedback check also asserts the host is told.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:02:11 +02:00
Ludovic Marie 9a2d87ec97 fix(server): move players to another dimension with execute in ... run tp
On a dedicated server, `execute in <dimension> run tp @s ...` from a player
moved them inside the level they were in. It now does what vanilla's
TeleportCommand does: ServerPlayer.teleport into the other level, with the
Respawn packet keeping all data and no portal sound, then the feedback. The
players there are tracked to them and they are removed from the ones they
left.

tools/test_server_dimension_players_parity.py joins two players to a vanilla
and a Horizon server and compares, step by step, the players each is sent and
loses and the dimensions it respawns into, while they go to the Nether and
the End by command and through an End portal. LocatorBarClient gains
`players on` and `still NAME` (the position reminder a still client sends).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:01:56 +02:00
Ludovic Marie a1af7fdad5 Worlds without structures generate none
`generate-structures=false` (server.properties, stored by #733) and the
world screen's Generate Structures were written to the world's settings
but the generator ignored them. VanillaTerrain now builds its generator
from the world's `generate_structures`
(OverworldGenerator::for_world): without structures there are no starts,
terrain adaptation or structure pieces, as in
ChunkStatusTasks.generateStructureStarts, and `locate structure` and eyes
of ender find nothing (ChunkGenerator.findNearestMapStructure).

The server world gen harness's world without structures now also
compares `locate structure` for a village and a mineshaft and the saved
chunks' structure starts and references.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:01:55 +02:00
Ludovic Marie 5e1abf2b4e Clients of a server show its primed TNT, falling blocks, projectiles and crystals
A Horizon client of a server places what PR #766 sends: primed TNT with
its fuse, falling blocks with their block state and start position,
arrows (critical, in the ground), snowballs, eggs, pearls, fireballs,
wither skulls, wind charges and llama spit, tridents, firework rockets
and end crystals with their beam and base. They interpolate like mobs,
turn with the move packets, and are cleared with the connection, a
respawn or a dimension change.

`status` lists them (`projectiles`), and lan_e2e has a `projectiles`
check: the guest sees the host's primed TNT, end crystal and landed
arrow where the host has them, and a falling block lands on both sides.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 03:00:42 +02:00
Ludovic Marie 946bf84818 Load summoned and saved primed TNT as live TNT; step the entity harness
`/summon minecraft:tnt` and primed TNT in a saved chunk were kept as an
unsimulated entity. They now become primed TNT with the fuse (80 when
absent) and motion they were saved with (PrimedTnt.readAdditionalSaveData).

The entity harness runs its scene for a fixed 200 ticks (`tick step`),
so what still changes when the client stops recording (a fuse) ends the
same on both servers. Its scene has two primed TNT (one falling), a
floating falling block, an arrow that lands and an end crystal. Unit
tests cover arrows' position and rotation, fireballs' bundled power and
precise position syncs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 02:57:12 +02:00
Ludovic Marie 866e772227 Server: track primed TNT, falling blocks, projectiles, tridents, fireworks and crystals
These entities had no id in Horizon, so a server could not send them to
its clients. Each now has one, given from the entity counter before it is
first tracked, and goes to guests as vanilla's ServerEntity sends it:

- primed TNT with its fuse (sent each tick it changes) and falling blocks
  with their block state and start position; both sync their exact
  position while they touch a block (requiresPrecisePosition);
- arrows and tridents send their position and rotation every update
  (AbstractArrow), with their flags, pierce level, in-ground state,
  loyalty and foil; their owner is the spawn data;
- fireballs, wither skulls and wind charges bundle their velocity with
  ClientboundProjectilePowerPacket (new in horizon-protocol);
- snowballs, eggs, pearls, llama spit, shulker bullets and splash potions;
- firework rockets with their item, the player they boost and whether
  they were shot at an angle; end crystals with their beam and base.

The entity harness's scene gains primed TNT, a falling block, an arrow, a
snowball and a trident that land, a fireball, a firework and a crystal.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 02:57:12 +02:00
Ludovic Marie 583502f0f4 Clients of a server show its boats, minecarts, armor stands, frames and paintings
ClientPacketListener.handleAddEntity for the objects a server tracks: a
Horizon client of a server (a LAN host, a dedicated server, single
player's server thread) now places the boats, minecarts, armor stands,
item frames and paintings it is sent, where the server says.

- Spawn: carts by kind, boats and rafts by wood (with a chest), armor
  stands, frames and paintings at their block with the direction from the
  spawn data.
- Entity data: frame items and rotation, painting variants (a registry
  holder), armor stand flags and health, boat paddles, vehicle hurt.
- Equipment: what an armor stand wears and holds.
- Moves interpolate like mobs'; rotation and ground state follow.
- They are cleared with the connection, a respawn or a dimension change.

`status` lists them (`objects`), and lan_e2e has an `objects` check: the
host summons them, the guest sees each as the host has it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 02:54:25 +02:00
Ludovic Marie 43e8b54918 Server: track boats, minecarts, armor stands, frames and paintings to clients
A server sent its clients only mobs and dropped items. Boats, every kind of
minecart, armor stands, item frames, paintings and the entities Horizon keeps
without simulating are now tracked as ServerEntity does: the AddEntity data
(hanging entities at their block, with their direction), the synched data that
differs from the defaults, equipment, passengers (ClientboundSetPassengersPacket
at pairing and on change; a passenger syncs only its rotation and resyncs its
position when it dismounts), and the type's update interval and range.

Also vanilla-exact on the way, as the new harness found:
- mobs pair with their health (always non-default) and Mob flags (no AI, left-handed);
- /summon without NBT summons any type from an empty compound;
- armor stands move before gravity (LivingEntity.travelInAir), so a stand at rest
  keeps vanilla's -0.0784 vertical motion.

tools/test_server_entities_parity.py compares, from a vanilla-codec client, what
vanilla's dedicated server and Horizon's track for a scene of 20 entities.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 02:50:14 +02:00
LookImEcho-Rick 2faa99e5f1 Fix item tooltip display parity 2026-10-17 19:30:23 -05:00
Ludovic Marie ff94490992 Block entities: tick only those with a ticker, in vanilla's order
World::block_entities keeps vanilla's Level.blockEntityTickers beside the
map: a slot when a block entity whose state has a ticker is added, kept
when it is replaced, freed when it is removed, unloaded or its state loses
the ticker; a loaded chunk's in its block entity map's order. The tick
visits that list once, in block-ticking chunks within the world border,
instead of scanning the whole map once per kind.

New harness block_entity_tickers: real LevelChunks of a server level
against BlockEntities.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-18 00:08:44 +02:00
Ludovic Marie cf63dcd39f Merge remote-tracking branch 'pr/724' into bm2/combined
# Conflicts:
#	crates/horizon-client/src/game/lan_actions.rs
#	tools/lan_e2e.py
2026-10-17 23:57:19 +02:00
Ludovic Marie 40e9e9660b Merge remote-tracking branch 'pr/727' into bm2/combined
# Conflicts:
#	crates/horizon-client/src/game/agent.rs
#	tools/lan_e2e.py
2026-10-17 23:55:19 +02:00
Ludovic Marie e74d5207dc Merge remote-tracking branch 'pr/726' into bm2/combined
# Conflicts:
#	crates/horizon-client/src/game/remote.rs
#	tools/lan_e2e.py
2026-10-17 23:54:59 +02:00
Ludovic Marie 9bb22caa22 Merge remote-tracking branch 'pr/725' into bm2/combined
# Conflicts:
#	tools/lan_e2e.py
2026-10-17 23:54:22 +02:00
Ludovic Marie 6f5a3319ee Merge commit '123e8286ac55894a0e9f61c78b3844fd46241e2a' into bm2/combined
# Conflicts:
#	crates/horizon-client/src/game/remote.rs
#	tools/lan_e2e.py
2026-10-17 23:54:21 +02:00
LookImEcho-Rick b9d61e5701 Make pr_ready portable to Windows 2026-10-17 15:48:49 -05:00
Ludovic Marie 8bfe19245b Merge commit 'bf1cd958686ffc95a6ff30cdbedc9a8de59315ad' into HEAD
# Conflicts:
#	tools/lan_e2e.py
2026-10-17 22:33:41 +02:00
Ludovic Marie bf1cd95868 Merge main into feat/server-command-tree
tools/lan_e2e.py: the check lists keep #700's effects and portals and this PR's commands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 22:33:18 +02:00
Ludovic Marie 95bdb96f16 Merge commit '805d5532e541deb1888216c8ebfc15775d8b2ea5' into HEAD 2026-10-17 21:40:51 +02:00
Ludovic Marie 4ae51c1d5e perf_bench --warm: measure a later start, after a first one built the caches
A Horizon game with content mods builds its content root and block behaviour
snapshot on its first start, in its game folder, and reuses them afterwards.
perf_bench starts every game from an empty folder, so it only measured first
starts. --warm starts the game once to the title screen first, unmeasured.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 21:39:48 +02:00
Ludovic Marie d746be2ca3 Merge main into feat/server-levels
game/lan.rs: #586's movement-check rules are set before the per-level passes.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-17 20:56:26 +02:00
Ludovic Marie dc1a8a4f39 Merge pull request #734 from ludovic111/fix/guest-command-feedback
🤖 Agent: merged by Ludovic's AI agent. Combined with #733 on current main: workspace clippy clean, client 827 tests pass, server_world_gen + dedicated_server PASS (agent: parity --changed 89/89).
2026-10-17 20:43:37 +02:00
Ludovic Marie e2e0752489 Merge pull request #733 from ludovic111/fix/server-level-type
🤖 Agent: merged by Ludovic's AI agent. Combined with #734 on current main: workspace clippy clean, client 827 tests pass, server_world_gen + dedicated_server PASS (agent: parity --changed 89/89).
2026-10-17 20:43:34 +02:00