LethalBreed siege manual Distance field Manual Français

Flow field pathfinding

Zombies do not follow a classic per-entity A*: a flow field (shared cost map) is recomputed for an entire dimension, and each of them locally reads the descending direction. The field also encodes whether a block must be broken or a bridge built, and it closes the columns where water rises to the players' own plane.

Recompute and extent

The field is recomputed every 10 ticks (0.5s), off the server thread (dedicated pool), on a grid bounded to 192 blocks plus a 24-block margin around the subjects under surveillance.

GPU with CPU fallback

If OpenCL is available, the GPU is used automatically (useGpu is a kill-switch: setting it to false forces the CPU, true does not force the GPU if there is none). Any GPU error falls back silently to the CPU. There is no size gate: a device that is present takes every solve, whatever the grid. The smallest field the game ever builds is 49×49 anyway (a lone player plus the default 24-block margin).

The CPU uses a parallel multi-core Bellman-Ford (available cores − 2 threads), not a single-core Dijkstra: a headless dedicated server without a GPU therefore runs identically, just on several cores rather than one.

The GPU and the CPU are designed to stay numerically identical: same edge weights (orthogonal/diagonal, configurable) and same break/build penalties (the OpenCL kernel reads the same cost array as the CPU solver). Enabling or disabling the GPU should therefore not change the paths taken.

Size-aware block breaking

The break height to advance is computed from the true height of the zombie's collision box (rounded up, floor 1, ceiling 4 blocks): a body enlarged by random variation therefore breaks higher than a normal-sized one.

Within arm's reach, the hands stop

Before picking between climbing, descending and breaking, the driver asks a simpler question: is the target already reachable. Three measurements answer it together. Under meleeStopRange blocks horizontally between the two centres, no more than meleeStopHeight block of vertical gap, and a line of sight the game grants. Miss one and the answer is no, so the activation carries on.

When the answer is yes, everything stops there: the zombie bites like any vanilla monster, breaking no block, laying no bridge, starting no pillar. The question comes before the level-of-detail sort, so it holds for the most distant tracked zombie exactly as it holds for the one on top of you.

This is what spares you the sight of a wall coming down behind a player already in contact. Without that test, a zombie wedged into a corner while it swings would count activations without progress, declare itself stuck and start digging, with its target an arm away. Both values go down to 0, which makes the test impossible to satisfy and hands the zombies back their pickaxe at point-blank range.

One breach per group

Ten zombies on a wall, each hitting its own front block, is ten blocks at 10 % and no hole. The breach coordinator exists for that. There is one per dimension, and any zombie about to break submits three things to it: the column in front of it, the cell it attacks from, and the hunt target that breach serves.

The answer follows four cases. A zombie already committed to its column keeps it, and registers it as the rallying point rather than being dragged off to a neighbour's mid-break. Otherwise the coordinator looks for open breaches within breachRadius blocks serving roughly the same target, with two radii of tolerance on the target itself so two unrelated walls never merge. If the nearest one is its own column, it refreshes it. And if the group already holds its maxConcurrentBreaches breaches, it adopts the nearest: the caller steers it toward the first breaker's approach cell, so the crowd funnels into a single hole. That leaves the case where there is room, and it opens its own.

A breach nobody works for breachGraceTicks is forgotten, which frees the slot, and one whose column no longer blocks motion goes too: the hole is through, there is nothing left to coordinate.

Concentration pays in speed. The breaker counts the distinct zombies that requested this block inside the grace window, and multiplies progress by 1 + (breakers − 1) × breakConcentrationPerBreaker, capped by breakConcentrationCap. Four zombies on the same stone go 2.8 times faster than one; the default cap is reached at six, and a whole horde will never go past four times. A wooden door gives way in seconds, stone holds, and it is always the same wall opening rather than ten scratches side by side.

CombatMoveConfig: contact and breach
FieldDescriptionDefault
meleeStopRangeHorizontal distance under which the target counts as reachable, line of sight included. At 0 nothing ever stops: zombies dig while in contact.2.0
meleeStopHeightLargest vertical gap for that stop to apply. Past it the target is above or below, so block ops resume.1.5
breachEnabledSwitch for the coordination. At false each zombie breaks its own column, as before.true
breachRadiusRadius within which an existing breach is adopted instead of opening another. Wider funnels the crowd from further out.6.0
maxConcurrentBreachesBreaches open at once inside one group. 1 enforces strictly one block at a time.1
breachGraceTicksTicks without work before a breach is forgotten and its slot returned.20 (1s)
breakConcentrationPerBreakerSpeed gained per extra breaker on the same block. At 0 speed no longer depends on the count.0.6
breakConcentrationCapCeiling on the multiplier, so a pile of zombies cannot pulverise stone.4.0

