On a dedicated server (and single player's server thread) the End is ticked
with no local player, and `tick_fight` returned before spawning the dragon:
players in the End found crystals but never a dragon.
- The fight finds its players as `EnderDragonFight.updatePlayers` does, every
20 ticks: every player alive within 192 blocks of (0, 128, 0), the host and
the network players in the level alike. Scanning the state, the respawn
sequence, `createNewDragon` and the crystal count run while it has one;
the dragon and crystals tick whenever the End does.
- The dragon is tracked to network players (`minecraft:ender_dragon`, its
health and `DATA_PHASE` as vanilla pairs them, no attribute instances) and
reserves its eight part ids after its own, as `EnderDragon`'s constructor
does, so clients can attack the parts; a network player's attack on a part
or an end crystal is aimed at it.
tools/test_server_dragon_parity.py sends a lone vanilla-codec client to the
End of vanilla's dedicated server and of Horizon's: the fight starts and the
dragon is tracked with the same spawn data, synched data entries and
attributes. VanillaProtocolClient's entity mode answers a scene's teleport
with the acceptance alone, as the 26.3 client does.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
(cherry picked from commit 618db927d93bbcf7f3669ad0d630377c4646729d)