mirror of
https://github.com/horizon-rust/horizon.git
synced 2026-11-07 02:56:17 -10:00
Retain vanilla biomes during below-zero regeneration
This commit is contained in:
1 parent
32ad4ba6aa
commit
18d0c44e8d
15 files changed
+814
-27
No files matched your search
@@ -0,0 +1,202 @@
|
||||
{
|
||||
"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": 40,
|
||||
"fills": 740,
|
||||
"block_queries": 24020,
|
||||
"retrogen_fills": 560,
|
||||
"resolver_queries": 2800,
|
||||
"sources_sha256": {
|
||||
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBiomeChunkOracle.java": "7fc0ed0e73178509939630ccb04b6b6737ebd1caf6bd16b4d9436dd9e5265bdf",
|
||||
"tools/test_biome_chunk_parity.py": "d0bbfa5a165f0e2eaabe9b825101a873d7934b2756fa4821b03afbafce3b4b3d",
|
||||
"tools/test_worldgen_parity.py": "b40972ab2ad222aa6d77537cc36b434a217baa1f1b56bbaad945d6e12fe776af",
|
||||
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
|
||||
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
|
||||
"Cargo.toml": "4f803d21656a1420555bee6369617ddc825219a2cf05f842a209b3f8eaa583ec",
|
||||
"Cargo.lock": "b1674833e1d5e66032589eea75643bf1c1eb2f2d6503e79ff7da8efa1b6d21dc",
|
||||
"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_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
|
||||
"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/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
|
||||
"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": "2995b209aa3dc24cfcbba405cf8b97a398efbc0de97bb04ef2f51abb4cd2b84c",
|
||||
"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/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
|
||||
"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": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
|
||||
"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/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
|
||||
"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": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
|
||||
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
|
||||
"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/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
|
||||
"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": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
|
||||
"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/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
|
||||
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f",
|
||||
"crates/horizon-world/examples/biome_chunk_fixture.rs": "810d00491e29b4fa91ef2e4447dc95314abc7191939a0c5f98306d57d36c0711"
|
||||
},
|
||||
"fixtures_sha256": {
|
||||
".local/rust-biome-chunk-parity/inputs.txt": "ee52367acd9cf70183e21b696204ac285f0ef371ccf057707790f0949283c20b"
|
||||
},
|
||||
"rust_output_sha256": "d70591bab59501e722318c80c7d8cdffba42342124edee804ebf0fb5b17cb9dd",
|
||||
"references": [
|
||||
{
|
||||
"side": "client",
|
||||
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
|
||||
"output_sha256": "d70591bab59501e722318c80c7d8cdffba42342124edee804ebf0fb5b17cb9dd",
|
||||
"matched_output_lines": 593152
|
||||
},
|
||||
{
|
||||
"side": "server",
|
||||
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
|
||||
"output_sha256": "d70591bab59501e722318c80c7d8cdffba42342124edee804ebf0fb5b17cb9dd",
|
||||
"matched_output_lines": 593152
|
||||
}
|
||||
],
|
||||
"scope": "Actual ChunkAccess.fillBiomesFromNoise, LevelChunkSection.fillBiomesFromNoise and chunk/section biome reads using synthetic registered holder identities. Ordered resolver queries, section contents and clamped/wrapped chunk lookups are compared after repeated fills and failures at section boundaries. Covers full supported aligned vertical bounds, generation bounds cutting through sections, negative/extreme chunk coordinates and 1..512 possible biome identities. Completed earlier sections survive failure while the failing section retains its previous values. Additional BelowZeroRetrogen.getBiomeResolver cases compare all three retained cave keys, a lookalike foreign namespace, ordinary keyed holders and a direct holder without a key. All four combinations of upgrade activation at resolver construction and after construction test the captured wrapping decision. Candidate invocation order, injected candidate failures, old-column reads with quart Y fixed to zero and X/Z wrapping, repeated fills, and overlap of generation bounds with the old column section are exercised. Synthetic generation bounds deliberately override the fixed native retrogen height to expose section commit/read ordering. Direct holder values and all keyed holders are identity-only placeholders; biome properties are not evaluated. This compares stored biome values and resolver behavior, not native in-memory palette layout, wire encoding, biome-source generation integration, nonempty blending or complete generated worlds."
|
||||
}
|
||||
@@ -0,0 +1,216 @@
|
||||
{
|
||||
"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": 396,
|
||||
"retrogen_fixtures": 144,
|
||||
"fills": 610,
|
||||
"biome_values": 728576,
|
||||
"block_queries": 93510,
|
||||
"preset_entries": {
|
||||
"minecraft:nether": 5,
|
||||
"minecraft:overworld": 7594
|
||||
},
|
||||
"source_fixtures": {
|
||||
"multi": 132,
|
||||
"fixed": 104,
|
||||
"checkerboard": 80,
|
||||
"end": 80
|
||||
},
|
||||
"sources_sha256": {
|
||||
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBiomeGenerationOracle.java": "790bcfaf5cf67a41b0abe0994cc64f44bf809142db464573d64a3a018df9014d",
|
||||
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaBiomeExport.java": "f9a773713cf21b69bfa10018b76f27b953bda140ede9934f43d3aa3091101cf5",
|
||||
"tools/test_biome_generation_parity.py": "3a48dfff639e261e58f07ab00126331f46ee31e65312171044e48d01b0926c45",
|
||||
"tools/test_worldgen_parity.py": "b40972ab2ad222aa6d77537cc36b434a217baa1f1b56bbaad945d6e12fe776af",
|
||||
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
|
||||
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
|
||||
"Cargo.toml": "4f803d21656a1420555bee6369617ddc825219a2cf05f842a209b3f8eaa583ec",
|
||||
"Cargo.lock": "b1674833e1d5e66032589eea75643bf1c1eb2f2d6503e79ff7da8efa1b6d21dc",
|
||||
"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_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
|
||||
"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/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
|
||||
"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": "2995b209aa3dc24cfcbba405cf8b97a398efbc0de97bb04ef2f51abb4cd2b84c",
|
||||
"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/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
|
||||
"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": "8fdfe6ebe3ffeca97611fd5991a5bc6b2783ea1c62f4d8ef3b2dd53c04a5dc1d",
|
||||
"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/chorus_plant.rs": "29224c164ede919e280a65a68f155c873e2c8fd0aa7d7e244d8fa9e468760250",
|
||||
"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": "da132fca9fdafb0d89a917d5f4b68c60b70fb33cadf948a107da0e35d83dcd91",
|
||||
"crates/horizon-world/src/worldgen/feature_region.rs": "df0ff142a461cafa9a3b42b949ad3376887f2be8d4ea5cc794a3ed2e977bb499",
|
||||
"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/speleothem.rs": "c71651c1c97818a8a85863e14414d6139ea3bdeb897fa422043bcc1499d99aae",
|
||||
"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": "fd1f2e0afc15daf66f484ea40a1f2b7013650bda0941b23c64c81ee9f79cb673",
|
||||
"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/write_zone.rs": "8e17a179764d3f68c05882aef35f6810c28a0000f9a83e58bd6030660b76e64e",
|
||||
"crates/horizon-world/src/worldgen.rs": "e8e9f099ee1fcec8eedce31805d676d3f89c18e84f494a147ffcbfee23d3d54f",
|
||||
"crates/horizon-world/examples/biome_generation_fixture.rs": "5beb21fbf872a05082f5b7a0531188990ae14d3f35421b118dd529db2b36ce30"
|
||||
},
|
||||
"fixtures_sha256": {
|
||||
".local/rust-biome-generation-parity/inputs.txt": "15c002f4aeeedfeccf9e26ab93c198fe089822dc702bf39740c81a92dd041f79",
|
||||
".local/rust-biome-generation-parity/registries.json": "c6868228cc1002755dab31d947e953cc4be785a1b6ae82697755817a238b7de9",
|
||||
".local/rust-biome-generation-parity/presets-client.json": "b03e2fbe85c191a22f333bc989bd2a73c66f0f9fbcd9ddb54774f17c247832e9",
|
||||
".local/rust-biome-generation-parity/presets-server.json": "b03e2fbe85c191a22f333bc989bd2a73c66f0f9fbcd9ddb54774f17c247832e9"
|
||||
},
|
||||
"rust_output_sha256": "e200d072cb701cba116f6d4375e36fd9ea8e4fec650ce0b86fd87cee7bf9cfdb",
|
||||
"references": [
|
||||
{
|
||||
"side": "client",
|
||||
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
|
||||
"output_sha256": "e200d072cb701cba116f6d4375e36fd9ea8e4fec650ce0b86fd87cee7bf9cfdb",
|
||||
"matched_output_lines": 834080
|
||||
},
|
||||
{
|
||||
"side": "server",
|
||||
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
|
||||
"output_sha256": "e200d072cb701cba116f6d4375e36fd9ea8e4fec650ce0b86fd87cee7bf9cfdb",
|
||||
"matched_output_lines": 834080
|
||||
}
|
||||
],
|
||||
"scope": "Actual ChunkGenerator.doCreateBiomes through NoiseBasedChunkGenerator with empty Blender, in ordinary and below-zero upgrade modes. Both bundled Overworld/Nether multi-noise preset tables are independently exported from authenticated JARs; Rust imports quantized tables and compiles climate routers itself. All seven bundled routers, both random modes, multiple seeds and distant positive/negative chunks are tested. Complete section biome values and subsequent BiomeManager block lookups are compared, including repeated generation with fresh density contexts and persistent previous-leaf search state, and generation bounds excluding top/bottom sections. Holders are identity placeholders; no biome properties are evaluated. Fixed, checkerboard and End source fixtures also run actual chunk generation through every bundled router, including real seeded End erosion, the central-island shortcut, distant coordinates and wrapped checkerboard shifts. Retrogen cases initialize patterned old biome columns, install actual below-zero metadata with a full target on an empty persisted-stage ProtoChunk, and use its native generation height. Four below-zero noise settings, all source kinds, fixed candidates for each of the three retained cave biomes, both random modes, signed/distant seeds and repeated fills are compared. Above-zero stored biomes remain checked alongside regenerated sections and block-level biome zoom. Rust composes seeded candidate resolvers with the independently tested retention fill. Preset builders, complete biome-source codecs, nonempty blending, complete terrain-stage scheduling and complete generated worlds remain pending."
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Original transport for native chunk biome fill order and failure state.
|
||||
use horizon_core::position::ChunkPos;
|
||||
use horizon_world::worldgen::biome_chunk::BiomeChunk;
|
||||
use horizon_world::{retrogen::RetrogenBiomeResolver, worldgen::biome_chunk::BiomeChunk};
|
||||
use serde_json::Value;
|
||||
use std::{
|
||||
fs,
|
||||
@@ -10,6 +10,16 @@ use std::{
|
||||
fn n(v: &Value) -> i32 {
|
||||
v.as_i64().unwrap() as i32
|
||||
}
|
||||
fn biome_key(id: &i32) -> Option<&str> {
|
||||
match *id {
|
||||
0 => Some("minecraft:lush_caves"),
|
||||
1 => Some("minecraft:dripstone_caves"),
|
||||
2 => Some("minecraft:deep_dark"),
|
||||
3 => Some("horizon:lush_caves"),
|
||||
511 => None,
|
||||
_ => Some("horizon:other"),
|
||||
}
|
||||
}
|
||||
fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
let arg = std::env::args().nth(1).expect("private fixture directory");
|
||||
let dir = Path::new(&arg);
|
||||
@@ -25,7 +35,7 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
)?;
|
||||
for op in f["ops"].as_array().unwrap() {
|
||||
let mut calls = 0;
|
||||
let result = chunk.fill(n(&op[3]), n(&op[4]), |[x, y, z]| {
|
||||
let resolve = |[x, y, z]: [i32; 3]| {
|
||||
writeln!(out, "resolve {x} {y} {z}").unwrap();
|
||||
let previous = calls;
|
||||
calls += 1;
|
||||
@@ -37,7 +47,20 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
.wrapping_add(z.wrapping_mul(17))
|
||||
.wrapping_add(n(&op[0]))
|
||||
.rem_euclid(n(&op[1])))
|
||||
});
|
||||
};
|
||||
let result = if let Some(before) = op.get(5) {
|
||||
// Native wrapper activation is captured before the later metadata
|
||||
// mutation at op[6]; filling still uses the supplied bounds.
|
||||
chunk.fill_with_retrogen(
|
||||
n(&op[3]),
|
||||
n(&op[4]),
|
||||
before.as_bool().unwrap(),
|
||||
resolve,
|
||||
biome_key,
|
||||
)
|
||||
} else {
|
||||
chunk.fill(n(&op[3]), n(&op[4]), resolve)
|
||||
};
|
||||
writeln!(
|
||||
out,
|
||||
"fill {} {calls}",
|
||||
@@ -57,6 +80,25 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
)?;
|
||||
}
|
||||
}
|
||||
if let Some(queries) = f["resolver_queries"].as_array() {
|
||||
for query in queries {
|
||||
let p = [n(&query[1]), n(&query[2]), n(&query[3])];
|
||||
let mut resolver =
|
||||
RetrogenBiomeResolver::new(query[4].as_bool().unwrap(), |[x, y, z]| {
|
||||
writeln!(out, "resolve_query {x} {y} {z}").unwrap();
|
||||
if n(&query[0]) < 0 {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(n(&query[0]))
|
||||
}
|
||||
});
|
||||
let result = resolver.sample(p, biome_key, |old| Ok(*chunk.noise_biome(old)));
|
||||
match result {
|
||||
Ok(value) => writeln!(out, "resolver_query {value}")?,
|
||||
Err(()) => writeln!(out, "resolver_query error")?,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
@@ -46,7 +46,12 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
);
|
||||
let climate = router.compile_climate(&mut compiler)?;
|
||||
let definition = match f["source"].as_str().unwrap_or("multi") {
|
||||
"fixed" => BiomeSourceDefinition::Fixed("minecraft:plains".into()),
|
||||
"fixed" => BiomeSourceDefinition::Fixed(
|
||||
f["fixed_biome"]
|
||||
.as_str()
|
||||
.unwrap_or("minecraft:plains")
|
||||
.into(),
|
||||
),
|
||||
"checkerboard" => BiomeSourceDefinition::Checkerboard {
|
||||
biomes: BiomeSet::Direct(vec![
|
||||
"minecraft:plains".into(),
|
||||
@@ -72,6 +77,18 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
height,
|
||||
"minecraft:plains".to_owned(),
|
||||
)?;
|
||||
let retrogen = f["retrogen"].as_bool().unwrap_or(false);
|
||||
if retrogen {
|
||||
chunk.fill(min, min + height - 1, |[x, y, z]| {
|
||||
Ok::<_, std::convert::Infallible>(format!(
|
||||
"horizon:old_{}",
|
||||
x.wrapping_mul(31)
|
||||
.wrapping_add(y.wrapping_mul(7))
|
||||
.wrapping_add(z.wrapping_mul(17))
|
||||
.rem_euclid(3)
|
||||
))
|
||||
})?;
|
||||
}
|
||||
for repeat in 0..n(&f["repeats"]) {
|
||||
let mut context = SamplerContext::cached();
|
||||
let volume = resolver.prepare_volume(
|
||||
@@ -79,11 +96,17 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
[cx.wrapping_shl(4) >> 2, min >> 2, cz.wrapping_shl(4) >> 2],
|
||||
[4, height >> 2, 4],
|
||||
)?;
|
||||
chunk.fill(n(&f["write_min"]), n(&f["write_max"]), |quart| {
|
||||
resolver
|
||||
.sample_prepared(&mut context, volume.as_ref(), quart)
|
||||
.map(str::to_owned)
|
||||
})?;
|
||||
chunk.fill_with_retrogen(
|
||||
n(&f["write_min"]),
|
||||
n(&f["write_max"]),
|
||||
retrogen,
|
||||
|quart| {
|
||||
resolver
|
||||
.sample_prepared(&mut context, volume.as_ref(), quart)
|
||||
.map(str::to_owned)
|
||||
},
|
||||
|name| Some(name),
|
||||
)?;
|
||||
writeln!(out, "fill {repeat}")?;
|
||||
for section in 0..height as usize / 16 {
|
||||
writeln!(out, "section {section}")?;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//! Below-zero upgrade metadata and resident block transformations.
|
||||
//! Generation scheduling and biome resolution remain separate.
|
||||
//! Generation scheduling remains owned by the caller.
|
||||
use crate::{chunk_status::ChunkStatus, compression::invalid, nbt::Tag};
|
||||
use std::io;
|
||||
|
||||
@@ -141,3 +141,40 @@ impl BelowZeroRetrogen {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
/// The native decoration decision is captured when the resolver is created.
|
||||
/// Removing upgrade metadata afterwards does not unwrap an existing resolver.
|
||||
/// Candidate sampling runs before deciding whether to read an old column biome.
|
||||
pub struct RetrogenBiomeResolver<F> {
|
||||
upgrading: bool,
|
||||
resolve: F,
|
||||
}
|
||||
impl<F> RetrogenBiomeResolver<F> {
|
||||
pub fn new<T, E>(upgrading: bool, resolve: F) -> Self
|
||||
where
|
||||
F: FnMut([i32; 3]) -> Result<T, E>,
|
||||
{
|
||||
Self { upgrading, resolve }
|
||||
}
|
||||
pub fn sample<T, E>(
|
||||
&mut self,
|
||||
quart: [i32; 3],
|
||||
biome_key: impl FnOnce(&T) -> Option<&str>,
|
||||
old_biome: impl FnOnce([i32; 3]) -> Result<T, E>,
|
||||
) -> Result<T, E>
|
||||
where
|
||||
F: FnMut([i32; 3]) -> Result<T, E>,
|
||||
{
|
||||
let candidate = (self.resolve)(quart)?;
|
||||
if !self.upgrading
|
||||
|| matches!(
|
||||
biome_key(&candidate),
|
||||
Some("minecraft:lush_caves" | "minecraft:dripstone_caves" | "minecraft:deep_dark")
|
||||
)
|
||||
{
|
||||
Ok(candidate)
|
||||
} else {
|
||||
old_biome([quart[0], 0, quart[2]])
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -66,6 +66,30 @@ impl<T: Clone> BiomeChunk<T> {
|
||||
min_y: i32,
|
||||
max_y: i32,
|
||||
mut resolve: impl FnMut([i32; 3]) -> Result<T, E>,
|
||||
) -> Result<(), BiomeFillError<E>> {
|
||||
self.fill_using_chunk(min_y, max_y, |quart, _| resolve(quart))
|
||||
}
|
||||
/// Decorate candidate sampling with the pinned below-zero biome policy.
|
||||
/// `upgrading` is captured once for this fill, as at native resolver creation.
|
||||
/// Keys describe holder identity; unkeyed/direct values must return `None`.
|
||||
pub fn fill_with_retrogen<E>(
|
||||
&mut self,
|
||||
min_y: i32,
|
||||
max_y: i32,
|
||||
upgrading: bool,
|
||||
resolve: impl FnMut([i32; 3]) -> Result<T, E>,
|
||||
biome_key: impl Fn(&T) -> Option<&str>,
|
||||
) -> Result<(), BiomeFillError<E>> {
|
||||
let mut resolver = crate::retrogen::RetrogenBiomeResolver::new(upgrading, resolve);
|
||||
self.fill_using_chunk(min_y, max_y, |quart, chunk| {
|
||||
resolver.sample(quart, &biome_key, |old| Ok(chunk.noise_biome(old).clone()))
|
||||
})
|
||||
}
|
||||
fn fill_using_chunk<E>(
|
||||
&mut self,
|
||||
min_y: i32,
|
||||
max_y: i32,
|
||||
mut resolve: impl FnMut([i32; 3], &Self) -> Result<T, E>,
|
||||
) -> Result<(), BiomeFillError<E>> {
|
||||
if min_y < self.min_y || max_y >= self.min_y + self.height || min_y > max_y {
|
||||
return Err(BiomeFillError::InvalidBounds);
|
||||
@@ -84,7 +108,7 @@ impl<T: Clone> BiomeChunk<T> {
|
||||
z.wrapping_add(dz),
|
||||
];
|
||||
values[index(dx, dy, dz)] =
|
||||
resolve(quart).map_err(BiomeFillError::Resolve)?;
|
||||
resolve(quart, self).map_err(BiomeFillError::Resolve)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,117 @@
|
||||
use horizon_core::position::ChunkPos;
|
||||
use horizon_world::{
|
||||
retrogen::RetrogenBiomeResolver,
|
||||
worldgen::biome_chunk::{BiomeChunk, BiomeFillError},
|
||||
};
|
||||
use std::cell::RefCell;
|
||||
|
||||
#[test]
|
||||
fn candidates_precede_old_columns_and_errors_short_circuit() {
|
||||
let events = RefCell::new(Vec::new());
|
||||
let mut resolver = RetrogenBiomeResolver::new(true, |p| {
|
||||
events.borrow_mut().push(p);
|
||||
if p[1] == 99 {
|
||||
Err("candidate")
|
||||
} else {
|
||||
Ok("minecraft:plains")
|
||||
}
|
||||
});
|
||||
let old = |p| {
|
||||
events.borrow_mut().push(p);
|
||||
Ok("horizon:old")
|
||||
};
|
||||
assert_eq!(
|
||||
resolver.sample([-3, -15, 8], |v| Some(*v), old),
|
||||
Ok("horizon:old")
|
||||
);
|
||||
assert_eq!(*events.borrow(), [[-3, -15, 8], [-3, 0, 8]]);
|
||||
events.borrow_mut().clear();
|
||||
assert_eq!(
|
||||
resolver.sample([1, 99, 2], |v| Some(*v), old),
|
||||
Err("candidate")
|
||||
);
|
||||
assert_eq!(*events.borrow(), [[1, 99, 2]]);
|
||||
assert_eq!(
|
||||
resolver.sample([1, -1, 2], |v| Some(*v), |_| Err("old")),
|
||||
Err("old")
|
||||
);
|
||||
for name in [
|
||||
"minecraft:lush_caves",
|
||||
"minecraft:dripstone_caves",
|
||||
"minecraft:deep_dark",
|
||||
] {
|
||||
let mut resolver = RetrogenBiomeResolver::new(true, |_| Ok::<_, ()>(name));
|
||||
assert_eq!(
|
||||
resolver.sample(
|
||||
[0, -1, 0],
|
||||
|v| Some(*v),
|
||||
|_| panic!("retained candidate must not read old column")
|
||||
),
|
||||
Ok(name)
|
||||
);
|
||||
assert_eq!(
|
||||
resolver.sample([0, -1, 0], |_| None, |_| Ok("old")),
|
||||
Ok("old")
|
||||
);
|
||||
}
|
||||
let mut normal = RetrogenBiomeResolver::new(false, |_| Ok::<_, ()>("candidate"));
|
||||
assert_eq!(
|
||||
normal.sample(
|
||||
[0, 0, 0],
|
||||
|_| panic!("normal resolver must not inspect keys"),
|
||||
|_| panic!("normal resolver must not read old columns")
|
||||
),
|
||||
Ok("candidate")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn upgrade_fill_preserves_columns_and_section_atomicity() {
|
||||
let mut chunk = BiomeChunk::new(ChunkPos::new(-1, 2), -64, 128, String::new()).unwrap();
|
||||
chunk
|
||||
.fill(-64, 63, |[x, y, z]| Ok::<_, ()>(format!("old:{x}:{y}:{z}")))
|
||||
.unwrap();
|
||||
let original = chunk.clone();
|
||||
let mut calls = 0;
|
||||
let result = chunk.fill_with_retrogen(
|
||||
-64,
|
||||
-1,
|
||||
true,
|
||||
|_| {
|
||||
calls += 1;
|
||||
if calls == 66 {
|
||||
Err("failure")
|
||||
} else {
|
||||
Ok("minecraft:plains".to_owned())
|
||||
}
|
||||
},
|
||||
|name| Some(name),
|
||||
);
|
||||
assert_eq!(result, Err(BiomeFillError::Resolve("failure")));
|
||||
for y in -16..-12 {
|
||||
for x in -4..0 {
|
||||
for z in 8..12 {
|
||||
assert_eq!(
|
||||
chunk.noise_biome([x, y, z]),
|
||||
original.noise_biome([x, 0, z])
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
for section in 1..8 {
|
||||
assert_eq!(chunk.section(section), original.section(section));
|
||||
}
|
||||
chunk
|
||||
.fill_with_retrogen(
|
||||
-64,
|
||||
-1,
|
||||
true,
|
||||
|_| Ok::<_, ()>("minecraft:lush_caves".to_owned()),
|
||||
|name| Some(name),
|
||||
)
|
||||
.unwrap();
|
||||
assert_eq!(chunk.noise_biome([-4, -16, 8]), "minecraft:lush_caves");
|
||||
for section in 4..8 {
|
||||
assert_eq!(chunk.section(section), original.section(section));
|
||||
}
|
||||
}
|
||||
+29
-1
@@ -71,7 +71,7 @@ block lookups use seeded fuzzy selection and clamped chunk reads.
|
||||
Both JARs independently export the preset tables and must agree: **7,594 Overworld
|
||||
entries** and **5 Nether entries**. Rust imports those quantized tables; preset
|
||||
builders remain unported. Registry-bound source codecs are described below. Reference holders
|
||||
supply identities without evaluating biome properties. The comparison uses empty
|
||||
supply identities without evaluating biome properties. That baseline uses empty
|
||||
blending and no below-zero retrogen. An additional 168 fixtures generate chunks through fixed, checkerboard and End
|
||||
sources using every bundled terrain router. They cover real seeded End erosion,
|
||||
the central-island boundary and wrapped checkerboard shifts. The [surface-stage integration](material-surfaces.md#chunk-surface-stage) now
|
||||
@@ -80,6 +80,34 @@ stored neighbor biome lookups. Saved biome palettes and complete world generatio
|
||||
remain pending.
|
||||
|
||||
|
||||
### Below-zero biome retention
|
||||
|
||||
`RetrogenBiomeResolver` captures whether an upgrade is active when the resolver
|
||||
is created. Later metadata changes do not add or remove its retention policy.
|
||||
It always samples the candidate first. Keyed `lush_caves`, `dripstone_caves` and
|
||||
`deep_dark` in the `minecraft` namespace are retained; other candidates read the
|
||||
old biome at the same quart X/Z and quart Y = 0. Unkeyed holders do not qualify.
|
||||
|
||||
`BiomeChunk::fill_with_retrogen` reads committed old sections while staging the
|
||||
current section separately. A failure preserves that section's old values;
|
||||
later sections can observe earlier completed writes. This matters when supplied
|
||||
generation bounds overlap the section selected by the clamped old-column read.
|
||||
|
||||
The [retention/fill report](../benchmarks/rust-retrogen-biome-fill-2026-10-06/scoped-parity.json)
|
||||
records **593,152 matching lines per reference JAR**, with 40 fixtures, 740 fills
|
||||
(560 decorated), and 2,800 direct resolver queries. It includes all activation
|
||||
timings, keyed and direct holders, foreign namespace lookalikes, callback failures,
|
||||
boundary sections and extreme coordinates.
|
||||
|
||||
The expanded [generation report](../benchmarks/rust-retrogen-biome-generation-2026-10-06/scoped-parity.json)
|
||||
records **834,080 matching lines per JAR** across **396 fixtures and 610 fills**.
|
||||
Its 144 added upgrade fixtures use actual native below-zero metadata and generation
|
||||
heights, patterned old biome columns, all source kinds, each retained cave biome,
|
||||
four settings with below-zero storage, both random modes and repeated fills.
|
||||
Every stored section and subsequent block-biome lookup is compared, including
|
||||
unchanged data above Y = 0. Nonempty blending, preset builders, full terrain-stage
|
||||
scheduling and complete saved-world integration remain pending.
|
||||
|
||||
## Fixed, checkerboard and End sources
|
||||
|
||||
`FixedBiomeSource` always returns its configured value. `CheckerboardBiomeSource`
|
||||
|
||||
@@ -921,3 +921,22 @@ also matches **3,028,057 lines per JAR** across 138 upgrade fixtures. Seven focu
|
||||
region tests, all-target Clippy and the region corpus test pass. These checks do
|
||||
not yet cover the biome resolver's cave-biome retention, structure restrictions,
|
||||
automatic scheduling or complete saved-world integration.
|
||||
|
||||
## Retained biomes during below-zero generation
|
||||
|
||||
The [biome-retention implementation](biome-lookup.md#below-zero-biome-retention)
|
||||
now preserves the pinned three cave-biome candidates and otherwise reads the old
|
||||
column at quart Y = 0. The resolver captures upgrade activation at construction;
|
||||
candidate failures precede fallback reads. Section fills preserve native commit
|
||||
ordering and partial-failure behavior while allowing access to old biome storage.
|
||||
|
||||
The [retention/fill comparison](../benchmarks/rust-retrogen-biome-fill-2026-10-06/scoped-parity.json)
|
||||
matches **593,152 lines per JAR** across 740 fills and 2,800 direct queries. The
|
||||
[generation integration](../benchmarks/rust-retrogen-biome-generation-2026-10-06/scoped-parity.json)
|
||||
matches **834,080 lines per JAR** across 396 fixtures and 610 fills, including 144
|
||||
upgrading chunks alongside the ordinary-generation cases. It executes actual
|
||||
native `ChunkGenerator.doCreateBiomes`, including retained-status old biome reads,
|
||||
native below-zero generation bounds, repeated fills and all biome-source kinds.
|
||||
This closes the resolver gap described in the preceding checkpoint. Nonempty
|
||||
blending, structure restrictions, automatic generation scheduling and complete
|
||||
saved-world/gameplay integration remain pending.
|
||||
@@ -10,13 +10,20 @@ import net.minecraft.world.level.*;
|
||||
import net.minecraft.world.level.biome.*;
|
||||
import net.minecraft.world.level.block.*;
|
||||
import net.minecraft.world.level.chunk.*;
|
||||
import net.minecraft.world.level.levelgen.BelowZeroRetrogen;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
|
||||
/** Original transport calling vanilla section-atomic biome fill and chunk reads. */
|
||||
public final class VanillaBiomeChunkOracle {
|
||||
public static void main(String[] args) throws Exception {
|
||||
net.minecraft.SharedConstants.tryDetectVersion();net.minecraft.server.Bootstrap.bootStrap();
|
||||
var ids=new IdMapper<Holder<Biome>>();
|
||||
for(int i=0;i<512;i++)ids.add(Holder.Reference.createStandAlone(new HolderOwner<Biome>(){},ResourceKey.create(Registries.BIOME,Identifier.parse("horizon:biome_"+i))));
|
||||
for(int i=0;i<512;i++) {
|
||||
String key=switch(i){case 0->"minecraft:lush_caves";case 1->"minecraft:dripstone_caves";case 2->"minecraft:deep_dark";case 3->"horizon:lush_caves";default->"horizon:biome_"+i;};
|
||||
// No biome properties are accessed; direct holders have no registry key.
|
||||
ids.add(i==511?Holder.direct(null):Holder.Reference.createStandAlone(new HolderOwner<Biome>(){},ResourceKey.create(Registries.BIOME,Identifier.parse(key))));
|
||||
}
|
||||
var upgrade=BelowZeroRetrogen.CODEC.parse(JsonOps.INSTANCE,JsonParser.parseString("{\"target_status\":\"minecraft:features\"}")).getOrThrow();
|
||||
Path dir=Path.of(args[1]);
|
||||
try(var out=new PrintWriter(Files.newBufferedWriter(dir.resolve(args[0]+".txt"),StandardCharsets.UTF_8))) {
|
||||
for(String line:Files.readAllLines(dir.resolve("inputs.txt"))) {
|
||||
@@ -27,11 +34,16 @@ public final class VanillaBiomeChunkOracle {
|
||||
chunk.setPersistedStatus(net.minecraft.world.level.chunk.status.ChunkStatus.BIOMES);
|
||||
for(var value:f.getAsJsonArray("ops")) {
|
||||
var op=value.getAsJsonArray();bounds[0]=op.get(3).getAsInt();bounds[1]=op.get(4).getAsInt();var calls=new int[1];boolean ok=true;
|
||||
try { chunk.fillBiomesFromNoise((x,y,z)->{
|
||||
try { BiomeResolver candidate=(x,y,z)->{
|
||||
out.println("resolve "+x+" "+y+" "+z);int previous=calls[0]++;
|
||||
if(previous==op.get(2).getAsInt())throw new IllegalStateException("synthetic provider failure");
|
||||
return ids.byId(Math.floorMod(x*31+y*7+z*17+op.get(0).getAsInt(),op.get(1).getAsInt()));
|
||||
});}catch(IllegalStateException error){ok=false;}
|
||||
};
|
||||
chunk.setBelowZeroRetrogen(op.size()>5&&op.get(5).getAsBoolean()?upgrade:null);
|
||||
var resolver=BelowZeroRetrogen.getBiomeResolver(candidate,chunk);
|
||||
chunk.setBelowZeroRetrogen(op.size()>6&&op.get(6).getAsBoolean()?upgrade:null);
|
||||
chunk.fillBiomesFromNoise(resolver);
|
||||
}catch(IllegalStateException error){ok=false;}
|
||||
out.println("fill "+(ok?"ok":"error")+" "+calls[0]);
|
||||
for(int section=0;section<height/16;section++) {
|
||||
out.println("section "+section);var data=chunk.getSection(section);
|
||||
@@ -39,6 +51,18 @@ public final class VanillaBiomeChunkOracle {
|
||||
}
|
||||
for(var q:f.getAsJsonArray("queries")){var a=q.getAsJsonArray();out.println("query "+ids.getId(chunk.getNoiseBiome(a.get(0).getAsInt(),a.get(1).getAsInt(),a.get(2).getAsInt())));}
|
||||
}
|
||||
if(f.has("resolver_queries"))for(var value:f.getAsJsonArray("resolver_queries")) {
|
||||
var q=value.getAsJsonArray();
|
||||
chunk.setBelowZeroRetrogen(q.get(4).getAsBoolean()?upgrade:null);
|
||||
var resolver=BelowZeroRetrogen.getBiomeResolver((x,y,z)->{
|
||||
out.println("resolve_query "+x+" "+y+" "+z);
|
||||
if(q.get(0).getAsInt()<0)throw new IllegalStateException("synthetic candidate failure");
|
||||
return ids.byId(q.get(0).getAsInt());
|
||||
},chunk);
|
||||
chunk.setBelowZeroRetrogen(q.get(5).getAsBoolean()?upgrade:null);
|
||||
try {out.println("resolver_query "+ids.getId(resolver.getNoiseBiome(q.get(1).getAsInt(),q.get(2).getAsInt(),q.get(3).getAsInt())));}
|
||||
catch(IllegalStateException error){out.println("resolver_query error");}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ public final class VanillaBiomeGenerationOracle {
|
||||
for(var e:bundle.getAsJsonObject("densities").entrySet())densities.register(ResourceKey.create(Registries.DENSITY_FUNCTION,Identifier.parse(e.getKey())),DensityFunctions.DIRECT_CODEC.parse(ops,JsonParser.parseString(e.getValue().getAsString())).getOrThrow(),RegistrationInfo.BUILT_IN);densities.freeze();
|
||||
var presets=new TreeMap<String,Climate.ParameterList<ResourceKey<Biome>>>();MultiNoiseBiomeSourceParameterList.knownPresets().forEach((preset,list)->presets.put(preset.id().toString(),list));
|
||||
var ids=new IdMapper<Holder<Biome>>();var holders=new TreeMap<String,Holder<Biome>>();
|
||||
var keys=new TreeSet<String>();keys.add("minecraft:plains");keys.addAll(List.of("minecraft:the_end","minecraft:end_highlands","minecraft:end_midlands","minecraft:small_end_islands","minecraft:end_barrens"));for(var list:presets.values())for(var entry:list.values())keys.add(entry.getSecond().identifier().toString());
|
||||
var keys=new TreeSet<String>();keys.add("minecraft:plains");keys.addAll(List.of("horizon:old_0","horizon:old_1","horizon:old_2"));keys.addAll(List.of("minecraft:the_end","minecraft:end_highlands","minecraft:end_midlands","minecraft:small_end_islands","minecraft:end_barrens"));for(var list:presets.values())for(var entry:list.values())keys.add(entry.getSecond().identifier().toString());
|
||||
for(var key:keys){var holder=Holder.Reference.<Biome>createStandAlone(new HolderOwner<Biome>(){},ResourceKey.create(Registries.BIOME,Identifier.parse(key)));holders.put(key,holder);ids.add(holder);}
|
||||
var factory=new PalettedContainerFactory(Strategy.createForBlockStates(Block.BLOCK_STATE_REGISTRY),Blocks.AIR.defaultBlockState(),null,Strategy.createForBiomes(ids),holders.get("minecraft:plains"),null);
|
||||
var fill=ChunkGenerator.class.getDeclaredMethod("doCreateBiomes",Blender.class,RandomState.class,ChunkAccess.class);fill.setAccessible(true);
|
||||
@@ -46,7 +46,7 @@ public final class VanillaBiomeGenerationOracle {
|
||||
for(var entry:presets.get(f.get("preset").getAsString()).values())entries.add(com.mojang.datafixers.util.Pair.of(entry.getFirst(),holders.get(entry.getSecond().identifier().toString())));
|
||||
BiomeSource source=MultiNoiseBiomeSource.createFromList(new Climate.ParameterList<>(entries));
|
||||
if(f.has("source"))switch(f.get("source").getAsString()) {
|
||||
case "fixed" -> source=new FixedBiomeSource(holders.get("minecraft:plains"));
|
||||
case "fixed" -> source=new FixedBiomeSource(holders.get(f.has("fixed_biome")?f.get("fixed_biome").getAsString():"minecraft:plains"));
|
||||
case "checkerboard" -> source=new CheckerboardColumnBiomeSource(HolderSet.direct(List.of(holders.get("minecraft:plains"),holders.get("minecraft:the_end"),holders.get("minecraft:nether_wastes"))),f.get("scale").getAsInt());
|
||||
case "end" -> {var constructor=TheEndBiomeSource.class.getDeclaredConstructor(Holder.class,Holder.class,Holder.class,Holder.class,Holder.class);constructor.setAccessible(true);source=constructor.newInstance(holders.get("minecraft:the_end"),holders.get("minecraft:end_highlands"),holders.get("minecraft:end_midlands"),holders.get("minecraft:small_end_islands"),holders.get("minecraft:end_barrens"));}
|
||||
default -> throw new IllegalArgumentException("unknown source");
|
||||
@@ -55,8 +55,11 @@ public final class VanillaBiomeGenerationOracle {
|
||||
var settings=new NoiseGeneratorSettings(NoiseSettings.create(min,height),Blocks.STONE.defaultBlockState(),Blocks.WATER.defaultBlockState(),router,material,List.of(),sea,false,Optional.empty(),legacy,NoiseGeneratorSettings.DebugFunctions.EMPTY);
|
||||
var generator=new NoiseBasedChunkGenerator(source,Holder.direct(settings));
|
||||
var bounds=LevelHeightAccessor.create(f.get("write_min").getAsInt(),f.get("write_max").getAsInt()-f.get("write_min").getAsInt()+1);
|
||||
var chunk=new ProtoChunk(new ChunkPos(f.get("cx").getAsInt(),f.get("cz").getAsInt()),UpgradeData.EMPTY,LevelHeightAccessor.create(min,height),factory,null){@Override public LevelHeightAccessor getHeightAccessorForGeneration(){return bounds;}};
|
||||
chunk.setPersistedStatus(net.minecraft.world.level.chunk.status.ChunkStatus.BIOMES);
|
||||
var chunk=new ProtoChunk(new ChunkPos(f.get("cx").getAsInt(),f.get("cz").getAsInt()),UpgradeData.EMPTY,LevelHeightAccessor.create(min,height),factory,null){@Override public LevelHeightAccessor getHeightAccessorForGeneration(){return f.has("retrogen")&&f.get("retrogen").getAsBoolean()?super.getHeightAccessorForGeneration():bounds;}};
|
||||
if(f.has("retrogen")&&f.get("retrogen").getAsBoolean()) {
|
||||
chunk.fillBiomesFromNoise((x,y,z)->holders.get("horizon:old_"+Math.floorMod(x*31+y*7+z*17,3)));
|
||||
chunk.setBelowZeroRetrogen(BelowZeroRetrogen.CODEC.parse(JsonOps.INSTANCE,JsonParser.parseString("{\"target_status\":\"minecraft:full\"}")).getOrThrow());
|
||||
} else chunk.setPersistedStatus(net.minecraft.world.level.chunk.status.ChunkStatus.BIOMES);
|
||||
for(int repeat=0;repeat<f.get("repeats").getAsInt();repeat++) {
|
||||
fill.invoke(generator,Blender.empty(),state,chunk);out.println("fill "+repeat);
|
||||
for(int section=0;section<height/16;section++){out.println("section "+section);var data=chunk.getSection(section);for(int y=0;y<4;y++)for(int z=0;z<4;z++)for(int x=0;x<4;x++)out.println("biome "+data.getNoiseBiome(x,y,z).unwrapKey().orElseThrow().identifier());}
|
||||
|
||||
@@ -6,7 +6,7 @@ class BiomeChunkCorpusTests(unittest.TestCase):
|
||||
def test_bounds_section_failure_and_query_coverage(self):
|
||||
fixtures = list(chunk.corpus())
|
||||
self.assertEqual(fixtures, list(chunk.corpus()))
|
||||
self.assertEqual(len(fixtures), 20)
|
||||
self.assertEqual(len(fixtures), 40)
|
||||
self.assertTrue(any(f['height'] == 4064 for f in fixtures))
|
||||
self.assertTrue(any(f['cx'] == -(2**31) for f in fixtures))
|
||||
for f in fixtures:
|
||||
@@ -18,6 +18,17 @@ class BiomeChunkCorpusTests(unittest.TestCase):
|
||||
for q in f['queries']:
|
||||
self.assertTrue(all(-(2**31) <= v < 2**31 for v in q))
|
||||
|
||||
def test_retained_keys_direct_holders_and_resolver_creation_timing(self):
|
||||
fixtures = [f for f in chunk.corpus() if 'resolver_queries' in f]
|
||||
self.assertEqual(len(fixtures), 20)
|
||||
self.assertTrue(any(f['min'] > 0 for f in fixtures))
|
||||
self.assertTrue(any(f['min'] + f['height'] <= 0 for f in fixtures))
|
||||
for f in fixtures:
|
||||
expected = {(False, False), (False, True), (True, False), (True, True)}
|
||||
self.assertEqual({tuple(op[5:7]) for op in f['ops'] if len(op) > 5}, expected)
|
||||
self.assertEqual({tuple(q[4:6]) for q in f['resolver_queries']}, expected)
|
||||
self.assertEqual({q[0] for q in f['resolver_queries']}, {-1, 0, 1, 2, 3, 4, 511})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -9,7 +9,7 @@ class BiomeGenerationCorpusTests(unittest.TestCase):
|
||||
'presets': {'minecraft:overworld': '[]', 'minecraft:nether': '[]'}}
|
||||
all_fixtures = list(generation.corpus(bundle))
|
||||
self.assertEqual({f.get('source', 'multi') for f in all_fixtures}, {'multi', 'fixed', 'checkerboard', 'end'})
|
||||
fixtures = [f for f in all_fixtures if 'source' not in f]
|
||||
fixtures = [f for f in all_fixtures if 'source' not in f and not f.get('retrogen')]
|
||||
self.assertEqual(all_fixtures, list(generation.corpus(bundle)))
|
||||
self.assertEqual(len(fixtures), 12)
|
||||
self.assertEqual(sum(f['repeats'] for f in fixtures), 16)
|
||||
@@ -22,6 +22,20 @@ class BiomeGenerationCorpusTests(unittest.TestCase):
|
||||
self.assertTrue(any(q[1] < f['min'] for q in f['queries']))
|
||||
self.assertTrue(any(q[1] >= f['min'] + f['height'] for q in f['queries']))
|
||||
|
||||
def test_upgrade_height_all_sources_and_retained_cave_candidates(self):
|
||||
bundle = {'settings': {
|
||||
'minecraft:overworld': json.dumps({'noise': {'min_y': -64, 'height': 384}}),
|
||||
'minecraft:end': json.dumps({'noise': {'min_y': 0, 'height': 128}})},
|
||||
'presets': {'minecraft:overworld': '[]', 'minecraft:nether': '[]'}}
|
||||
fixtures = [f for f in generation.corpus(bundle) if f.get('retrogen')]
|
||||
self.assertEqual(len(fixtures), 36)
|
||||
self.assertEqual({f['setting'] for f in fixtures}, {'minecraft:overworld'})
|
||||
self.assertEqual({f.get('source', 'multi') for f in fixtures}, {'multi', 'fixed', 'checkerboard', 'end'})
|
||||
self.assertEqual({f['fixed_biome'] for f in fixtures if 'fixed_biome' in f},
|
||||
{'minecraft:lush_caves', 'minecraft:dripstone_caves', 'minecraft:deep_dark'})
|
||||
self.assertTrue(all((f['write_min'], f['write_max'], f['repeats']) == (-64, -1, 2) for f in fixtures))
|
||||
self.assertTrue(all(any(q[1] == 0 for q in f['queries']) for f in fixtures))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
@@ -25,6 +25,21 @@ def corpus():
|
||||
ops=[[0,1,-1,minimum,maximum],[17,67,-1,minimum,maximum],[97,129,0,minimum,maximum],[5,2,63,minimum,maximum],[9,8,64,minimum,maximum],[123,512,65,minimum,maximum],[17,3,-1,minimum+1,maximum-1],[-2**31,67,-1,minimum,maximum]]
|
||||
yield {'cx':cx,'cz':cz,'min':minimum,'height':height,'default':rng.randrange(512),'ops':ops,'queries':queries}
|
||||
|
||||
# Retention uses an existing column at quart Y=0. Include fills that overlap
|
||||
# that column's section so later sections observe earlier committed sections.
|
||||
for minimum,height in [(-64,128),(-64,64),(-16,32),(0,32),(64,16)]:
|
||||
for cx,cz in [(0,0),(-1,2),(1875000,-1875000),(-2**31,2**31-1)]:
|
||||
maximum=minimum+height-1
|
||||
queries=[[-2**31,-2**31,2**31-1],[2**31-1,2**31-1,-2**31],[-1,0,1],[0,-16,0],[3,15,3]]
|
||||
ops=[[17,67,-1,minimum,maximum]]
|
||||
for before,after in [(False,False),(True,True),(False,True),(True,False)]:
|
||||
for salt,count,fail in [(19,512,-1),(0,3,-1),(7,512,0),(9,512,63),(17,512,64),(23,512,65)]:
|
||||
ops.append([salt,count,fail,minimum,maximum,before,after])
|
||||
ops.append([31,512,-1,minimum+1,maximum-1,before,after])
|
||||
resolver_queries=[[candidate,*q,before,after] for candidate in [0,1,2,3,4,511,-1]
|
||||
for before,after in [(False,False),(False,True),(True,False),(True,True)] for q in queries]
|
||||
yield {'cx':cx,'cz':cz,'min':minimum,'height':height,'default':4,'ops':ops,'queries':queries,'resolver_queries':resolver_queries}
|
||||
|
||||
|
||||
def main():
|
||||
parser=argparse.ArgumentParser(description=__doc__);parser.add_argument("--prepare",action="store_true");args=parser.parse_args()
|
||||
@@ -39,7 +54,7 @@ def main():
|
||||
fixtures=list(corpus());inputs=build/"inputs.txt";inputs.write_text("".join(json.dumps(f,separators=(",",":"))+"\n" for f in fixtures),encoding="utf-8")
|
||||
fixture_paths=[inputs];tested_fixtures=base.source_hashes(fixture_paths);classes=build/"classes";classes.mkdir(exist_ok=True)
|
||||
def run(command,name):
|
||||
with (build/(name+".log")).open("w",encoding="utf-8") as log:base.run(list(map(str,command)),stdout=log,stderr=subprocess.STDOUT)
|
||||
with (build/(name+".log")).open("w",encoding="utf-8") as log:subprocess.run(list(map(str,command)),cwd=lab.ROOT,check=True,timeout=3600,stdout=log,stderr=subprocess.STDOUT)
|
||||
dependency_path=os.pathsep.join(map(str,libraries))
|
||||
run(["javac","--release",lock["minecraft"]["java_major"],"-proc:none","-cp",str(jars["server"])+os.pathsep+dependency_path,"-d",classes,oracle],"compile-java")
|
||||
run(["cargo","build","--release","-p","horizon-world","--example","biome_chunk_fixture"],"compile-rust")
|
||||
@@ -56,9 +71,9 @@ def main():
|
||||
base.ensure_sources_unchanged(sources,tested_sources);base.ensure_sources_unchanged(fixture_paths,tested_fixtures)
|
||||
report={"schema":1,"minecraft":lock["minecraft"]["version"],"manifest_sha1":lock["minecraft"]["manifest_sha1"],"platform":platform.platform(),
|
||||
"java":subprocess.check_output(["java","--version"],text=True).splitlines()[0],"rustc":subprocess.check_output(["rustc","--version"],text=True).strip(),
|
||||
"fixtures":len(fixtures),"fills":sum(len(f["ops"]) for f in fixtures),"block_queries":sum(len(f["ops"])*len(f["queries"]) for f in fixtures),
|
||||
"fixtures":len(fixtures),"fills":sum(len(f["ops"]) for f in fixtures),"block_queries":sum(len(f["ops"])*len(f["queries"]) for f in fixtures),"retrogen_fills":sum(len(op)>5 for f in fixtures for op in f["ops"]),"resolver_queries":sum(len(f.get("resolver_queries",[])) for f in fixtures),
|
||||
"sources_sha256":tested_sources,"fixtures_sha256":tested_fixtures,"rust_output_sha256":lab.digest(build/"rust.txt","sha256"),"references":references,
|
||||
"scope":"Actual ChunkAccess.fillBiomesFromNoise, LevelChunkSection.fillBiomesFromNoise and chunk/section biome reads using synthetic registered holder identities. Ordered resolver queries, section contents and clamped/wrapped chunk lookups are compared after repeated fills and failures at section boundaries. Covers full supported aligned vertical bounds, generation bounds cutting through sections, negative/extreme chunk coordinates and 1..512 possible biome identities. Completed earlier sections survive failure while the failing section retains its previous values. This compares stored biome values, not native in-memory palette layout, wire encoding, biome-source generation, blending, retrogen or complete generated worlds."}
|
||||
"scope":"Actual ChunkAccess.fillBiomesFromNoise, LevelChunkSection.fillBiomesFromNoise and chunk/section biome reads using synthetic registered holder identities. Ordered resolver queries, section contents and clamped/wrapped chunk lookups are compared after repeated fills and failures at section boundaries. Covers full supported aligned vertical bounds, generation bounds cutting through sections, negative/extreme chunk coordinates and 1..512 possible biome identities. Completed earlier sections survive failure while the failing section retains its previous values. Additional BelowZeroRetrogen.getBiomeResolver cases compare all three retained cave keys, a lookalike foreign namespace, ordinary keyed holders and a direct holder without a key. All four combinations of upgrade activation at resolver construction and after construction test the captured wrapping decision. Candidate invocation order, injected candidate failures, old-column reads with quart Y fixed to zero and X/Z wrapping, repeated fills, and overlap of generation bounds with the old column section are exercised. Synthetic generation bounds deliberately override the fixed native retrogen height to expose section commit/read ordering. Direct holder values and all keyed holders are identity-only placeholders; biome properties are not evaluated. This compares stored biome values and resolver behavior, not native in-memory palette layout, wire encoding, biome-source generation integration, nonempty blending or complete generated worlds."}
|
||||
|
||||
lab.write_json(report_path,report);print(f"Scoped biome-chunk parity passed: {report_path}")
|
||||
|
||||
|
||||
@@ -31,6 +31,18 @@ def corpus(bundle):
|
||||
queries=[[cx*16+x,y,cz*16+z] for x in [-1,0,7,15,16] for z in [-1,0,7,15,16] for y in [minimum-1,minimum+17,minimum+height]]
|
||||
yield {'setting':setting,'preset':'minecraft:overworld','source':source,'scale':scale,'seed':seed,'legacy':legacy,'cx':cx,'cz':cz,'min':minimum,'height':height,'write_min':minimum,'write_max':minimum+height-1,'queries':queries,'repeats':2 if seed==0 else 1}
|
||||
|
||||
for setting,raw in sorted(bundle['settings'].items()):
|
||||
value=json.loads(raw);minimum=value['noise']['min_y'];height=value['noise']['height']
|
||||
if minimum != -64: continue
|
||||
for legacy in [False,True]:
|
||||
for mode in ['multi_overworld','multi_nether','fixed','cave_fixed','checkerboard','end']:
|
||||
for sample,(seed,cx,cz) in enumerate([(0,0,0),(-1,-2,3),(0x123456789abcdef,1875000,-1875000)]):
|
||||
queries=[[cx*16+x,y,cz*16+z] for x in [-1,0,7,15,16] for z in [-1,0,7,15,16] for y in [-65,-64,-17,-1,0,1,minimum+height-1,minimum+height]]
|
||||
fixture={'setting':setting,'preset':'minecraft:nether' if mode=='multi_nether' else 'minecraft:overworld','seed':seed,'legacy':legacy,'cx':cx,'cz':cz,'min':minimum,'height':height,'write_min':-64,'write_max':-1,'retrogen':True,'queries':queries,'repeats':2,'scale':2}
|
||||
if not mode.startswith('multi_'):fixture['source']='fixed' if mode=='cave_fixed' else mode
|
||||
if mode=='cave_fixed':fixture['fixed_biome']=['minecraft:lush_caves','minecraft:dripstone_caves','minecraft:deep_dark'][sample]
|
||||
yield fixture
|
||||
|
||||
|
||||
def main():
|
||||
parser=argparse.ArgumentParser(description=__doc__);parser.add_argument("--prepare",action="store_true");args=parser.parse_args()
|
||||
@@ -45,7 +57,7 @@ def main():
|
||||
tested_sources=base.source_hashes(sources)
|
||||
classes=build/"classes";classes.mkdir(exist_ok=True)
|
||||
def run(command,name):
|
||||
with (build/(name+".log")).open("w",encoding="utf-8") as log:base.run(list(map(str,command)),stdout=log,stderr=subprocess.STDOUT)
|
||||
with (build/(name+".log")).open("w",encoding="utf-8") as log:subprocess.run(list(map(str,command)),cwd=lab.ROOT,check=True,timeout=3600,stdout=log,stderr=subprocess.STDOUT)
|
||||
dependency_path=os.pathsep.join(map(str,libraries))
|
||||
run(["javac","--release",lock["minecraft"]["java_major"],"-proc:none","-cp",str(jars["server"])+os.pathsep+dependency_path,"-d",classes,oracle,exporter],"compile-java")
|
||||
bundle={}
|
||||
@@ -78,9 +90,9 @@ def main():
|
||||
base.ensure_sources_unchanged(sources,tested_sources);base.ensure_sources_unchanged(fixture_paths,tested_fixtures)
|
||||
report={"schema":1,"minecraft":lock["minecraft"]["version"],"manifest_sha1":lock["minecraft"]["manifest_sha1"],"platform":platform.platform(),
|
||||
"java":subprocess.check_output(["java","--version"],text=True).splitlines()[0],"rustc":subprocess.check_output(["rustc","--version"],text=True).strip(),
|
||||
"fixtures":len(fixtures),"fills":sum(f["repeats"] for f in fixtures),"biome_values":sum(f["repeats"]*f["height"]*4 for f in fixtures),"block_queries":sum(f["repeats"]*len(f["queries"]) for f in fixtures),"preset_entries":{name:len(json.loads(raw)) for name,raw in bundle["presets"].items()},"source_fixtures":{name:sum(f.get("source","multi")==name for f in fixtures) for name in ["multi","fixed","checkerboard","end"]},
|
||||
"fixtures":len(fixtures),"retrogen_fixtures":sum(f.get("retrogen",False) for f in fixtures),"fills":sum(f["repeats"] for f in fixtures),"biome_values":sum(f["repeats"]*f["height"]*4 for f in fixtures),"block_queries":sum(f["repeats"]*len(f["queries"]) for f in fixtures),"preset_entries":{name:len(json.loads(raw)) for name,raw in bundle["presets"].items()},"source_fixtures":{name:sum(f.get("source","multi")==name for f in fixtures) for name in ["multi","fixed","checkerboard","end"]},
|
||||
"sources_sha256":tested_sources,"fixtures_sha256":tested_fixtures,"rust_output_sha256":lab.digest(build/"rust.txt","sha256"),"references":references,
|
||||
"scope":"Actual ChunkGenerator.doCreateBiomes through NoiseBasedChunkGenerator with empty Blender and no retrogen. Both bundled Overworld/Nether multi-noise preset tables are independently exported from authenticated JARs; Rust imports quantized tables and compiles climate routers itself. All seven bundled routers, both random modes, multiple seeds and distant positive/negative chunks are tested. Complete section biome values and subsequent BiomeManager block lookups are compared, including repeated generation with fresh density contexts and persistent previous-leaf search state, and generation bounds excluding top/bottom sections. Holders are identity placeholders; no biome properties are evaluated. Fixed, checkerboard and End source fixtures also run actual chunk generation through every bundled router, including real seeded End erosion, the central-island shortcut, distant coordinates and wrapped checkerboard shifts. Preset builders, complete biome-source codecs, blending, retrogen, terrain-stage linkage and complete generated worlds remain pending."}
|
||||
"scope":"Actual ChunkGenerator.doCreateBiomes through NoiseBasedChunkGenerator with empty Blender, in ordinary and below-zero upgrade modes. Both bundled Overworld/Nether multi-noise preset tables are independently exported from authenticated JARs; Rust imports quantized tables and compiles climate routers itself. All seven bundled routers, both random modes, multiple seeds and distant positive/negative chunks are tested. Complete section biome values and subsequent BiomeManager block lookups are compared, including repeated generation with fresh density contexts and persistent previous-leaf search state, and generation bounds excluding top/bottom sections. Holders are identity placeholders; no biome properties are evaluated. Fixed, checkerboard and End source fixtures also run actual chunk generation through every bundled router, including real seeded End erosion, the central-island shortcut, distant coordinates and wrapped checkerboard shifts. Retrogen cases initialize patterned old biome columns, install actual below-zero metadata with a full target on an empty persisted-stage ProtoChunk, and use its native generation height. Four below-zero noise settings, all source kinds, fixed candidates for each of the three retained cave biomes, both random modes, signed/distant seeds and repeated fills are compared. Above-zero stored biomes remain checked alongside regenerated sections and block-level biome zoom. Rust composes seeded candidate resolvers with the independently tested retention fill. Preset builders, complete biome-source codecs, nonempty blending, complete terrain-stage scheduling and complete generated worlds remain pending."}
|
||||
|
||||
lab.write_json(report_path,report);print(f"Scoped biome-generation parity passed: {report_path}")
|
||||
|
||||
|
||||
Reference in new issue
Block a user