# Magma live mob-AI fidelity audit

## Verdict

Mob AI is **not solved for the live simulator**. Magma accepts eleven ordinary mob types plus the Ender Dragon, but ordinary mobs share one small direct-steering loop rather than vanilla's prioritized, mutex-aware `EntityAITasks` scheduler. Of the requested special behaviors, only basic melee pursuit, a simplified wander, damage-only passive panic, a simplified creeper fuse/explosion, single-shot skeleton/blaze projectiles, wither-skeleton wither-on-hit, and a three-state custom dragon flight loop exist. Vanilla path navigation is not connected to the live loop. Pig zombies are present in a scenario tape but have no live entity type or AI.

This conclusion does not conflict with tape replay parity. Replay explicitly runs with `mobs=False` because spawn RNG does not match the oracle, and turns recorded entities into render/physics inputs (`verify/trace/replay_tape.py:642-678,844-868`). It therefore verifies rendering and tape-driven interaction, not autonomous mob decisions or trajectories. The standalone `mob_ai_*` kernels are also not the implementation called by the live game.

The pre-existing CPU checks were run without rebuilding and passed:

```
./magma/game/test_mob_live
mob_live: chase z 14.500000 -> 12.691686 y 4.000000
mob_live: wander moved 6.470 mind 31.346
mob_live: PASS

./magma/game/test_dragon_live
dragon_live: PASS melee/death/portal
```

Those are useful regression checks for the current simplified behavior, not vanilla parity tests.

### Citation notation

- `M/` means `/home/infatoshi/dev/netherite/`.
- `O/` means `/home/infatoshi/dev/minecraft/mc-1.11.2-env/java/oracle-src/net/minecraft/`.
- "Implemented" below means reachable from `gm_runtime_tick`, not merely present in an isolated `blaze` header. The live call is `M/magma/game/runtime.c:398-410`; accepted ordinary types are declared in `M/magma/game/mob_live.h:32-39` and `M/blaze/core/entity_hostile_spine.h:20-43`.

## Live implementation inventory and per-mob diff

All ordinary mobs pass through the same decision chain in `M/magma/game/mob_live.c:386-528`. It acquires only the player and requires current line of sight (`:434-446`), freezes ranged mobs and schedules a shot (`:447-452`), handles creeper/melee attacks (`:453-469`), uses straight-line panic (`:474-480`), chooses a stateless-hash waypoint every 120 ticks (`:481-505`), and performs only a one-cell jump/drop check (`:506-523`). Vanilla instead combines prioritized tasks, target tasks, navigation, look helpers, and persistent target state. Common vanilla parameters include: wander default chance 1/120 and radius 10 horizontal by 7 vertical (`O/entity/ai/EntityAIWander.java:17-27,33-68`); nearest-target chance 1/10 (`O/entity/ai/EntityAINearestAttackableTarget.java:32-46,61-107`); unseen target memory 60 ticks (`O/entity/ai/EntityAITarget.java:44-47,81-119`); idle look chance 2 percent for 20-39 ticks (`O/entity/ai/EntityAILookIdle.java:25-46`); melee repath randomness and width-derived reach (`O/entity/ai/EntityAIAttackMelee.java:111-176`).

