In January 2019 I forked Coterie into a new game called Bulwark. Same idea of placing cards on a small board, but on a 5x5 grid, and instead of converting cards you destroyed them. Every card was a unit with health and an attack pattern, and it attacked once, the moment you placed it, at whatever stood in those cells, friend or foe. That last part was the whole game. A careless archer would happily put an arrow into your own knight.

It had problems I didn’t notice for five years. The rules text promised each player a hidden hand of three cards, and the code dealt you your whole hand face up. Every card was a random unit type, so one side could draw four ballistas and the other none. The AI scored every placement by the damage it did right now and never looked at what it opened up. And when I finally reread the end-of-game code, it counted your own destroyed cards as your points. “You win!” meant you’d lost. Nobody ever told me, which says something about how many people finished a game.
So I rebuilt it in Godot. The one thing I kept on purpose was the art direction, because the units in the 2019 version were already crystals.
Crystals instead of cards
Each unit is now a cut crystal on a stone plinth. There’s no model file anywhere: every type is a cluster of faceted shards built in code with SurfaceTool, so the silhouette says what it does. The archer is one long double-pointed shard, the ram is a wedge lying on its side, the catapult is a ring of short shards around a raised stone, and the tower is a tall cluster like the old drawing. Your crystals are jade on octagon plinths and the opponent’s are garnet on diamond plinths, so the sides differ in shape and brightness and not just in hue.
Cards in hand became tablets: little stone slabs with the unit’s strike map engraved on them. A miniature crystal stands in its own cell, gold studs mark every cell it hits (one stud per point of damage), and gems along the bottom show its health. You can read a unit at a glance without opening a rules page.

Damage cracks a crystal with glowing fractures (a Voronoi edge pattern in the shader that gets denser as health drops) and a crystal at 0 health shatters. The shards scatter across the board and a clouded stump stays behind as rubble, which matters later.
Aiming
The 2019 version decided which way a unit faced by which side of the card your mouse was hovering over. That was miserable on a phone. Now you pick a tablet, pick a cell, and turn the unit with a ring of eight arrows around it. While you turn, every cell it would strike lights up with the damage it would take, gold for enemies and red for your own, and anything that would break is marked. Back or right-click steps back a stage. Nothing is committed until you hit Strike.
Hidden hands and honest opponents
The hidden hand from the old rules text is real now. You see your three tablets, the opponent’s stay face down, and you draw after every placement. Both sides field the same roster each game, a tower plus eleven of the thirteen attacking units, so it’s public what each side has left even if it isn’t public what’s in hand. The Reserve panel counts it for you.

None of the three opponents cheats by reading your hand. They see what you see: the board, their own three tablets and the reserve counts.
- The Squire plays the best immediate strike, except when it doesn’t feel like it.
- The Marshal plays the best immediate strike while minding which of its wounded crystals it leaves next to open cells.
- The Warden looks a reply ahead. For its best few dozen candidates it works out the strongest answer each unit type left in your reserve could give, then weights those answers by the odds that you’re actually holding that type (a little hypergeometric math over the three cards in your hand).
The Warden beats the Marshal about two games in three and the Marshal beats the Squire 95% of the time. The Warden thinks for about 20 milliseconds a move, which matters when it runs in a browser tab.
Balancing with self-play
I kept the original unit patterns and let the Warden play itself a few hundred games per rule change to see what was broken. Plenty was. In the old rules the coin-flip winner, the defender, moved first and got one extra card. Make that extra card a tower and the defender won only 34% of the time, because going first just puts a target on the board. Giving the defender the one attacking unit the roster left out instead brings it to 47% against the attacker’s 48%.
A quarter of games also ended in a draw, which feels terrible after twenty-five careful placements, so level scores now go to whoever dealt more damage. That brought draws down to about 5%. Then six units got new health values (the archer dropped to 2, a handful of others went up) until every unit type broke about as many enemy crystals as it lost, give or take an eighth of a crystal per placement.
The daily battle
Same idea as a daily word puzzle. Everyone gets the same roster and the same draws each day against the Warden, and the Warden’s tie-breaks are seeded, so the same moves always get the same answers. Every day’s deal is checked before it ships: the Warden plays your side against itself, and the deal is only kept if your side wins. That winning line’s margin is the day’s par. 728 of the first 730 days have a winning line; the other two will just be hard.
There’s also a siege variant for versus games. Towers and rubble block straight shots from archers, crossbowmen and ballistas, catapults and slingers lob right over them, and three high-ground cells (mirrored, so neither side starts closer) add 1 to every strike from a unit standing there. Suddenly the rubble you made two turns ago is a wall.

Every sound is rendered by a small Python script too, from the stone thunk of a plinth to the glass breaking on a shatter. It’s at bulwark.twinspear.com. Try not to break your own knight.
