Skip to content
Ayotl

← All notes

October 9, 2026 · In War Zone

War Zone: fat pixels that reach the phone crisp

A game drawn at 320 by 180 with the Atari 2600 palette, and the icon came out blurry on Android. It wasn't the drawing: it was three rescalings nobody asked for.

War Zone is turn-based artillery with stick figures: a 320 by 180 canvas, the 128-colour palette of the 2600's video chip, a 3 by 5 font and a 13 by 13 pixel skull as the logo. Everything is drawn with rectangles, not a single PNG, and the canvas is scaled with image-rendering: pixelated. In the browser, flawless. On the phone, the first complaint was “the logo at launch doesn't look very sharp”.

The game doesn't draw the icon or the launch screen: a tool generates them from a 1024-pixel PNG, rescaling it to every Android density with a Lanczos filter. That's right for a photo and the worst thing for a 13-cell skull: every edge becomes a two- or three-pixel gradient. Then Android 12 takes the adaptive icon, meant for 108 dp, and paints it at 240 dp on the launch screen with bilinear filtering: a second rescale, upwards, by 2.2. And along the way the adaptive icon crops 16.7 % per side for the mask. Three transforms, none of them whole.

// celda de un número entero de píxeles, para que la calavera
// quepa en el círculo visible de cada recurso
const celdaEnCirculo = (diametro, aire = 0.92) =>
  Math.max(1, Math.floor(diametro / 2 / radio * aire));

for (const [d, k] of Object.entries({ mdpi: 1, hdpi: 1.5, xhdpi: 2, xxhdpi: 3, xxxhdpi: 4 })) {
  const fg = Math.round(108 * k), sp = Math.round(288 * k);
  escribir(`mipmap-${d}/ic_launcher_foreground.png`, calavera(fg, celdaEnCirculo(fg)));
  escribir(`mipmap-${d}/splash_icono_fg.png`, calavera(sp, celdaEnCirculo(sp * 2 / 3)));
}
Every resource is drawn at its exact size. Nothing gets rescaled, ever.

Android 12's launch screen accepts its own icon (windowSplashScreenAnimatedIcon), so it gets a 288 dp one with the skull inside the visible 192 dp circle, instead of letting it enlarge the launcher's. And the window background while the WebView loads, which as a PNG was stretched to the screen, becomes a layer-list: flat colour and the same bitmap centred, unscaled. It was verified with adb screenshots right after launching the app, with two free traps: with the screen off the captures come out black, and the launch one comes out rotated, because the system draws it portrait even though the game is landscape.

What limits the 2600 is what gives it its look, and the game uses it on purpose:

And the crooked eye. With everything sharp at last, the logo still looked off: the skull's right socket had been shifted one pixel since day one. At 5 pixels it doesn't show; at 50, on the launch screen, it does, and Adrián spotted it the moment he saw it big. Sharpness is good for that too: it lets the mistakes show.

War Zone is playable at dailychallenge.click/warzone and is entering Google Play as a closed test.

All notes