No description
Find a file
Troy Redfearn 4f86be0bc3 Extend goal-class glossary to FollowParentGoal, ResetUniversalAngerTargetGoal, RangedAttackGoal, LeapAtTargetGoal, PatrollingMonster.LongDistancePatrolGoal
Next tier down by usage frequency (11 and 5-6 occurrences). Verified
against each class's decompiled source:

- FollowParentGoal: only usable while the animal is a baby, holds a rough
  3-16 block follow band rather than beelining onto the parent.
- ResetUniversalAngerTargetGoal: only matters if the universalAnger
  gamerule is on; alertOthersOfSameType mirrors HurtByTargetGoal's
  same-class alert pattern almost exactly (same FOLLOW_RANGE/±10 box).
- RangedAttackGoal: never finds its own target (reads whatever
  targetSelector already set); the 4-arg constructor interpolates shot
  cadence by distance, faster up close.
- LeapAtTargetGoal: only fires in a 2-4 block band, and even then only on
  a ~1-in-3 per-tick roll (reducedTickDelay halves the literal "5") -
  explains why leaps look bursty rather than immediate.
- PatrollingMonster.LongDistancePatrolGoal: doesn't decide to patrol, just
  executes an already-assigned destination; patrol leaders push new
  waypoints to companions directly, which is why patrols move as a pack.

Coverage: 48 -> 50 mob reports (the remaining uncovered classes mostly
appear only on 1-2 mobs each, so this is a reasonable stopping point).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-26 14:15:15 -07:00
analysis Extend goal-class glossary to FollowParentGoal, ResetUniversalAngerTargetGoal, RangedAttackGoal, LeapAtTargetGoal, PatrollingMonster.LongDistancePatrolGoal 2026-07-26 14:15:15 -07:00
scripts Extend goal-class glossary to FollowParentGoal, ResetUniversalAngerTargetGoal, RangedAttackGoal, LeapAtTargetGoal, PatrollingMonster.LongDistancePatrolGoal 2026-07-26 14:15:15 -07:00
.gitignore Resolve RunOne/TriggerGate weighted lists and rewrite reports for readability 2026-07-26 12:06:33 -07:00
README.md Resolve RunOne/TriggerGate weighted lists and rewrite reports for readability 2026-07-26 12:06:33 -07:00

Minecraft Mob AI Investigation

Pulls the official Mojang server jar for a given version, decompiles it, and extracts every mob's AI logic (goal-selector priorities and brain activities/behaviors) into readable per-mob reports.

Minecraft's server jar is no longer obfuscated as of recent versions — Mojang ships it with real class/method names, so no separate deobfuscation mapping step is needed, just a plain decompiler.

Pipeline

  1. tools/jdk/ — portable JDK 21 (Temurin), used to run the decompiler.
  2. tools/vineflower.jar — decompiler.
  3. versions/<version>/server.jar — downloaded from Mojang's version manifest.
  4. versions/<version>/src/ — decompiled source (via Vineflower).
  5. scripts/extract_mob_ai.py — parses net.minecraft.world.entity.* classes for registerGoals() (classic goal system) and Brain.Provider setups (activity/behavior system), writing analysis/mob_ai.json.
  6. scripts/generate_reports.py — turns that JSON into analysis/mobs/*.md (one file per mob) plus analysis/index.md.

Outputs

Two deliberately different artifacts, both under analysis/:

  • mob_ai.json — machine-readable. One record per mob with the full, untruncated data: every goal/behavior's raw expression text, priorities, weighted-choice sublists, sensors, memory types, etc. This is the thing to parse if you're writing another tool against the extracted data.
  • mobs/*.md + index.md — human-readable. Same underlying data, formatted as prose explanations, fenced/pretty-printed Java snippets, and an index grouped by mob category (Monsters / Animals / NPCs / Bosses / Raiders). This is the thing to actually read.

Reproducing for a new version

# 1. Get the version's server jar URL from Mojang's manifest, download it to
#    versions/<version>/server.jar, then unzip the nested
#    META-INF/versions/<version>/server-<version>.jar (bundler format).
# 2. Decompile:
tools/jdk/bin/java -jar tools/vineflower.jar -log=WARN \
  versions/<version>/META-INF/versions/<version>/server-<version>.jar \
  versions/<version>/src/
# 3. Extract + report (edit VERSION_DIR in both scripts first):
python3 scripts/extract_mob_ai.py
python3 scripts/generate_reports.py

Notes / limitations

  • tools/ and versions/ are gitignored: the JDK/decompiler are large binaries, and the Mojang jars + decompiled source aren't ours to redistribute (Mojang's EULA permits decompiling your own copy for personal study/modding, not republishing the result). analysis/ — our own derived notes about goal names, priorities, and behavior structure — is the actual output of this project.
  • The extractor is regex/brace-matching based, not a real Java parser. It handles the common patterns well — Guava's Pair.of(priority, behavior) lists, the new Pair[]{...} overflow-array pattern for lists with more than 12 entries, and the weighted random-choice sublists inside RunOne and TriggerGate.triggerOneShuffled/triggerGate — but for a mob with unusual code layout, the decompiled source in versions/<version>/src/ is the ground truth — check it directly.
  • Expressions are pretty-printed by breaking top-level arguments onto their own line once they get long, recursing into single-argument wrapper calls (e.g. TriggerGate.triggerOneShuffled(ImmutableList.of(...))). It doesn't understand lambdas or anonymous-class bodies, so those occasionally still render as one long (but complete, untruncated) line.
  • Mobs that only inherit AI from a superclass without overriding it (e.g. Husk inherits Zombie's goals untouched) don't get their own entry; look up the superclass's report instead.