| Mob | Magma live tasks | Vanilla 1.11.2 tasks and parameters | Concrete divergence and present coverage |
|---|---|---|---|
| Zombie | Player LOS acquisition; direct chase; melee damage 3 every 20 ticks; simplified daylight burn; generic wander/despawn. Natural spawn exists. | Priority 0 swim; 2 zombie melee speed 1.0, short memory; 5 move toward restriction speed 1; 6 move through village speed 1; 7 avoid-water wander speed 1; 8 watch player at 8 and look idle. Target priorities: hurt-by with help excluding pig zombies, nearest player, villager, then iron golem (`O/entity/monster/EntityZombie.java:77-95`). Attributes are follow 35, speed 0.23, damage 3, armor 2, plus reinforcement chance (`:97-105`). It also has probabilistic sky burn with helmet handling (`:208-242`), hard-difficulty reinforcement spawning (`:253-304`), burning attack propagation (`:314-328`), and spawn-time break-door/equipment bonuses (`:525-552`). | Magma says and uses follow 40 (`M/magma/game/mob_live.c:91-92`), not 35. It requires LOS every tick and has no 1/10 acquisition chance or 60-tick unseen memory (`:434-446` versus the common oracle citations above). Daylight burn is immediate whenever its simplified sky column is open (`:139-148,423-433`), not brightness/random/helmet based. No swim, restriction, village, watch/look, villager/golem targeting, group retaliation, door breaking, reinforcement, armor, equipment, or burning-on-hit logic exists. `M/magma/game/test_mob_live.c:21-29,48-98,156-200` covers coarse chase, damage, drops, sunlight, despawn, and existence only; it never checks task choice or oracle trajectory. |
| Skeleton | Player LOS acquisition; at any acquired range it stops and emits one exact-aim arrow immediately, then every 40 ticks; generic wander/despawn; simplified daylight burn. Natural spawn exists. | Swim; restrict sun; flee sun speed 1; avoid wolf within 6 at speeds 1/1.2; wander speed 1; watch player at 8; look idle; hurt-by, nearest player, and iron-golem targets (`O/entity/monster/AbstractSkeleton.java:79-90`). Bow AI is speed 1, initial cooldown 20, range 15 (`:51-52`), changed to cooldown 40 at normal difficulty (`:235-258`). It approaches until in range and visible for 20 ticks, then strafes with 20-tick and 0.3-random decisions, draws for 20 ticks, and fires (`O/entity/ai/EntityAIAttackRangedBow.java:80-170`). Arrow launch uses speed 1.6 and difficulty-dependent inaccuracy (`O/entity/monster/AbstractSkeleton.java:265-274`). | Magma's inherited follow range is 16, it stops immediately, and `attack_time=40` creates the projectile on that same state transition (`M/magma/game/mob_live.c:447-452`; `M/magma/game/runtime.c:138-155`). There is no 15-block bow range, approach, LOS warm-up/memory, draw, randomized strafe, or spread; isolated intent even hardcodes skeleton strafe to zero (`M/blaze/core/entity_hostile_spine.h:103-107`). Daylight has the same deterministic simplification as zombie. Height is the generic 1.95 rather than 1.99 (`M/blaze/core/entity_hostile_spine.h:58-73`; `O/entity/monster/AbstractSkeleton.java:55-59`). `M/magma/game/test_runtime.c:350-365` checks only that an arrow eventually exists and damages the player. |
| Wither skeleton | Accepted by the live store and test hook; direct player chase; melee damage 8 every 20 ticks; applies wither for 200 ticks; generic wander/despawn. It is not naturally spawned. | Inherits skeleton's task lists, but `setCombatTask` selects melee speed 1.2 with short memory when holding its stone sword (`O/entity/monster/AbstractSkeleton.java:235-258`). It is size 0.7 by 2.4 and fire immune (`O/entity/monster/EntityWitherSkeleton.java:24-31`), equips a stone sword and sets base attack damage 4 (`:85-107`), and applies Wither II for 200 ticks on a successful hit (`:116-130`). | Magma correctly has the specialized size/speed, effective repository-modeled sword damage 8, fire immunity, and 200-tick wither (`M/blaze/core/entity_hostile_spine.h:45-73`; `M/magma/game/mob_live.c:63-67,423-433,460-469`). It still omits swim, navigation, wolf avoidance, watch/look, hurt-by/golem targeting, target chance and memory, equipment state, and all inherited scheduler behavior. `M/magma/game/test_mob_live.c:61-78` covers only damage and wither pulses. The `wither_skeleton` tape (`M/verify/scenarios/wither_skeleton.yaml:19`) supplies recorded state and therefore adds no live-AI coverage. |
| Creeper | Player LOS acquisition; direct chase; begins swelling at horizontal distance at most 3; explodes at fuse 30 with radius 3; immediately decrements fuse while outside trigger; generic wander/despawn. Natural spawn exists. | Swim; swell; avoid ocelot within 6 at speeds 1/1.2; melee speed 1, short memory; wander speed 0.8; watch player at 8; look idle; nearest-player and hurt-by targets (`O/entity/monster/EntityCreeper.java:50-80`). Swell begins below squared distance 9, then keeps running until target is absent or beyond squared distance 49; it sets negative swell if LOS is lost (`O/entity/ai/EntityAICreeperSwell.java:22-65`). Fuse is 30 and radius 3 (`O/entity/monster/EntityCreeper.java:50-54,180-187`). | Fuse length and radius agree, but the state machine does not. Magma reverts to chase and subtracts one fuse tick immediately outside 3 blocks (`M/magma/game/mob_live.c:453-459,470-473`); vanilla has a 3-block start and 7-block continuation envelope plus LOS cancellation. Magma omits ocelot avoidance, swim, watch/look, proper target tasks, and max-fall handling. Generic height is 1.95 instead of 1.7 (`M/blaze/core/entity_hostile_spine.h:58-73`; `O/entity/monster/EntityCreeper.java:57-73`). `M/magma/game/test_runtime.c:367-377` checks only the simplified 30-tick explosion; `test_mob_live.c:131-154` checks coarse far wander. |
| Spider | Player targeting at night, or indefinitely after any hurt; direct chase; generic melee damage 4 every 20 ticks; generic wander/despawn. Natural spawn exists. | Swim priority 1; leap at target with vertical motion 0.4 priority 3; spider melee speed 1 priority 4; wander 0.8 priority 5; watch player at 8 and look idle priority 6; hurt-by, darkness-gated player target, and iron-golem target (`O/entity/monster/EntitySpider.java:53-64,237-282`). It climbs on horizontal collision (`:74-98`) and has health 16 and speed 0.3 (`:101-106`). Leap requires squared range 4 through 16, on-ground, and a 1/5 random check (`O/entity/ai/EntityAILeapAtTarget.java:26-65`). | Magma has no leap or climbing and the isolated spine explicitly leaves spider jump absent (`M/blaze/core/entity_hostile_spine.h:117-119`). It uses world time instead of measured brightness, never performs the vanilla 1/100 bright-light target drop, and hurt aggro has no expiry (`M/magma/game/mob_live.c:434-446`). Health is 20 instead of 16 (`:57` versus oracle `EntitySpider.java:101-106`); melee is 4 instead of the generic monster base 2 (`:63-67` versus `O/entity/SharedMonsterAttributes.java:23` and `O/entity/monster/EntityMob.java:98-100,191-194`). Reach is a fixed horizontal cylinder of 2 with vertical tolerance 3, not spider's squared `4 + target.width` (`M/magma/game/mob_live.c:13,460-469`; `O/entity/monster/EntitySpider.java:237-265`). No spider-specific live test exists. |
| Enderman | Targets only after being hurt; direct chase; melee damage 7; generic wander/despawn. Natural spawn exists. | Swim; melee speed 1; zero-chance override wander; watch player at 8; look idle; place and take blocks; stare-aware player target, hurt-by, and player-spawned endermite target (`O/entity/monster/EntityEnderman.java:61-95`). Follow is 64, health 40, speed 0.3, damage 7 (`:89-95`). Stare checks view direction and pumpkin (`:205-218`); player acquisition delays 5 ticks, close staring causes random teleport, and far pursuit teleports toward the player after 30 ticks (`:432-539`). It also has wet/daylight and projectile teleports (`:244-287,365-393`) and block placement/taking probabilities 1/2000 and 1/20 (`:541-620`). | Health, base speed, damage, and size match, but follow range is 16 rather than 64 (`M/magma/game/mob_live.c:57,63-67,91-92`; `M/blaze/core/entity_hostile_spine.h:45-73`). Stare acquisition, pumpkin immunity, 5-tick anger delay, speed boost, all teleports, wet/day response, projectile evasion, endermite target, and block griefing are absent. The `enderman_fight` tape (`M/verify/scenarios/enderman_fight.yaml:19`) replays recorded positions and does not exercise this live logic. No enderman-specific live test exists. |
| Blaze | Player LOS acquisition to only 16 blocks; stops and emits one exact-aim small fireball immediately, then every 40 ticks; generic ground wander/despawn. Nether spawner spawn exists. | Priority 4 fireball attack; 5 move toward restriction speed 1; 7 zero-chance override wander speed 1; 8 watch player at 8 and look idle; hurt-by with nearby help and nearest-player target (`O/entity/monster/EntityBlaze.java:58-75`). Follow is 48, speed 0.23, attack 6. Below squared distance 4 it melees every 20 ticks and moves; within follow range it charges 60 ticks, fires three fireballs six ticks apart, then cools down 100; outside it moves toward the target (`:212-323`). It has flight/descent behavior and a randomized height offset (`:116-162`). | Magma follow is 16, ranged handling wins even at melee distance, and it has no charge animation/state, three-shot burst, 6/100 timings, Gaussian spread, melee, approach, vertical flight, restriction, watch/look, or group help (`M/magma/game/mob_live.c:91-92,447-452`; `M/magma/game/runtime.c:138-155`). Its small fireball is speed 0.6 and damage 5/fire 100 in the runtime (`M/magma/game/runtime.c:149-155,174-215`), while vanilla's listed attack attribute is 6 and projectile behavior is not reproduced by this direct hit model. Generic height is 1.95 rather than 1.8 (`M/blaze/core/entity_hostile_spine.h:58-73`; `O/entity/monster/EntityBlaze.java:45-50`). `M/magma/game/test_mob_live.c:100-108` kills a blaze for loot but never lets its AI attack. All three blaze tapes (`M/verify/scenarios/blaze_bow_demo.yaml:20`, `blaze_bow.yaml:20`, `blaze_melee.yaml:19`) are recorded-state replay only. |
| Sheep | Generic wander; on damage, 100 ticks of straight-line movement directly away from player at base movement speed; generic despawn. Natural spawn exists. | Swim; panic speed 1.25; mate 1; tempt with wheat 1.1; follow parent 1.1; eat grass; wander 1; watch player at 6; look idle (`O/entity/passive/EntitySheep.java:87-99`). Health 8 and speed 0.23 (`:121-126`). Vanilla panic can start from an attacker or burning and asks navigation for a random target within 5 horizontal/4 vertical (`O/entity/ai/EntityAIPanic.java:20-77`). | Only a damage-triggered approximation of panic and wander exist. Panic is fixed at 100 ticks and points away from the current player, not the navigator-selected target; fire does not start it, and speed 1.25 is not applied (`M/magma/game/mob_live.c:17,106-109,474-480`). Health is 20 for explicit store spawn and 10 for natural spawn, neither vanilla 8 (`:57,334-345`). Generic collision size is wrong. No swim, breeding, temptation, parent following, grazing, watch, or look. `M/magma/game/test_mob_live.c:110-129` checks only positive displacement and drops. |
| Pig | Same generic wander and damage-only straight panic as sheep. Natural spawn exists. | Swim; panic 1.25; mate 1; carrot-stick temptation 1.2; carrot/potato/beetroot temptation 1.2; parent following 1.1; wander 1; watch at 6; look idle (`O/entity/passive/EntityPig.java:57-68`). Health 10, speed 0.25 (`:70-75`). | All tasks except approximate wander/panic are missing. Magma uses generic speed 0.23 instead of 0.25 (`M/blaze/core/entity_hostile_spine.h:39-55`), does not apply panic multiplier, and has the same fixed 100-tick/direct-away mismatch (`M/magma/game/mob_live.c:474-505`). Explicit spawn health is 20 while natural health is 10 (`:57,334-345`). Size is generic and wrong. No pig-specific test exists. |
| Cow | Same generic wander and damage-only straight panic as sheep. Natural spawn exists. | Swim; panic 2; mate 1; wheat temptation 1.25; parent following 1.25; wander 1; watch at 6; look idle (`O/entity/passive/EntityCow.java:41-58`). Health 10, speed 0.2. | All tasks except approximate wander/panic are missing. Magma uses generic speed 0.23 instead of 0.2 and does not apply panic speed 2 (`M/blaze/core/entity_hostile_spine.h:39-55`; `M/magma/game/mob_live.c:474-505`). Explicit spawn health is 20 while natural health is 10 (`M/magma/game/mob_live.c:57,334-345`). Size is generic and wrong. No cow-specific test exists. |
| Chicken | Same generic wander and damage-only straight panic as sheep. Natural spawn exists. | Swim; panic 1.4; mate 1; seed temptation 1; parent following 1.1; wander 1; watch at 6; look idle (`O/entity/passive/EntityChicken.java:47-77`). It also has fall-motion damping and egg timing (`:83-110`). Health 4, speed 0.25, size 0.4 by 0.7. | All tasks except approximate wander/panic are missing. Magma uses generic speed 0.23, health 20 explicit or 10 natural, and generic 0.6 by 1.95 collision size (`M/magma/game/mob_live.c:57,334-345`; `M/blaze/core/entity_hostile_spine.h:39-73`). It does not apply panic multiplier, flap/fall behavior, or egg laying. No chicken-specific test exists. |
| Ender Dragon | A separate live wrapper runs a custom three-state loop: circle, strafe, hover. It selects a nearest crystal and heals, moves at constant direct velocity 0.6, allows externally-injected coarse contact damage, and has death/portal handling (`M/magma/game/dragon_live.c:37-102`; `M/blaze/core/ender_dragon.h:18-29,118-203`). | Vanilla exposes 11 phases: holding, strafe, landing approach, landing, takeoff, sitting flaming/scanning/attacking, charging, dying, and hover (`O/entity/boss/dragon/phase/PhaseList.java:10-20`). It starts in hover (`O/entity/boss/dragon/phase/PhaseManager.java:14-38`), navigates a 24-node graph/A* and applies acceleration, yaw and drag (`O/entity/boss/EntityDragon.java:105-133,261-308,734-793,836-965`), performs autonomous head/wing contact and block destruction (`:348-401`), and probabilistically retargets crystals (`:435-467`). Holding and strafing choose graph paths and transitions (`O/entity/boss/dragon/phase/PhaseHoldingPattern.java:63-165`); strafe charges and fires a dragon fireball (`O/entity/boss/dragon/phase/PhaseStrafePlayer.java:61-182`); sitting flame creates the breath cloud (`O/entity/boss/dragon/phase/PhaseSittingFlaming.java:59-107`). | The core labels itself as only phases 0/1/2 with fixed arena and no block destruction/contact (`M/blaze/core/ender_dragon.h:1-8`). Its phase transitions are fixed counters and distance checks (`:139-173`), not vanilla's phase manager or path graph. It starts at a seed-dependent damaged health and seed-dependent phase age (`:205-235`), unlike vanilla health 200 and hover initialization. Eight phases, landing/perching/takeoff, graph navigation, fireball, breath cloud, autonomous contact, part-aware collision/damage, and block destruction are absent. `M/magma/game/test_dragon_live.c:7-27` covers melee kill/death/portal only; `M/magma/game/test_mob_live.c:32-45` injects contact rather than observing autonomous collision. End tapes replay recorded dragon states, so they do not validate this flight loop. |