Climbing and descent

Climbing: real vertical velocity impulse + placement of a support block at each landing, never teleportation. Three conditions, not two: the target must be at least 2 blocks high and at most 5 blocks horizontally, the zombie must be stuck (two consecutive activations without closing in) and it must be near enough to be finely driven. A zombie still gaining ground stays on foot. Capped at 24 blocks of total height. The pillar always places blocks to climb (it stands on what it builds); there is no block-less climb variant.

Descent: in order of preference, walking or a safe short fall (up to 3 blocks) → a staircase already carved into the terrain → a safe vertical shaft → building a staircase over the void as a last resort. As a rule it does not break the last block overhanging a deep void. One exception: when the target is within 1.5 blocks horizontally (that is, almost straight under its feet), it digs down through that block anyway to follow the target into the hole rather than stranding above it.

At the foot of an obsidian wall, two dirt blocks a zombie has stacked, with the zombie standing on top of them.
The start of a pillar, caught at the second step. The block comes from nowhere, it is marked, and it goes away on its own after 600 ticks.

Water that closes the road

The cell classifier opens on a question about water, before it looks for footing in the column at all. It reads waterAvoidDepth blocks stacked from the reference plane, two by default, tunable from 1 to 8. If every one of them is water, source or flowing, the cell turns impassable and the solver treats it as a solid wall. A one-block ford keeps its ordinary cost. Lava is not part of that test: sitting on hard ground, a lava column stays passable at the usual price.

The reference plane is the average height of the players the mod may target, rounded to the block their feet are in. One slice per dimension, shared by the whole horde, and with no targetable player there is no field at all: a zombie sent after a villager walks into water without a detour.

Those two blocks are a shipped figure, not the height of whoever reads the cell. A field computed once for everyone cannot know anyone's stature. A large build is therefore shut out of two blocks of water it would have crossed with its eyes clear.

The detour has a blind spot, and a wide one. The two cells read are the one the players' feet are in and the one directly above. A pond level with its bank has its surface one block lower, so both tested cells are air, the column falls back to the ordinary rules, the footing search drops as far as 4 blocks (flowVerticalTolerance) and finds the bottom. The route crosses the water instead of skirting it. For a lake to be genuinely routed around, its surface has to reach the level the players stand on: a flooded cellar, a basin held up on a rise, a player out on an island.

None of this goes through the game's own pathfinder. PathType and the fluid malus stay as they were, and setCanFloat is never called. A malus applies to the whole entity and turns down a ford as surely as a lake, whereas depth belongs to a place and is judged cell by cell.

The field is read afresh on every path re-issue, at any distance. When that read fails, navigation goes back to walking straight at the target. It fails with no field active, or because the zombie is off the grid or standing on an impassable cell, or because its cell carries no direction, or because vanilla navigation cannot reach the downhill waypoint.

A zombie already in the lake is the second of those: its own cell is the one the classifier closed. But the moment its head goes under it leaves the routing logic before consulting it at all and heads back for the bank, which Mood, flee and survival describes. Where no way round exists, the horde does not queue on the shore: with nothing left for the field to offer, it walks in and drowns.

One side effect is worth knowing. The water test runs ahead of the breakable-wall branch, so two submerged blocks stacked at the reference plane, stairs, slabs or fences, send zombies around a barrier the same zombie would have smashed on dry land.

CombatMoveConfig: water-related fields
FieldDescriptionDefault
cannotSwimThe switch over both halves: deep water becomes a wall to the field, and a zombie with its head under drowns. At false, water goes back to being ordinary for everyone.true
waterAvoidDepthHow many water blocks stacked from the reference plane make the column impassable (bounded 1 to 8).2
drownGraceTicksAir available before the first drowning damage (bounded 1 to 280, that is 14 s at most).40 (2s)
drownDamageDamage step added on every activation past the grace. At 0, a zombie stays under water indefinitely and never dies of it.4.0
floatInWaterSurface swimming, the opposite behavior. Neutralized while cannotSwim is on, along with its whole block of speed and dive settings.true

These five are set in game like any other, through the three interfaces. Turning cannotSwim off mid-game gives swimming back to any zombie that has a target, on its next activation, because the mod's own driving re-reads the option each pass; one without a target stays on vanilla's. What only later spawns get back is vanilla's surface bobbing, attached once when the entity is created. In the JSON file, waterAvoidDepth joins floatInWater and the water* block under Water, while the three names carrying neither water nor float fall through to Misc.

