Commit Graph

12 Commits

Author SHA1 Message Date
Ludovic Marie 0b581f9ffe Give each crate's probe example its own target name
horizon-client, horizon-world and horizon-protocol each had an example
named `probe`. Cargo copies every crate's examples into one
<profile>/examples/ directory, so parallel parity harnesses sharing a
target dir could run another crate's probe (CI parity run 40055656303:
command_parse ran the horizon-world dispatcher). The examples are now
client_probe, world_probe and protocol_probe ([[example]] in each
Cargo.toml; the files stay where they are), and every harness builds
and runs its own crate's name.

tools/parity.py recognises the new names when it counts the probes a
harness ran, and renames the old `probe` in recorded artifacts to the
crate's target (from the record's -p, else its probe sources), so the
prebuild still builds them instead of dropping them as unknown.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-24 08:08:18 +02:00
Ludovic Marie fdae4b895c horizon-world probes: one binary, probe <name>
The 168 horizon-world examples the parity harnesses run become modules of
one example, examples/probe, that dispatches on its first argument;
crate::args() gives each the command line its example saw. Linking ~170
binaries, each instantiating horizon-world's generics again, was most of
the parity job's probe build (review plan, section 1).

The harnesses build `--example probe` and run `probe <name> ...`.
tools/parity.py counts only the probes a harness ran, and the support
modules they name, as its dependencies, so editing one probe still reruns
only its own harnesses (and PARITY_RUST_SCOPE keeps working).

The six manual tools (benches, loot_fill, structure_blocks, vanilla_diff,
attribute_memory, behaviour_load_profile) stay separate examples.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-23 16:30:38 +02:00
Ludovic Marie e725e5257f Chunk generation harness: compare postprocessing marks too
The oracle prints every ProtoChunk postprocessing position and chunk_dump
prints Horizon's, so a chunk that schedules different fluid or shape
updates after generation (the blocks that later tick and drop items in
fresh chunks, #996) fails the harness.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 19:39:37 +02:00
Ludovic Marie ce87bfb8c7 Tools read the pinned Minecraft version from research-lock.json
lab.VERSION, lab.GAME (.local/minecraft/<version>) and lab.RESOURCES
(.local/horizon-client/<version>) come from the lock, and lab.version_info()
reads the pinned client jar's version.json. Every harness, generator and
tool that named 26.3 (resource folders, jar and source paths, result
records, the vanilla client's --version and asset index, the bare login
client's protocol, the benchmark's options.txt data version, the packet id
table's header) uses them, so a candidate worktree pinned to another version
runs them unchanged.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-21 12:22:20 +02:00
Ludovic Marie 1c3fd6e23c Save every generated chunk and the proto chunks decoration wrote to (#249)
Horizon saved a chunk only once a player changed it and never saved proto
chunks, so leaving an area dropped decorated chunks while the final chunks
next to them stayed loaded (or were regenerated later). Coming back, those
chunks were generated again and their decoration was skipped beside a final
neighbour: whole chunks of a bastion lost their pieces, other chunks their
features. Like vanilla, generated chunks are now saved, proto chunks that
decoration wrote to are saved with their status (terrain or features) and
restored onto the chunk generated again, columns that finish after the player
left are saved, and saving waits for the decorations in flight.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-15 06:37:05 +02:00
Ludovic Marie 2c8de2b015 chunk_generation: compare scheduled ticks; HORIZON_ORDER decoration order
Both dumps list each proto chunk's scheduled block and fluid ticks in
scheduling order (`t block|fluid NAME X Y Z PRIORITY`) and the harness
compares them: they run once the chunk is live, and the leaf ticks of
updateShapeAtEdge were missing without any block differing at FEATURES.

HORIZON_ORDER names a file of `x z` lines both sides decorate in, instead of
row-major: decoration is order dependent (a chunk's features write into its
neighbours), and vanilla's chunk system decorates around a player in its own
order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-13 23:38:02 +02:00
Ludovic Marie 13759ef16b Reuse unchanged vanilla oracle runs, and keep test games silent
tools/parity_shim.py stands in for java and javac in harness runs: it
records each oracle run's outputs and the content of every file under the
paths its arguments name, and replays the run while those are unchanged.
After a Rust-only change a harness only pays for its Rust side
(block_update 53 s -> 5 s). A harness that fails while reusing oracle
results is rerun fresh, and stops reusing them if that passes; --all and
--fresh never reuse them.

Harness probes built in the dev profile are optimised (overflow checks
and debug assertions kept), and the chunk generation harness runs its
vanilla and Horizon sides concurrently.

HORIZON_NO_AUDIO keeps the game off the speakers; tools/parity.py sets it,
since the save round-trip harness launches the game on a virtual screen.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-11 15:43:26 +02:00
Ludovic Marie 1d70ca47a8 Generate whole chunks block for block as vanilla does
The chunk generation harness found 70 differing chunks across three seeds in
the overworld, Nether and End. Proto chunks, biomes and decoration now span
the dimension type's build range rather than the noise height, so features
above y=128 in the Nether and End city upper floors survive; the decoration
level reports no sky light, as unlit vanilla chunks do, so mushrooms and crops
pass or fail their light checks the same way; beehive decorators store their
bees; iceberg ellipses skip NaN distances; double slabs never waterlog;
mineshaft spawners save an empty SpawnPotentials list; and the dump example
forgets structure starts between rectangles, as the oracle starts each with
fresh chunks.

The oracle prints absent block entity keys as vanilla loads them from an empty
tag, and the harness treats vanilla's save-format equivalences (plain sign
text, absent empty banner patterns, unfiltered sign messages) as equal. All 2,352
chunks over 225 structure sites match with zero block, biome or block entity
differences.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-10 21:20:51 +02:00
Ludovic Marie 9c20cc7bb2 Fill dungeon chests and spawners and keep block entities across same-block updates
A monster room's chest took its loot table and seed from the level random in vanilla, and its spawner got the chosen mob's spawn data, but the worldgen world ignored both, so the random sequence and the block entities diverged. A block entity also now survives a set of the same kind of block (a waterlogging chest in a ruined portal), as in a vanilla proto chunk. The chunk harness stops reporting default block entities and vault reward tables as differences.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-10 08:09:01 +02:00
Ludovic Marie afb92f7c84 Fix the chunk oracle's enabled features so jigsaw final states parse
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-10 07:25:59 +02:00
Ludovic Marie 50084d03d4 Ignore sections above the noise height and NBT integer widths in the chunk harness
The Nether roof and End sky sections are all air in vanilla and Horizon keeps none, and structure templates keep their stored integer width while vanilla re-saves block entities with its own, so neither is a generation difference.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-10 07:00:31 +02:00
Ludovic Marie 90023be7c2 Add a whole-chunk differential harness against vanilla generation
The new oracle drives vanilla's own chunk stages (structure starts and references, biomes, terrain with surface and carvers, then biome decoration with every placed feature and structure piece) through real WorldGenRegion instances, and the chunk_dump example runs the same stages in the same order in Horizon. The Python runner compares every block state, quart biome and block entity over terrain sites and structure sites found by scanning each seed, in the overworld, Nether and End, with phases that stop before features or run structure pieces only.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-09 14:02:16 +02:00