Match status effect countdown, hidden restoration and client blending

This commit is contained in:
Ludovic Marie committed 2026-10-07 10:32:07 +02:00
1 parent 9bb87815a1
commit aad69bc4f3
7 files changed
+806 -1

No files matched your search

@@ -0,0 +1,293 @@
{
"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": 2552,
"sources_sha256": {
"mods/horizon/src/test/java/dev/horizonlab/parity/VanillaStatusTickOracle.java": "01b3b61eb779b40c238243dae54d7f4bb48aa52199564f25d69e842d3b812bf0",
"tools/test_status_tick_parity.py": "f38956b1be4ef211818c7a5492d8fcac1e5779cb7a1dc8418caafe6492f055e0",
"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": "afea3cb5761e8b82ee4d9bb4ef3c6fd10182a324dbaec99e6c9ebfac255dda09",
"crates/horizon-world/src/blocking_rules.rs": "83c5e2105cec56a90182ce582e1c67ade2b189be6de1a34d08035000cc07c492",
"crates/horizon-world/src/bundle_weight.rs": "a0e7b0587ab5d46cd55588f25d55a088b7a4725099c13ba6df146957be36014c",
"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_durability.rs": "37a46e184f95bc5027e2b9af72ff52f729ad03601d08e1827f181fca383a35af",
"crates/horizon-world/src/component_patch.rs": "f6f8992f241dfb25e012a06a7ba3fecab8d958686dddd096595a4806e56f0ab3",
"crates/horizon-world/src/compression.rs": "4db73e6ca9a0d552d415ce60e7e88b89c9cf2b7d060a669ff8328f518316e101",
"crates/horizon-world/src/consumable.rs": "ba3575cb85866cb940f33a1ac86455d71cf0cc6395b848588a8ee1fe33f5c326",
"crates/horizon-world/src/consume_effect.rs": "03f2aac6879ce133347d42f6f6667d62c06d956ff9faac5dc14182a788b6a236",
"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/extra_items.rs": "6eba0a0c795d5fd841d31471708e78324b4852adebb2e6ed700dcc0caab668cd",
"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_properties.rs": "0926fa3f3bc3d0608c45d02f564355825ca3c3526a82bf9c1375c7a191fa5e12",
"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/identifier.rs": "a3ad79b1a4ea171726f07b1fc6e2b78f224157e8f0d53dd2ce96e93ccd2d38dd",
"crates/horizon-world/src/interaction_shapes.rs": "f321284ddab440a394372b6dedc8b5cc29a653c0745251a9e96c650f21c33dea",
"crates/horizon-world/src/inventory_pickup.rs": "ea830c7916e7f2d95c6db7ef48be1e876e6ebafcb438e47fc72f9a5bd7c37d07",
"crates/horizon-world/src/inventory_tick.rs": "293a3d57a1689337cfd58e5a73dcdbed4cb360f94d98ff5458f0df92de387365",
"crates/horizon-world/src/inventory_use.rs": "6a6c2ecc73c83dda4cd798c0304df12ace6096eb110d899f4f0c7ffd852bf001",
"crates/horizon-world/src/item_after_use.rs": "2b6598ce5b7b304dea2c8057b4a1eb6530264ac4d0546c3da0c76deed9609da5",
"crates/horizon-world/src/item_blocking.rs": "f6eee0d6d177cc3148960122327ba1b459a2f0e85241c1d9a3e40f0b8c169296",
"crates/horizon-world/src/item_cooldowns.rs": "7b625868509ab3c51e72db0ac714bb0e7ec5e2610d37271005a1a737f4d14431",
"crates/horizon-world/src/item_durability.rs": "9fdf835e5c7bd0e1dd63ef2ba0076b770cdd4d6d14cdcd11de27690f0702f94e",
"crates/horizon-world/src/item_particles.rs": "861b14f65adb9b14f8158fe9f0b7128beac3df8107b1337c31b8b9b49434ba3f",
"crates/horizon-world/src/item_stack_refs.rs": "18d3ca85cac0daf59200857513761359e5690f719cb3f7f64ae552f0c4169ea3",
"crates/horizon-world/src/item_stack_storage.rs": "b4dcb83dcaa346848c5484161feb3e2cf08e83f7793d7ed83be25b14b9d12884",
"crates/horizon-world/src/item_template.rs": "dc80025215d1867e656924ea2a9d273aacbcaea21293d986ba42d0004ee93b69",
"crates/horizon-world/src/item_use.rs": "b1c79428986efbf9dd5ede703a39eb387fb6dcc7d9950f0e49243a353a5b8070",
"crates/horizon-world/src/item_use_catalog.rs": "a9b53d2e816583239a75c3c61e78dacc5e3b27dee595be34b1c7fa169f17a571",
"crates/horizon-world/src/item_use_lifecycle.rs": "4639b70440cf811e79de09c48a3e035143fcb6be8a64c2f61b10ae55a2f133b7",
"crates/horizon-world/src/item_use_start.rs": "a84092dfb8b8f0a89d0928bb2f8ac252bd9bfd3f8d74fce1a7f7a5b3c3f4f50b",
"crates/horizon-world/src/java_hash_map.rs": "6bd97d87f0e3eaad440162145a1515b9a0b7cfb85cb0ea337874ed9745f8dd45",
"crates/horizon-world/src/lib.rs": "b4184f71a8d817197b8730c8f002b96bdeb248028b2330fbc7bdd7fe11ea7049",
"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/living_use_flags.rs": "826f4fdeba7e208368cbbf910fa408db0afbc6442d842d178a70fae53e0d0ea6",
"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_equipment.rs": "1fa8c53e67624c4641246249d79a800a28a4858c62482bd880b4e3b866b936ef",
"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_inventory.rs": "f4f67d8312793f25930626c4ac06db688fcf2e2292d6675071d105fb1708d952",
"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/simple_container.rs": "0fedbc7e974b1db79b88bd6aff977654189a5d553cf42852fe8bf0885cf90b30",
"crates/horizon-world/src/status_effect.rs": "588bfcf4d93f50be86cb89545bd5c431edbc71771f704ff55cb52906b1964c37",
"crates/horizon-world/src/suffocation.rs": "bed219dd5bbab6263b98fbe3d0eb512cb96c52ae847210efe49514d05f22f11e",
"crates/horizon-world/src/swimming.rs": "49d2dae13c109b37ff832cde98a857944ff45247b864a527b9c4f03ecca7a7b7",
"crates/horizon-world/src/synced_floats.rs": "0152f2752bafaf68769d56dbc88494a976496a680c6b113d6b48a446158ba072",
"crates/horizon-world/src/synced_values.rs": "adffa15026497d6671ffd12e5e17df9329c93f0e022700cdfebb80ab494382ae",
"crates/horizon-world/src/teleport_consume.rs": "d6a53bbb6ac4dbbd4c0591d0646017898a95beb8ef093dc5d81b9833963be6c3",
"crates/horizon-world/src/tick_data.rs": "f8d04a69ea263f4168bce33f92e5b4ee2fe07d7caf50a1621c6b3ef6eb2479f3",
"crates/horizon-world/src/use_remainder.rs": "f555335afeca7970888131a6da2f5a614a73253b631185d1ba804593a349535e",
"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/status_tick_fixture.rs": "3883b38bde9e55f6e5cd411615441f8f2682198ad7e4d30a28a8edccb17b392b"
},
"fixtures_sha256": {
".local/rust-status-tick-parity/inputs.txt": "c3548162354280e1cacb5a45a060c6f38212679242f6907a42ee12e20c491b56"
},
"rust_output_sha256": "707a7790ec99f9d9e8e328d76a421c1df1be6d28936b4790303bad6b0380989a",
"references": [
{
"side": "client",
"jar_sha256": "4508d006323f24fa02876310c192d739af56516eb259000ac50f0909a68c9a2d",
"output_sha256": "707a7790ec99f9d9e8e328d76a421c1df1be6d28936b4790303bad6b0380989a",
"matched_output_lines": 412552
},
{
"side": "server",
"jar_sha256": "a362163eec5d1612d520772bc16e5b39c09e3b234fdc045f56bf544284ee8ae6",
"output_sha256": "707a7790ec99f9d9e8e328d76a421c1df1be6d28936b4790303bad6b0380989a",
"matched_output_lines": 412552
}
],
"scope": "Actual MobEffectInstance server/client ticks, skipBlending and getBlendFactor with shared instance/hidden-chain storage. Controlled MobEffect scheduling/application/blend-duration callbacks compare duration countdown, infinite actor clocks, hidden restoration and notification, live-state rereads, float interpolation, removed actors and callback mutation/failure prefixes. Concrete registered effect behaviors, entity effect maps, UI rendering and full gameplay remain pending."
}
@@ -0,0 +1,221 @@
use horizon_world::status_effect::{BlendState, Details, EffectInstance};
use horizon_world::status_effect::{BlendWorld, TickWorld};
use serde_json::Value;
use std::{
fs,
io::{self, Write},
path::Path,
};
type Effect = EffectInstance<u8>;
fn n(v: &Value, k: &str) -> i32 {
v[k].as_i64().unwrap() as i32
}
fn fl(v: &Value, k: &str) -> f32 {
f32::from_bits(v[k].as_u64().unwrap() as u32)
}
fn bits(v: f32) -> u32 {
if v.is_nan() { 0x7fc00000 } else { v.to_bits() }
}
fn details(v: &Value) -> Details {
Details {
duration: n(v, "duration"),
amplifier: n(v, "amplifier"),
ambient: v["ambient"].as_bool().unwrap(),
visible: v["visible"].as_bool().unwrap(),
show_icon: v["icon"].as_bool().unwrap(),
}
}
fn id(ids: &mut Vec<Effect>, e: &Effect) -> usize {
if let Some(i) = ids.iter().position(|v| v.same_reference(e)) {
i
} else {
ids.push(e.clone());
ids.len() - 1
}
}
fn dump(out: &mut dyn Write, slots: &[Effect], ids: &mut Vec<Effect>) {
let mut visit = Vec::<Effect>::new();
for (i, e) in slots.iter().enumerate() {
writeln!(out, "slot {i} {}", id(ids, e)).unwrap();
if !visit.iter().any(|v| v.same_reference(e)) {
visit.push(e.clone());
}
}
let mut i = 0;
while i < visit.len() {
let e = visit[i].clone();
let d = e.read();
let h = d
.hidden
.as_ref()
.map(|v| id(ids, v).to_string())
.unwrap_or("none".into());
if let Some(v) = &d.hidden {
if !visit.iter().any(|e| e.same_reference(v)) {
visit.push(v.clone());
}
}
writeln!(
out,
"node {} {} {} {} {} {} {} {h} {} {}",
id(ids, &e),
d.effect,
d.details.duration,
d.details.amplifier,
d.details.ambient,
d.details.visible,
d.details.show_icon,
bits(d.blend.factor),
bits(d.blend.previous)
)
.unwrap();
i += 1;
}
}
struct World<'a> {
f: Value,
out: &'a mut dyn Write,
slots: Vec<Effect>,
ids: Vec<Effect>,
calls: i32,
changed: bool,
}
impl World<'_> {
fn config(&self) -> &Value {
&self.f[if self.changed { "after" } else { "initial" }]
}
fn reset(&mut self) {
let c = self.config().clone();
for (i, v) in c["instances"].as_array().unwrap().iter().enumerate() {
let mut e = self.slots[i].write();
e.details = details(v);
e.blend = BlendState {
factor: fl(v, "factor"),
previous: fl(v, "previous"),
};
}
}
fn all(&mut self) {
writeln!(
self.out,
"state {} {} {}",
self.calls,
self.changed,
n(self.config(), "tick")
)
.unwrap();
dump(self.out, &self.slots, &mut self.ids);
}
fn event(&mut self, name: String) -> Result<(), &'static str> {
writeln!(self.out, "event {name}").unwrap();
let i = self.calls;
self.calls += 1;
self.all();
if i == n(&self.f, "fail") {
return Err("callback");
}
if i == n(&self.f, "mutate") {
self.changed = true;
self.reset();
}
Ok(())
}
}
impl TickWorld<u8> for World<'_> {
type Error = &'static str;
type Level = i32;
fn actor_tick_count(&self) -> i32 {
n(self.config(), "tick")
}
fn should_apply(
&mut self,
e: u8,
time: i32,
amp: i32,
_: &Effect,
) -> Result<bool, Self::Error> {
self.event(format!("should {e} {time} {amp}"))?;
Ok(self.config()["should"].as_bool().unwrap())
}
fn apply_tick(&mut self, e: u8, l: i32, amp: i32, _: &Effect) -> Result<bool, Self::Error> {
self.event(format!("apply {e} {l} {amp}"))?;
Ok(self.config()["apply"].as_bool().unwrap())
}
fn downgraded(&mut self, _: &Effect) -> Result<(), Self::Error> {
self.event("downgrade".into())
}
}
impl BlendWorld<u8> for World<'_> {
type Error = &'static str;
fn advance_ticks(&mut self, e: u8, _: &Effect) -> Result<i32, Self::Error> {
self.event(format!("advance {e}"))?;
Ok(n(self.config(), "advance"))
}
fn duration_ticks(&mut self, e: u8, blending_in: bool, _: &Effect) -> Result<i32, Self::Error> {
self.event(format!("blend-duration {e} {blending_in}"))?;
Ok(n(
self.config(),
if blending_in { "blend_in" } else { "blend_out" },
))
}
}
fn run(f: Value, out: &mut dyn Write) {
let mut slots: Vec<Effect> = Vec::new();
for v in f["initial"]["instances"].as_array().unwrap() {
let h = n(v, "hidden");
let e = Effect::new(
n(v, "effect") as u8,
details(v),
(h >= 0).then(|| slots[h as usize].clone()),
);
slots.push(e);
}
let mut w = World {
f,
out,
slots,
ids: Vec::new(),
calls: 0,
changed: false,
};
w.reset();
w.all();
let ops = w.f["ops"].as_array().unwrap().clone();
for op in ops {
let a = n(&op, "a") as usize;
let b = n(&op, "b") as usize;
let e = w.slots[a].clone();
let result: Result<String, &'static str> = match op["op"].as_str().unwrap() {
"server" => e
.tick_server(&mut w, n(&op, "level"))
.map(|v| v.to_string()),
"client" => e.tick_client(&mut w).map(|_| "ok".into()),
"skip" => e.skip_blending(&mut w).map(|_| "ok".into()),
"factor" => Ok(bits(
e.blend_factor(fl(&op, "partial"), op["removed"].as_bool().unwrap()),
)
.to_string()),
"update" => Ok(e.update(&w.slots[b]).to_string()),
"alias" => {
w.slots[b] = e;
Ok("ok".into())
}
"copy" => {
w.slots[b] = e.copy_instance();
Ok("ok".into())
}
_ => panic!("unknown operation"),
};
writeln!(w.out, "result {}", result.unwrap_or_else(str::to_string)).unwrap();
w.all();
}
}
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() {
run(serde_json::from_str(line)?, &mut out);
}
Ok(())
}
+153
View File
@@ -154,3 +154,156 @@ impl<H: PartialEq> PartialEq for EffectInstance<H> {
}
}
impl<H: Eq> Eq for EffectInstance<H> {}
pub trait TickWorld<H> {
type Error;
type Level: Copy;
fn actor_tick_count(&self) -> i32;
fn should_apply(
&mut self,
effect: H,
time: i32,
amplifier: i32,
instance: &EffectInstance<H>,
) -> Result<bool, Self::Error>;
fn apply_tick(
&mut self,
effect: H,
level: Self::Level,
amplifier: i32,
instance: &EffectInstance<H>,
) -> Result<bool, Self::Error>;
fn downgraded(&mut self, instance: &EffectInstance<H>) -> Result<(), Self::Error>;
}
pub trait BlendWorld<H> {
type Error;
fn advance_ticks(
&mut self,
effect: H,
instance: &EffectInstance<H>,
) -> Result<i32, Self::Error>;
fn duration_ticks(
&mut self,
effect: H,
blending_in: bool,
instance: &EffectInstance<H>,
) -> Result<i32, Self::Error>;
}
fn float_clamp(v: f32, lo: f32, hi: f32) -> f32 {
if v < lo {
lo
} else if v.is_nan() || hi.is_nan() {
f32::NAN
} else if v == 0.0 && hi == 0.0 {
f32::from_bits(v.to_bits() | hi.to_bits())
} else {
v.min(hi)
}
}
impl<H> EffectInstance<H> {
fn tick_down(&self) {
let hidden = self.read().hidden.clone();
if let Some(hidden) = hidden {
hidden.tick_down();
}
let mut data = self.write();
if data.details.duration != -1 && data.details.duration != 0 {
data.details.duration = data.details.duration.wrapping_sub(1);
}
}
fn downgrade(&self) -> bool {
if self.read().details.duration != 0 {
return false;
}
let hidden = self.read().hidden.clone();
if let Some(hidden) = hidden {
let details = hidden.read().details;
let next = hidden.read().hidden.clone();
let mut data = self.write();
data.details = details;
data.hidden = next;
true
} else {
false
}
}
/// Entity.isRemoved is a final field-based query. Removal snaps the
/// previous factor before interpolation, including for non-finite partials.
pub fn blend_factor(&self, partial: f32, actor_removed: bool) -> f32 {
let mut data = self.write();
if actor_removed {
data.blend.previous = data.blend.factor;
}
data.blend.previous + partial * (data.blend.factor - data.blend.previous)
}
}
impl<H: Clone> EffectInstance<H> {
pub fn tick_server<W: TickWorld<H>>(
&self,
world: &mut W,
level: W::Level,
) -> Result<bool, W::Error> {
if !self.has_remaining() {
return Ok(false);
}
let time = if self.infinite() {
world.actor_tick_count()
} else {
self.read().details.duration
};
let effect = self.read().effect.clone();
let amplifier = self.read().details.amplifier;
if world.should_apply(effect, time, amplifier, self)? {
let effect = self.read().effect.clone();
let amplifier = self.read().details.amplifier;
if !world.apply_tick(effect, level, amplifier, self)? {
return Ok(false);
}
}
self.tick_down();
if self.downgrade() {
world.downgraded(self)?;
}
Ok(self.has_remaining())
}
fn blend_has_effect<W: BlendWorld<H>>(&self, world: &mut W) -> Result<bool, W::Error> {
let effect = self.read().effect.clone();
let advance = world.advance_ticks(effect, self)?;
Ok(!self.ends_within(advance))
}
pub fn skip_blending<W: BlendWorld<H>>(&self, world: &mut W) -> Result<(), W::Error> {
let target = if self.blend_has_effect(world)? {
1.0
} else {
0.0
};
self.write().blend = BlendState {
factor: target,
previous: target,
};
Ok(())
}
pub fn tick_client<W: BlendWorld<H>>(&self, world: &mut W) -> Result<(), W::Error> {
if self.has_remaining() {
self.tick_down();
self.downgrade();
}
let previous = self.read().blend.factor;
self.write().blend.previous = previous;
let has_effect = self.blend_has_effect(world)?;
let target = if has_effect { 1.0 } else { 0.0 };
if self.read().blend.factor == target {
return Ok(());
}
let effect = self.read().effect.clone();
let ticks = world.duration_ticks(effect, has_effect, self)?;
if ticks == 0 {
self.write().blend.factor = target;
} else {
let step = 1.0 / ticks as f32;
let mut data = self.write();
data.blend.factor += float_clamp(target - data.blend.factor, -step, step);
}
Ok(())
}
}
+16
View File
@@ -2057,3 +2057,19 @@ subsequent random state, height overflow, float edges, attempt exhaustion,
captured/live positions and callback mutation/failure prefixes. Targeted Clippy
passes. Destination validation and teleporting, passenger links and world event
delivery remain controlled services; full gameplay integration remains pending.
`status_effect` also implements server/client ticking and client blend updates.
Hidden instances count down with their parent. When the active duration reaches
zero, the hidden details are restored before the server downgrade callback.
Infinite effects use the actor's tick count for scheduling. Blend updates retain
native callback/read ordering, duration-dependent steps and interpolation.
`python3 tools/test_status_tick_parity.py` compares actual MobEffectInstance
ticks, skipBlending and getBlendFactor with controlled MobEffect callbacks. The
[status tick report](../benchmarks/rust-status-tick-2026-10-07/scoped-parity.json)
records **412,552 matching lines per JAR**, including shared hidden chains,
zero/negative/infinite durations, raw amplifiers, early application failures,
downgrade notifications, blend float edge cases, removed actors and callback
mutation/failure prefixes. Targeted Clippy passes. Registered effect behaviors,
entity effect maps, UI rendering and full gameplay remain pending.
+4 -1
View File
@@ -18,7 +18,10 @@ item templates, remainders, checked bundle weights and cooldown expiry have
native comparisons. Item completion composes stack copies with remainder and
cooldown effects and server inventory delivery. Consumable start/completion now
composes food storage, native random streams and eating particles, with exact
sound parameters and effect ordering checked against both pinned JARs. These
sound parameters and effect ordering checked against both pinned JARs. Consume
effect bodies now cover status application/removal/clearing, sounds and random
teleport attempts. Shared status instances implement hidden-chain updates,
server/client countdown and client blending with native comparisons. These
kernels still need complete entity/world lifecycle bindings. All pinned block-survival
families now have native differential coverage. Full simulation callbacks,
complete chunk generation, entity behavior, networking, rendering and playable
@@ -0,0 +1,45 @@
package dev.horizonlab.parity;
import com.google.gson.*;import java.io.*;import java.lang.reflect.*;import java.nio.file.*;import java.util.*;
import net.minecraft.world.entity.*;import net.minecraft.server.level.ServerLevel;
import net.minecraft.world.effect.*;import net.minecraft.core.Holder;
/** Native server/client ticking, hidden downgrades and blend interpolation. */
public final class VanillaStatusTickOracle {
static Field duration,amplifier,ambient,visible,icon,hidden,blend,factor,previous;
static List<Holder<MobEffect>> effects;
static Field field(Class<?> c,String n)throws Exception{var f=c.getDeclaredField(n);f.setAccessible(true);return f;}
static int n(JsonObject v,String k){return v.get(k).getAsInt();}
static float fl(JsonObject v,String k){return Float.intBitsToFloat((int)v.get(k).getAsLong());}
static long bits(float v){return Integer.toUnsignedLong(Float.floatToIntBits(v));}
static final class Stop extends RuntimeException{}
static int id(IdentityHashMap<MobEffectInstance,Integer> ids,MobEffectInstance e){return ids.computeIfAbsent(e,k->ids.size());}
static void dump(PrintWriter out,MobEffectInstance[] slots,IdentityHashMap<MobEffectInstance,Integer> ids)throws Exception {
var visit=new ArrayList<MobEffectInstance>();var seen=new IdentityHashMap<MobEffectInstance,Boolean>();
for(int i=0;i<slots.length;i++){var e=slots[i];out.println("slot "+i+" "+id(ids,e));if(seen.put(e,true)==null)visit.add(e);}
for(int i=0;i<visit.size();i++){var e=visit.get(i);var h=(MobEffectInstance)hidden.get(e);String hid=h==null?"none":Integer.toString(id(ids,h));if(h!=null&&seen.put(h,true)==null)visit.add(h);var b=blend.get(e);out.println("node "+id(ids,e)+" "+effects.indexOf(e.getEffect())+" "+e.getDuration()+" "+e.getAmplifier()+" "+e.isAmbient()+" "+e.isVisible()+" "+e.showIcon()+" "+hid+" "+bits(factor.getFloat(b))+" "+bits(previous.getFloat(b)));}
}
static Object unsafe;static Method allocate;static Field removed;static Data active;
static <T>T make(Class<T> c)throws Exception{return c.cast(allocate.invoke(unsafe,c));}
static final class Data {JsonObject f;PrintWriter out;MobEffectInstance[] slots;IdentityHashMap<MobEffectInstance,Integer> ids=new IdentityHashMap<>();LivingEntity actor;ServerLevel[] levels;int calls;boolean changed;
JsonObject config(){return f.getAsJsonObject(changed?"after":"initial");}
void reset(){try{var c=config();actor.tickCount=n(c,"tick");for(int i=0;i<slots.length;i++){var v=c.getAsJsonArray("instances").get(i).getAsJsonObject();var e=slots[i];duration.setInt(e,n(v,"duration"));amplifier.setInt(e,n(v,"amplifier"));ambient.setBoolean(e,v.get("ambient").getAsBoolean());visible.setBoolean(e,v.get("visible").getAsBoolean());icon.setBoolean(e,v.get("icon").getAsBoolean());factor.setFloat(blend.get(e),fl(v,"factor"));previous.setFloat(blend.get(e),fl(v,"previous"));}}catch(Exception e){throw new AssertionError(e);}}
void all(){try{out.println("state "+calls+" "+changed+" "+actor.tickCount);dump(out,slots,ids);}catch(Exception e){throw new AssertionError(e);}}
void event(String name){out.println("event "+name);int i=calls++;all();if(i==n(f,"fail"))throw new Stop();if(i==n(f,"mutate")){changed=true;reset();}}
}
static final class Effect extends MobEffect {int id;Effect(int id){super(MobEffectCategory.BENEFICIAL,0);this.id=id;}
@Override public boolean shouldApplyEffectTickThisTick(int time,int amp){active.event("should "+id+" "+time+" "+amp);return active.config().get("should").getAsBoolean();}
@Override public boolean applyEffectTick(ServerLevel level,LivingEntity actor,int amp){if(actor!=active.actor)throw new AssertionError();int l=level==active.levels[0]?0:level==active.levels[1]?1:-1;if(l<0)throw new AssertionError();active.event("apply "+id+" "+l+" "+amp);return active.config().get("apply").getAsBoolean();}
@Override public int getBlendOutAdvanceTicks(){active.event("advance "+id);return n(active.config(),"advance");}
@Override public int getBlendInDurationTicks(){active.event("blend-duration "+id+" true");return n(active.config(),"blend_in");}
@Override public int getBlendOutDurationTicks(){active.event("blend-duration "+id+" false");return n(active.config(),"blend_out");}
}
public static void main(String[] args)throws Exception{net.minecraft.SharedConstants.tryDetectVersion();net.minecraft.server.Bootstrap.bootStrap();effects=List.of(Holder.direct(new Effect(0)),Holder.direct(new Effect(1)),Holder.direct(new Effect(2)));var u=Class.forName("sun.misc.Unsafe");unsafe=field(u,"theUnsafe").get(null);allocate=u.getMethod("allocateInstance",Class.class);removed=field(Entity.class,"removalReason");duration=field(MobEffectInstance.class,"duration");amplifier=field(MobEffectInstance.class,"amplifier");ambient=field(MobEffectInstance.class,"ambient");visible=field(MobEffectInstance.class,"visible");icon=field(MobEffectInstance.class,"showIcon");hidden=field(MobEffectInstance.class,"hiddenEffect");blend=field(MobEffectInstance.class,"blendState");factor=field(blend.getType(),"factor");previous=field(blend.getType(),"factorPreviousFrame");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 d=new Data();active=d;d.f=JsonParser.parseString(line).getAsJsonObject();d.out=out;d.actor=make(net.minecraft.world.entity.decoration.ArmorStand.class);d.levels=new ServerLevel[]{make(ServerLevel.class),make(ServerLevel.class)};var input=d.config().getAsJsonArray("instances");d.slots=new MobEffectInstance[input.size()];for(int i=0;i<d.slots.length;i++){var v=input.get(i).getAsJsonObject();int h=n(v,"hidden");d.slots[i]=new MobEffectInstance(effects.get(n(v,"effect")),n(v,"duration"),n(v,"amplifier"),v.get("ambient").getAsBoolean(),v.get("visible").getAsBoolean(),v.get("icon").getAsBoolean(),h<0?null:d.slots[h]);}d.reset();d.all();
for(var value:d.f.getAsJsonArray("ops")){var op=value.getAsJsonObject();int a=n(op,"a"),b=n(op,"b");String result="ok";try{switch(op.get("op").getAsString()){
case "server"->result=Boolean.toString(d.slots[a].tickServer(d.levels[n(op,"level")],d.actor,()->d.event("downgrade")));
case "client"->d.slots[a].tickClient();case "skip"->d.slots[a].skipBlending();
case "factor"->{removed.set(d.actor,op.get("removed").getAsBoolean()?Entity.RemovalReason.DISCARDED:null);result=Long.toString(bits(d.slots[a].getBlendFactor(d.actor,fl(op,"partial"))));}
case "update"->result=Boolean.toString(d.slots[a].update(d.slots[b]));case "copy"->d.slots[b]=new MobEffectInstance(d.slots[a]);case "alias"->d.slots[b]=d.slots[a];default->throw new AssertionError();
}}catch(Stop e){result="callback";}out.println("result "+result);d.all();}
}}
}
}
+74
View File
@@ -0,0 +1,74 @@
#!/usr/bin/env python3
"""Compare native status-effect ticking, hidden restoration and blending."""
import argparse
import json
import os
from pathlib import Path
import platform
import subprocess
import random
try:
from . import lab, test_rust_parity as base
except ImportError:
import lab
import test_rust_parity as base
def corpus():
durations=[-2147483648,-2,-1,0,1,2,3,20,2147483647]
floats=[0,0x80000000,1,0x3f000000,0x3f800000,0xbf800000,0x40000000,0x7f800000,0xff800000,0x7fc00000]
def instance(**kw):
v=dict(effect=0,duration=20,amplifier=1,ambient=False,visible=True,icon=True,hidden=-1,factor=0x3f000000,previous=0);v.update(kw);return v
def config(**kw):
v=dict(instances=[instance(duration=8),instance(duration=1,hidden=0),instance(duration=-1,hidden=1)],tick=99,should=True,apply=True,advance=2,blend_in=4,blend_out=8);v.update(kw);return v
def op(name,a=1,b=0,**kw):
v=dict(op=name,a=a,b=b,level=0,partial=0x3f000000,removed=False);v.update(kw);return v
def row(**kw):
v=dict(initial=config(),after=config(instances=[instance(duration=-1,amplifier=999),instance(duration=1,amplifier=-9),instance(duration=0)],tick=2147483647,should=False,apply=False,advance=0,blend_in=0,blend_out=-2),fail=-1,mutate=-1,ops=[op('server'),op('client'),op('factor')]);v.update(kw);return v
for mode in ['server','client','skip']:
for fail in range(-1,5):
for mutate in range(-1,5):yield row(fail=fail,mutate=mutate,ops=[op(mode),op('factor')])
for duration in durations:
for hidden_duration in durations:
for should in [False,True]:
for apply in [False,True]:yield row(initial=config(instances=[instance(duration=hidden_duration),instance(duration=duration,hidden=0),instance(duration=3,hidden=1)],should=should,apply=apply),ops=[op('server'),op('server'),op('client'),op('client'),op('factor')])
for value in floats:
for blend_ticks in [-2147483648,-2,-1,0,1,2,20,2147483647]:
for duration in [-1,0,1,20]:yield row(initial=config(instances=[instance(factor=value),instance(duration=duration,factor=value),instance(factor=value)],blend_in=blend_ticks,blend_out=blend_ticks),ops=[op('client'),op('factor',partial=value),op('factor',removed=True),op('skip'),op('factor',partial=value)])
rng=random.Random(0x4546465449434b)
def random_config():return config(instances=[instance(effect=rng.randrange(3),duration=rng.choice(durations),amplifier=rng.choice([-2147483648,-1,0,1,255,256,2147483647]),ambient=bool(rng.randrange(2)),visible=bool(rng.randrange(2)),icon=bool(rng.randrange(2)),hidden=rng.randrange(-1,i),factor=rng.choice(floats),previous=rng.choice(floats)) for i in range(3)],tick=rng.choice(durations),should=bool(rng.randrange(2)),apply=bool(rng.randrange(2)),advance=rng.choice(durations),blend_in=rng.choice(durations),blend_out=rng.choice(durations))
for _ in range(1800):yield row(initial=random_config(),after=random_config(),fail=rng.randrange(-1,20),mutate=rng.randrange(-1,20),ops=[op(rng.choice(['server','client','skip','factor','update','copy','alias']),a=rng.randrange(3),b=rng.randrange(3),level=rng.randrange(2),partial=rng.choice(floats),removed=bool(rng.randrange(2))) for _ in range(16)])
def main():
parser=argparse.ArgumentParser(description=__doc__);parser.add_argument('--prepare',action='store_true');args=parser.parse_args()
build=lab.LOCAL/'rust-status-tick-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/VanillaStatusTickOracle.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/status_tick_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.VanillaStatusTickOracle',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','status_tick_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'/('status_tick_fixture.exe' if os.name=='nt' else 'status_tick_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:,} status_tick 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 MobEffectInstance server/client ticks, skipBlending and getBlendFactor with shared instance/hidden-chain storage. Controlled MobEffect scheduling/application/blend-duration callbacks compare duration countdown, infinite actor clocks, hidden restoration and notification, live-state rereads, float interpolation, removed actors and callback mutation/failure prefixes. Concrete registered effect behaviors, entity effect maps, UI rendering and full gameplay remain pending.'}
lab.write_json(report_path,report);print(f'Scoped status_tick parity passed: {report_path}')
if __name__=='__main__':main()