A falling block's move now runs vanilla's checkInsideBlocks along its path: a
cobweb it passes or lands in makes it stuck (0.25, 0.05, 0.25), which scales
its next move and zeroes its velocity, and resets its fall distance.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
ClientboundUpdateAttributesPacket, as vanilla's ServerEntity sends it: every
client-syncable instance when an entity is paired, the changed ones with the
dirty entity data, and a player's dirty set to the player itself.
- Mobs and armor stands report the instances vanilla would have created
(movement speed, finalizeSpawn's bases and modifiers, the baby modifier,
effects', equipment's and /attribute's), players their LiveAttributes.
- Guests get the per-tick movement speed instance and the creative reach
modifiers (ServerPlayer.updatePlayerAttributes).
- cube::set_size sets the attribute bases as AbstractCubeMob.setSize does,
so a summoned slime has its size's health and speed.
- server_entities compares attributes again, the player's own too, with a
slime and a scaled pig in its scene.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`/summon minecraft:tnt` and primed TNT in a saved chunk were kept as an
unsimulated entity. They now become primed TNT with the fuse (80 when
absent) and motion they were saved with (PrimedTnt.readAdditionalSaveData).
The entity harness runs its scene for a fixed 200 ticks (`tick step`),
so what still changes when the client stops recording (a fuse) ends the
same on both servers. Its scene has two primed TNT (one falling), a
floating falling block, an arrow that lands and an end crystal. Unit
tests cover arrows' position and rotation, fireballs' bundled power and
precise position syncs.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
These entities had no id in Horizon, so a server could not send them to
its clients. Each now has one, given from the entity counter before it is
first tracked, and goes to guests as vanilla's ServerEntity sends it:
- primed TNT with its fuse (sent each tick it changes) and falling blocks
with their block state and start position; both sync their exact
position while they touch a block (requiresPrecisePosition);
- arrows and tridents send their position and rotation every update
(AbstractArrow), with their flags, pierce level, in-ground state,
loyalty and foil; their owner is the spawn data;
- fireballs, wither skulls and wind charges bundle their velocity with
ClientboundProjectilePowerPacket (new in horizon-protocol);
- snowballs, eggs, pearls, llama spit, shulker bullets and splash potions;
- firework rockets with their item, the player they boost and whether
they were shot at an angle; end crystals with their beam and base.
The entity harness's scene gains primed TNT, a falling block, an arrow, a
snowball and a trident that land, a fireball, a firework and a crystal.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A server sent its clients only mobs and dropped items. Boats, every kind of
minecart, armor stands, item frames, paintings and the entities Horizon keeps
without simulating are now tracked as ServerEntity does: the AddEntity data
(hanging entities at their block, with their direction), the synched data that
differs from the defaults, equipment, passengers (ClientboundSetPassengersPacket
at pairing and on change; a passenger syncs only its rotation and resyncs its
position when it dismounts), and the type's update interval and range.
Also vanilla-exact on the way, as the new harness found:
- mobs pair with their health (always non-default) and Mob flags (no AI, left-handed);
- /summon without NBT summons any type from an empty compound;
- armor stands move before gravity (LivingEntity.travelInAir), so a stand at rest
keeps vanilla's -0.0784 vertical motion.
tools/test_server_entities_parity.py compares, from a vanilla-codec client, what
vanilla's dedicated server and Horizon's track for a scene of 20 entities.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>