Implement bonus chest search, loot seeding and torches

This commit is contained in:
Ludovic Marie committed 2026-10-06 14:08:13 +02:00
1 parent b344304c62
commit 736424e01c
10 files changed
+459 -1

No files matched your search

+4
View File
@@ -151,6 +151,10 @@ jobs:
env:
RUSTUP_TOOLCHAIN: stable
run: python tools/test_end_gateway_parity.py
- name: Compare bonus chest placement and conditional loot seeding
env:
RUSTUP_TOOLCHAIN: stable
run: python tools/test_bonus_chest_parity.py
- name: Compare replacement blob search and Manhattan shells
env:
RUSTUP_TOOLCHAIN: stable
@@ -0,0 +1,220 @@
{
"schema": 1,
"minecraft": "26.3",
"manifest_sha1": "4fe1aa1ef8da1cb95c5bad1fb98890ca56dd8ca3",
"platform": "Linux-7.0.0-31-generic-x86_64-with-glibc2.43",
"java": "openjdk 25.0.4.1 2026-08-18",
"rustc": "rustc 1.99.0 (b940084d7 2026-09-28)",
"fixtures": 42396,
"candidate_states": 35723,
"double_plant_blocks": 10,
"mossy_carpet_blocks": 1,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaSimpleBlockOracle.java": "d2f9843f8fb20d392cf19d14d1cdd99f0422cead8ef12487ff5b3b0e18576726",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaPlacementOracle.java": "12b1c46cc397755ef6827da777faef3e71c008cafa48403669c03ca2bdc3c7cb",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBlockSurvivalOracle.java": "4e7cc151617c1b02e872f9ca3e9fe4632379f225f4f07718ff6492df4ee551e7",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBlockPropertiesOracle.java": "e871d3a01f15616a98ca9227c27a81e4d17e2d57ac4e68a5650a70fa29811497",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBlockSupportOracle.java": "04350901a2d708fb8fa672de61d058f73f332d2e90df1b93a67781862f89c1ad",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBlockStateCodecOracle.java": "5c217a8cb72094020082bd4846ed675a6399b9fa371be95a221bd92d227b2e09",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaCollisionOracle.java": "60ff9ef7c1d5e23c080f9aec95ab2e7d3b7c5b5bcd67b9efa9518776c400629a",
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaHeightmapOracle.java": "145c943637ed177cc4ef8a85f2484da8afd164868e84a8463882feec1653a860",
"tools/test_simple_block_parity.py": "50b783323051fe8cd369bb733448b0314f1e6e7994a950e4cb6cd2fe4f7f8e11",
"tools/test_bonus_chest_parity.py": "c882c5a11b12d71b882c0653e48dbb3d9fac1319a366ca003b915a6e80f32c97",
"tools/test_block_survival_parity.py": "9e8dff3bd4b95dbfd29f8adc6a2f6d66abf19a6b1cd91423b794a345d4ec244a",
"tools/test_worldgen_parity.py": "b40972ab2ad222aa6d77537cc36b434a217baa1f1b56bbaad945d6e12fe776af",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"Cargo.toml": "dc370d5fdde37238c3e4820046f11c3201020406a4edfa1308257c13edbdcda4",
"Cargo.lock": "7307d0c887364db36d327685ecf0671b75305e31e5ba5fbdcdbb15eaf156d20e",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-world/Cargo.toml": "977338bf3e654193685b015d383493b9f59ff6f5d6210bec212cef8ac4a50bed",
"crates/horizon-core/src/bin/density_parity.rs": "e5b1dd33b7d01306c73cf072629b4fb186e9ab87b672a00108999d1a72263fd0",
"crates/horizon-core/src/bin/float_log_parity.rs": "4a655fcf8822ee7668c4bd126bc84d0b118864a6fc7f5a6aeee667d8bf2590b1",
"crates/horizon-core/src/bin/geometry_parity.rs": "27f6c09fe5018ac3de8e70e0f0bbf78f9abb14f5e4783bcaf46e8ca87b9c6f8a",
"crates/horizon-core/src/bin/noise_parity.rs": "c135bfc708d853e7061e81487d2cfe10de64b2f65677d3b4837cbfe0b8341010",
"crates/horizon-core/src/bin/parity.rs": "f35d928c66f958de39fac5e7e836a657eed95f83599e84899f7ea7a5802ba481",
"crates/horizon-core/src/bin/tick_parity.rs": "a54c164fe4814034d369947a887f5273966f5a878ba849204b80d1c729526a8f",
"crates/horizon-core/src/biome/seed_hash.rs": "5afbb4921c750826b395a08bf06f382fc7f01b5759a93de02a2749c523e2a317",
"crates/horizon-core/src/biome.rs": "908efa8cd4aa0a7adf1cb5e1a222e3dfb640eed5e9172e0fe7f0d1287afae7e8",
"crates/horizon-core/src/carving/ellipsoid.rs": "09232a7588610e8a9176fd9c62d40afb1fb89f2ecab6d555536a1d847b142d86",
"crates/horizon-core/src/carving.rs": "0aa3093caa0437868a8c0ed52a6c6e1993bd51c03583c670a2837e749eae5426",
"crates/horizon-core/src/density/arithmetic.rs": "372faec96c923e2cf4aa6c66c1ac398e676853274557823850dbc8933dd15ab1",
"crates/horizon-core/src/density/beardifier.rs": "bb1052e27dae4a01954ca78d7d5babafef85f3b2c704ccaf1920cb85a098cb50",
"crates/horizon-core/src/density/cache.rs": "38d0b6c9dd04ffef979fdad3f29cfebf98d331c8c9d430be5f39aa34f6c30975",
"crates/horizon-core/src/density/end_islands.rs": "168b9384237bd2e41d0ae5a74e944da4dc74e493bdec31fb73184c9a49e3de55",
"crates/horizon-core/src/density/graph/compiler.rs": "ac67deeb16f16d0859aa20e5a165811a29aca0b910037ee6bf5098211f3a6ede",
"crates/horizon-core/src/density/graph/mod.rs": "b776e7da934cb03051a3053d56d461c71e9978e084922fe4194147aa580c07bf",
"crates/horizon-core/src/density/graph/seeded.rs": "6bcdcaa3dffcfa9df673bbbea35120057a16ba3d2b506c52709c36cf8976b74a",
"crates/horizon-core/src/density/graph/tests.rs": "6bfb8cbff462587dd147b0775ea01d370abbd97544b9bd596c792df1b5f7e634",
"crates/horizon-core/src/density/interpolation.rs": "8c890f52b6467f38a94c654986a6a484b8e0b296ab98c398e60a6ce465b5b010",
"crates/horizon-core/src/density/interval.rs": "b42629163baa6b599a233afe8596d1c370cd81d015cc6fc36a9663aa47b98424",
"crates/horizon-core/src/density/mod.rs": "ca0d77d3282e3746ddcbc92bee97dbf640b9a56214e6ac1537f51f9a5b63d6e7",
"crates/horizon-core/src/density/power.rs": "d5b7270a128d4264268cd772109ad16d71a8ec3ff2d3b63b84cb985296d54a91",
"crates/horizon-core/src/density/rounding.rs": "71840c5206ff8d218ac29bf6f66915d5212764ba270c675711a866ba5b55a7a6",
"crates/horizon-core/src/density/selection.rs": "0dd26af2e85004ec5e053039ad11c384c17c56ace9ab45eb3f5cb3503c0b0330",
"crates/horizon-core/src/density/slice.rs": "5d77605573c0deda47778f1f78f7fa3fbf1944d8f5efbcc65cf589181cadf80b",
"crates/horizon-core/src/density/spline.rs": "6bb2e40f940fc6544d6fb09cb0b8cac722be03bc663dbdfb0f61faae207400bc",
"crates/horizon-core/src/density/surface.rs": "159e0e69cda74f870e80ea64fe523c4397e64af4ccb861bb9fd07b2c3cb91b00",
"crates/horizon-core/src/density/terrain_noise.rs": "8d0059d25eb5d248cb97a4c5a2e670d61528928ea151495c004f25adb723fe3e",
"crates/horizon-core/src/density/tests.rs": "7817796ee40d0ae241bfbebec6bca190e0a8e7d5a1caa8ddf858c3eaa58b8858",
"crates/horizon-core/src/density/world_fields.rs": "c1ce305cb8046b384d90c564cafb24af7365d580389637910f3d8b0cc18eb583",
"crates/horizon-core/src/geometry/mod.rs": "dc92f73885dd0a7760743bf74f1ab8afa839d61cef2dfef890f8a23b67b4742e",
"crates/horizon-core/src/geometry/movement.rs": "930e34abef6f6eeec1ee7a6c920b5ba01bfe37b90678884490f4be53241f6b96",
"crates/horizon-core/src/geometry/shape/create.rs": "189812b91d5e0e3ad963afcd1a6e2831b31b8188df91a904ef27061e644806ad",
"crates/horizon-core/src/geometry/shape/face.rs": "f243bce81384040a95ce7984b02b5699206c596c537b2713097e86005b4d3a5c",
"crates/horizon-core/src/geometry/shape/join.rs": "f1b51887b7bf9482557e3ffa99e136f2e5db07ceeb05fdb116adf45e87129075",
"crates/horizon-core/src/geometry/shape.rs": "e8d88a763de1525f77a30b99591641e8a8b80946263acbde035a9bcc356df960",
"crates/horizon-core/src/geometry/sweep.rs": "abd6009c61555161ef2f18b431b2aa384b126c0871cae8b96a62358498a56a1d",
"crates/horizon-core/src/geometry/traversal.rs": "77a3da570a0b85582b669cf4d841cba4b06327006dda26d4a26df4e8ce05bae4",
"crates/horizon-core/src/geometry/trig.rs": "05cef9341a298a474221a0556a11ddf47650393ea7a97b4b2022a4da6628fe37",
"crates/horizon-core/src/lib.rs": "47350edab5791f5074a54563ba98108818c5c6b1c5818a591388eab2ac9f5490",
"crates/horizon-core/src/noise/mod.rs": "1dab5a713abf702402e69ace1bf9e476bba544b0ede5a61c3c3afc60af0a03f3",
"crates/horizon-core/src/noise/normal.rs": "e9e7a46472a54a02c98c46da819842090567153b32fe0c84249009ef19af7aad",
"crates/horizon-core/src/noise/perlin.rs": "e73815447432eab7542f67366cb3f1b368d164e33f6c9cdbd045ac8e4db0932a",
"crates/horizon-core/src/noise/simplex.rs": "6c0dbc15b2b7510195dd28fceca01dcaac1847ccc4a84d299c351589c642fe7a",
"crates/horizon-core/src/noise/stack.rs": "7f6ef0e7d920139ef1a6ad3ec5640f92765715f86dcc5ec29f1a149984f45fa3",
"crates/horizon-core/src/noise/volume.rs": "3f05d2b1780acfdfee60037677d309937a5033b45ef428fc2d540942d4b56b43",
"crates/horizon-core/src/position/iter.rs": "32d2d8e74821cc4e49e3354202d35d3120e4415bfdda9375a73f2137ef651129",
"crates/horizon-core/src/position.rs": "e10101088e6902386b9b6d27773d44312f1ff72bebb19e57967a54945dde9dcd",
"crates/horizon-core/src/random/hash.rs": "0f88a127a1ba2705d3d6c0ebd009324d6ba86ffa2d27edf2d2a84765e690e4a3",
"crates/horizon-core/src/random/positional.rs": "35494745e5d4cf89e282c3ae0ee245e9f2640ddbbc03bc0055df742006a9c862",
"crates/horizon-core/src/random/worldgen.rs": "9f07ff33bcc038d34e27aa5465753bb21df18f2975e43cae201f709bc186945a",
"crates/horizon-core/src/random.rs": "ddb95d3a83e28ad605ff1f49f5df270cc543ca5ef1130e37d989dc74c8d861e6",
"crates/horizon-core/src/storage.rs": "f6c32201c64aefde06e57a2c767be46918df613548a322801546b133799cc33d",
"crates/horizon-core/src/ticks/generation.rs": "be1237e790693f633a61714ddae68c6506a777588a8a3ab5efbe53a35774dbd2",
"crates/horizon-core/src/ticks/heap.rs": "bf28afab8af77c3d243aa96cd8a1fb8d934140a4dbd07dbfdbf4e7908bb4b845",
"crates/horizon-core/src/ticks/index.rs": "1f1a6a568c2a30eafecb020ca4d5f5fc414860de85b8b381fc419a2e3e65c24a",
"crates/horizon-core/src/ticks/mod.rs": "01634630668172516b8b79d0907bad47f6e2c543a6d499c2fa4b201823b375cb",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "cec2af81d212d5eed7a2196e4cf0be2daf4cecf53248f78cc68f2190e4d83f9a",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/chunk.rs": "8843e6f48dbbc4245ce4e95564dfba3a4d7a051ba0b1577fb038c07adb0ff0f9",
"crates/horizon-world/src/collision.rs": "05313e0c1f3089524fe029f9aac3e439cd47f1c9584c8c7e154c9adcfa88c335",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/dynamic_support.rs": "e799b31e5120cfdb04e0b342f2097d610ed98ef8c4be031620ee00368d82df59",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/lib.rs": "a8cd85f6223668c1446ff103276d80937b9707d9a7dc619a176b1b1ceed36a4a",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "1eae82604d2b3377fd35aaa3a914a67e5af28f93923815a49e895b4d437433cd",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/worldgen/anchor.rs": "d156b8a0b147a274cdd143409b441f4f43edecde6e8ee14ef9cf0309f743143a",
"crates/horizon-world/src/worldgen/aquifer/config.rs": "fcd2cc3a520c1527c88f095a3b5d38487e7ebb1ccecc5f757f93d04a069add4f",
"crates/horizon-world/src/worldgen/aquifer/noise_based.rs": "74daaa389b5c3dfdc99214dfff256a9e172f83548d2326cbc941d9637cc53fb7",
"crates/horizon-world/src/worldgen/aquifer.rs": "cb4b66d87de3f9f79ae6ffe4badd6f0f44886cd42ad9de2771b8b56c4f1e28c7",
"crates/horizon-world/src/worldgen/bamboo.rs": "d9b47113c99be34256e58308bc6f40072ff25c579d6bf995182aa862c0006102",
"crates/horizon-world/src/worldgen/biome.rs": "3fe316b875aa32683759c337dc71f624910faf0812a2d6d83b8098d6d0bac7a0",
"crates/horizon-world/src/worldgen/biome_chunk.rs": "d6389c8d1adf900eb8f0e6c8833feafe43dc92d74e5c7ffa6f3950975529d624",
"crates/horizon-world/src/worldgen/biome_predicate.rs": "bfc581bc40077cc74ffda43e990a55fe997adc04c7130f98e039c3305ca79aac",
"crates/horizon-world/src/worldgen/biome_source/codec.rs": "2b9e4f5d679eb444cb73174f511e3b9f32e9eb138248ab12cffc6cfd76adf3a8",
"crates/horizon-world/src/worldgen/biome_source/runtime.rs": "f0b02c1521178e4d0377c6ca62694604b6a773f1f234f070ff0cde4685911d45",
"crates/horizon-world/src/worldgen/biome_source.rs": "e181e1736f3e0b75f7091a24c88de3fd116e01b98424d02382aea7a503d1eb54",
"crates/horizon-world/src/worldgen/biome_temperature.rs": "cde4bbab5e260c4065b113376c423b8511ade93c5aa5fd976e245ee8a58b5ad1",
"crates/horizon-world/src/worldgen/biome_weather.rs": "96b1f9494559ed31d06257b83d604d00cc069ccc8c7b68094117e034b4a71bd7",
"crates/horizon-world/src/worldgen/block_blob.rs": "c608c57b3d77279646ecb89e50677dd8e452b0422ffd357ba755536c5589eb89",
"crates/horizon-world/src/worldgen/block_column.rs": "f72c21a9066ee0aa68c2fb79fba436d05afb14c6ef5a2cb012f1ed35fc17cd22",
"crates/horizon-world/src/worldgen/block_feature.rs": "36b4e46ee7f7f73bcb94d8bce8d99013e4b16234c9a03542eeb3186e88dd1c21",
"crates/horizon-world/src/worldgen/block_pile.rs": "623e369b77e0526ed2756485a6c0bb09683cd28ad8876dea907360ca6665b39d",
"crates/horizon-world/src/worldgen/block_predicate.rs": "074c692367e3f2191a1bb28d87b23402430a843c246bd30a4ea838ee3500280e",
"crates/horizon-world/src/worldgen/blue_ice.rs": "eedd77bdaff808330b864166d303378096daa5c7d235e925770b171c05109247",
"crates/horizon-world/src/worldgen/bonus_chest.rs": "05d0f63fbc7412f13ba1fa37a7238114b8f70bfff318beb2dece590482d49cc0",
"crates/horizon-world/src/worldgen/bulk_section.rs": "eecf61532d7793f853884c5a18a7f436a59835c7b13d3ec9075804511553c9ba",
"crates/horizon-world/src/worldgen/carver/canyon.rs": "509c4d5a9d689849e98e894ab14a9fbf82d10707d38e9cc688ded3c4778df3e2",
"crates/horizon-world/src/worldgen/carver/generation.rs": "a4498d0d1457536de3922a08e9c40ccce8d2ef9cc263801c15a412327513c098",
"crates/horizon-world/src/worldgen/carver.rs": "46b251e28225fe1250de38f49dec5dacda4e2c4ba1e556e21e6d1e14e2651fc3",
"crates/horizon-world/src/worldgen/carving.rs": "4e77d4e5c4a0ca55ca3563b9bdf6f379342e0bdf9d019d60f7bc57ce4afb5fbd",
"crates/horizon-world/src/worldgen/climate/codec.rs": "d567adeb5d837816fca69102db51d790f71aec1b51c09298230d24612e400a14",
"crates/horizon-world/src/worldgen/climate/index.rs": "c5ce61679a5f0e0f2f0af2a373424effa124d0cce8250609eff38b7034650756",
"crates/horizon-world/src/worldgen/climate.rs": "1b9ad44407f40aee4c1cd5357a5c9c443c1b105728f01cf5c644072f99f8357e",
"crates/horizon-world/src/worldgen/decoration.rs": "75a79b20b21e133816e729f16e758be6165d0db18a64bfbd5fd3618325a2adf3",
"crates/horizon-world/src/worldgen/delta.rs": "c2bf49ddf3231d28c109e68871429bc13d76a7bebe14eb33e84aa856bdd66145",
"crates/horizon-world/src/worldgen/density.rs": "65a98c156a290a6b374ef670d28cd5dfbe0aa93171824d1bbd96422536273f84",
"crates/horizon-world/src/worldgen/disk.rs": "6f8f9e059755af44c9bfa1b91eba54a7d13fad811dce31717c5502d7f6df33d7",
"crates/horizon-world/src/worldgen/end_gateway.rs": "f53fde77d6a36a525cd15d890003b2c129d0689a4cbfa2cf443a0c2e3acae040",
"crates/horizon-world/src/worldgen/end_podium.rs": "8f6d0d6d60ff0fde63de5781e867239db321f82cf12639f0537d410a3731ee1d",
"crates/horizon-world/src/worldgen/feature.rs": "40500af71ee6628dfb27518262d99f08d0383ae6c7b9397452feef0c213eadd9",
"crates/horizon-world/src/worldgen/feature_catalog.rs": "efc7b17b227e71622ef34108be9abd010f5675b68ea0409fcab82581d9aab88a",
"crates/horizon-world/src/worldgen/feature_graph.rs": "dcc811a313ff93c477bb9e19325420b3cd0e64c8173d7bac68825cd5e19019a8",
"crates/horizon-world/src/worldgen/feature_region.rs": "ae7552027b2efc0db6299dc14ab04c28615e43b876b5d67644855fd7a047e33e",
"crates/horizon-world/src/worldgen/feature_sort.rs": "3488a093dfe1321aaa29d8a30cfb115d8e666a81bf195514e87b170de626835c",
"crates/horizon-world/src/worldgen/fluid_predicate.rs": "64197c9e63bebf1ce04bc280bfe980bb6c1b9aa887ca5cded904aeb0d9ae6c46",
"crates/horizon-world/src/worldgen/height_provider.rs": "368d4dc119854742a045c4a717679c921456da681fc5f71aa9b37102d6f33b47",
"crates/horizon-world/src/worldgen/material_condition/codec.rs": "09b909bc384472f76d163c8069ec6b507c7d5c6a028a36d5e0e3df20deff7b3b",
"crates/horizon-world/src/worldgen/material_condition/density.rs": "df9d0761e978e5010663ae8b44f2d6c1ecb4907331e333bdb6a2b487c1e107de",
"crates/horizon-world/src/worldgen/material_condition/library.rs": "a55534c5da97575a819af5a7dc0dbec9069993fa8b2619c6c9d5576946e683fa",
"crates/horizon-world/src/worldgen/material_condition/noise.rs": "ffb59cc6be2275d7a5621bf7d768527e74a8326ed7ad78618746711540921675",
"crates/horizon-world/src/worldgen/material_condition/rule.rs": "fed643352efbcb1f68f29b6241896617db889fc7c577a6247564e01922fec1fe",
"crates/horizon-world/src/worldgen/material_condition.rs": "d638dcb8cbcb5da20b3cb29602b0ae6a86c4fdf9d8c0fb725de8ec5fc108717e",
"crates/horizon-world/src/worldgen/material_extensions.rs": "ab806eb679d5116e1aebb64fca70e1499ae71f83c9507a8cb4c3201c2b1bf037",
"crates/horizon-world/src/worldgen/material_stage.rs": "698cbc786eff13c246e2bc2ea062401918cd4265899fbc3d53abc87e45a8e7a1",
"crates/horizon-world/src/worldgen/material_surface.rs": "5d37b90099df3d6da0845dab164e71469fb287019c2ee74bc6714f3b9d6d6d5b",
"crates/horizon-world/src/worldgen/ore_feature.rs": "83b89fd3be691c5412c0215b6abefdcaa44119a05aa41217e061970eb7e12ebd",
"crates/horizon-world/src/worldgen/placement/chain.rs": "9218399b4d3757f7bbc550d7729a7201f32a1c83a7030865e0c12aab8a80d116",
"crates/horizon-world/src/worldgen/placement/context.rs": "a278304795136677ad4b4933ea50c972b9729a1c671c03fa309c193e224b1fd6",
"crates/horizon-world/src/worldgen/placement/layer.rs": "a0f5ca776f33f9d4f72b8fdcd163426152e5e43cb4a7572fc1d4fc57bf965de1",
"crates/horizon-world/src/worldgen/placement.rs": "b0397e5818fae84358546193a95f84bcb0b5bffafce909e6fcb3386179ee8023",
"crates/horizon-world/src/worldgen/replace_blobs.rs": "bf3377d86d2570cd15288ba69dde64a2cf67c5bcbb9a31d0c23421964af74afa",
"crates/horizon-world/src/worldgen/router.rs": "2cee7cf15a0d2ada12be6b39d83e78177fd3033922e4f4cce87a64073cec2847",
"crates/horizon-world/src/worldgen/rule_test.rs": "d1662ec492489ebaa4b87e20f9a8c809dcf3a223a151211bd65ec241a63692fc",
"crates/horizon-world/src/worldgen/settings.rs": "a8fe87752e1982ef11cb67f8d80d8e3428b2c27db178044cb425ba803e689e59",
"crates/horizon-world/src/worldgen/simple_block.rs": "9ba1a88d5db4925f8c37366557887f776c805f9a6444781615b5dbaff52e92a4",
"crates/horizon-world/src/worldgen/snow_freeze.rs": "9040be3d5c7f8f0fd812d2df45e154bf8a9eeef038530b83fa4159d246eac35f",
"crates/horizon-world/src/worldgen/spike.rs": "eacf0d9d3d2bc3d4bcf62bc87555f90031138236a5bfef0eb5270204f7c2a4fc",
"crates/horizon-world/src/worldgen/spring.rs": "830849e9b89fcdf09e9b06fbefdcdebe3c8c3f82804f60b8bd5de04ba303cb62",
"crates/horizon-world/src/worldgen/state_provider/catalog.rs": "c8687e15a4887a9200c8d365857d801efaa8f90e669eee3e600a1db4905119eb",
"crates/horizon-world/src/worldgen/state_provider/noise.rs": "7ee369c2a032e5620cb9bdf9ee7adad1f70870fb0a27efb7b7c514d92f83491f",
"crates/horizon-world/src/worldgen/state_provider/properties.rs": "9909139aaca1dc4f743957257fadaa9d423d21fa401fa9abc050505f79365139",
"crates/horizon-world/src/worldgen/state_provider.rs": "be29ada818826a90afe01ab60916360fdfc4cbde5af15c9359cd56b1f1f7b156",
"crates/horizon-world/src/worldgen/tags.rs": "d35ded93fe6e95ea045cadcf4925e656dc34ef832b742179b9ad0cc49f902f31",
"crates/horizon-world/src/worldgen/terrain.rs": "b8fb9fb80a66a851d916f07f15df1a40b6cc95b49e71aaec4d4b4107f13d9f9f",
"crates/horizon-world/src/worldgen/underwater_magma.rs": "7317e40af5ee5a9780f90ce358fa5d3e7f5b3d513b731df6ff97754d9c2a0154",
"crates/horizon-world/src/worldgen/value_provider.rs": "3358b563db8cb0bc8a9cfbbe2b8b3e70941cd2d37a0b519fbb6545f8d0dcbb69",
"crates/horizon-world/src/worldgen/vines.rs": "ee9b79b65012bd86a838241d2ef708680f7fe8eafc8aa656dae9cf2abf3c6418",
"crates/horizon-world/src/worldgen/weighted.rs": "839840aae25302933bbd97a81a2336330e2d03a0ad1684e1e16ac769ed408e6b",
"crates/horizon-world/src/worldgen.rs": "6fc51d32f71db3d802354456bfef35133a05fa4cd11ed3ab9ea7287cc9bfcebe",
"crates/horizon-world/examples/simple_block_fixture.rs": "c2827b81f21886027d2a53ff41457586a4c6ed7eafe451906320922b11756ca0"
},
"fixtures_sha256": {
".local/rust-bonus-chest-parity/inputs.txt": "df73f89f50423ab3ef6b9615ee795eb2d95be8c5ae6e90ffe1a5a361789c7254",
".local/rust-bonus-chest-parity/block-properties.nbt": "1aba22092f70d16b8092014c058ddc210e4aaa77bac32f6ec62e4d0e91d92a99",
".local/rust-bonus-chest-parity/block-registry.nbt": "5042073c80753f9548cb8fdb5b1000f0e5a1220127a0cc3c6a75737e180bf9bb",
".local/rust-bonus-chest-parity/cached-collision.nbt": "f3a5c6a5b2d51dad6c52e486e2b9989e79fd55db1a9bda6196db399550b04078",
".local/rust-bonus-chest-parity/cached-support.nbt": "b6fdc9471b0b61e904206d3f099f4dc235aad6d723536c210be0cb7c3560d82c",
".local/rust-bonus-chest-parity/catalog.json": "93581107e3564e60261044fdca61e3b7f237b9e6724c14b86e335ccc01198ba9",
".local/rust-bonus-chest-parity/facts.json": "5e89a805514cabfe46e082d651db406b9479781e1d97b65faa2ab9f6f871309b",
".local/rust-bonus-chest-parity/feature-catalog.json": "c048c761c5084a40560731955cc999a364d14055bdd86fa50989a92e4a771286",
".local/rust-bonus-chest-parity/fluid-tags.json": "f1e5eb6d22ea7effbb118a2282709cfdeef1bfae4516b775a55ad7a4df29d7d0",
".local/rust-bonus-chest-parity/placement-definitions.json": "f8a972ec87c2352500af6481158a3192bdbf699951025639bea744e4127b97c4",
".local/rust-bonus-chest-parity/support-cached-states.json": "353945a58fe69b352925473f1693f9b14a9ad19f13c15159c4184f2c29258622",
".local/rust-bonus-chest-parity/survival-classes.json": "361832008eea0aa9151d367a125a19c6353d99a0b88b27dd0682f55b7954553e",
".local/rust-bonus-chest-parity/survival-extra-definitions.json": "170f2db5bc97a49fa25cc249540aa7f04beea455cdbaf43742ed9415f5090a02",
".local/rust-bonus-chest-parity/survival-placement-classes.json": "7fdbf48ab18c87098bbe1b6176cb81f4842b6c5d9a4d6bbaf7037ff61cb1848c",
".local/rust-bonus-chest-parity/survival-rules.json": "8805c18b3195bb1eac1f1e5281333df56e2892505f64023e5403c58ce2ec4368",
".local/rust-bonus-chest-parity/survival-support-tags.json": "15d88d5bb5ad10d65124d5abb2cc055d251b06d129bca7be06f55b43dc13f6fd",
".local/rust-bonus-chest-parity/tags.json": "36975358262568f32bf84778d63d9989a36e7394ed4796d70a34809a8f4a64f0"
},
"rust_output_sha256": "e0397cb071d5b1503138824af16d4f2c4c66c1f972825ed9e8d9d5e1cb3f8633",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "e0397cb071d5b1503138824af16d4f2c4c66c1f972825ed9e8d9d5e1cb3f8633",
"matched_output_lines": 1505542
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "e0397cb071d5b1503138824af16d4f2c4c66c1f972825ed9e8d9d5e1cb3f8633",
"matched_output_lines": 1505542
}
],
"scope": "Native BonusChestFeature unit codec, independently shuffled chunk X/Z coordinates, ordered heightmap candidate search, air short-circuit and second-read empty-context collision, chest writes, conditional randomizable-container loot seeding, north/east/south/west torch survival and writes. Every state participates in collision prefixes; complete searches cover absent/unrelated/actual native chest entities, repeated mutation, rejected writes, injected failures, both random modes, shuffled search exhaustion, sole viable columns, extreme coordinates/heights and placement composition. Actual ChestBlockEntity loot table and seed are compared; fixtures control heights and entity existence independently of writes. Loot generation, inventory behavior, automatic block-entity lifecycle, world updates and complete spawn generation remain pending."
}
@@ -48,6 +48,9 @@ struct World<'a, 'r, W, R> {
water_mask: u8,
survival: &'a BlockSurvivalRegistry<'r>,
support: &'a BlockSupportRegistry<'r>,
collision: &'a BlockCollisionRegistry<'r>,
loot_container: bool,
loot: BTreeMap<[i32; 3], (String, i64)>,
calls: i32,
fail: i32,
reject: i32,
@@ -181,6 +184,30 @@ impl<W: Write, R: RandomSource> PlacementContext for World<'_, '_, W, R> {
}
Ok(BiomeId(0))
}
fn state_collision_empty(
&mut self,
state: BlockStateId,
p: [i32; 3],
) -> Result<bool, PlacementQueryError> {
let collision = self.collision;
collision
.collision_shape(self, state, p)
.map(|shape| shape.is_empty())
.map_err(query)
}
fn set_block_entity_loot_table(
&mut self,
p: [i32; 3],
table: &str,
random: &mut impl RandomSource,
) -> Result<(), PlacementQueryError> {
self.event(format_args!("entity {} {} {}", p[0], p[1], p[2]))
.map_err(query)?;
if self.loot_container {
self.loot.insert(p, (table.into(), random.next_long()));
}
Ok(())
}
fn configure_end_gateway(
&mut self,
p: [i32; 3],
@@ -361,6 +388,7 @@ fn fixture<R: RandomSource>(
blocks: FeatureBlocks,
survival: &BlockSurvivalRegistry<'_>,
support: &BlockSupportRegistry<'_>,
collision: &BlockCollisionRegistry<'_>,
fluids: &FluidStateTable,
water_mask: u8,
out: &mut impl Write,
@@ -418,6 +446,9 @@ fn fixture<R: RandomSource>(
})
.transpose()?;
let mut world = World {
collision,
loot_container: f.get("loot_entity").and_then(Value::as_str) == Some("chest"),
loot: BTreeMap::new(),
gateway_entity: f.get("gateway_entity").and_then(Value::as_str) == Some("gateway"),
gateways: BTreeMap::new(),
biome,
@@ -500,6 +531,9 @@ fn fixture<R: RandomSource>(
for (p, state) in &world.states {
writeln!(world.out, "stored {} {} {} {}", p[0], p[1], p[2], state.0)?;
}
for (p, (table, seed)) in &world.loot {
writeln!(world.out, "loot {} {} {} {table} {seed}", p[0], p[1], p[2])?;
}
for (p, (exit, exact)) in &world.gateways {
writeln!(
world.out,
@@ -631,7 +665,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
&registry,
&properties,
support.clone(),
collision,
collision.clone(),
&definitions,
&tags.tags,
&fluid_tags.tags,
@@ -709,6 +743,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
blocks,
&survival,
&support,
&collision,
&fluids,
water_mask,
&mut out,
@@ -726,6 +761,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
blocks,
&survival,
&support,
&collision,
&fluids,
water_mask,
&mut out,
+1
View File
@@ -15,6 +15,7 @@ pub mod block_feature;
pub mod block_pile;
pub mod block_predicate;
pub mod blue_ice;
pub mod bonus_chest;
pub mod bulk_section;
pub mod carver;
pub mod carving;
@@ -0,0 +1,102 @@
//! Spawn bonus chest search, loot-table assignment and surrounding torches.
use super::{
DecodeError,
block_feature::FeatureBlockBindings,
feature::FeatureWorld,
placement::{PlacementContext, PlacementQueryError},
};
use crate::{heightmap::HeightmapType, registry::BlockStateId};
use horizon_core::random::{InvalidBound, RandomSource};
#[derive(Clone, Debug)]
pub struct BonusChestFeature {
air: [BlockStateId; 3],
chest: BlockStateId,
torch: BlockStateId,
}
#[derive(Debug)]
pub enum BonusChestError<E> {
World(E),
Query(PlacementQueryError),
Random(InvalidBound),
}
impl<E: std::fmt::Display> std::fmt::Display for BonusChestError<E> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::World(e) => e.fmt(f),
Self::Query(e) => e.fmt(f),
Self::Random(e) => e.fmt(f),
}
}
}
impl<E: std::error::Error + 'static> std::error::Error for BonusChestError<E> {}
impl BonusChestFeature {
pub fn new(bindings: &FeatureBlockBindings<'_>) -> Result<Self, DecodeError> {
let get = |name| {
bindings
.registry()
.default_state(name)
.ok_or_else(|| DecodeError::Registry(format!("unknown bonus chest block {name}")))
};
Ok(Self {
air: bindings.air,
chest: get("minecraft:chest")?,
torch: get("minecraft:torch")?,
})
}
pub fn place<W: FeatureWorld + PlacementContext>(
&self,
world: &mut W,
random: &mut impl RandomSource,
origin: [i32; 3],
) -> Result<bool, BonusChestError<W::Error>> {
let mut xs: [i32; 16] = std::array::from_fn(|i| (origin[0] & !15).wrapping_add(i as i32));
let mut zs: [i32; 16] = std::array::from_fn(|i| (origin[2] & !15).wrapping_add(i as i32));
for values in [&mut xs, &mut zs] {
for end in (2..=16).rev() {
let other = random
.next_int_bound(end as i32)
.map_err(BonusChestError::Random)? as usize;
values.swap(end - 1, other);
}
}
for x in xs {
for z in zs {
let y = world
.height(HeightmapType::MotionBlockingNoLeaves, x, z)
.map_err(BonusChestError::Query)?;
let p = [x, y, z];
if !self
.air
.contains(&world.block(p).map_err(BonusChestError::World)?)
{
let state = world.block(p).map_err(BonusChestError::World)?;
if !world
.state_collision_empty(state, p)
.map_err(BonusChestError::Query)?
{
continue;
}
}
world
.set_block(p, self.chest, 2)
.map_err(BonusChestError::World)?;
world
.set_block_entity_loot_table(p, "minecraft:chests/spawn_bonus_chest", random)
.map_err(BonusChestError::Query)?;
for [dx, dz] in [[0, -1], [1, 0], [0, 1], [-1, 0]] {
let at = [x.wrapping_add(dx), y, z.wrapping_add(dz)];
if world
.block_survives(self.torch, at)
.map_err(BonusChestError::Query)?
{
world
.set_block(at, self.torch, 2)
.map_err(BonusChestError::World)?;
}
}
return Ok(true);
}
}
Ok(false)
}
}
@@ -55,6 +55,7 @@ pub enum FeatureDefinition {
ReplaceBlobs(super::replace_blobs::ReplaceBlobsFeature),
EndPodium(super::end_podium::EndPodiumFeature),
EndGateway(super::end_gateway::EndGatewayFeature),
BonusChest(super::bonus_chest::BonusChestFeature),
Spike(super::spike::SpikeFeature),
BlueIce(super::blue_ice::BlueIceFeature),
UnderwaterMagma(super::underwater_magma::UnderwaterMagmaFeature),
@@ -88,6 +89,7 @@ pub enum FeatureExecutionError<E> {
ReplaceBlobs(super::replace_blobs::ReplaceBlobsError<E>),
EndPodium(super::end_podium::EndPodiumError<E>),
EndGateway(super::end_gateway::EndGatewayError<E>),
BonusChest(super::bonus_chest::BonusChestError<E>),
Spike(super::spike::SpikeError<E>),
BlueIce(super::blue_ice::BlueIceError<E>),
UnderwaterMagma(super::underwater_magma::UnderwaterMagmaError<E>),
@@ -112,6 +114,7 @@ impl<E: std::fmt::Display> std::fmt::Display for FeatureExecutionError<E> {
Self::ReplaceBlobs(e) => e.fmt(f),
Self::EndPodium(e) => e.fmt(f),
Self::EndGateway(e) => e.fmt(f),
Self::BonusChest(e) => e.fmt(f),
Self::Spike(e) => e.fmt(f),
Self::BlueIce(e) => e.fmt(f),
Self::UnderwaterMagma(e) => e.fmt(f),
@@ -306,6 +309,10 @@ impl FeatureDefinition {
)
.map(Self::ReplaceBlobs)
}
"minecraft:bonus_chest" => super::bonus_chest::BonusChestFeature::new(
blocks.ok_or(DecodeError::Field("bonus chest bindings"))?,
)
.map(Self::BonusChest),
"minecraft:end_gateway" => super::end_gateway::EndGatewayFeature::from_json(
json,
blocks.ok_or(DecodeError::Field("end gateway bindings"))?,
@@ -674,6 +681,9 @@ impl FeatureDefinition {
Self::ReplaceBlobs(feature) => feature
.place(world, random, origin)
.map_err(FeatureExecutionError::ReplaceBlobs),
Self::BonusChest(feature) => feature
.place(world, random, origin)
.map_err(FeatureExecutionError::BonusChest),
Self::EndGateway(feature) => feature
.place(world, origin)
.map_err(FeatureExecutionError::EndGateway),
@@ -26,6 +26,25 @@ pub enum LayerBlock {
Ground,
}
pub trait PlacementContext {
/// Test the already-read state's collision shape in an empty entity context.
fn state_collision_empty(
&mut self,
_state: crate::registry::BlockStateId,
_position: [i32; 3],
) -> Result<bool, PlacementQueryError> {
Err(PlacementQueryError::Unavailable)
}
/// Look up a randomizable container, then consume a loot seed only when one
/// exists. Missing or unrelated block entities are successful no-ops.
fn set_block_entity_loot_table(
&mut self,
_position: [i32; 3],
_table: &str,
_random: &mut impl horizon_core::random::RandomSource,
) -> Result<(), PlacementQueryError> {
Err(PlacementQueryError::Unavailable)
}
/// Look up the block entity at this position and set its exit only if it is
/// an End gateway. Missing or other entities are successful no-ops. The
/// owning world applies the gateway's dirty notification after the update.
+18
View File
@@ -731,3 +731,21 @@ fixture dependency: decoration retains its six-feature corpus independently of
region spring/tick/query probes; regenerated inputs are byte-identical to their
validated corpora. Gateway entity creation/removal, dirty propagation, exit search
and teleportation remain pending.
## Bonus chest placement and loot assignment
Bonus chest generation now independently shuffles the chunk's X and Z columns,
searches motion-blocking-no-leaves heights and checks air or empty collision.
After a chest write it looks up a randomizable container, consuming a loot seed
only when one exists, then checks torch survival in native horizontal order.
Rejected writes retain the subsequent entity and torch operations.
The [bonus-chest comparison](../benchmarks/rust-bonus-chest-2026-10-06/scoped-parity.json)
matches **1,505,542 lines per reference JAR** across **42,396 fixtures**. All
35,723 states participate in collision prefixes; complete searches cover both
random streams, missing/unrelated/chest entities, sole viable columns, exhausted
searches, repeated mutation, rejected writes, partial failures, extreme positions
and placement composition. Actual native chest loot-table and seed fields are
compared. Workspace tests and all-target Clippy pass. Heights and entity existence
are controlled by the fixture; inventory contents, loot generation, automatic
entity lifecycle and complete spawn generation remain pending.
@@ -67,6 +67,7 @@ public final class VanillaSimpleBlockOracle {
final JsonObject f;final PrintWriter out;final RandomSource random;final Holder<Biome> biome;int calls;
final TreeMap<BlockPos,BlockState> states=new TreeMap<>(Comparator.<BlockPos>comparingInt(BlockPos::getX).thenComparingInt(BlockPos::getY).thenComparingInt(BlockPos::getZ));
World(JsonObject f,PrintWriter out,RandomSource random){this.f=f;this.out=out;this.random=random;this.biome=f.has("biome")?Holder.direct(makeBiome(f.getAsJsonObject("biome"))):null;for(var raw:f.getAsJsonArray("states")){var v=raw.getAsJsonArray();states.put(pos(v),Block.stateById(v.get(3).getAsInt()));}}
final TreeMap<BlockPos,ChestBlockEntity> lootContainers=new TreeMap<>(Comparator.<BlockPos>comparingInt(BlockPos::getX).thenComparingInt(BlockPos::getY).thenComparingInt(BlockPos::getZ));
final TreeMap<BlockPos,TheEndGatewayBlockEntity> gateways=new TreeMap<>(Comparator.<BlockPos>comparingInt(BlockPos::getX).thenComparingInt(BlockPos::getY).thenComparingInt(BlockPos::getZ));
final Map<ChunkPos,ProtoChunk> chunks=new HashMap<>();
ProtoChunk chunk(BlockPos p) {
@@ -93,6 +94,12 @@ public final class VanillaSimpleBlockOracle {
if(name.equals("getRawBrightness")){var p=(BlockPos)args[0];event("light "+xyz(p)+" "+args[1]);return f.get("brightness").getAsInt();}
if(name.equals("getBlockEntity")){
var p=((BlockPos)args[0]).immutable();event("entity "+xyz(p));String mode=f.has("gateway_entity")?f.get("gateway_entity").getAsString():"none";
if(f.has("loot_entity")){
String lootMode=f.get("loot_entity").getAsString();
if(lootMode.equals("chest"))return lootContainers.computeIfAbsent(p,key->new ChestBlockEntity(key,Blocks.CHEST.defaultBlockState()));
if(lootMode.equals("other"))return new TheEndGatewayBlockEntity(p,Blocks.END_GATEWAY.defaultBlockState());
return null;
}
if(mode.equals("other"))return new ShulkerBoxBlockEntity(p,Blocks.SHULKER_BOX.defaultBlockState());
if(mode.equals("gateway"))return gateways.computeIfAbsent(p,key->new TheEndGatewayBlockEntity(key,Blocks.END_GATEWAY.defaultBlockState()){@Override public void setChanged(){event("gateway_changed "+xyz(key));}});
return null;
@@ -156,6 +163,7 @@ public final class VanillaSimpleBlockOracle {
handler.calls=0;try{out.println("place "+decoded.get().place(world,generator,random,origin));}catch(Stop|IllegalArgumentException error){out.println("place error");}
out.println("next "+random.nextLong()+" "+worldRandom.nextLong());out.println("calls "+handler.calls);
for(var entry:handler.states.entrySet())out.println("stored "+xyz(entry.getKey())+" "+Block.getId(entry.getValue()));
for(var entry:handler.lootContainers.entrySet())if(entry.getValue().getLootTable()!=null)out.println("loot "+xyz(entry.getKey())+" "+entry.getValue().getLootTable().identifier()+" "+entry.getValue().getLootTableSeed());
for(var entry:handler.gateways.entrySet()) {
var exit=TheEndGatewayBlockEntity.class.getDeclaredField("exitPortal");exit.setAccessible(true);var exact=TheEndGatewayBlockEntity.class.getDeclaredField("exactTeleport");exact.setAccessible(true);
out.println("gateway "+xyz(entry.getKey())+" "+xyz((BlockPos)exit.get(entry.getValue()))+" "+exact.getBoolean(entry.getValue()));
+40
View File
@@ -0,0 +1,40 @@
#!/usr/bin/env python3
"""Compare native bonus chest candidate search, loot assignment and torches."""
import itertools
import json
try:
from . import test_simple_block_parity as harness
except ImportError:
import test_simple_block_parity as harness
def corpus(facts, placement):
get=lambda name:facts['defaults']['minecraft:'+name]
def case(**extra):
value={'definition':json.dumps({'type':'bonus_chest'}),'mode':'feature','origin':[0,64,0],
'legacy':False,'seed':0,'world_seed':1,'fail':-1,'reject':0,'brightness':15,
'fallback':get('air'),'states':[],'repeats':1,'loot_entity':'chest'}
value.update(extra);return value
# Read each state's actual empty-context collision through a candidate prefix.
for state in range(len(facts['states'])):
yield case(fallback=state,fail=8)
names=['air','cave_air','void_air','stone','water','lava','tall_grass','oak_leaves','oak_slab','snow','shulker_box','moving_piston','powder_snow','chest','torch']
for legacy,seed,name,entity,fail,reject in itertools.product([False,True],[0,-1],names,['none','other','chest'],[-1,0,1,2,3,4,5,8,12,20],[0,1,3]):
yield case(legacy=legacy,seed=seed,fallback=get(name),loot_entity=entity,fail=fail,reject=reject,repeats=2)
for legacy,seed,entity in itertools.product([False,True],range(256),['none','chest']):
yield case(legacy=legacy,seed=seed,loot_entity=entity,air_above=63,fallback=get('stone'),repeats=2)
for legacy,origin,height in itertools.product([False,True],[[0,0,0],[-1,-64,-1],[16,319,16],[2147483647,-2147483648,-2147483648]],[-2147483648,-64,0,319,2147483647]):
yield case(legacy=legacy,origin=origin,height=height,air_above=height-1 if height>-2147483648 else -2147483648,fallback=get('stone'))
# Force search through many solid candidates before finding the sole air cell.
for legacy,seed in itertools.product([False,True],range(32)):
yield case(legacy=legacy,seed=seed,fallback=get('stone'),states=[[15,64,15,get('air')]])
for legacy,seed,fail,reject in itertools.product([False,True],[0,-1,987654321],[-1,0,5,20],[0,1,3]):
placed={'feature':{'type':'bonus_chest'},'placement':[{'type':'count','count':2},{'type':'in_square'}]}
yield case(definition=json.dumps(placed),mode='placed',legacy=legacy,seed=seed,fail=fail,reject=reject,air_above=63,fallback=get('stone'))
yield case(definition=json.dumps({'type':'overlay','features':[placed,{'feature':{'type':'bonus_chest'},'placement':[]}]}),legacy=legacy,seed=seed,fail=fail,reject=reject)
yield case(definition=json.dumps({'type':'bonus_chest','ignored':None}))
if __name__=='__main__':
harness.run(corpus,'rust-bonus-chest-parity',__file__,
'Native BonusChestFeature unit codec, independently shuffled chunk X/Z coordinates, ordered heightmap candidate search, air short-circuit and second-read empty-context collision, chest writes, conditional randomizable-container loot seeding, north/east/south/west torch survival and writes. Every state participates in collision prefixes; complete searches cover absent/unrelated/actual native chest entities, repeated mutation, rejected writes, injected failures, both random modes, shuffled search exhaustion, sole viable columns, extreme coordinates/heights and placement composition. Actual ChestBlockEntity loot table and seed are compared; fixtures control heights and entity existence independently of writes. Loot generation, inventory behavior, automatic block-entity lifecycle, world updates and complete spawn generation remain pending.')