### Pig zombie: present in tapes, absent from live AI

`pigmen_aggro.yaml` records pig zombies (`M/verify/scenarios/pigmen_aggro.yaml:19-23`), but `GmMobType` has no pig-zombie value and `gm_type_ok` accepts no such entity (`M/magma/game/mob_live.h:32-39`; `M/magma/game/mob_live.c:26-28`). Vanilla pig zombies replace zombie targeting with anger-gated player targeting and hurt-by group propagation (`O/entity/monster/EntityPigZombie.java:40-68,246-278`), acquire a temporary speed boost, and become angry for `400 + nextInt(400)` with a `nextInt(40)` sound delay after player attack (`:70-101,165-200`). None of that can run live. This is the clearest scenario-level missing mob, not merely a partial implementation.

## Scenario-tape coverage versus live-AI coverage

The scenario population is zombie (`M/verify/scenarios/smoke_zombie.yaml:18`), blaze (three files cited in the table), pig zombie, wither skeleton, enderman, and dragon. Their live status is:

- Zombie: partial generic chase/melee; the scenario does not test it autonomously.
- Blaze: partial one-shot ranged approximation; no vanilla burst, melee, follow range, or flight.
- Pig zombie: entirely missing as a live type.
- Wither skeleton: partial melee/wither implementation; no inherited scheduler/navigation behavior and no natural spawn route.
- Enderman: only hurt-triggered melee chase; stare and teleport, the defining AI, are missing.
- Dragon: custom three-phase approximation; most vanilla phases and attacks are missing.

