A genus is one JSON file in a datapack at
data/<your_pack>/zombiemod/genus/<name>.json.
Run /reload and it is live - no restart,
because genera are a datapack registry and vanilla's own reload picks them up.
Start here
The point of the original mod was that its zombies borrowed Minecraft's own pathfinder goals and recombined them into new creatures. That is what this format is for.
A genus with only look_at and no movement goals stands dead still and
tracks you with its head. One with avoid_entity on
player runs. One with melee_attack plus
nearest_target behaves like a normal, angry zombie.
Same engine, entirely different monsters, no code.
{
"name": "Coward",
"base": "minecraft:zombie",
"weight": 30,
"health": 14.0,
"damage": 1.0,
"speed": 1.25,
"follow_range": 24.0,
"scale": 0.9,
"armor_color": 11003600,
"clear_goals": true,
"goals": [
{ "type": "zombiemod:float", "priority": 0 },
{ "type": "zombiemod:avoid_entity", "priority": 1, "target": "player", "distance": 12.0, "sprint_speed": 1.5 },
{ "type": "zombiemod:random_stroll", "priority": 7, "speed": 0.9 },
{ "type": "zombiemod:look_at", "priority": 8, "target": "player", "distance": 16.0, "probability": 0.35 },
{ "type": "zombiemod:random_look", "priority": 9 }
]
}
Reference
| Field | Default | Meaning |
|---|---|---|
| name | (none) | Display name, shown when you look at it. Omit for an anonymous mob. |
| description | (none) | The write-up a player reads in the ZombieDex. |
| base | minecraft:zombie | Which vanilla mob to dress up. Any entity type that is a Mob. |
| weight | 0 | Relative spawn frequency against other genera on the same base mob. 0 means never spawns naturally, command only. |
| health | vanilla | Max health. |
| damage | vanilla | Attack damage. |
| speed | 1.0 | Movement speed multiplier on the base mob, as in the old configs - 1.25 is 25% quicker than a zombie. |
| follow_range | vanilla | How far away it notices you (the old agro). Vanilla is 16. This is the knob for a monster that ignores you until you are close. |
| scale | 1.0 | Body size multiplier, 0.0625 to 16. Giants and tiddlers cost nothing. |
| armor_color | (none) | Dyes a full set of leather armour this RGB colour - the cheapest way to tell genera apart. |
| clear_goals | true | Throw away the vanilla AI before adding yours. Set false to add behaviour to a normal zombie. |
| goals | [] | What it does. |
| target_goals | [] | Who it picks a fight with. |
| spawn | (anywhere) | Where and when it may appear. |
| abilities | [] | Things it does repeatedly while alive. |
| attributes | {} | Any other attribute by id, e.g. {"minecraft:armor": 8.0}. Covers everything the named fields do not, including other mods' attributes. |
| head | (none) | A player head to wear - "head": "jeb_", or the full profile form with an explicit texture. Beats armor_color for the head slot. |
| boss | (none) | Present makes this a boss. |
| phases | [] | Stages that open up as it is worn down. |
| loot | (none) | { "table": "<id>", "replace": false } - genus-specific drops. |
| bounty | (none) | What killing it is worth. |
| xp | vanilla | Experience dropped on death. A Tank worth the same 5xp as a stray zombie is a strange reward for a two-minute fight. |
| behaviours | [] | Goal sets that switch on and off with a condition. |
| ghost | false | Take the name and face of a real player - a config seed list plus everyone who has logged in. |
| mount | (none) | Something to ride in on - the old jockey field. |
| navigation | default | climb makes it scale walls like a spider; swim and amphibious are the aquatic ones. |
| equipment | {} | Held and worn items. Beats armor_color and head for any slot it names. |
| invisible | false | Render nothing but the equipment - armour walking around on its own. |
| baby | false | The vanilla baby variant: half size, quicker, and its own proportions rather than a shrunken adult. |
| burning | false | Permanently alight, harmlessly. |
| arrows | 0 | Arrows left sticking out of it. |
| glow | (none) | An outline colour - any of the 16 - visible through walls. |
| villager | (none) | { "profession": ..., "type": ... } for a zombie_villager base. |
Appearance
"equipment": {
"mainhand": "minecraft:iron_sword",
"offhand": "minecraft:shield",
"head": "minecraft:iron_helmet",
"chest": "minecraft:chainmail_chestplate",
"legs": "minecraft:chainmail_leggings",
"feet": "minecraft:iron_boots",
"drop_chance": 0.0
}
Each slot takes either a bare item id or a full stack with components, so a genus can carry something enchanted, renamed, trimmed or dyed:
"mainhand": {
"id": "minecraft:iron_axe",
"components": {
"minecraft:enchantments": { "minecraft:sharpness": 2 },
"minecraft:custom_name": "\"Pry Bar\""
}
}
drop_chance defaults to 0 for every slot. Kitting a genus out should not turn it into a loot pinata, and a farmable diamond-armour zombie is an economy bug rather than a feature.
Appearance cascades broad to specific:
armor_color dresses all four armour slots, head replaces the helmet, equipment overrides whichever slots it names.
A mob wearing any helmet does not burn in daylight. That is vanilla behaviour and it applies to the dyed leather set too, so most genera survive the morning without asking.
Trims are the largest untapped space here and cost nothing
but JSON: 18 patterns by 16 materials on any trimmable piece, layering over the dye. Outrider
wears rib-on-copper so a skeleton seems to show through the plate; Juggernaut has
sentry-on-netherite. minecraft:enchantment_glint_override shimmers a weapon
with no enchantment behind it, which is a warning a player reads instantly.
Burning does not use remainingFireTicks. That sets the mob
genuinely on fire, and a zombie is not fire-immune, so a permanently-burning genus built that
way dies of its own costume. The burning field sets the display-only
visual fire instead, which vanilla saves, so it needs no upkeep either.
Freezing past the threshold buys a shiver animation and a speed penalty, not the ice-blue skin it sounds like - the only blue tint vanilla draws is the player's own frost vignette. It also charges a point of freeze damage every forty ticks. An effect nobody would notice, for a damage-cancelling hook and a slow death.
glow puts the mob on a scoreboard team and turns on its glowing tag,
because a team colour is the only thing vanilla consults for an outline. An outline is visible
through walls, so every one of these is a monster the
player can never be surprised by. One genus out of fifty is about right.
The best variety-per-line in the mod. A minecraft:zombie_villager base plus one
field picks from seven biome styles and a dozen-odd professions - roughly ninety looks, every one a
texture a vanilla client already ships.
"base": "minecraft:zombie_villager",
"villager": { "profession": "minecraft:cleric", "type": "minecraft:swamp" }
Townsfolk, Apothecary and Field Hand use it, and none of them sets head - the
helmet slot would cover the very face being chosen. They ride vanilla's own 5% zombie-villager spawn
chance, so they stay uncommon without needing a low weight.
Spawning
A genus with a weight above zero can claim a spawn its base mob was going to make anyway. Which genus gets it is a weighted draw, and "leave it as a plain zombie" is an entry in that same draw. Without that, the moment you shipped one genus it would claim every zombie in the world and plain zombies would quietly cease to exist.
"spawn": {
"reasons": ["natural", "spawner"],
"conditions": [
{ "type": "zombiemod:dimension", "dimensions": ["minecraft:overworld"] },
{ "type": "zombiemod:biome", "biomes": "#minecraft:is_forest" },
{ "type": "zombiemod:light", "max": 7 },
{ "type": "zombiemod:height", "max": 62 }
]
}
The spawn block is optional. Omit it and the genus can appear anywhere its
base mob does.
Conditions are ANDed - every one must pass.
reasons defaults to natural, chunk generation and spawner, which is
deliberately narrow: a genus riding conversion would replace drowning
zombies and cured villagers, and one riding reinforcement could summon a
horde of itself.
| Condition | Options |
|---|---|
| zombiemod:biome | biomes - a tag ("#minecraft:is_swamp") or a list of ids |
| zombiemod:dimension | dimensions - list of dimension ids |
| zombiemod:height | min, max - either may be omitted |
| zombiemod:light | min, max - light at the spawn point, so it follows day and night outdoors |
| zombiemod:see_sky | value (default true) - open sky above, or deliberately not |
| zombiemod:depth | min, max - blocks below the local surface. 0 in a field, a few under your own roof, hundreds in a cave |
| zombiemod:time | phase (day / night), or min / max on the 24000-tick cycle |
| zombiemod:moon | phases - any of vanilla's eight, e.g. ["full_moon"] |
| zombiemod:in_claim | value (default true) - inside an FTB Chunks claim. Always false without FTB Chunks installed. |
| zombiemod:city_district | districts - CityWorld district types. Always fails without CityWorld. |
| zombiemod:city_lot | lots - CityWorld lot styles. Same. |
| zombiemod:city_nature | min, max - CityWorld's wilderness-to-dense-city grading. Same. |
| zombiemod:any_of | conditions - passes if any nested condition passes |
| zombiemod:not | condition - inverts one |
Of the fourteen, any_of and not are combinators rather
than places, and four - in_claim and the three
city_* ones - only come alive when the mod they read is installed.
Conditions are a registry, not a fixed list, so another mod can contribute its own types without ZombieMod knowing it exists.
Behaviours
A genus's plain goals are always active. behaviours add goals that switch on and off underneath them, gated by the same conditions that gate
spawning.
That example is the Nightstalker: it flees from you in daylight and hunts you after dark. Any condition works, so "hostile only in the wilderness" or "docile in this biome" are the same shape.
time is deliberately distinct from light: light asks
is it dark here, which is true in a cave at noon; time asks is it night in this
world, which is true in a lit room at midnight. Spawning usually wants light; behaviour
switching usually wants time.
Nothing is rebuilt when the condition flips. Both sets are registered up front and each goal is gated on its own, which is what the goal system is already for.
"behaviours": [
{
"when": { "type": "zombiemod:time", "phase": "day" },
"goals": [
{ "type": "zombiemod:avoid_entity", "priority": 2, "target": "player", "distance": 8.0 }
]
},
{
"when": { "type": "zombiemod:time", "phase": "night" },
"goals": [ { "type": "zombiemod:melee_attack", "priority": 3, "speed": 1.15 } ],
"target_goals": [ { "type": "zombiemod:nearest_target", "priority": 2, "target": "player" } ]
}
]
Goals
Each goal takes a priority (lower runs first, as in vanilla) plus its own options.
| Type | Options | Does |
|---|---|---|
| zombiemod:avoid_entity | target, distance (8.0), walk_speed (1.0), sprint_speed (1.35) | Runs away. This is the coward. |
| zombiemod:melee_attack | speed (1.0), follow_unseen (false) | Walks up and hits its target. |
| zombiemod:bow_attack | speed, interval, range | Draws and looses a bow, using vanilla's own goal. |
| zombiemod:look_at | target (player), distance (8.0), probability (0.02) | Watches. At high range and probability, this is Herobrine. |
| zombiemod:random_stroll | speed (1.0) | Wanders. Without it, an idle mob stands perfectly still. |
| zombiemod:seek_blocks | blocks, speed, range, vertical_range, only_when_idle | Walks to blocks it has an opinion about. |
| zombiemod:sound_target | sprint_radius, walk_radius, sneak_radius | Targets by ear: sprinting carries far, sneaking almost nothing, and walls and invisibility count for nought. |
| zombiemod:random_look | - | Idle head movement. Cheap, but its absence reads as "broken". |
| zombiemod:float | - | Swims instead of sinking. |
| zombiemod:nearest_target | target, must_see (true), unseen_memory (60) | Picks a victim. unseen_memory is how many ticks it holds a target it cannot see. Belongs in target_goals. |
| zombiemod:hurt_by_target | - | Fights back when struck. Belongs in target_goals. |
target is one of: player, living, mob, monster, animal, villager, zombie, wolf,
ocelot, cat.
"navigation": "climb" lets the pathfinder route straight up a wall - but
executing that path needs the mob to consider itself on something climbable, which for a
vanilla zombie only answers for ladders and vines. The navigator alone plans a climb the mob
cannot perform, and it stands at the bottom of the wall. So a climbing genus also gets a goal
that pushes it upward while it is pressed against something. Like a spider, it climbs whenever
it collides, target or not.
bow_attack gives real bow behaviour - nock, draw, hold, release - but
whether it looks right is a renderer question. Only the skeleton renderer has a
bow-and-arrow arm pose, so a zombie with a bow will fire arrows
perfectly and never draw the string. For the animation, give the genus a skeleton base,
which is what the shipped Archer does. For a ranged zombie, use the
projectile ability instead - no draw animation, but it works on anything
and can fire whatever you like.
Abilities
Goals decide where a zombie goes. Abilities are what it does - the 1.8 plugin's per-tick tricks, now
declared per genus with their own timing. Every ability takes interval (ticks
between attempts, 20 is one second) and chance (0 to 1). First firings are
staggered per mob, so a horde that spawned together does not act in lockstep.
"abilities": [
{ "type": "zombiemod:particles", "interval": 20, "particle": "minecraft:sneeze" },
{ "type": "zombiemod:heal", "interval": 60, "amount": 1.0 },
{ "type": "zombiemod:effect", "interval": 60, "chance": 0.5, "target": "nearby_players",
"effect": "minecraft:poison", "duration": 80, "radius": 4.0 },
{ "type": "zombiemod:explode", "interval": 20, "power": 2.5, "trigger_radius": 2.5 }
]
| Ability | Options |
|---|---|
| zombiemod:effect | effect, target, duration, amplifier, radius - apply a potion effect |
| zombiemod:heal | amount - regenerate |
| zombiemod:lightning | target, radius, visual_only - call down a bolt |
| zombiemod:explode | power, destroy_blocks, kills_self, trigger_radius - immediate |
| zombiemod:fuse | fuse_ticks, trigger_radius, swell_to, power, destroy_blocks, kills_self, sound - creeper-style |
| zombiemod:shockwave | radius, damage, knockup - launch and hurt everything nearby |
| zombiemod:leap | range, power, lift - pounce at the victim |
| zombiemod:pull | range, power - drag nearby players toward it |
| zombiemod:summon | entity, count, max_nearby, radius - spawn reinforcements |
| zombiemod:alert | radius, who, max_alerted - hand your target to everything nearby |
| zombiemod:break_blocks | allowed, reach, infest - chew through walls when the path is blocked |
| zombiemod:projectile | projectile, range, power, inaccuracy - fire something |
| zombiemod:place_block | block, target, radius, air_only - cobweb the victim |
| zombiemod:infect | chance, duration, effect, genus, announce - bite now, turn later |
| zombiemod:convert | victims, genus, chance, max_nearby, radius, cooldown, inherit_equipment, inherit_name - what it kills gets up as one of them |
| zombiemod:beam | range, damage, duration, elder - a real guardian beam, from anything |
| zombiemod:ray | range, damage, particle, density, ignite, charge - a hitscan beam drawn with particles |
| zombiemod:adapt | resistance, max_adaptations - learn what hurt it and stop taking it |
| zombiemod:teleport | mode, range, distance, only_when_unseen, min_distance, on_projectile, vanish_chance |
| zombiemod:particles | particle, count, spread |
| zombiemod:sound | sound, volume, pitch |
target is self, victim (whatever
it is currently attacking) or nearby_players.
Two defaults worth knowing. explode has
destroy_blocks: false - a zombie that eats your build is a very different
proposition from one that hurts, so griefing is opt-in. And it only fires when something is
actually within trigger_radius, or an interval-timed bomb is just a mob that
deletes itself in an empty field.
Rather than one ability per 1.8 name, the set is compositional:
effect, particles and sound between them build most of the old flavour abilities, so you assemble a screamer or a plague
carrier out of parts instead of waiting for that exact ability to exist.
In detail
The defining idea of the genre: what a zombie kills gets up as one of them. It fires on a kill, so it is a consequence of the fight rather than something that happens nearby. Where vanilla has an undead counterpart the corpse rises as its own kind - a villager becomes a zombie villager, a piglin a zombified piglin, a horse a zombie horse. "That used to be my villager" lands considerably harder than a generic zombie standing where it fell.
Four guards, because unchecked this is how a server ends. victims has no
default, so a genus must name what it can turn. Nothing already undead is converted, so zombies
cannot endlessly re-raise each other. max_nearby caps how many of the
risen genus may exist within the radius. And cooldown rate-limits one
killer, because an entity query cannot see what was added earlier in the same tick - tested at
40 kills in a single tick, which produce exactly one conversion.
Conversion raises a corpse the instant it dies, which is the effect but not the story. The trope is a bite, a while of knowing, and then it not mattering what actually killed you.
Get bitten and you are marked for a minute. Die while marked, to anything at all including a fall or another player, and you get up. Re-biting refreshes rather than stacks, so a long fight is not a death sentence measured in hits.
Milk cures it. The marker is a real potion effect as well
as a stored timer and the death check requires both, so clearing the effect clears the
infection. A curable infection is a far better mechanic than an inevitable one, and it costs one
extra condition. duration is also the effect's duration, so the HUD icon
is the timer a player can read.
A guardian's beam is drawn entirely by the guardian renderer from that guardian's synced attack target, and no other renderer draws one - so particles cannot imitate it and a zombie cannot be given one. What can be done is give the zombie a guardian: the ability parks a real Guardian, invisible, silent, inert and never persisted, inside the caster's head, points it at the victim and moves it along each tick. Damage is applied at the end by the mod, so the guardian is scenery rather than a second attacker.
ray is the other way, and often the better one: it draws the line itself
with particles, so there is no second entity to manage and nothing to leak. The trade is look -
it will not be a guardian beam, but the colour is yours.
{ "type": "zombiemod:ray", "range": 20.0, "damage": 4.0, "density": 6.0,
"particle": { "type": "minecraft:dust", "color": 16711680, "scale": 1.0 } }
A ray charges before it fires. The wind-up is loud as well as bright, and the warning sound's volume is scaled to the weapon's range, so a shot that reaches 24 blocks can be heard at 24 blocks - a player learns the noise and moves, including when it is behind them. Breaking line of sight or leaving range during the wind-up aborts the shot, which is what makes the telegraph honest rather than decorative.
This is the one that changes what the mod is: without it a wall is a solution to zombies, and with a Breaker in the world it is a delay. It only fires when the mob has a target it cannot reach and has stopped making progress, so it eats walls rather than scenery.
Two deliberate opt-ins before anything of yours gets damaged: the ability itself, and
allowed, which has no default - a genus must name every block it may
break. It also asks NeoForge's griefing hook rather than reading the
mobGriefing gamerule directly, which is how a land-protection mod vetoes
griefing per entity and per position. Reading the gamerule instead would work perfectly and
quietly ignore every claim on the server.
Give a breaker a long memory. Vanilla forgets an unseen
target after 60 ticks, which is right for a mob that walks around obstacles and exactly wrong
for one that digs through them - the instant the wall blocks line of sight it forgets why it
was digging. The shipped breakers use "must_see": false with
"unseen_memory": 1200, so they stay committed for a full minute.
They also name a tag rather than a list, so there is one place to change what gets eaten and server owners can override it without touching a genus.
"mode": "behind" is the old plugin's BACKSTAB rebuilt: it reads the
victim's look direction and lands 180 degrees opposite - behind them, already facing
their back. The tell is not seeing it move, it is the sound at your shoulder.
"Looking at it" is a cone of about 53 degrees plus line of sight, so it is about what is on your screen rather than exact aim.
A creeper in zombie form: come within trigger_radius and it hisses,
freezes, swells and detonates - and stands down, at double speed, if you back off.
The swell is real, not a trick of particles. A creeper's own swell cannot be borrowed, because it is the creeper renderer that inflates the model and a vanilla client has no way to draw a swelling zombie. But scale is a synced attribute, so ramping it over the fuse genuinely inflates the mob on an unmodified client. It swells relative to whatever size the genus already is, so a big genus gets bigger rather than snapping to a fixed size.
That is the general shape of this mod's limits: anything bound to a specific mob's renderer is out of reach, and anything expressed through synced attributes, equipment, effects, sounds or particles is fair game.
| Tag | Contains |
|---|---|
| #zombiemod:breakable/soft | Dirt, sand, gravel, glass, doors, planks, torches, ladders and the like |
| #zombiemod:breakable/stone | Stone, cobblestone, mossy cobblestone, granite, diorite, andesite, tuff, calcite, dripstone |
| #zombiemod:breakable/deepslate | Deepslate, cobbled deepslate |
| #zombiemod:breakable/breaker | soft + stone |
| #zombiemod:breakable/big_breaker | breaker + deepslate |
Nothing player-crafted is in any of them. Stone bricks, deepslate bricks, polished variants, concrete and metal blocks are all absent, so a properly built base still holds. That is a deliberate line: breakers should make a hole in the hillside you hid in, not walk through your walls.