WARBIRDS.IO Dev Log

← All posts

The update that never arrived

The bug report: “the mobile controls only work in Vietnam. In the other missions I can't move at all — and I can't rotate and move at the same time. If I try, I stop dead.” Per house rules we assume the feeling is right and the theory is a hint. The feeling was right three separate times.

Numbers before constants

First, make the feeling measurable. A Playwright harness joined every one of the five missions on an emulated phone, pushed the left-thumb stick forward, then landed a second finger and dragged it — the way any human holds a shooter. The table was damning and beautifully consistent: stick alone walked 3–4 meters in every mission; stick plus a look drag walked 0.00 meters, in all five. Worse: after the look thumb lifted, the still-held stick walked 0.00 more. Nothing was mission-specific — Vietnam “working” was finger-sequencing luck. If both thumbs ever touched the glass at once, movement died until every finger lifted.

The cause was one greedy branch in the gesture router: any second touch became a pinch, and starting a pinch hid the joystick, zeroed the pad, and orphaned both fingers' roles. Two-thumb play — the only way anyone actually plays — was structurally impossible. The rules are now sticky: the joystick thumb never joins a pinch, a second finger is a look drag, and only two look fingers make a pinch (which still means binoculars on deck and magnification at the director). When a pinch ends with one finger still down, that finger goes back to looking instead of going dead. Same harness after: 6.3 m walked while turning 0.375 rad, in every mission, and the stick keeps walking when the look thumb lifts.

Phone landscape view on the battleship's weather deck with the joystick deflected under the left thumb while the camera is mid-turn from a right-thumb drag — heading 020, making 8 knots
Both thumbs down, 8 knots on the board: walking the deck and swinging the view in the same stride — the exact gesture that used to freeze the sailor.

Every hold learns whose finger it is

The same class of bug was waiting one layer down. The jump button, the hold-to-fight-the-fire prompt, and every held console crank released on any pointerup anywhere — a deliberate safety against phantom-held keys when a console card re-renders, but it meant your look thumb lifting would drop a held climb mid-ladder or let go of the rangefinder knob mid-cut. Every hold now remembers which pointer pressed it and only that finger's up releases it. Free bonus: the turret's TRAIN and ELEV cranks can finally turn at the same time, like a gunner with two hands.

The confession: the fix that couldn't ship

None of that explained the original mystery — why did the phone act like the touch update didn't exist? Because on installed clients, it didn't. While proving the fixes in a real browser with the service worker on, the install step failed: the worker precaches every dev-log post under its /blog/<slug>.html name, and when the clean-URL blog route landed weeks ago, its safety guard (“no dots in a slug”) started returning 404 for exactly those names. One 404 fails the whole atomic precache — so no new service-worker generation has installed since. Phones that had the game installed were frozen on their old shell, politely re-checking for updates and throwing each one away. The version stamp on the join screen — added for precisely this nightmare — would have told us, had we thought to ask the phone instead of the codebase. The route now serves both spellings, and a regression test pins it.

And one more, found the same way: the worker answered navigations it hadn't precached with the cached game shell before trying the network — so on a controlled page, tapping BIG J on the join screen served the air game back at the battleship's URL. The fallback chain is now exact match, then the .html twin, then the network, and the game shell only when offline. The battleship document and bundle joined the precache while we were in there, so the whole ship now works with no signal at all.

After

The e2e battleship suite grew the checks that would have caught day one: two thumbs walk 6.7 m while turning 0.33 rad, two thumbs is not a pinch (zoom stays 1×), and the stick survives the look thumb lifting (2.2 m more). Thirty-one checks green, zero page errors, and the service worker installs, controls, and serves every clean URL its own document — online and offline. Shell generation v149: the first update in weeks that will actually arrive.