Recorded positions make these tapes valuable source material for a future trajectory gate, but current replay explicitly substitutes those recorded positions rather than asking C AI to regenerate them.

## Pathfinding verdict

**Live magma does not implement or call vanilla `PathNavigateGround`/A* for mobs.** The live loop ray-tests current LOS, aims directly at a target/waypoint, invokes living collision physics, and checks only a single forward block for jump/drop behavior (`M/magma/game/mob_live.c:111-137,269-290,434-446,481-523`). There is no path object, open/closed set, node cost, door flag, water flag, repath-delay model, or stuck detector in that reachable path.

The repository contains two disconnected navigation surfaces:

1. The legacy `pf_*` A* is explicitly described as a hand-rolled, non-faithful 1.11.2 grid search used by isolated `mob_ai_*` and `entities_world` checks (`M/blaze/core/pathfinding.h:1-13`). CPU/CUDA agreement for those kernels is internal consistency only.
2. The newer `pf12_*` is a vanilla-faithful synthetic port of `PathFinder`, `PathHeap`, and `WalkNodeProcessor`, including node classifications/priorities and door/water handling (`M/blaze/core/pathfinding.h:9-13,341-343`; `M/blaze/core/path_node_processor.h:31-74,157-173,379-413`). It has a Java golden. The separate `path_navigate` battery follows already-supplied points on open ground and explicitly omits finding, solids, stuck/repath, and full movement (`M/blaze/core/path_navigate.h:1-27`).

