Play alone and three of the four castles are defended by a machine. Each computer warlord runs the same short loop, find the ball worth fearing, guess where it will cross your wall, slide to meet it, and the gap between a pushover and a menace comes down to four numbers.
A warlord's first job, a hundred and twenty times a second, is triage. With up to two balls loose in the arena, the AI must decide which one deserves its shield. It scores every active, un-held ball by distance to its own king, then subtracts a fixed bonus of 250 units from any ball that is actually heading toward the corner, a ball moving away is treated as if it were 250 units further off than it really is.1 The lowest score wins the shield's attention.
The effect is a defender that does not panic over a ball sailing harmlessly past, yet snaps onto one that is closer and inbound. It is a crude model of what a human does without thinking: watch the thing coming at you, ignore the thing leaving. The whole judgment is a single dot product between the ball's velocity and the direction to the king, positive means "aimed at me," and that is enough.
Having chosen a threat, the warlord must decide where on its diagonal rail to be. It does not solve the full bounce path, no reflection tracing, no forecasting off walls. It takes the ball's position, nudges it a short step forward along its current velocity (a 0.12-second lead), and projects that future point straight onto the rail to get a target fraction between 0 and 1.1
This is deliberately shallow prediction, and it is why the AI can be beaten. Because it leads only an eighth of a second and never anticipates a ricochet, a ball that will arrive by way of a wall bounce fools it; it commits to where the ball is pointing now. A human who bounces shots off the arena edges is exploiting exactly this blind spot. The machine reacts to the present with a whisker of foresight; it does not plan.
The computer does not compute the future of the ball. It leans an eighth of a second forward, points its shield at where the ball would be if nothing intervened, and lets everything that intervenes be your opportunity.
The three difficulties share one identical body of code. What changes between easy, medium, and hard is a row of four tuning numbers.1 Jitter adds random error to the shield's target, so an easy warlord's aim wanders by nearly a fifth of its rail while a hard one is nearly exact. React distance sets how close a ball must come before the warlord bothers to track it, an easy one ignores anything more than 420 units from its king, a little under half the width of the board; a hard one tracks across the entire arena. Catch chance is the odds it will grab a ball that comes close enough to its shield to be caught. And aim-at-rivals is a single switch that decides whether the warlord plays offense at all.
| Dial | Easy | Medium | Hard |
|---|---|---|---|
| Aim jitter (rail-fractions) | 0.18 | 0.07 | 0.015 |
| React distance (units) | 420 | 700 | 2,000 |
| Catch chance | 0% | 25% | 55% |
| Aims at rivals? | no | no | yes |
All four values come from one small tuning table inside the Bulwark game engine, one row per tier. React distance on hard is written as twice the arena's width, and the arena is 1,000 units square, so 2,000 units means “always tracking.”1
An easy or medium warlord never catches with intent to strike. An easy one never catches at all, and a medium one only now and then, without a plan for what to do with the ball once it has it. Flip the aim-at-rivals switch, the thing only the hard tier does, and the AI stops being purely reactive. When it holds the ball, it looks across the board, picks the most wounded rival (the one with the fewest bricks left), and aims there.1
It does this without any pathfinding. It samples eleven candidate positions along its own rail, and for each one reproduces the engine's release math to see which direction that shot would fly, then keeps the position whose outgoing vector points most directly at the chosen victim.1 It is brute force over a handful of options rather than cleverness, but it is patient about it: having chosen a spot, the warlord holds the ball until the shield has actually slid there, and only lets go once it has arrived or it has held on long enough that waiting would cost more than the shot is worth. The intent is unmistakably strategic, exactly what a human hunting an easy kill would do. Choosing the target by “fewest bricks” points three independent defenders at whoever is already losing.
Every "random" thing a warlord does, the jitter in its aim, the coin-flip on whether to catch, is drawn from a seeded generator, a compact routine known as mulberry32 that turns one starting number into a long, repeatable stream of pseudo-random values.2 Give it the same seed and it produces the same sequence forever. A live match takes its seed from the clock, so no two games open alike, but hand the same seed back and the match runs again exactly: the same launch angles, the same wobbles, the same catches.
That determinism is not a cosmetic detail. It is what makes the game testable, its test suite plays whole computer-versus-computer matches from a fixed seed and expects the same result every time, and it is what lets the entire simulation, the generator's cursor included, be packed into JSON and rebuilt, so that online the host can stream its state and each of the other players rebuilds an identical board. The warlords feel alive because their errors look human; underneath, their "instincts" are a short arithmetic recurrence anyone can wind back to the start. A machine that guards a castle, it turns out, needs only a few numbers and a stream of reproducible luck.2