The leap and the cling

A zombie chasing something can throw itself at it instead of walking the rest of the way. The attempt only comes round once every leapCooldownActivations activations, and only if the roll beats leapChance. The target has to sit in the leapMinRange to leapMaxRange horizontal band, and no more than leapMaxVerticalDiff blocks above or below. Any closer and a step would do the same job, any further and the leap falls short.

Before committing, the zombie probes the ground ahead of it, leapLandingScanDist blocks forward and leapLandingScanDepth blocks under its feet. Nothing solid down there means no leap. That is what stops it launching into a ravine for nothing, without forbidding the hop across a one-block trench.

What follows is new. When a leap comes down on the prey rather than beside it, the zombie latches on. It stops navigating, settles where a passenger would have sat, and gnaws for a duration rolled between leapClingMinSeconds and leapClingMaxSeconds. The hold costs leapClingDamage health a second, deliberately little: the longest one takes five of an unarmoured player's twenty, and an ordinary bite hurts more. It is there to pin, not to finish.

Two measurements decide whether a landing counts. The horizontal distance between the two centres has to stay under leapClingReachSq, squared so no test needs a root, and the zombie cannot be more than leapClingMaxDropBelow block below the prey. It is meant to come down on top of it, not to reach up from the floor.

Once latched, the zombie is placed on its prey's head every tick. Where the ceiling leaves no room for a 1.95-block body, it slips into the prey's own footprint instead, down at its feet, which keeps its eyes out of the rock and off a point of suffocation a tick. When neither spot is free it lets go. It also lets go if the victim dies, vanishes or changes dimension, and a save taken mid-bite leaves nothing behind on the zombie.

The damage is banked before it is paid. Vanilla swallows any hit no bigger than the last one inside a ten-tick window, so a steady quarter-heart would land every other time. The mod accumulates what it owes and hands it over whole as soon as the window reopens. The shove that normally comes with a mob hit is undone in the same breath: vanilla answers a zero direction with a random one plus a jump's worth of lift, which would bounce the prey twice a second out from under a zombie supposed to be holding it.

The same zombie cannot start again for leapClingCooldownActivations activations, six seconds at the default pace, longer than the longest hold. So one zombie alone never pins a player indefinitely. A crowd is a different matter.

On screen, a latched zombie is not standing: the arms close downward, the knees come up, the head is bowed into the prey and nods along with the bites. Two waves at different rates carry that motion, one for the nod and one for the roll, so the loop never shows across five seconds. The whole thing rides one synced boolean from the server, and two zombies latched at the same moment are never in phase, each counting from its own birth.

LeapConfig: the leap
FieldDescriptionDefault
leapEnabledThe leap's switch. At false zombies always walk their target down, and the cling can no longer fire either.true
leapCooldownActivationsActivations between two attempts, for a given zombie.12
leapChanceOdds of leaping on an eligible activation.0.4
leapMinRangeHorizontal distance below which the zombie is already too close to leap.2.5
leapMaxRangeHorizontal distance past which the leap would fall short.8.0
leapHorizontalSpeedHorizontal velocity given at takeoff.0.55
leapUpwardVertical impulse of the takeoff.0.42
leapMaxVerticalDiffLargest vertical gap, absolute, that still lets a leap fire.3.0
leapLandingScanDistBlocks probed ahead for ground before committing.3
leapLandingScanDepthBlocks that same probe scans downward.3
LeapConfig: the cling
FieldDescriptionDefault
leapClingEnabledThe cling's switch. At false a leap that connects bounces off the way it used to.true
leapClingMinSecondsShortest duration a cling can roll.2.0
leapClingMaxSecondsLongest one. The two fields are sorted before the roll, so writing a maximum under the minimum just swaps the bounds instead of breaking the hold.5.0
leapClingDamageHealth removed per second of clinging. At 0 the zombie holds its prey without hurting it.1.0
leapClingReachSqSquared horizontal distance under which a landing counts as a hit.1.0
leapClingMaxDropBelowBlocks below the prey where the zombie can still latch on.1.0
leapClingCooldownActivationsActivations before the same zombie may latch again.24

All seventeen fields live under Leap in config/oas/lethalbreed.json and are also reachable through the three interfaces. Turning leapClingEnabled off mid-cling does not cut it short: the one running goes to the end of its duration, no other one starts.