Vanilla dynamically transforms closed/open doors, rails, water/lava, hazards, fences and open/drop nodes (`O/pathfinding/WalkNodeProcessor.java:303-369,388-447`) and exposes break-door, enter-door, swim, and avoid-sun navigation policy (`O/pathfinding/PathNavigateGround.java:275-361`). The C oracle runner performs exact Java-to-CPU line comparison only when a Java golden exists (`M/blaze/oracle/runner.py:41-64,114-138`). `pathfinding12` and `path_navigate` have such goldens; `mob_ai_zombie_astar`, the other `mob_ai_*` cases, and `ender_dragon` do not. Therefore the low-level `pf12` node processor is verified on its synthetic battery, but **live obstacle routing, node weights, door policy, water avoidance, and path following are wholly unverified because the verified pieces are not wired into live mobs**.

## RNG and determinism verdict

Vanilla uses a per-entity `Random`: `Entity` constructs `rand = new Random()` and immediately consumes it for UUID construction (`O/entity/Entity.java:230-247`). AI tasks call the entity's RNG. The world has a separate `World.rand` (`O/world/World.java:95,108`) for world/spawn operations; for example zombie and spider spawn initialization consumes world randomness (`O/entity/monster/EntityZombie.java:502-519`; `O/entity/monster/EntitySpider.java:200-216`). It is not accurate to model vanilla AI as one shared world RNG.

