Conflicts kept from both sides: crates/horizon-client/src/entity_nbt.rs tools/command_exec_corpus.py tools/test_command_exec_parity.py
Co-Authored-By: Claude Opus 5.5 <[email protected]>
SnbtGrammar accepts one trailing comma before the closing brace or
bracket; a comma alone and two in a row stay errors. Both readers take it:
horizon-world's parse_snbt (NBT arguments, item components) and the text
component reader (tellraw and other component arguments).
Fixes#11285
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Reuse the admitted modern SNBT decode contract for merge and literal modify.
Add actual Game storage and command-oracle regressions for typed values and
no-change copy callbacks.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>
Enderman.hurtServer teleports inside the hurt (teleport(), or
repeatedlyTryToTeleport() for a projectile or a thrown potion). Mob::damage
has no world, so it only leaves the tries in counter2 and the enderman's
next AI step ran them. Game::settle_hurt_teleports runs them right after
/damage, and in the creature tick before the mobs tick and after the
systems' outbox: a command after /damage no longer finds it in place, and
under /tick freeze it teleports at all.
Command harness group "enderman command damage": 3/5 -> 5/5.
Fixes#11069
Co-Authored-By: Claude Opus 5.5 <[email protected]>
All three add a command_exec fixture group at the same lines and a test
module at the end of entity_nbt.rs; keep every group, flag, dispatch block
and module. Queued in order so whichever lands first leaves the others
mergeable.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Both add a command_exec fixture group at the same lines; keep both groups,
their isolation sets, flags and dispatch blocks. Queued in order so either
landing first leaves the other mergeable.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Adopt and project the existing fall counter, including Java's per-movement float narrowing before double accumulation. Preserve travel and landing-call order, and cover the real tick/save route plus decoded saves without raw data.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>
Write CanPickUpLoot on every save through the existing virtual getter, preserving the Allay and sulfur-cube overrides instead of retaining stale raw bytes. Cover decoded and mutated models plus frozen actual command reads.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>
Reuse the existing identity getter rather than generating a UUID per read. Cover repeated saved reads, absent raw input and stale raw UUIDs through the actual Game getter and command fixture.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>
Floor floating Health values before short narrowing and preserve integer narrowing. Add an actual decode-to-save regression and an isolated Game/Java command fixture.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>
From review, each measured against vanilla:
- DragonHoverPhase.getFlySpeed is 1, not the default 0.6: a hovering dragon thrown upwards
climbs back at vanilla's rate (new harness case, 12 commands off before).
- wrap / wrap64 are Mth.wrapDegrees: Java's % then one step of 360. rem_euclid lost the low
bits of a negative angle (-10.123456 became -10.123444) every tick (unit test).
- The parts' placement, the strafe aim and the flap timing use Mth.sin / Mth.cos and vanilla's
float casts.
- DragonSittingScanningPhase turns only while the player is more than 10 degrees off the
heading, with Mth.atan2 and vanilla's degree constant; dist is clamped in both divisions.
- A dragon's parts start at the origin, as vanilla's part entities do until the first aiStep,
so its first scanning turn aims from there.
The command execution harness gets "dragon scanning turn" (a dragon facing a survival player and
one turned away): 6/12 before, 12/12 now. All dragon and End harnesses match; the whole command
execution harness: 15832/15832.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
EnderDragon's constructor sets EnderDragonPhase.HOVERING; only EnderDragonFight.createNewDragon
sets the holding pattern. Dragon::new started every dragon holding its pattern, so a dragon from
/summon, a spawn egg or a save without DragonPhase flew off. It now starts hovering, and
create_new_dragon sets the holding pattern.
Hovering had never run on the server, and the flight step diverged there: the target is a hair
away, where Vec3.normalize returns zero under 1.0E-5 and vanilla's Mth.sin/cos table and
Mth.atan2 turn the dragon differently from the exact functions. The step now uses them, the
doubles of moveRelative's input vector and vanilla's 0.91F and 0.8F as doubles.
The command execution harness gets "summoned dragon hovers" (phase and position every 20 ticks
over 120): 0/13 before, 25/25 now. The dragon harnesses (server dragon, contacts, NoAI, not the
fight's, death outside the End, death roar, forced End, spawn eggs in fluids, dispensers) match.
Fixes#10285
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Keep spectral duration in the loaded arrow state and always write its integer
value, including the default 200. Cover the live command route and load/save
without raw input while retaining broader type and display diagnostics.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>
From review:
- A perched dragon shrugs off a direct arrow, trident or wind charge given as `by`
(AbstractDragonSittingPhase.onHurt is 0, under 0.01): the command is refused.
- dealDefaultKnockback: a counted hit of a type not in #no_knockback pushes the dragon away from
the command's source position (`at`, else the direct entity), or in no direction without one.
- credit_dragon_kill switches to the credited guest whenever they are not the one acting, as the
mob kill credit does, so a guest's command that credits another guest awards that guest.
The harness scenario summons its dragons holding their pattern (DragonPhase 0): vanilla summons a
hovering dragon, which is sitting, and Horizon one holding its pattern; that gap is separate.
The intermediate build: 36/39; now 39/39.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
cmd_damage had no arm for them, so both said "Target is invulnerable".
EnderDragon.hurtServer is hurt(body, ...): a quarter plus up to 1; reallyHurt runs only with a
player behind the source or an #is_explosion type and refuses fire, and hurt succeeds either
way unless the dragon is dying or the hit is under 0.01. EndCrystal.hurtServer refuses an
Invulnerable crystal (unless generic_kill, out_of_world or a creative player), fire and the
dragon's own damage; else it is removed, and blows up unless the damage is an explosion.
The command execution harness gets a "dragon command damage" group: 15/31 before, 31/31 after.
Fixes#10265
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Keep the map-crafting, transmute, mob-effect and frame-map groups and their
isolation sets. The merged game passes the focused 62-record Java replay.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>
Use the level's backed maps for crafting recipe matching and run map
post-processing on the actual stacks taken by swap, pickup and quick-move.
Keep the original-copy callback used by quick-move and preserve cartography.
Add a real Game/Menu regression and a guarded connected-owner Java/Game
fixture covering previews, consumed inputs, transferred maps and saved backing.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>
Project live effect IDs, amplifiers and durations into the existing view.
Cover named if/unless predicates and actual Game view construction.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>
Retain template patch presence so explicit removals and zero-valued
components override the input without losing inherited data. Preserve
transient map postprocessing through assembly and add powered-crafter
and resource-free regression coverage.
Co-Authored-By: Codex gpt-6.1-sol <[email protected]>