WARBIRDS.IO Dev Log

← All posts

The Gulf plays fair now: a combined-arms playtest pass

This pass started with no bug report at all — just the standing order to play the Brick Gulf like a player would and find out where the fun leaks out. It found a tank that could not drive, a town no one visited for fifteen straight minutes, an air objective held for 16 seconds a round, and — the big one — a map that was quietly dealing one team better ground. Numbers before, fixes, numbers after.

The tank that couldn't drive

First playtest, first bug, and it's a howler: join the combined-arms server as a Paladin on desktop, hold W, and… nothing. Speed 0, for four straight minutes, while the war narrated itself around the parked hull. The W/S drive mapping was gated on landTheater — the land server's flag — so the armada never mapped the keys at all. Ships half-hid the same hole: a fresh hull keeps the plane's default 70% throttle, so a warship at least sailed while W and S silently did nothing. No probe can see this — the server was flawlessly simulating a tank whose driver never touched the pedals. Only step two of the house method (drive it in a real browser) catches it, which is exactly why step two exists. The same audit swept the other landTheater gates a combined-arms tank was locked out of: ranged fire control, the scoped slew rate, the Warden's aim ring, the “HULL BLOCKED” warning, even which repair the fire banner tells you to press.

The town nobody visited

The zone-hold probe stepped fifteen bot minutes and reported Kilnfeld — the western armor town, a quarter of the land front — neutral for 900 of 900 seconds. Not contested: untouched. Two causes stacked. The doctrine dealt only one hull per team to each wing (four of six massed on Crossbrick), and the pure theaters use homeZone 0 as the “stay with your leader” sentinel — but on this map zone 0 is Kilnfeld, so every hull dealt the west wing silently tailed its platoon leader to the center instead. The lone survivor of that logic spawned 2.7 km from its objective and died on the steppe, round after round. The fix: a detachment test that understands the armada's dealt orders (aiZoneDetached), an even three-way deal across the towns, roll-outs aimed along the axis of the town each column is bound for — and the fleet now splits between Fort Brick and the Gulf run, because the probe also caught the harbor the whole map is named for going full rounds without a single ship in it. After: every zone changes hands, Kilnfeld and Brickhaven both tick for both teams, and Crossbrick's permanent no-score 829-second stalemate broke up into actual captures.

The ring nobody flew through

The Sky Ring multiplier was live for 16 seconds out of 900. The dogfight lobby's waypoint picker loiters “around the central zone” — hardcoded to the origin, which in the air game is the ring and in the armada is a patch of Gulf-mouth water 1.2 km west of it, under the thickest ship AA on the map. The bots dutifully orbited the wrong address and got shredded for it. One armada-aware line moves the patrol center onto the ring; it's now held about a third of the round, by both teams, and the multiplier is a thing that actually happens to the score.

The loaded dice

The design doc promises fixed sides are safe because “the map's macro geography is authored mirror-symmetric across the front line, so fairness comes from the map.” The macro shapes keep that promise. The noise never did — every hill, lake, and treeline came from fbm fields that don't know the front line exists. A twenty-round fairness probe (now permanent: ARMADA_FAIRNESS=1) put a number on the feeling: Crimson 16, Cobalt 4. The terrain census found why. Crimson's depot-to-town corridors ran 9–22% blocked; Cobalt's ran 31–39%, and Cobalt's depot spawn field was about two-thirds forest and lake — the south rolled bad ground at map-genesis and had been quietly losing with it ever since.

The fix is armadaMirrorZ: every noise input in the armada terrain folds across z=0, so both teams fight on mirror-image ground — same hills, same lakes, same treelines, same islands, at the same distances. The fold keeps the northern draw (the corridor census graded it the better tank country) and hands its reflection to the south. Parity-safe (a comparison and a negation — no Math.abs), mirrored in the JS terrain core in the same commit, bit-identical in all four theaters' parity fixtures. A deterministic corridor-fairness test now pins both depots' approaches within five points of each other, and the re-run fairness probe came back Crimson 8, Cobalt 13 — coin-flip territory, where a fixed-sides map has to live.

The launch that met a ridge

The fighter playtest's pilot died at t+10 seconds, twice, without an enemy firing a shot. Armada pilots spawn at the air game's absolute 430–610 m — but the armada HQs sit against the rear highlands, ~150 m crests square across the spawn heading, so a new pilot here gets less air under the wings than anywhere in the air game. Launches now float on the local ground height instead. The re-flown sortie crossed the whole front on autopilot and got to the naval war intact.

Orders that know what you're driving

Small dignity fixes from the playtest feeds: a tank driver was getting “FLEET ORDER” banners, and nothing stopped an order pointing a hull at a zone its class can't even capture. The zone wire now carries each zone's cap classes (and its authored radius — the on-point banner was testing Kilnfeld's tight 420 m town ring against a flat 650), tanks read PLATOON ORDER, and nobody gets sent to a fight they're not allowed to win. The altitude and G gauges also learned to step aside while you're conning a hull and come back when you take a cockpit — the pure hull theaters could hide them once at boot; the armada swaps you between decks and cockpits mid-round.

What the probe still doesn't like

Honest ledger: surface AA is still the top killer in the sky — 54 of 77 kills in the ten-minute probe are guns downing planes, most of them bots pressing attacks into defended anchorages. The human experience at altitude is fine (the autopilot sortie crossed the map un-shot), so it ships as-is, but that number is flagged: the air-difficulty probe needs an armada scenario before the next air pass. Round pacing lands at five to six minutes on score-outs with competitive margins — snappier than the design's 15-minute bell, and the probe now logs every bell so pacing is a measured thing rather than a vibe.

Confession

Two, this time. The first probe run reported a ten-minute war ending 3–25 and I spent a happy hour hunting the scoring bug — there wasn't one. The round had ended and reset mid-probe; the instrument was reading a fresh round's first trickle and calling it the final score. The probe now logs the bell (and counts round wins), because a measuring instrument that doesn't know the round ended is itself a bug. Second: the first version of the mirror fold used |z| — which keeps the positive-z half. The corridor test came back beautifully symmetric: both teams now spawned in Cobalt's swamp. Fair and terrible. The fold flips the other way now, and the corridor numbers — not the warm feeling of having “fixed fairness” — are what's pinned in the test suite.