The Malmo oracle makes construction reproducible but retains the per-entity model: `MixinEntityRandom` replaces an entity's generator with `SeedHelper.getRandom("entity")` (`M/java/Minecraft/src/main/java/com/microsoft/Malmo/Mixins/MixinEntityRandom.java:19-29`), and `SeedHelper` derives a new seed from the named allocator and returns a distinct `Random` (`M/java/Minecraft/src/main/java/com/microsoft/Malmo/Utils/SeedHelper.java:43-51,85-96,121-143`). Construction order still matters, as does every RNG consumption after construction.

Magma has no per-mob `java.util.Random` state in `GmMobLive` (`M/magma/game/mob_live.h:11-29`). Wander chooses a fresh stateless hash of world seed, tick and slot (`M/magma/game/mob_live.c:481-495`); natural spawning similarly hashes tick/attempt (`:334-383`). This is deterministic within C but cannot reproduce vanilla's 48-bit cursor, Gaussian cache, per-entity consumption order, or separate world RNG stream.

Per-mob oracle determinism is feasible under the controlled Malmo oracle, but only after C stores the exact 48-bit `java.util.Random` state (and Gaussian cache) for each entity, obtains or reproduces the exact derived seed in construction order, mirrors UUID/setup consumption, and consumes random values in the exact task order. A separate mirrored world RNG is required where spawn/group logic is in scope. It is not feasible to claim exact parity against an uncontrolled ordinary client whose `new Random()` seeds are not captured.

