Implement synchronized float tables and reentrant update ordering

This commit is contained in:
Ludovic Marie committed 2026-10-07 04:53:08 +02:00
1 parent b4ae7cf88d
commit 5b6ce7faa9
7 files changed
+693

No files matched your search

@@ -0,0 +1,251 @@
{
"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": 3019,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaSyncedFloatsOracle.java": "567a871ed82ad0c0d1fef6f84cc2a68732ddae9110a9926c659af77933c6f61d",
"tools/test_synced_floats_parity.py": "64a2a3ef6c4ab63fcfd18fb3cd0442e2bbe2249481cbf7899aeadb3b6b61256f",
"tools/test_rust_parity.py": "29d3db08005873528894b45ca10dcd6278753650473b3eb574e53e06ede40ec6",
"tools/lab.py": "d00bf107fa01b6c579734a082c3ca4ade3018f0d6851d46844acf17574f66e64",
"Cargo.toml": "3f93319c1eb70dbd7ba25cd74ef343fbf35c52c7c4752f955605c58699cbff9d",
"Cargo.lock": "cb1e87d449114a63edd904c0559d631e8fa9feeb27efd6539aacdcfeae178876",
"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/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/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/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/damage_reduction.rs": "f5a599ab11e077f526237018aeda803ea3c420c5b35c78ae9d85e32267e23bf3",
"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/lib.rs": "fc5fe4b491968e0c70c46561cf548138469c93f76629e1f9b20016f94b22e8d2",
"crates/horizon-world/src/liquid_collision.rs": "0f0a83b04e5a5bc9d98ed05fde4d6584ba69642e93522e726e4cfc325d6fcb1d",
"crates/horizon-world/src/living_air.rs": "b2de36bb50bed15e2808fe4a874fcef07f9fea0d2c96385b7b5e8ee9560d4442",
"crates/horizon-world/src/living_damage.rs": "711e78438ece3e94eb156c0e64cfea06a63f79640a7a81e396ae2c1b277cdce6",
"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_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_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/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/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": "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/synced_floats_fixture.rs": "71858a47a15cb62eb8b53dfb507d6e2e96d23dda04b84bdd660b49301eeb9757"
},
"fixtures_sha256": {
".local/rust-synced-floats-parity/inputs.txt": "22904cc4d2748db510a0a5935c1024fb2d8d5bc9ce994b414cf6d265d6ca60c9"
},
"rust_output_sha256": "80bb47d39c2d89981b03a0dd25715fcf9ab6d3f41671e9074f3a143b0bc78c2b",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "80bb47d39c2d89981b03a0dd25715fcf9ab6d3f41671e9074f3a143b0bc78c2b",
"matched_output_lines": 554909
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "80bb47d39c2d89981b03a0dd25715fcf9ab6d3f41671e9074f3a143b0bc78c2b",
"matched_output_lines": 554909
}
],
"scope": "Actual SynchedEntityData Float fields: boxed equality, forced updates, callback-before-dirty flags, ordered dirty/default extraction, received assignment including duplicates, partial unknown-ID/observer failures, batch callbacks and reentrant set/assign/pack. Native table gaps are untouched default dummy Float items; tested keys are explicit configured IDs. Other serializers, type-mismatch errors, wire codecs and player absorption integration remain pending."
}
@@ -0,0 +1,161 @@
use horizon_world::synced_floats::{DataError, FloatValue, Observer, SyncedFloats};
use serde_json::Value;
use std::{
fs,
io::{self, Write},
path::Path,
};
fn single(v: &Value) -> f32 {
f32::from_bits(u32::from_str_radix(v.as_str().unwrap(), 16).unwrap())
}
fn bits(v: f32) -> u32 {
if v.is_nan() {
f32::NAN.to_bits()
} else {
v.to_bits()
}
}
fn parse(v: &Value) -> Vec<FloatValue> {
v.as_array()
.unwrap()
.iter()
.map(|v| FloatValue {
id: v["id"].as_u64().unwrap() as u8,
value: single(&v["value"]),
})
.collect()
}
fn values(v: Option<&[FloatValue]>) -> String {
match v {
None => "none".into(),
Some([]) => "empty".into(),
Some(v) => v
.iter()
.map(|v| format!("{}:{:08x}", v.id, bits(v.value)))
.collect::<Vec<_>>()
.join(","),
}
}
struct Callback<'a> {
out: &'a mut dyn Write,
op: &'a Value,
calls: i64,
nested: bool,
}
impl Callback<'_> {
fn event(&mut self, s: &str) -> io::Result<()> {
writeln!(self.out, "{s}")?;
let n = self.calls;
self.calls += 1;
if n == self.op["fail"].as_i64().unwrap() {
Err(io::Error::other("injected synchronized callback failure"))
} else {
Ok(())
}
}
}
impl Observer for Callback<'_> {
type Error = io::Error;
fn updated(&mut self, data: &mut SyncedFloats, id: u8) -> io::Result<()> {
self.event(&format!(
"updated {id} {:08x} {} {}",
bits(data.get(id).unwrap()),
data.is_dirty(),
data.item_dirty(id).unwrap()
))?;
if self.nested {
return Ok(());
}
self.nested = true;
let other = self.op["other"].as_u64().unwrap() as u8;
let value = single(&self.op["other_value"]);
let result = match self.op["hook"].as_str().unwrap() {
"none" => Ok(()),
"pack" => writeln!(
self.out,
"callback-pack {}",
values(data.take_dirty().as_deref())
),
"set" => data
.set(
other,
value,
self.op["other_force"].as_bool().unwrap(),
self,
)
.map_err(|e| match e {
DataError::Observer(e) => e,
DataError::UnknownId(_) => panic!("hook uses registered ID"),
}),
"assign" => data
.assign(&[FloatValue { id: other, value }], self)
.map_err(|e| match e {
DataError::Observer(e) => e,
DataError::UnknownId(_) => panic!("hook uses registered ID"),
}),
_ => panic!("hook"),
};
self.nested = false;
result
}
fn assigned(&mut self, _: &mut SyncedFloats, v: &[FloatValue]) -> io::Result<()> {
self.event(&format!("assigned {}", values(Some(v))))
}
}
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: Value = serde_json::from_str(line)?;
let initial = parse(&f["initial"]);
let mut ids = initial.iter().map(|v| v.id).collect::<Vec<_>>();
ids.sort_unstable();
let mut data = SyncedFloats::new(&initial)?;
for op in f["ops"].as_array().unwrap() {
let mut cb = Callback {
out: &mut out,
op,
calls: 0,
nested: false,
};
let id = op["id"].as_u64().unwrap() as u8;
let result = match op["mode"].as_str().unwrap() {
"set" => data.set(
id,
single(&op["value"]),
op["force"].as_bool().unwrap(),
&mut cb,
),
"assign" => data.assign(&parse(&op["values"]), &mut cb),
"get" => data.get(id).map_err(DataError::UnknownId).and_then(|v| {
writeln!(cb.out, "get {:08x}", bits(v)).map_err(DataError::Observer)
}),
"pack" => writeln!(cb.out, "packed {}", values(data.take_dirty().as_deref()))
.map_err(DataError::Observer),
"defaults" => {
writeln!(cb.out, "defaults {}", values(data.non_default().as_deref()))
.map_err(DataError::Observer)
}
_ => panic!("mode"),
};
match result {
Ok(()) => writeln!(cb.out, "result ok")?,
Err(DataError::Observer(_)) => writeln!(cb.out, "error observer")?,
Err(DataError::UnknownId(_)) => writeln!(cb.out, "error id")?,
}
writeln!(cb.out, "dirty {}", data.is_dirty())?;
for id in &ids {
writeln!(
cb.out,
"state {id} {:08x} {} {}",
bits(data.get(*id).unwrap()),
data.item_dirty(*id).unwrap(),
data.is_default(*id).unwrap()
)?;
}
writeln!(cb.out, "calls {}", cb.calls)?;
}
}
Ok(())
}
+1
View File
@@ -66,6 +66,7 @@ pub mod registry_fluid;
pub mod retrogen;
pub mod suffocation;
pub mod swimming;
pub mod synced_floats;
pub mod tick_data;
pub mod water_splash;
pub mod world_movement;
+151
View File
@@ -0,0 +1,151 @@
//! Multiple synchronized float fields with native callback and dirty ordering.
//! Other serializer types and wire codecs are not represented by this module.
use crate::compression::invalid;
use std::{fmt, io};
#[derive(Clone, Copy, Debug)]
pub struct FloatValue {
pub id: u8,
pub value: f32,
}
#[derive(Clone, Copy, Debug)]
struct Entry {
id: u8,
initial: f32,
value: f32,
dirty: bool,
}
#[derive(Clone, Debug)]
pub struct SyncedFloats {
entries: Vec<Entry>,
dirty: bool,
}
#[derive(Debug)]
pub enum DataError<E> {
UnknownId(u8),
Observer(E),
}
impl<E: fmt::Display> fmt::Display for DataError<E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
Self::UnknownId(id) => write!(f, "unknown synchronized float ID {id}"),
Self::Observer(e) => e.fmt(f),
}
}
}
impl<E: std::error::Error + 'static> std::error::Error for DataError<E> {}
pub trait Observer {
type Error;
fn updated(&mut self, data: &mut SyncedFloats, id: u8) -> Result<(), Self::Error>;
fn assigned(
&mut self,
_data: &mut SyncedFloats,
_values: &[FloatValue],
) -> Result<(), Self::Error> {
Ok(())
}
}
fn equal(a: f32, b: f32) -> bool {
a.to_bits() == b.to_bits() || (a.is_nan() && b.is_nan())
}
impl SyncedFloats {
pub fn new(values: &[FloatValue]) -> io::Result<Self> {
let mut entries = values
.iter()
.map(|v| Entry {
id: v.id,
initial: v.value,
value: v.value,
dirty: false,
})
.collect::<Vec<_>>();
entries.sort_unstable_by_key(|e| e.id);
if entries.iter().any(|e| e.id == 255) || entries.windows(2).any(|e| e[0].id == e[1].id) {
return Err(invalid("duplicate or reserved synchronized float ID"));
}
Ok(Self {
entries,
dirty: false,
})
}
fn index(&self, id: u8) -> Result<usize, u8> {
self.entries
.binary_search_by_key(&id, |e| e.id)
.map_err(|_| id)
}
pub fn get(&self, id: u8) -> Result<f32, u8> {
Ok(self.entries[self.index(id)?].value)
}
pub fn is_dirty(&self) -> bool {
self.dirty
}
pub fn item_dirty(&self, id: u8) -> Result<bool, u8> {
Ok(self.entries[self.index(id)?].dirty)
}
pub fn is_default(&self, id: u8) -> Result<bool, u8> {
let e = &self.entries[self.index(id)?];
Ok(equal(e.initial, e.value))
}
pub fn set<O: Observer>(
&mut self,
id: u8,
value: f32,
force: bool,
observer: &mut O,
) -> Result<(), DataError<O::Error>> {
let index = self.index(id).map_err(DataError::UnknownId)?;
if force || !equal(value, self.entries[index].value) {
self.entries[index].value = value;
observer.updated(self, id).map_err(DataError::Observer)?;
self.entries[index].dirty = true;
self.dirty = true;
}
Ok(())
}
/// Received values always notify, even when equal, and do not set/clear dirty
/// flags. A failure preserves earlier entries and skips later/batch callbacks.
pub fn assign<O: Observer>(
&mut self,
values: &[FloatValue],
observer: &mut O,
) -> Result<(), DataError<O::Error>> {
for v in values {
let index = self.index(v.id).map_err(DataError::UnknownId)?;
self.entries[index].value = v.value;
observer.updated(self, v.id).map_err(DataError::Observer)?;
}
observer.assigned(self, values).map_err(DataError::Observer)
}
pub fn take_dirty(&mut self) -> Option<Vec<FloatValue>> {
if !self.dirty {
return None;
}
self.dirty = false;
let mut values = Vec::new();
for e in &mut self.entries {
if e.dirty {
e.dirty = false;
values.push(FloatValue {
id: e.id,
value: e.value,
});
}
}
Some(values)
}
pub fn non_default(&self) -> Option<Vec<FloatValue>> {
let values: Vec<_> = self
.entries
.iter()
.filter(|e| !equal(e.initial, e.value))
.map(|e| FloatValue {
id: e.id,
value: e.value,
})
.collect();
if values.is_empty() {
None
} else {
Some(values)
}
}
}
+16
View File
@@ -1283,3 +1283,19 @@ resistance/stat boundaries, numeric edges, query failures/mutations and actual
empty-equipment protection iteration. Targeted Clippy passes. Equipment is empty;
enchanted components, actual armor durability, registered damage/effect bindings
and the full hurt sequence remain pending.
`synced_floats` stores multiple synchronized float fields. It preserves boxed
float equality, per-field/global dirty state, ascending-ID dirty/default lists,
received assignment without newly marking dirty, per-entry and batch callbacks,
and prefix effects when an observer or field lookup fails. Callbacks may reenter
the table to set/assign fields or drain existing dirty values.
`python3 tools/test_synced_floats_parity.py` compares actual `SynchedEntityData`.
The [synchronized float report](../benchmarks/rust-synced-floats-2026-10-07/scoped-parity.json)
records **554,909 matching lines per JAR**, including forced/equal updates,
received duplicates, reentrant operations, missing IDs, callback failures and
NaN/signed-zero equality. Native gaps are untouched default float items; observed
keys are explicit configured IDs. Targeted Clippy passes. Other serializers,
serializer-mismatch errors, wire codecs and player absorption binding remain
pending.
@@ -0,0 +1,36 @@
package dev.horizonlab.parity;
import com.google.gson.*;import java.io.*;import java.nio.file.*;import java.util.*;
import net.minecraft.network.syncher.*;
/** Native multi-float dirty/default lists, assignment and reentrant callbacks. */
public final class VanillaSyncedFloatsOracle {
static final class Stop extends RuntimeException {}
static float single(JsonElement v){return Float.intBitsToFloat(Integer.parseUnsignedInt(v.getAsString(),16));}
static String bits(float v){return String.format("%08x",Float.floatToIntBits(v));}
static String values(List<SynchedEntityData.DataValue<?>> list){if(list==null)return "none";var s=new StringJoiner(",");for(var v:list)s.add(v.id()+":"+bits((Float)v.value()));return s.length()==0?"empty":s.toString();}
static EntityDataAccessor<Float> key(int id){return new EntityDataAccessor<Float>(id,EntityDataSerializers.FLOAT);}
static List<SynchedEntityData.DataValue<?>> values(JsonArray values){var result=new ArrayList<SynchedEntityData.DataValue<?>>();for(var x:values){var v=x.getAsJsonObject();result.add(new SynchedEntityData.DataValue<Float>(v.get("id").getAsInt(),EntityDataSerializers.FLOAT,single(v.get("value"))));}return result;}
static final class Holder implements SyncedDataHolder {
SynchedEntityData data;SynchedEntityData.DataItem<?>[] items;JsonObject op;PrintWriter out;int calls;boolean nested;
void event(String s){out.println(s);if(calls++==op.get("fail").getAsInt())throw new Stop();}
@Override public void onSyncedDataUpdated(EntityDataAccessor<?> key){int id=key.id();event("updated "+id+" "+bits((Float)items[id].getValue())+" "+data.isDirty()+" "+items[id].isDirty());if(nested)return;nested=true;try{switch(op.get("hook").getAsString()){
case "none":break;case "pack":out.println("callback-pack "+values(data.packDirty()));break;
case "set":data.set(key(op.get("other").getAsInt()),single(op.get("other_value")),op.get("other_force").getAsBoolean());break;
case "assign":data.assignValues(List.of(new SynchedEntityData.DataValue<Float>(op.get("other").getAsInt(),EntityDataSerializers.FLOAT,single(op.get("other_value")))));break;
default:throw new AssertionError();}}finally{nested=false;}}
@Override public void onSyncedDataUpdated(List<SynchedEntityData.DataValue<?>> values){event("assigned "+values(values));}
}
public static void main(String[] args)throws Exception {
net.minecraft.SharedConstants.tryDetectVersion();net.minecraft.server.Bootstrap.bootStrap();var ctor=SynchedEntityData.class.getDeclaredConstructor(SyncedDataHolder.class,SynchedEntityData.DataItem[].class);ctor.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 holder=new Holder();holder.out=out;var initial=f.getAsJsonArray("initial");var ids=new ArrayList<Integer>();int max=-1;for(var v:initial){int id=v.getAsJsonObject().get("id").getAsInt();ids.add(id);max=Math.max(max,id);}Collections.sort(ids);holder.items=new SynchedEntityData.DataItem<?>[max+1];for(int i=0;i<=max;i++)holder.items[i]=new SynchedEntityData.DataItem<Float>(key(i),0f);for(var v:initial){var e=v.getAsJsonObject();int id=e.get("id").getAsInt();holder.items[id]=new SynchedEntityData.DataItem<Float>(key(id),single(e.get("value")));}holder.data=ctor.newInstance(holder,holder.items);
for(var v:f.getAsJsonArray("ops")){var op=v.getAsJsonObject();holder.op=op;holder.calls=0;try{switch(op.get("mode").getAsString()){
case "set":holder.data.set(key(op.get("id").getAsInt()),single(op.get("value")),op.get("force").getAsBoolean());break;
case "get":out.println("get "+bits(holder.data.get(key(op.get("id").getAsInt()))));break;
case "assign":holder.data.assignValues(values(op.getAsJsonArray("values")));break;
case "pack":out.println("packed "+values(holder.data.packDirty()));break;
case "defaults":out.println("defaults "+values(holder.data.getNonDefaultValues()));break;
default:throw new AssertionError();}out.println("result ok");}catch(Stop e){out.println("error observer");}catch(IndexOutOfBoundsException e){out.println("error id");}
out.println("dirty "+holder.data.isDirty());for(int id:ids){var e=holder.items[id];out.println("state "+id+" "+bits((Float)e.getValue())+" "+e.isDirty()+" "+e.isSetToDefault());}out.println("calls "+holder.calls);
}
}}
}
}
+77
View File
@@ -0,0 +1,77 @@
#!/usr/bin/env python3
"""Compare multiple synchronized float fields, assignment and reentrant callbacks with vanilla."""
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 bits(v):return struct.pack('>f',v).hex()
def value(id=9,v=0):return dict(id=id,value=bits(v))
def op(mode='set',id=9,v=0,**kw):
o=dict(mode=mode,id=id,value=bits(v),force=False,values=[],hook='none',other=17,other_value=bits(7),other_force=False,fail=-1);o.update(kw);return o
def row(initial,ops):return dict(initial=initial,ops=ops)
values=[-float('inf'),-1e30,-1,-0.,0.,1e-40,.1,1,7,20,1e30,float('inf'),float('nan')]
for start in values:
for v in values:
for hook in ['none','pack','set','assign']:
for force in [False,True]:yield row([value(17),value(9,start)],[op(v=v,force=force,hook=hook),op('defaults'),op('pack'),op(v=v,hook=hook),op('assign',values=[value(17,v),value(9,start),value(9,start)],hook=hook),op('pack'),op('defaults')])
for mode in ['set','assign']:
for hook in ['none','pack','set','assign']:
for fail in range(-1,9):
for other in [9,17]:yield row([value(9),value(17)],[op(v=3),op(mode,v=5,values=[value(9,5),value(17,7)],hook=hook,other=other,fail=fail),op('pack'),op('defaults')])
for initial in [[],[value(0)],[value(1),value(254)],[value(i,i) for i in range(8)]]:
yield row(initial,[op('get',255),op('set',255),op('assign',values=[value(v['id'],2) for v in initial]+[value(255)]),op('assign',values=[]),op('pack'),op('defaults')])
rng=random.Random(0x53594e43464c4f41)
for _ in range(1500):
ids=rng.sample(range(64),rng.randrange(1,12));initial=[value(id,rng.choice(values)) for id in ids];ops=[]
for __ in range(rng.randrange(5,60)):
ops.append(op(rng.choice(['set','set','get','pack','defaults','assign']),rng.choice(ids+[255]),rng.choice(values),force=bool(rng.randrange(2)),values=[value(rng.choice(ids+[255]),rng.choice(values)) for ___ in range(rng.randrange(6))],hook=rng.choice(['none','pack','set','assign']),other=rng.choice(ids),other_value=bits(rng.choice(values)),other_force=bool(rng.randrange(2)),fail=rng.choice([-1,-1,-1,0,1,2,3])))
yield row(initial,ops)
for nan in ['7fa12345','7fc00000','ffa12345']:
initial=[value(9),value(17)];initial[0]['value']=nan;yield row(initial,[op(v=float('nan')),op('defaults'),op('pack')])
def main():
parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--prepare',action='store_true');args=parser.parse_args()
build=lab.LOCAL/'rust-synced-floats-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/VanillaSyncedFloatsOracle.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/synced_floats_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.VanillaSyncedFloatsOracle',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','synced_floats_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'/('synced_floats_fixture.exe' if os.name=='nt' else 'synced_floats_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:,} synchronized float 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 SynchedEntityData Float fields: boxed equality, forced updates, callback-before-dirty flags, ordered dirty/default extraction, received assignment including duplicates, partial unknown-ID/observer failures, batch callbacks and reentrant set/assign/pack. Native table gaps are untouched default dummy Float items; tested keys are explicit configured IDs. Other serializers, type-mismatch errors, wire codecs and player absorption integration remain pending.'}
lab.write_json(report_path,report);print(f'Scoped synchronized float parity passed: {report_path}')
if __name__=='__main__':main()