Commit Graph

511 Commits

Author SHA1 Message Date
Ludovic Marie 0e2fc82f4e Datafix: thrown potion item field; legacy scene additions for 1.13.2 to 1.15 2026-10-13 00:32:00 +02:00
Ludovic Marie d229326779 Datafix harness: --band TARGET checks the fixes up to a DataVersion on legacy-layout worlds; fixes sorted by key 2026-10-13 00:06:19 +02:00
Ludovic Marie 93ac585c74 Datafix worlds: list 1.12.2, 1.13.2 and 1.14.4 2026-10-13 00:02:25 +02:00
Ludovic Marie 19896fb6f1 Support saves from 1.16.5 (DataVersion 2571 on): replaceitem for pre-1.17 scenes 2026-10-12 23:59:20 +02:00
Ludovic Marie 0870b5064b Merge branch 'parity-base' into parity/old-saves 2026-10-12 23:50:33 +02:00
Ludovic Marie 4b93509137 Note the render distance 2 loading hang, and run harnesses here by default
The Mac mini and ThinkPad no longer keep the shared vanilla data, so the
other machines are opt-in again.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 19:50:58 +02:00
Ludovic Marie 6fab5eb279 Merge branch 'main' into parity-base
# Conflicts:
#	README.md
#	crates/horizon-client/src/game.rs
2026-10-12 19:02:09 +02:00
Ludovic Marie c51bfda80c Run the server files harness and platform-sensitive harnesses where they agree
Number the server files cases, whose folders eula-true and eula-TRUE collide
on case-insensitive macOS file systems; keep world_border_render and mob_ai
off the Mac, where platform float math changes their results; give the local
executor the dead flag the flake check reads.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 18:57:30 +02:00
Ludovic Marie fc7420f74b Merge branch 'parity/old-saves' (before its WIP commit) into parity-base 2026-10-12 17:55:17 +02:00
Ludovic Marie 5731a9406f Merge branch 'parity/dedicated-server' (before its WIP commit) into parity-base 2026-10-12 17:55:17 +02:00
Ludovic Marie 404072d5e5 Merge branch 'parity/warden-sculk' (before its WIP commit) into parity-base
# Conflicts:
#	crates/horizon-client/examples/entity_anim_fixture.rs
#	crates/horizon-client/src/game.rs
#	crates/horizon-client/src/game/creatures.rs
#	tools/test_entity_model_parity.py
2026-10-12 17:55:17 +02:00
Ludovic Marie 2e3063d821 Merge branch 'parity/mobs-b' into parity-base
# Conflicts:
#	crates/horizon-client/examples/entity_anim_fixture.rs
#	crates/horizon-client/examples/mob_ai_probe.rs
#	crates/horizon-client/src/game/creatures.rs
#	crates/horizon-client/src/mobs.rs
#	crates/horizon-client/src/mobs/ai.rs
#	mods/horizon/src/test/java/dev/horizonlab/parity/VanillaMobAiOracle.java
#	tools/test_mob_ai_parity.py
2026-10-12 17:54:20 +02:00
Ludovic Marie f02c47d289 Merge branch 'parity/mobs-a' into parity-base 2026-10-12 17:50:53 +02:00
Ludovic Marie 14bff2518f Merge branch 'parity/raids' into parity-base
# Conflicts:
#	README.md
#	docs/rust-parity.md
2026-10-12 17:50:53 +02:00
Ludovic Marie c195cd3239 Merge branch 'parity/tablist-border' into parity-base
# Conflicts:
#	README.md
#	crates/horizon-client/src/lib.rs
#	docs/rust-parity.md
2026-10-12 17:50:31 +02:00
Ludovic Marie 69b191b1f4 Merge branch 'parity/loom-crafter' into parity-base
# Conflicts:
#	README.md
#	crates/horizon-client/src/game/dispense_fixture.rs
#	docs/rust-parity.md
#	mods/horizon/src/test/java/dev/horizonlab/parity/VanillaDispenserOracle.java
2026-10-12 17:48:44 +02:00
Ludovic Marie b6fa612bee Merge branches 'parity/tooling', 'parity/score-subtitles' and 'parity/block-followups' into parity-base 2026-10-12 17:47:58 +02:00
Ludovic Marie 54b939e717 WIP: unfinished old-saves parity work, stopped by Ludovic
Uncommitted changes the agent had in progress when it was stopped on
2026-10-12; may not build or pass its harnesses yet.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:46:50 +02:00
Ludovic Marie c90cd5f072 Match vanilla llama caravans, trader llamas, breeding and wolves
A lead gives its mob a home at the holder (PathfinderMob.whenLeashedTo)
and every random position helper honours homes (generateRandomPos-
TowardDirection's lean back and GoalUtils.isRestricted), as the happy
ghast's float area now does too. LlamaFollowCaravanGoal keeps 2.1F, a
llama's baby and the breeding experience are drawn from the parent's
random, wolves run from llamas by strength (WolfAvoidEntityGoal), a
growing mob refits its box (fudgePositionAfterSizeChange) and a happy
ghast's new controls want nothing. Scenarios can lead mobs.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:45:09 +02:00
Ludovic Marie b0ce83dd2d Port the 1.17 to 1.18 chunk height, biome and tick fixes (2825 to 2846)
ChunkHeightAndBiomeFix, ChunkProtoTickListFix, ChunkRenamesFix,
OverreachingTickFix, SpawnerDataFix, the world generation settings fixes
and the Caves & Cliffs biome and advancement renames, with the chunk's
Level tag and UNTAGGED_SPAWNER in the schema walker. A 1.17.1 sample
world upgrades as vanilla's.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:42:59 +02:00
Ludovic Marie 63f628762f Tick creaking hearts as vanilla and compare them with the oracle
mobs::creaking_heart is CreakingHeartBlockEntity: the ticker drawn from
the level random, the state following the night and the logs, the
protector spawned with SpawnUtil.trySpawnMob (five tries within 16
blocks, on top of a collider, then EntityType.create's yaw and
Mob.finalizeSpawn's follow range bonus), its sounds, letting it go by
day, beyond 34 blocks or with a player stuck in it, and when a player
hurts it the trails and the resin spread over the logs. The game ticks
its hearts through it, and its level random now carries on between
ticks.

The mob AI harness gains hearts: the oracle places them when a scenario
starts, ticks block entities after the mobs, seeds the creakings the
level creates and adds them to the scenario, prints each heart's state
and block entity, and lets the player hit a mob (hurt T I). Five heart
scenarios (night, day, uprooted, no player near, hit twice) match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:40:47 +02:00
Ludovic Marie b5c0bf7859 Draw the loom and crafter screens as the vanilla client does
LoomScreen.extractBackground (slot icons, scroller, pattern buttons
with their swatches and tooltip, the result banner or the six-layer
error) and CrafterScreen's background, disabled slots and redstone
arrow become screen_layout calls the game paints. A new harness runs
vanilla's screens on stand-in menus and compares 1,600 call lists.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:38:25 +02:00
Ludovic Marie 225c12f4cc Move subtitles into the HUD overlays and save scoreboards end to end
The subtitle overlay now lays out GuiDraw calls in hud_overlays and the
game paints them like the other overlays. Hover events that show an entity
save its UUID as an int array, as UUIDUtil.CODEC does. The save round trip
builds a vanilla scoreboard with every saved field (objectives, number
formats, display slots, locked and displayed scores, teams with every
option) and requires Horizon to save scoreboard.dat as vanilla did.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:35:05 +02:00
Ludovic Marie 01db93a987 Port server.properties, eula.txt and the server user lists
DedicatedServerProperties with every key, default, parser and serializer,
java.util.Properties load/store, Eula and the four StoredUserList files,
checked against the pinned server JAR by test_server_files_parity.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:34:57 +02:00
Ludovic Marie 13102892c4 Render, save and gift copper golems as vanilla does
The copper golem takes its weathering's texture and glowing eyes, saves
and loads next_weather_age and weather_state, starts with its weathering
unset instead of weathering on its first tick, and throws what it carries
to the player as BehaviorUtils.throwItem does. Iron golems offer their
poppy to copper golems too (#candidate_for_iron_golem_gift) and put it on
an empty antenna when the offer runs out beside one.

The entity model harness now poses the copper golem with its idle and
chest interaction animations (44 cases), and the entity death loot harness
includes it (1,595 cases over 88 types); both match vanilla.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:31:52 +02:00
Ludovic Marie 82eda1d8bf Port the 1.18 structure fixes (2967, 2970) and add a 1.18.1 sample world
Old server jars run on Mojang's own Java runtimes, pinned in
research-lock.json and installed beside the shared vanilla data.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:30:48 +02:00
Ludovic Marie 515d15d36f Merge the integration branch into parity/tablist-border
Keep the integration branch's StringSplitter port and HUD overlays: the tab
list now emits hud_layout::GuiDraw calls and wraps with its split_lines, and
the vignette's border warning comes from WorldBorder::warning_strength
through hud_overlays::border_warning.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:25:13 +02:00
Ludovic Marie a425de4c1c Merge the integration branch: villager brain, mob AI fixes and HUD overlays
The raid bars now draw through hud_overlays. Villagers' raid field is
what getRaidAt finds where they stand, with lost raids and the wave flag
kept apart, so the brain's SetRaidStatus, ResetRaidStatus (which resets on
a lost raid), ReactToBell and raid packages read vanilla's conditions.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:23:59 +02:00
Ludovic Marie e664d2f7c4 Merge origin/t3/achieve-full-parity into parity/block-followups
Explosion drops keep their random sequences and the pot's dynamic drops;
/setblock destroy and /fill destroy run Level.destroyBlock through the
behaviour library, so the block entity spills as vanilla's does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:19:39 +02:00
Ludovic Marie e723c8ad6c Merge origin/t3/achieve-full-parity into parity/score-subtitles
Mobs push through the new pushEntities with the teams' collision rules;
lang keeps the integration branch's deprecated.json handling; the
scoreboard keeps this branch's vanilla hash orders.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:19:13 +02:00
Ludovic Marie 2edae5746a Merge origin/t3/achieve-full-parity into parity/mobs-b
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:18:39 +02:00
Ludovic Marie 5dd2840cee Merge remote-tracking branch 'origin/t3/achieve-full-parity' into parity/warden-sculk
# Conflicts:
#	crates/horizon-client/src/game.rs
#	crates/horizon-client/src/game/creatures.rs
2026-10-12 17:18:11 +02:00
Ludovic Marie a5eb241c32 Merge remote-tracking branch 'origin/t3/achieve-full-parity' into parity/loom-crafter
# Conflicts:
#	crates/horizon-client/src/game/commands/world_cmds.rs
2026-10-12 17:15:59 +02:00
Ludovic Marie 8393b8de0f Match vanilla breeding sniffers and tempted happy ghasts
Mobs set each other's brain memories within the tick (the breed target
and lockGazeAndWalkToEachOther), the partner rests and forgets at the
birth, and an animal in love draws its heart particle randoms. The adult
happy ghast's TemptGoal.ForNonPathfinders ticks every other tick and
follows creative players. The mob AI scenarios can give the player an
item and a mob love, taming, an age or a llama strength.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:15:34 +02:00
Ludovic Marie 233dadf29f Run harnesses on the ThinkPad too, two at a time at nice 19
A sample of 27 harnesses (the 20 quickest, options, datafix's six shards)
passed there; it builds against the same ALSA headers as the desktop.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:15:18 +02:00
Ludovic Marie b56b4c3cea Bring the copper golem into the game and build it and shear it as vanilla does
The copper golem code (its goals, chest transport, weathering, statues and
interactions) was in the tree but not compiled; it is now a species with
its model, keyframe animations, sounds and game hooks. Its antenna flower
sits in the saddle slot as vanilla's EQUIPMENT_SLOT_ANTENNA, sheared by
players and dispensers with the unequip event and the 1.5-up drop, and
dropped with the carried stack as preserved equipment. A pumpkin on a
copper block builds it after the snow and iron golem patterns: both blocks
clear, the block becomes the matching copper chest (CopperChestBlock
getFromCopperBlock with the least oxidized of connected chests), and the
golem takes the block's weathering and plays its spawn sound. Weathering
draws from the level random, the statue pose from the golem's own.

The dispenser harness now builds copper golems and shears and equips them:
6000/6000 cases match.

Block.popResource of tall flowers and flower beds and the composter's
bone meal pop when the behaviour asks, as vanilla does.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:14:20 +02:00
Ludovic Marie 8ba728287f Order the recipe book's buttons as the vanilla client does
ClientRecipeBook keeps the displays it was sent in a HashMap of display
ids, whose iteration order (buckets, then arrival) orders the
collections; the game now keeps such a client book (on the verified
Java HashMap port) synced with the server book, with display ids
numbered as RecipeManager does. A new harness runs the client's
ClientRecipeBook, RecipeCollection selection and the tab and page logic
of RecipeBookComponent over 1,200 cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:14:14 +02:00
Ludovic Marie 59a966a9e3 Compare breezes and creakings with vanilla in the mob AI harness
Eight scenarios: a breeze alone and fighting a player near, inside and
beyond its jump circle; a creaking alone, watched, unwatched, and woken
then hunting once the player turns away (a new player turn= option).
The oracle now faces the player +z with its head too (it kept a random
head yaw from its creation, which the breeze's jump target reads).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:14:07 +02:00
Ludovic Marie b98c67b04f Merge remote-tracking branch 'origin/t3/achieve-full-parity' into parity/mobs-a 2026-10-12 17:13:55 +02:00
Ludovic Marie a4355c7c9b Catch flaky harnesses: --repeat, and three runs in the gate
parity.py --repeat N runs each harness N times; its runs must agree, else it
is reported FLAKY and recorded as failing. Later rounds run on the machine
that ran the first, reusing its oracle results, and never two at once there.
With --flake-check REF (passed by gate.py, merge base with parity-base; by
supervise.py integrate, the integration branch before the merge), harnesses
whose script, oracle or probe is new or changed must pass three runs in a
row; a pass records its rounds so it is not repeated again. gate.py matches
shards of a known failure by the harness's name.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:10:08 +02:00
Ludovic Marie bbae62fc4b Render subtitles exactly as vanilla's SubtitleOverlay
The overlay listens to the sound engine from the frame that renders it with
Show Subtitles on until one renders with it off (keeping its captions),
forgets plays as it renders, picks the latest play in range (the first of
full ties), fades in float arithmetic, lays the boxes out in integers under
the pose translation and takes its background from the text background
opacity options. Translations now apply the game's deprecated.json renames,
as ClientLanguage does ("Chick hurts"). tools/test_subtitle_parity.py runs
vanilla's SubtitleOverlay on 1500 scripted cases.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:07:47 +02:00
Ludovic Marie 000e676b57 Compare the warden's animations and emissive layers with vanilla
The entity model harness now sets the warden's render state (tendril and
heart animation, the roar, sniff, emerge, dig, attack and sonic boom
animation states) and bakes its four emissive layers (tendrils, heart,
bioluminescent skin, pulsating spots) over WardenModel: 430 cases match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:06:36 +02:00
Ludovic Marie 621fca874c Keep the player's recipe book as vanilla's ServerRecipeBook does
The known and highlighted recipes, the book settings and the saved
recipeBook compound now live in one place (recipe_book::Settings with
a RecipeIndex of learnability and display counts): advancement rewards,
/recipe give and take (counting displays, never special recipes) and
crafting a recipe award through it, and loading drops unknown recipes
instead of rebuilding the set from done advancements. A new harness
compares 1,500 operation sequences with vanilla's ServerRecipeBook and
its codec.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:02:53 +02:00
Ludovic Marie 2f232d955c Charge sculk catalysts when the killing blow lands
Mobs die (LivingEntity.die: the death event, catalysts, loot and
experience) when they are killed, not when their death animation ends.
Catalysts take a death in the dispatcher's order (nearest by exact
distance, then visiting order); experience orbs draw their merge id from
the level random and their motion from their own. The sculk harness
gains catalyst scenarios: kills by the player near catalysts over
random terrain, with blooms, charge cursors and the sculk they spread.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 17:01:59 +02:00
Ludovic Marie acf4df3a90 Place recipe book recipes as vanilla's ServerPlaceRecipe does
ServerPlaceRecipe and StackedContents' RecipePicker run on the menu
engine (horizon_client::menu::place) for the inventory, crafting table
and furnaces: testClearGrid, clearGrid with placeItemBackInInventory,
the biggest craftable stack, clamping to stack sizes and moveItemToGrid.
A new harness compares 6,000 placements with vanilla; vanilla's item
order follows identity hash codes, so the oracle hands its order to the
Rust side. The game's recipe book now places through the engine, and
its craftable filter uses the same counts and placement ingredients.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:51:38 +02:00
Ludovic Marie 4490ff75fc Spill block entity contents when their block is replaced, as vanilla does
LevelChunk.setBlockState now runs BlockEntity.preRemoveSideEffects and
removes the block entity when a block with one is replaced by another
block (copper chests and copper golem statues keep theirs across
weathering; UPDATE_SKIP_BLOCK_ENTITY_SIDEEFFECTS skips the side effects).
Containers spill every slot through Containers.dropItemStack (spot and
pieces of 10 to 30 with triangular motions from the level random, empty
slots still drawing their spot), jukeboxes pop their record, lecterns
their book; shulker boxes keep their contents for the dropped box.
Campfires, decorated pots, chiseled bookshelves and shelves, which Horizon
keeps as loaded, spill too.

Block.dropResources now draws its loot and pop spots when the behaviour
calls it, not after it returns, and spawnAfterBreak awards ore, sculk and
spawner experience. Item entities and orbs the behaviour makes are added
before it returns to the game, in the same tick. Player mining follows
ServerPlayerGameMode.destroyBlock's order (removal and spill, tool wear,
then the drops); explosions let the removal spill the contents.
ExperienceOrb.award draws the merge id from the level random and moves
the orb with its own random. Decorated pots copy their decorations and
drop their sherds when cracked (loot tables' dynamic entries).

The block update oracle replays preRemoveSideEffects too, and the new
block removal harness (tools/test_block_removal_parity.py) compares
setBlock/destroyBlock/removeBlock on every block entity holder with
contents against vanilla: 2000/2000 cases match.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:49:20 +02:00
Ludovic Marie cdd05f8e8b Trial-merge branches before integrating them
supervise.py check trial-merges every candidate branch into the integration
branch with git merge-tree, without touching a worktree: each alone, every
pair, then the largest set that merges cleanly together, in about a second.
integrate starts from that set (or every parity/* branch with new commits,
with --ready), gates it once, and if the gate fails tries each half, so the
branches that pass still land.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-12 16:43:58 +02:00
Ludovic Marie e6aa9f71b0 Merge branch 'parity/rendering-be' into parity-base 2026-10-12 16:43:52 +02:00
Ludovic Marie 93c3de5d61 Merge branch 'parity/hud' into parity-base 2026-10-12 16:43:50 +02:00
Ludovic Marie 095991b946 Merge branch 'parity/rendering-hud' into parity-base 2026-10-12 16:43:49 +02:00