Existing tests sidestep the mismatch in two ways. `test_mob_live.sh`/`test_mob_live.c` use C's deterministic hashes and assert coarse facts such as "moved closer", "moved more than one block", damage, drops, or a timer, not oracle positions or selected tasks (`M/magma/game/test_mob_live.c:21-200`). Tape replay disables C mob simulation and consumes recorded entities (`M/verify/trace/replay_tape.py:642-678,844-868`). Neither approach tests live per-mob RNG parity.

## Ranked test gaps and proposed designs

1. **No live mob-trajectory parity gate.** Add a runner mode that initializes C mobs from a tape's first entity sample, disables recorded-entity injection, replays identical player inputs/world mutations, and compares stable entity IDs at every tick: position, motion, yaw, target ID, active task/phase, attack/fuse timers, health/fire/effects, and projectile events. Report the first divergent field/tick rather than only an aggregate endpoint.
2. **No task scheduler/priority tests.** Build table-driven C unit fixtures around an explicit task scheduler. Inject a finite sequence of RNG outputs and assert exact task start/continue/reset order, mutex preemption, target retention, task speed, and timer values. Start with common `swim > panic/attack > wander > watch/look` and separate target-task priority fixtures. These tests should compare integer state exactly; use bit equality for ported Java float/double values.
3. **No live navigation test.** Use fixed tiny worlds with a wall and gap, one-block ascent, two-block drop, water strip, lava/fire/cactus hazard, open/closed wooden door, iron door, fence, and sun/shade route. Assert the exact `pf12` node sequence first, then the live entity's waypoint index and trajectory. This exposes the present disconnected-pathfinder problem immediately.
4. **No blaze attack-cycle or flight test.** Seed a fixed entity RNG, place the player at squared distances below 4, between 4 and follow range, and outside 48. Assert melee every 20; 60-tick charge; shots at the vanilla burst ticks; 100-tick reset; vertical offset update; Gaussian projectile vectors; and help retaliation. A controlled oracle tape should record blaze state and all spawned projectiles for the same fixture.
5. **No enderman stare/teleport test.** Deterministic fixtures should vary pumpkin, view dot product around the threshold, 5-tick acquire delay, distance below 4 and above 16, water/daylight, and indirect damage. Record teleport attempts and chosen coordinates, including failed collision/liquid attempts, rather than asserting only a final position.
6. **No pig-zombie live test because the type is absent.** Add two pig zombies and verify player damage causes the vanilla anger duration/sound delay and nearby same-class propagation, while an unprovoked player is not targeted. Include the angry speed modifier's add/remove lifecycle and NBT persistence. This should be the first new scenario-mob acceptance test.
7. **No skeleton bow-state test.** Assert approach outside 15, 20 visible ticks before stopping, draw time, normal-difficulty 40 cooldown, LOS loss behavior, and the randomized strafe toggles. Compare exact projectile velocity/inaccuracy samples against the seeded oracle.
8. **No creeper state-machine test.** Tick at 2.99, between 3 and 7, beyond 7, and behind an LOS blocker. Assert swell task continuation, positive/negative state, fuse rollback, explosion tick 30, and ocelot preemption. The current test should be retained as a smoke but must not define the fidelity contract.
9. **No spider specialization test.** Seed the 1/5 leap decision at distance 2 through 4, horizontal-collision climb, bright-light 1/100 target drop, darkness target acquisition, and iron-golem targeting. Include exact health 16, damage 2, and spider reach.
10. **No zombie special-behavior test.** Cover target priority among player/villager/golem, 60-tick hidden-target memory, hard-difficulty reinforcement attempts, group help exclusion for pig zombies, door-breaking spawn flag, helmet daylight behavior, and burning-on-hit chance.
11. **No passive task test beyond sheep displacement.** Give each passive a compact parameterized fixture for correct health/size/speed, swim, damage/fire panic and multiplier, tempt items/speed, mate, parent follow, wander, watch/look; add sheep grass eating and chicken fall/egg timers. Pig/cow/chicken currently have zero dedicated live tests.
12. **No dragon flight/phase parity.** Record and compare phase ID, phase-local counters, path nodes, crystal target/heal event, part transforms, collision damage, destroyed blocks, fireballs and breath clouds. Use one deterministic tape per major transition rather than a single full fight: hover-to-holding, holding-to-strafe, landing/perch/flame/takeoff, charge, and dying. The current death/portal test remains useful but covers none of the missing flight AI.

