Implement shared component prototypes and ordered copy-on-write patches

This commit is contained in:
Ludovic Marie committed 2026-10-07 07:06:29 +02:00
1 parent 5d8ad5fc3a
commit c37a622f9c
7 files changed
+709

No files matched your search

@@ -0,0 +1,268 @@
{
"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": 4585,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaComponentPatchOracle.java": "c9a78740021f3529f30b9b127672f6b3f9f4ee8139b864edc08b32dfd18732ef",
"tools/test_component_patch_parity.py": "02c893ec443258f44ecc6a57f73a72419b0d08e45c0b8061e7e9417feb859216",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "6884c7209f007ab9ee742b9c3c73828cfa1c6753d35b5fe25a87cab5955b33f8",
"crates/horizon-core/Cargo.toml": "e21b502c949da93cf67826592459b687a8cbf737ef92fee514e3ed2cc7cd27ad",
"crates/horizon-world/Cargo.toml": "18bbad377a8047e4d4ecd0fc87d83d46d1c0f1ce2b8c47bbe64633e7b4420b57",
"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/border.rs": "1386f8080521231d05ba3e84d94a3e1d5218d35ccb3d5e9fe2bbb05a8739e573",
"crates/horizon-core/src/geometry/mod.rs": "c650386f9860e44a96c55f18c8f1428ca715fcb0bc5c2434db5b1caa43df27fe",
"crates/horizon-core/src/geometry/movement.rs": "bcfb452752940ce53ae6dc267a3c4eb29459046a063c1f884684ab4f4bd0068f",
"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": "4255e16837fde42a52ba118f60581d197c571bb530b60d635e506184ebf4db0b",
"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/text.rs": "e6553ddb5db5039e8dc4614b6a6dc9f35a26dc3d1673b68a04e72e7983b67abb",
"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/attribute_health.rs": "6135beb1baf9a55745ab95955bcd05e585e4042a6cffda0a14c13f05593e7186",
"crates/horizon-world/src/attributes/entity.rs": "56fb96b1beb9caaa769369bf7cddf522d2f2e84e241c213b51ae8d39d31a9f13",
"crates/horizon-world/src/attributes/mod.rs": "3d05ce2ff10c1b68540e3c87bbd2ac65c56a2e7b7127a7865b60890a2e9a690d",
"crates/horizon-world/src/attributes/operation_map.rs": "fc5bc8921d78ea6721a2eaa915e67483e2a33683927467bdba24f0492356ad97",
"crates/horizon-world/src/bin/worldgen_parity.rs": "3143ceb9b56eecfd7667e5feb5f9f0cd13cfb8754b38d4ea338dbba97f2819da",
"crates/horizon-world/src/block_collision.rs": "39207247f2f6dd3ddc77640229044246f91b32054563f88a435f1bd92ad2092c",
"crates/horizon-world/src/block_collision_scan.rs": "20802862364c110ff85eeaf48606596a8468b83768dda46b412d337958790b41",
"crates/horizon-world/src/block_entities.rs": "a9deae92e6e5a1fcf4f0476c33ea4d170ddad6fd4b3303e1bb66d933973d5e06",
"crates/horizon-world/src/block_entity_push.rs": "12ee91bf604946234b24a0da4333f07d1830ab9743a422d41c8d0afac7d49cfd",
"crates/horizon-world/src/block_landing.rs": "33083fe39266fbefec1b3ea1a19f2afc609791d189da247c895e116ad6eb266a",
"crates/horizon-world/src/block_placement.rs": "524f4892d50bab77b7d89d19f7b048ffe746996f2ed7f376db2c6ab00ed75c24",
"crates/horizon-world/src/block_properties.rs": "b0bd8a983336c48e488a20caa77dd5c39b1a74bbd14ebc03b3b64556a1c864fc",
"crates/horizon-world/src/block_render.rs": "8df52ee11aef406a1571198a64048062a0ef6864e0058d9293a57f64b73c916a",
"crates/horizon-world/src/block_support.rs": "ade4fbd47284b450dabdd682dc86138b2ac05a0fd379525d7110648908245476",
"crates/horizon-world/src/block_survival.rs": "28ce64375e09819a4f13da9cfbe37c08b5ad0daf01b289c1c360b4567e50e811",
"crates/horizon-world/src/blocking_item_damage.rs": "9b1ae81c5bd0aea5982e03da1973f15fd46757354b8dd539bbd27449cff45e6a",
"crates/horizon-world/src/blocking_rules.rs": "83c5e2105cec56a90182ce582e1c67ade2b189be6de1a34d08035000cc07c492",
"crates/horizon-world/src/chunk.rs": "795895284d6e615bcb2082fceacdfe7025c152fb2934bb43f598f17a00ab46f1",
"crates/horizon-world/src/chunk_status.rs": "dbb8583cfa775203c544d24d69e03720385428f15a267a561356c21f5025e9c7",
"crates/horizon-world/src/climbing.rs": "6cd2f919872ff0b726effddaa57eccb805b8eae43f9d01144716010853891879",
"crates/horizon-world/src/collision.rs": "a749794d5c27ccd6c0d964ad02f9dc31d49d9f4fe4b7366cd4bd8155e681b00b",
"crates/horizon-world/src/collision_context.rs": "2176c7034e07f547510a8327cdad9d3b63f26e4754032b76b7d5fe13166c333c",
"crates/horizon-world/src/combat_rules.rs": "01131f70d1acdd96a910e7f96deaa12e51a1e3bb9208085f04e3ec7b657d3cd4",
"crates/horizon-world/src/component_patch.rs": "3622244ccdee46e13956c64ffe9be6234e686adf58dbc3a24cece0f1814301a1",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/damage_immunity.rs": "fd39c41124d694e755cf7faadcf93c636df4042c78ec345092a856b5f952dbcf",
"crates/horizon-world/src/damage_reduction.rs": "f5a599ab11e077f526237018aeda803ea3c420c5b35c78ae9d85e32267e23bf3",
"crates/horizon-world/src/damage_source.rs": "24945e397a926d34695652980923609e4723e02fe6b6e56d4aaf673e45d759f7",
"crates/horizon-world/src/dynamic_support.rs": "5996bc1c436fb6215d8fc3d0bb4de5dd9b966d842d432580d624195771697fb8",
"crates/horizon-world/src/edge_backoff.rs": "5259d7aa44e64f88351d1556c44dd0edcad3b400a099c659755792efba7b5773",
"crates/horizon-world/src/entity_collision.rs": "09f2fd7f6cd56fc282f468ecfa765a94506929e9684bd3a5c90123e5b51cd627",
"crates/horizon-world/src/entity_fluid.rs": "02991040ae879a8914f09913128a3506e9e7a1ca33ffc0a22b5729a168346600",
"crates/horizon-world/src/entity_fluid_tick.rs": "4f9e070b88a73c98a4e2e659360ddd6edee636bca29377f1ea9011fd5a556f64",
"crates/horizon-world/src/entity_move.rs": "a40a50d3e841625a75d4cfbb7c2630ab5a62a574456567e7234f401ae8441b32",
"crates/horizon-world/src/entity_obstruction.rs": "a4b28a19bf83b23611c59d94535c488db37e4aee24b22c973c545910894a809f",
"crates/horizon-world/src/fall_damage.rs": "8c28e2933493569fe05dea22332024287d28b0746b514dd465681040b003296b",
"crates/horizon-world/src/fluid.rs": "a0a1f34ba94d8b59dc975becee8952960764d67ae08cf2d6a8bcd40a614b15c4",
"crates/horizon-world/src/fluid_box.rs": "b586af72b1c04a9354fe66205c28dc8b619e205ab9ea19a68232722e4b6e96c1",
"crates/horizon-world/src/fluid_flow.rs": "7c7e486b5c565df3602799648b37b879bcca51414337f607962d6c7951b86d05",
"crates/horizon-world/src/fluid_occupancy.rs": "26037579caeef6c8a5a2bde2c3d142d278558b76d77ebff401cee6e35f2ea961",
"crates/horizon-world/src/fluid_shape.rs": "28bb65a72f5bd074a354ba38a1b1707fcb0947537977a11540bba0adb85995c2",
"crates/horizon-world/src/food.rs": "3cf416fa632a5555a8116bb528a6e80bcb5b6b754b0748b4959ed310102418d3",
"crates/horizon-world/src/food_storage.rs": "58c433801a285efcc973638c11d694a41f85dc96703a3a7ce8d3673f3eb31d52",
"crates/horizon-world/src/free_space.rs": "913536bf4c85ddeeb378d76d1b5110b4175f5688e1a749f32fe6a6d86fbb478e",
"crates/horizon-world/src/ground_support.rs": "3e371d74ecede4d30beef0a7e8a2ee33463584a5b1ed3d852b394efcce1ffbe0",
"crates/horizon-world/src/heightmap.rs": "a5edef082b5af40d814421ea17e129b3b06d70abee6434ed263e4bba58571698",
"crates/horizon-world/src/interaction_shapes.rs": "f321284ddab440a394372b6dedc8b5cc29a653c0745251a9e96c650f21c33dea",
"crates/horizon-world/src/item_blocking.rs": "f6eee0d6d177cc3148960122327ba1b459a2f0e85241c1d9a3e40f0b8c169296",
"crates/horizon-world/src/item_durability.rs": "6a67fd660d771c59ffa9f4aa3225a25b56da31ea1079ca2efa4a915be6464179",
"crates/horizon-world/src/item_use.rs": "1d0a3afa61b60d356e81a063da79ec6cd38730315976640a591325fc4c8ab98c",
"crates/horizon-world/src/item_use_catalog.rs": "a9b53d2e816583239a75c3c61e78dacc5e3b27dee595be34b1c7fa169f17a571",
"crates/horizon-world/src/item_use_lifecycle.rs": "f9b29f42a528493d0d2521110d4f6e0bc89af8f579d539648cb7c3a9e68e31cd",
"crates/horizon-world/src/item_use_start.rs": "9996a9b90c313925cd90e78c02880f2a1d2ae65aef53f4ce081578a9dcd10c62",
"crates/horizon-world/src/lib.rs": "7b3c6671ac24942730e1c70cab097b7fcde8b63e556074557c499b9e824346a4",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/living_air.rs": "b2de36bb50bed15e2808fe4a874fcef07f9fea0d2c96385b7b5e8ee9560d4442",
"crates/horizon-world/src/living_damage.rs": "2b448209629b9bf2e678d667ad0d6c7fa22146892dd106b169d96b31b0df12bb",
"crates/horizon-world/src/living_fall.rs": "da0f176f4731e1c86e08bfeee8167742fd1b86380ff0e9304c13c1ce3f1c67ab",
"crates/horizon-world/src/living_fluid.rs": "d7cd914cfb2a1f4876ce0ae95e999bf0ff1af732cce3ab4a3aa2d1ab881c7339",
"crates/horizon-world/src/living_health.rs": "221659f85552424e937d503bba6d8003006b106ced042b32d3a6f6cc23e12ed0",
"crates/horizon-world/src/living_hurt.rs": "844239ad7d15c39629bb3cfc06ebae6d1cff20b7627468f26e0ee8dff3abdcb8",
"crates/horizon-world/src/living_landing.rs": "8bca4eb7977abc2b14fb7174be4ea355352106ea1e76ff5f3ad8696969d9eefd",
"crates/horizon-world/src/living_motion.rs": "56f8c84cfbe205a7a69912d5f76b52ef1efca149c1b6801d4684e25fb179aeb9",
"crates/horizon-world/src/main.rs": "fce57418b8c22a6a0a9044baa89ed3d9c243bc2e8413fea3ff0f32985daba021",
"crates/horizon-world/src/movement_emission.rs": "76e7d6f5b19c94676190f54389f9c4ce12cf89945ccfcb9c750de473223e7753",
"crates/horizon-world/src/movement_properties.rs": "6f01ab920b376a13f5ae12c3718f4dd067e1dff2b829585af00a8b2100f3775d",
"crates/horizon-world/src/movement_restitution.rs": "04b4fe0947e7e52576145bd8ed15920278e8a538afcc74d125eaca513dffa0ef",
"crates/horizon-world/src/movement_support.rs": "02d85cf572847f2e60b5a7f9d60b856888a67b3c1f4df03e81998c66fdf874be",
"crates/horizon-world/src/nbt.rs": "60262c3de8c8f68bc2da0370ccb17393d32b85f5f5022c6358599a7d32119ea6",
"crates/horizon-world/src/piston_movement.rs": "7a3fd2549a582b5f3a5c21aa05d67d944d62ca1105856679e100ac5b44e9a52f",
"crates/horizon-world/src/piston_shape.rs": "399c2337103b8e7e0eb5667227c5aa14f9549d6a467b7be7da3d0717f0263500",
"crates/horizon-world/src/player_food.rs": "f188dc110745bcc7acc15e6c521db943b06b404f69cd251bf74a345516070304",
"crates/horizon-world/src/player_health.rs": "79ecb6b4d7a044dc98e5552c53a5ac2724545b1c1cec4d797eb52576728e3480",
"crates/horizon-world/src/player_hurt.rs": "99c9bbd8587ec2dc287806049897b8034d2f5349ad47fc497b70d54148844a36",
"crates/horizon-world/src/player_travel.rs": "6841a677a900495eb6223031ef3ebe8d859bb98908dda0e2209e5f28839dc593",
"crates/horizon-world/src/powder_snow_collision.rs": "7289946a21478d11abfd2bdcdddff3d7f98e25bf6a68564fed45c3cc01ac2a36",
"crates/horizon-world/src/region.rs": "72b642e87fed37ed17f54d4c30f96c3b64d26c14bc0589c31ef40ff1616188fc",
"crates/horizon-world/src/registry/json.rs": "7a683afcd1742c5307756927d7f0aa779c7d7992af87d8d371dd98108728e235",
"crates/horizon-world/src/registry.rs": "f2e58b2b4d944ac8fc6226bd3352cefc3d2052d8473e02ccf7dc402b176df435",
"crates/horizon-world/src/registry_collision_scan.rs": "97cc950a9a4ba387b78e368f36d595f8664ab7730d132900d220ce23b92826ea",
"crates/horizon-world/src/registry_fall_ray.rs": "52935436132df505691144840dcbd858b15d00d8305997284e3a542ecf6bc0dc",
"crates/horizon-world/src/registry_fluid.rs": "b8959c05850cfeaaad1e4de8ca7c7d0d6ac56da9b2c1de3ebefa5871a11ed35e",
"crates/horizon-world/src/retrogen.rs": "6efd36a6293756688c1990a7965bd65609d7c5e2bf2a5f4f01d54932d2b9386b",
"crates/horizon-world/src/server_player_combat.rs": "a9743971581af86d926eeba42004d932caf83382c470dd98bf613cb9c417db58",
"crates/horizon-world/src/server_player_damage.rs": "828a4649fec3e9bda2dfe20aced8c95922c697321de2be4127bd4e5712ecbb7c",
"crates/horizon-world/src/suffocation.rs": "bed219dd5bbab6263b98fbe3d0eb512cb96c52ae847210efe49514d05f22f11e",
"crates/horizon-world/src/swimming.rs": "49d2dae13c109b37ff832cde98a857944ff45247b864a527b9c4f03ecca7a7b7",
"crates/horizon-world/src/synced_floats.rs": "f417aab280331ddd6f0ca265a12c0130c78b9924f407c7e07f198140501e6010",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/view_direction.rs": "e18120ae26dc5cf702b29fc4c8487088bab133c8ce5abce01226833fafb0d5a4",
"crates/horizon-world/src/water_splash.rs": "e0461ae1b2e8c851cca6e3251a188334293292201d7f80dc9e7d60fd1815f4d1",
"crates/horizon-world/src/world_movement.rs": "f8fe9e34f2395d2a04c839d1c8ba78e09ce493c26de6f6e4e237b9c19c061da5",
"crates/horizon-world/src/world_ray.rs": "879bdbbe12f56deb705cc183933431489e840b71eade40c33391eed5949c2e61",
"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": "74e4110fb19c4c4047192fd65c38015b8afc7f9fc50404d75380b5063808148c",
"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/component_patch_fixture.rs": "cb84b45649fda6c0cca3fe6bc798d7e41a6e3a8ed6edfc1ef6e5f01db1250948"
},
"fixtures_sha256": {
".local/rust-component-patch-parity/inputs.txt": "bb70bc0eca0351ea7bf3bee91ff2d1dbb03753ce42910bc8181501846659172e"
},
"rust_output_sha256": "03bed8f8da5e4965999e42081eae378ba343562ffa80b5415168b3a1963b03f0",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "03bed8f8da5e4965999e42081eae378ba343562ffa80b5415168b3a1963b03f0",
"matched_output_lines": 622680
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "03bed8f8da5e4965999e42081eae378ba343562ffa80b5415168b3a1963b03f0",
"matched_output_lines": 622680
}
],
"scope": "Actual PatchedDataComponentMap reads, set/remove return values, ordered patch iteration/key sets, apply versus unsanitized restore, fromPatch sanitation, saved patches and independent map copies. Immutable prototypes have at most seven keys so native builder order is defined without identity-hash tables. Integer and boxed-float values cover NaN/signed zero; generic Rust callers must supply native value equality and prototype order. Includes mutation-before-error for removal markers without prototype defaults. Component codecs, prototype hash-table construction, object identity hashes, mutable payload aliases and full item/inventory integration remain pending."
}
@@ -0,0 +1,136 @@
use horizon_world::component_patch::{ComponentMap, Patch, Prototype};
use serde_json::Value as Json;
use std::{
fs,
io::{self, Write},
path::Path,
};
#[derive(Clone, Debug, PartialEq)]
enum Value {
Int(i32),
Float(u32),
}
fn value(v: &Json) -> Option<Value> {
if v.is_null() {
None
} else if let Some(s) = v.as_str() {
let raw = u32::from_str_radix(s, 16).unwrap();
Some(Value::Float(if f32::from_bits(raw).is_nan() {
f32::NAN.to_bits()
} else {
raw
}))
} else {
Some(Value::Int(v.as_i64().unwrap() as i32))
}
}
fn text(v: Option<&Value>) -> String {
match v {
None => "none".into(),
Some(Value::Int(v)) => format!("i{v}"),
Some(Value::Float(v)) => format!("f{v:08x}"),
}
}
fn patch(v: &Json) -> Patch<usize, Value> {
Patch::new(
v.as_array()
.unwrap()
.iter()
.map(|v| (v[0].as_u64().unwrap() as usize, value(&v[1]))),
)
}
fn patch_text(p: &Patch<usize, Value>) -> String {
p.entries()
.iter()
.map(|(k, v)| format!("{k}={}", text(v.as_ref())))
.collect::<Vec<_>>()
.join(",")
}
fn snapshot(
out: &mut dyn Write,
maps: &[ComponentMap<usize, Value>; 3],
patches: &[Patch<usize, Value>; 3],
) -> io::Result<()> {
for (i, m) in maps.iter().enumerate() {
let entries = m
.entries()
.map(|(k, v)| format!("{k}={}", text(Some(v))))
.collect::<Vec<_>>()
.join(",");
let keys = m
.keys()
.iter()
.map(usize::to_string)
.collect::<Vec<_>>()
.join(",");
let values = (0..16)
.map(|k| text(m.get(&k)))
.collect::<Vec<_>>()
.join(",");
let flags = (0..16)
.filter(|k| m.has_non_default(k))
.fold(0u32, |v, k| v | (1 << k));
writeln!(
out,
"map {i} {} {entries} | {keys} | {values} | {flags} | {}",
m.len(),
patch_text(&m.as_patch())
)?;
}
for (i, p) in patches.iter().enumerate() {
writeln!(out, "patch {i} {}", patch_text(p))?;
}
writeln!(
out,
"equal {} {} {}",
maps[0] == maps[1],
maps[0] == maps[2],
maps[1] == maps[2]
)
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let arg = std::env::args().nth(1).unwrap();
let dir = Path::new(&arg);
let mut out = io::BufWriter::new(fs::File::create(dir.join("rust.txt"))?);
for line in fs::read_to_string(dir.join("inputs.txt"))?.lines() {
let f: Json = serde_json::from_str(line)?;
let base = Prototype::new(
f["prototype"]
.as_array()
.unwrap()
.iter()
.map(|v| (v[0].as_u64().unwrap() as usize, value(&v[1]).unwrap())),
);
let mut maps = std::array::from_fn(|_| ComponentMap::new(base.clone()));
let mut patches = std::array::from_fn(|_| Patch::new([]));
snapshot(&mut out, &maps, &patches)?;
for op in f["ops"].as_array().unwrap() {
let a = op["a"].as_u64().unwrap() as usize;
let b = op["b"].as_u64().unwrap() as usize;
let mut success = true;
match op["kind"].as_str().unwrap() {
"set" => {
match maps[a].set(op["key"].as_u64().unwrap() as usize, value(&op["value"])) {
Ok(v) => writeln!(out, "old {}", text(v.as_ref()))?,
Err(_) => success = false,
}
}
"remove" => {
let v = maps[a].remove(op["key"].as_u64().unwrap() as usize);
writeln!(out, "old {}", text(v.as_ref()))?;
}
"copy" => maps[b] = maps[a].clone(),
"save" => patches[b] = maps[a].as_patch(),
"apply" => maps[a].apply_patch(&patches[b]),
"restore" => maps[a].restore_patch(&patches[b]),
"clear" => maps[a].clear_patch(),
"build" => patches[b] = patch(&op["entries"]),
"from" => maps[a] = ComponentMap::from_patch(base.clone(), &patches[b]),
_ => panic!("operation"),
};
writeln!(out, "result {}", if success { "ok" } else { "error" })?;
snapshot(&mut out, &maps, &patches)?;
}
}
Ok(())
}
+190
View File
@@ -0,0 +1,190 @@
//! Shared immutable prototypes with ordered, copy-on-write component patches.
//! Keys stand for stable component-type identities. Callers supply prototype
//! iteration order and values whose equality matches their native component.
use std::{fmt, sync::Arc};
#[derive(Clone, Debug)]
pub struct Prototype<K, V>(Arc<Vec<(K, V)>>);
#[derive(Clone, Debug)]
pub struct Patch<K, V>(Arc<Vec<(K, Option<V>)>>);
#[derive(Clone, Debug)]
pub struct ComponentMap<K, V> {
prototype: Prototype<K, V>,
patch: Patch<K, V>,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct MissingPrototype;
impl fmt::Display for MissingPrototype {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str("removed component has no prototype value")
}
}
impl std::error::Error for MissingPrototype {}
fn index<K: Eq, V>(entries: &[(K, V)], key: &K) -> Option<usize> {
entries.iter().position(|(k, _)| k == key)
}
fn put<K: Eq, V>(entries: &mut Vec<(K, V)>, key: K, value: V) -> Option<V> {
if let Some(i) = index(entries, &key) {
Some(std::mem::replace(&mut entries[i].1, value))
} else {
entries.push((key, value));
None
}
}
fn remove<K: Eq, V>(entries: &mut Vec<(K, V)>, key: &K) -> Option<V> {
index(entries, key).map(|i| entries.remove(i).1)
}
fn map_equal<K: Eq, V: PartialEq>(a: &[(K, V)], b: &[(K, V)]) -> bool {
a.len() == b.len()
&& a.iter()
.all(|(k, v)| index(b, k).is_some_and(|i| b[i].1 == *v))
}
impl<K: Clone + Eq, V: Clone + PartialEq> Prototype<K, V> {
pub fn new(entries: impl IntoIterator<Item = (K, V)>) -> Self {
let mut values = Vec::new();
for (k, v) in entries {
put(&mut values, k, v);
}
Self(Arc::new(values))
}
pub fn get(&self, key: &K) -> Option<&V> {
index(&self.0, key).map(|i| &self.0[i].1)
}
pub fn entries(&self) -> &[(K, V)] {
&self.0
}
}
impl<K: Clone + Eq, V: Clone + PartialEq> Patch<K, V> {
/// None is an explicit removal, distinct from a missing patch entry.
pub fn new(entries: impl IntoIterator<Item = (K, Option<V>)>) -> Self {
let mut values = Vec::new();
for (k, v) in entries {
put(&mut values, k, v);
}
Self(Arc::new(values))
}
pub fn entries(&self) -> &[(K, Option<V>)] {
&self.0
}
}
impl<K: Clone + Eq, V: Clone + PartialEq> ComponentMap<K, V> {
pub fn new(prototype: Prototype<K, V>) -> Self {
Self {
prototype,
patch: Patch(Arc::new(Vec::new())),
}
}
pub fn from_patch(prototype: Prototype<K, V>, patch: &Patch<K, V>) -> Self {
let sanitized = patch.0.iter().all(|(k, v)| match v {
Some(v) => Some(v) != prototype.get(k),
None => prototype.get(k).is_some(),
});
if sanitized {
Self {
prototype,
patch: patch.clone(),
}
} else {
let mut result = Self::new(prototype);
result.apply_patch(patch);
result
}
}
pub fn prototype(&self) -> &Prototype<K, V> {
&self.prototype
}
pub fn get(&self, key: &K) -> Option<&V> {
match index(&self.patch.0, key) {
Some(i) => self.patch.0[i].1.as_ref(),
None => self.prototype.get(key),
}
}
pub fn has_non_default(&self, key: &K) -> bool {
index(&self.patch.0, key).is_some()
}
/// Vanilla set returns the prototype value for an earlier removal marker.
/// An unsanitized removal with no prototype causes an error after mutation.
pub fn set(&mut self, key: K, value: Option<V>) -> Result<Option<V>, MissingPrototype> {
let base = self.prototype.get(&key).cloned();
let entries = Arc::make_mut(&mut self.patch.0);
let previous = if value == base {
remove(entries, &key)
} else {
put(entries, key, value)
};
match previous {
Some(Some(v)) => Ok(Some(v)),
Some(None) => base.map(Some).ok_or(MissingPrototype),
None => Ok(base),
}
}
pub fn remove(&mut self, key: K) -> Option<V> {
let base = self.prototype.get(&key).cloned();
let entries = Arc::make_mut(&mut self.patch.0);
let previous = if base.is_some() {
put(entries, key, None)
} else {
remove(entries, &key)
};
previous.unwrap_or(base)
}
pub fn apply_patch(&mut self, patch: &Patch<K, V>) {
let entries = Arc::make_mut(&mut self.patch.0);
for (k, v) in patch.0.iter() {
if v.as_ref() == self.prototype.get(k) {
remove(entries, k);
} else {
put(entries, k.clone(), v.clone());
}
}
}
/// Restore preserves redundant values and removals, unlike apply_patch.
pub fn restore_patch(&mut self, patch: &Patch<K, V>) {
self.patch = patch.clone();
}
pub fn clear_patch(&mut self) {
self.patch = Patch(Arc::new(Vec::new()));
}
pub fn as_patch(&self) -> Patch<K, V> {
self.patch.clone()
}
pub fn len(&self) -> usize {
self.entries().count()
}
pub fn is_empty(&self) -> bool {
self.len() == 0
}
/// Patched values precede untouched prototype values; removed keys vanish.
pub fn entries(&self) -> impl Iterator<Item = (&K, &V)> {
self.patch
.0
.iter()
.filter_map(|(k, v)| v.as_ref().map(|v| (k, v)))
.chain(
self.prototype
.0
.iter()
.filter(|(k, _)| !self.has_non_default(k))
.map(|(k, v)| (k, v)),
)
}
/// Key-set order instead starts with prototype keys, then applies the patch.
pub fn keys(&self) -> Vec<K> {
let mut keys: Vec<_> = self.prototype.0.iter().map(|(k, _)| k.clone()).collect();
for (k, v) in self.patch.0.iter() {
let i = keys.iter().position(|key| key == k);
if v.is_some() {
if i.is_none() {
keys.push(k.clone());
}
} else if let Some(i) = i {
keys.remove(i);
}
}
keys
}
}
impl<K: Eq, V: PartialEq> PartialEq for ComponentMap<K, V> {
fn eq(&self, other: &Self) -> bool {
map_equal(&self.prototype.0, &other.prototype.0) && map_equal(&self.patch.0, &other.patch.0)
}
}
+1
View File
@@ -21,6 +21,7 @@ pub mod climbing;
pub mod collision;
pub mod collision_context;
pub mod combat_rules;
pub mod component_patch;
pub mod compression;
pub mod damage_immunity;
pub mod damage_reduction;
+16
View File
@@ -1594,3 +1594,19 @@ changes and component mutation sequences, override behavior, stackability,
durability and integer/float extremes. Targeted Clippy passes. The imported
projection does not implement all item components or their codecs; full inventory,
enchantment effects and stored gameplay integration remain pending.
`component_patch` stores shared immutable prototypes and ordered copy-on-write
patches. Set/remove return values, redundant-value sanitation, explicit removals,
unsanitized restoration, independent copies and saved patch snapshots retain
native behavior. Entry iteration emits patched values before untouched defaults;
key-set order instead applies the patch to the prototype's key sequence.
`python3 tools/test_component_patch_parity.py` compares actual native patched
maps. The [component-patch report](../benchmarks/rust-component-patch-2026-10-07/scoped-parity.json)
records **622,680 matching lines per JAR**, including integer/boxed-float equality,
NaN/signed zero, copy isolation and mutation-before-error when a restored removal
has no prototype default. Targeted Clippy passes. Prototypes have at most seven
keys in this suite; callers supply prototype order and native value equality.
Native large-prototype identity-hash ordering, codecs, mutable payload aliases
and full item/inventory integration remain pending.
@@ -0,0 +1,25 @@
package dev.horizonlab.parity;
import com.google.gson.*;import com.mojang.serialization.Codec;import java.io.*;import java.nio.file.*;import java.lang.reflect.*;import java.util.*;
import net.minecraft.core.component.*;
/** Actual patched maps, ordered immutable prototypes and shared copies. */
public final class VanillaComponentPatchOracle {
static DataComponentType<Object>[] keys;static Field patchMap;static Object removed;
static Object value(JsonElement v){if(v.isJsonNull())return null;if(v.getAsJsonPrimitive().isString())return Float.valueOf(Float.intBitsToFloat(Integer.parseUnsignedInt(v.getAsString(),16)));return Integer.valueOf(v.getAsInt());}
static String text(Object v){if(v==null||v==removed)return "none";if(v instanceof Float f)return "f"+String.format("%08x",Float.floatToIntBits(f));return "i"+v;}
static int id(Object key){for(int i=0;i<keys.length;i++)if(keys[i]==key)return i;throw new AssertionError();}
static DataComponentMap prototype(JsonArray a){var b=DataComponentMap.builder();for(var ev:a){var e=ev.getAsJsonArray();b.set(keys[e.get(0).getAsInt()],value(e.get(1)));}return b.build();}
static DataComponentPatch patch(JsonArray a){var b=DataComponentPatch.builder();for(var ev:a){var e=ev.getAsJsonArray();int k=e.get(0).getAsInt();var v=value(e.get(1));if(v==null)b.remove(keys[k]);else b.set(keys[k],v);}return b.build();}
static String patchText(DataComponentPatch p)throws Exception{var result=new StringJoiner(",");for(var e:((Map<?,?>)patchMap.get(p)).entrySet())result.add(id(e.getKey())+"="+text(e.getValue()));return result.toString();}
static void snapshot(PrintWriter out,PatchedDataComponentMap[] maps,DataComponentPatch[] patches)throws Exception{for(int i=0;i<maps.length;i++){var m=maps[i];var entries=new StringJoiner(",");for(var e:m)entries.add(id(e.type())+"="+text(e.value()));var ks=new StringJoiner(",");for(var k:m.keySet())ks.add(Integer.toString(id(k)));var values=new StringJoiner(",");int flags=0;for(int k=0;k<keys.length;k++){values.add(text(m.get(keys[k])));if(m.hasNonDefault(keys[k]))flags|=1<<k;}out.println("map "+i+" "+m.size()+" "+entries+" | "+ks+" | "+values+" | "+flags+" | "+patchText(m.asPatch()));}for(int i=0;i<patches.length;i++)out.println("patch "+i+" "+patchText(patches[i]));out.println("equal "+maps[0].equals(maps[1])+" "+maps[0].equals(maps[2])+" "+maps[1].equals(maps[2]));}
@SuppressWarnings("unchecked")public static void main(String[] args)throws Exception{net.minecraft.SharedConstants.tryDetectVersion();net.minecraft.server.Bootstrap.bootStrap();var removedField=Class.forName("net.minecraft.core.component.Removed").getDeclaredField("INSTANCE");removedField.setAccessible(true);removed=removedField.get(null);keys=new DataComponentType[16];for(int i=0;i<keys.length;i++)keys[i]=(DataComponentType<Object>)(DataComponentType<?>)DataComponentType.<Integer>builder().persistent(Codec.INT).build();patchMap=DataComponentPatch.class.getDeclaredField("map");patchMap.setAccessible(true);Path dir=Path.of(args[1]);try(var out=new PrintWriter(Files.newBufferedWriter(dir.resolve(args[0]+".txt")));var lines=Files.lines(dir.resolve("inputs.txt"))){for(var line:(Iterable<String>)lines::iterator){var f=JsonParser.parseString(line).getAsJsonObject();var base=prototype(f.getAsJsonArray("prototype"));PatchedDataComponentMap[] maps={new PatchedDataComponentMap(base),new PatchedDataComponentMap(base),new PatchedDataComponentMap(base)};DataComponentPatch[] patches={DataComponentPatch.EMPTY,DataComponentPatch.EMPTY,DataComponentPatch.EMPTY};snapshot(out,maps,patches);for(var ov:f.getAsJsonArray("ops")){var op=ov.getAsJsonObject();int a=op.get("a").getAsInt(),b=op.get("b").getAsInt();try{switch(op.get("kind").getAsString()){
case "set":out.println("old "+text(maps[a].set(keys[op.get("key").getAsInt()],value(op.get("value")))));break;
case "remove":out.println("old "+text(maps[a].remove(keys[op.get("key").getAsInt()])));break;
case "copy":maps[b]=maps[a].copy();break;
case "save":patches[b]=maps[a].asPatch();break;
case "apply":maps[a].applyPatch(patches[b]);break;
case "restore":maps[a].restorePatch(patches[b]);break;
case "clear":maps[a].clearPatch();break;
case "build":patches[b]=patch(op.getAsJsonArray("entries"));break;
case "from":maps[a]=PatchedDataComponentMap.fromPatch(base,patches[b]);break;
default:throw new AssertionError();}out.println("result ok");}catch(NullPointerException e){out.println("result error");}snapshot(out,maps,patches);}}}}
}
+73
View File
@@ -0,0 +1,73 @@
#!/usr/bin/env python3
"""Compare native component patch storage, ordered mutations and shared copies."""
import argparse
import json
import os
from pathlib import Path
import platform
import subprocess
import random
import struct
import math
try:
from . import lab, test_rust_parity as base
except ImportError:
import lab
import test_rust_parity as base
def corpus():
def op(kind,a=0,b=0,**kw):return dict(kind=kind,a=a,b=b,**kw)
values=[-2147483648,-1,0,1,2147483647,'00000000','80000000','7fc00000','7fa12345','ff800000','3f800000']
for initial in values:
for first in [None,*values]:
for second in [None,*values]:
yield dict(prototype=[[0,initial]],ops=[op('set',key=0,value=first),op('copy',b=1),op('save',b=0),op('set',key=0,value=second),op('remove',key=0),op('restore',a=2,b=0),op('set',a=2,key=0,value=second)])
yield dict(prototype=[],ops=[op('build',entries=[[0,None],[1,2],[0,None]]),op('restore'),op('set',key=0,value=1),op('clear'),op('from'),op('set',key=0,value=1)])
rng=random.Random(0x434f4d504f4e454e)
def val():return rng.choice(values) if rng.randrange(2) else (rng.randrange(-2147483648,2147483648) if rng.randrange(2) else f'{rng.getrandbits(32):08x}')
for _ in range(3000):
prototype=[[k,val()] for k in rng.sample(range(16),rng.randrange(8))]
ops=[]
for __ in range(rng.randrange(10,31)):
kind=rng.choice(['set','set','remove','copy','save','apply','restore','clear','build','from']);a=rng.randrange(3);b=rng.randrange(3)
if kind=='set':v=op(kind,a,b,key=rng.randrange(16),value=rng.choice([None,val()]))
elif kind=='remove':v=op(kind,a,b,key=rng.randrange(16))
elif kind=='build':v=op(kind,a,b,entries=[[rng.randrange(16),rng.choice([None,val()])] for ___ in range(rng.randrange(20))])
else:v=op(kind,a,b)
ops.append(v)
yield dict(prototype=prototype,ops=ops)
def main():
parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--prepare',action='store_true');args=parser.parse_args()
build=lab.LOCAL/'rust-component-patch-parity';build.mkdir(parents=True,exist_ok=True)
report_path=build/'report.json';report_path.unlink(missing_ok=True)
if args.prepare:lab.prepare()
lock,jars,libraries=base.verify_artifacts()
oracle=lab.ROOT/'mods/horizon/src/test/java/dev/horizonlab/parity/VanillaComponentPatchOracle.java'
sources=[oracle,Path(__file__),lab.ROOT/'tools/test_rust_parity.py',lab.ROOT/'tools/lab.py',lab.ROOT/'Cargo.toml',lab.ROOT/'Cargo.lock',lab.ROOT/'crates/horizon-core/Cargo.toml',lab.ROOT/'crates/horizon-world/Cargo.toml',*sorted((lab.ROOT/'crates/horizon-core/src').rglob('*.rs')),*sorted((lab.ROOT/'crates/horizon-world/src').rglob('*.rs')),lab.ROOT/'crates/horizon-world/examples/component_patch_fixture.rs']
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)
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')
def java(side,mode,path):
run(['java','-Xmx512M','-cp',os.pathsep.join([str(classes),str(jars[side]),dependency_path]),'dev.horizonlab.parity.VanillaComponentPatchOracle',mode,path],side+'-'+mode)
fixtures=list(corpus());inputs=build/'inputs.txt';inputs.write_text(''.join(json.dumps(value,separators=(',',':'))+'\n' for value in fixtures),encoding='utf-8')
fixture_paths=[inputs];tested_fixtures=base.source_hashes(fixture_paths)
run(['cargo','build','--release','-p','horizon-world','--example','component_patch_fixture'],'compile-rust')
metadata=json.loads(subprocess.check_output(['cargo','metadata','--no-deps','--format-version','1'],cwd=lab.ROOT,text=True))
binary=Path(metadata['target_directory'])/'release/examples'/('component_patch_fixture.exe' if os.name=='nt' else 'component_patch_fixture')
run([binary,build],'rust');references=[]
for side,jar in jars.items():
java(side,side,build);reference=build/f'{side}.txt';matched=base.compare(reference,build/'rust.txt')
references.append({'side':side,'jar_sha256':lab.digest(jar,'sha256'),'output_sha256':lab.digest(reference,'sha256'),'matched_output_lines':matched})
print(f'{side}: {matched:,} component patch output lines match Rust',flush=True)
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),'sources_sha256':tested_sources,'fixtures_sha256':tested_fixtures,'rust_output_sha256':lab.digest(build/'rust.txt','sha256'),'references':references,'scope':'Actual PatchedDataComponentMap reads, set/remove return values, ordered patch iteration/key sets, apply versus unsanitized restore, fromPatch sanitation, saved patches and independent map copies. Immutable prototypes have at most seven keys so native builder order is defined without identity-hash tables. Integer and boxed-float values cover NaN/signed zero; generic Rust callers must supply native value equality and prototype order. Includes mutation-before-error for removal markers without prototype defaults. Component codecs, prototype hash-table construction, object identity hashes, mutable payload aliases and full item/inventory integration remain pending.'}
lab.write_json(report_path,report);print(f'Scoped component patch parity passed: {report_path}')
if __name__=='__main__':main()