WARBIRDS.IO Dev Log

← All posts

A steady hand on the guns

Two reports came in from the hull theaters. From the sea: the gunsight is twitchy — swing onto a target and the crosshair sails past it, so you saw back and forth across the hull and never settle. From the steppe: the game is unplayable — the sight stares into dirt, shells burst on the ground in front of your own tracks, parachutes hang in the sky forever, and you can't find anyone to shoot anyway. Both were right. This pass fixes the hand, the eye, and the map.

The joystick you didn't know you were holding

The warship's gunnery was a rate control: the mouse cursor was a virtual joystick, and how far it sat from the centre of the screen set how fast the turrets slewed. That scheme is fine for a flak mount sweeping lead across the sky. It is terrible for laying a crosshair on a hull, because stopping requires a second action — you have to drag the stick back to centre at exactly the moment the sight crosses the target. Nobody's hand does that. The sight arrives carrying its slew rate, passes the target, you reverse, it passes again the other way. On top of that the client kept easing the crosshair toward the server's own (latency-lagged) idea of the mount, so even a perfect stop drifted on for most of a second. That was the “momentum.”

The fix is the scheme every shooter has taught your hand since forever: position control. Under pointer lock the crosshair now moves exactly as far as the mouse moves — scaled to the optic's zoom, so a hand-sweep covers the same screen fraction in and out of the gunsight — and when your hand stops, the sight stops. Dead. The turrets then chase the sight at their own mechanical rate, easing to a stop on it, which is what turrets are for. The rubber-band toward the server aim is gone from the sight entirely; measured drift after a sweep-and-stop is now zero. Sticks and the touch stick keep the old rate control — a thumb stick really is a joystick, and there the scheme is honest.

The naval binocular gunsight over open sea: a clean horizon, the lead scale and reticle, the salvo's impact ellipse on the water at 3.9 km, and no capture-ring band across the sight picture
The gunsight after the pass: your hand owns the crosshair, the salvo reticle owns the water, and the capture rings stay out of the optics.

Rings that whispered instead of walled

The naval capture zones drew themselves as chunky gold toruses on the sea at 60% opacity — from inside a zone, a golden wall across every sightline, exactly where you were trying to read distant hull silhouettes. They're now a faint 16% whisper a third as thick, they vanish completely while you're on the gunsight, and the minimap — which always drew them cleanly — picks up the slack. The minimap also finally shows you: the white heading arrow every pilot gets was skipped for ship captains and tank drivers, so your own hull was an anonymous team-colored dot among the fleet. Now the arrow rides your hull and points down your gun line in every theater.

The tank that shelled its own doorstep

The land theater's terrain renders — and collides — in quantized 3 m steps, and a rolling slope climbs a step or two per 12 m cell. The gunner's eye sat 2.6 m over the hull anchor and the muzzle 2.2 m, which put both below the first uphill lip one cell away. Through a 6° optic that lip was the whole world: the sight showed dirt, and the round fired into the shelf a few metres out and burst in your face. The AI tanks suffered it too — half the “shells exploding right in front of the vehicle” were the bots doing the same thing to themselves.

The sight head and the muzzle now ride at 6.4 m and 6.2 m — a periscope's view over the hull's own shelf — and they're kept within a hand's width of each other so the round still lands under the crosshair (the superelevation math assumes the bore and the sight agree). Shells and wire-guided missiles also get a short muzzle grace against bare terrain, the same principle the spotting code already wrote down for sightlines: the near crest a hull is peeking over is a firing position, not a mask. Hulls and buildings stay live inside the grace — point-blank tank duels still work.

The Paladin MBT on the open steppe: a clear view over the terrain to a treeline and ridge, a parachute drifting down in the middle distance, and the minimap showing the white self-arrow beside a white-rimmed enemy blip
The steppe from a sight that can see it. Note the parachute mid-frame — it will actually land now — and the white-rimmed enemy blip by the self-arrow on the map.

The parachutes that never came down

Ground fire over the steppe knocks the strike wing out of the sky, the pilots bail… and the canopies hung at their bail altitude until the round ended. The chute simulation itself was fine — drift, sink, landing, even a time-to-live leak guard — but the land theater's step loop simply never called it. One line (stepChutes joining the land tick) and every canopy comes down, lands, and resolves; a pilot who drifts out over the water is lost at sea rather than becoming an immortal rescue marker no land vehicle could ever reach. There's a regression test now that flies a chute down over the steppe and insists it arrives.

Finding the fight

Spotting on the steppe is honest fog-of-war — enemies outside your team's sightlines never reach your client at all. But even a spotted tank was three pixels of minimap and a hull-colored smudge on a hillside. Spotted enemy hulls now wear a marker: a caret hovering over them on screen, an edge arrow pointing at them off screen — the same markers the air war gives phones, promoted to every platform in the hull theaters, where a target is a handful of pixels even on a big monitor. On the minimap, enemy hulls pop a size up with a white rim. None of it leaks anything the fog hides: if the server didn't spot it for you, there's nothing to mark.

The measurements

The claims above are checked by driving the real client in a headless browser: a 400-pixel hand sweep turns the sight 0.88 rad and the drift over the next 1.8 hands-off seconds is 0.0003 rad (scoped: 0.086 rad and 0.0000 — the zoom scaling at work); the scoped land eye clears its terrain shelf by 7.4 m; a salvo laid on the horizon leaves cleanly where the old muzzle burst on the first lip. Cheap to run, and they caught a real stowaway: the zone-capture callout had been referencing a variable that only exists inside the render loop, so every zone flip threw and the “ZONE B CAPTURED” message never showed. Fixed in passing — the reward for testing the game instead of the diff.