For oracle trajectory scenarios, make determinism an explicit fixture contract: `doMobSpawning=false`, fixed day/weather/difficulty, fixed summon order and stable IDs, fixed blocks, no unrelated entities/random ticks, captured entity RNG seed/cursor (or an oracle hook that installs it after constructor setup), and a separately controlled world RNG when needed. Where the normal oracle cannot expose a seed, record the RNG outputs/cursor alongside the tape. Positions already exist in tapes, but phase/task IDs, motion, target ID and RNG state should be added so a positional divergence can be diagnosed rather than merely observed.

## Top 10 fixes for âmob AI solvedâ

Ranked by fidelity impact, scenario relevance, and implementation effort. The first three are shared infrastructure and prevent repeatedly implementing subtly incompatible one-off behavior.

1. **Add the per-entity Java RNG model and live trajectory parity mode.** Medium effort, highest leverage. Store the Java 48-bit state/Gaussian cache, separate world RNG, capture controlled oracle seeds, and make first-divergence trajectory comparison a gate.
2. **Replace the ordinary-mob `if/else` chain with a vanilla-shaped task/target scheduler.** High effort, very high impact. Implement priority, mutex bits, `shouldExecute`, `continueExecuting`, reset, current-task sets, target chance, and unseen memory once.
3. **Wire verified `pf12` plus a complete `PathNavigateGround` follower into the live world.** High effort, very high impact. Preserve per-entity door/swim/sun/path priorities, repath delays, waypoint skipping and stuck handling; add live obstacle batteries before migrating every task.
4. **Implement pig zombie as a live type with anger and group aggro.** Medium effort, high scenario impact. It is the only taped ordinary mob that is completely absent.
5. **Port blaze fireball/melee/flight AI exactly.** Medium effort, high scenario impact. Correct follow 48, charge/three-shot/cooldown timing, Gaussian spread, height offset, movement, and retaliation help.
6. **Port enderman stare, speed boost and teleport state machines.** Medium-high effort, high scenario impact. Correct follow 64, pumpkin/view test, delay, wet/day/projectile responses, collision-valid teleport, and block/endermite tasks.
7. **Replace the custom dragon loop with the vanilla phase manager and graph navigation.** Very high effort, very high product impact. Implement all 11 phases, graph/A*, crystal selection, part collision/contact, fireball/breath, landing/perching, and block destruction, each behind transition-specific gates.
8. **Complete skeleton ranged combat.** Medium effort, high gameplay impact. Implement 15-block bow range, approach/LOS accumulation, draw, difficulty cooldown, randomized strafing, and projectile inaccuracy; share inherited target/sun/wolf tasks with wither skeleton.
9. **Finish creeper and spider combat specializations.** Low-medium effort, high payoff. Creeper needs 3/7-block swell hysteresis and LOS/ocelot behavior; spider needs health/damage correction, leap, climb, brightness target drop, and golem targeting.
10. **Complete zombie specials and passive-animal task lists, attributes and dimensions.** Medium-high aggregate effort. Add zombie reinforcement/village/door/daylight-equipment behavior, then implement each animal's panic speed, swim, tempt/mate/parent/watch/look tasks plus sheep grass and chicken fall/egg behavior. Parameterize the shared animal tasks, but retain each vanilla mob's exact values.

The practical completion criterion should be: every reachable live mob has an exact vanilla task inventory and attributes, every scenario mob can autonomously reproduce a controlled oracle trajectory to the chosen bit/tolerance contract, path and RNG state are diagnosable at first divergence, and no CPU/CUDA-only isolated test is counted as oracle evidence unless it has a Java golden or a controlled oracle tape.
