Skip to content
Blog
Case studyAugust 27, 2026

The boar was purple

After release, I looked at my game like a painting: every image produced as needs arose, against a palette that no longer existed. The overhaul happened in waves, by measurement. And at the end, a purple beast that two out of three measurements declared fine.

Limon was live, and its world was fighting itself. The game had grown system by system, and so had its images: each sprite produced the moment the need appeared, against that day's palette. Then the ground changed. The terrain tiles were redone, dark, crepuscular, and on top of them sat buildings from another era: huts at 117 luminance resting on grass at 69, a temple in white stone, a granary with a yellow roof. The camp looked pasted in from another game.

Measure before repainting

I did not start by regenerating. I started by measuring the six grounds, because everything else is judged against them: forest at 38 luminance, water at 44, cultivated fields at 57, grassland at 69, mountain at 107, desert at 150. A sprite is never judged in the absolute, nor on a neutral background: it is judged sitting on the ground where the game actually places it. A neutral background lies about contrast, and contrast is the only thing that matters in game.

Out of those measurements came a doctrine, settled on an animated mockup before producing anything: buildings sink into the ground's palette, the living stay above it. After the overhaul, buildings sit between 44 and 75 luminance, with a floor so that a temple or a well survives a camp built in the forest, whose ground is at 38. Humans live at 84, wildlife between 85 and 98: above grass and forest, below desert. The temple stopped being a white stone edifice and became a cromlech of dark megaliths.

The waves

Production went in waves, each one closed before the next opened. Wave 1, all the buildings: 18 sprites, from the five dwellings to the pyre. Wave 2, flora and rock. Wave 3, the living: humans, wildlife, recalibrated silhouettes. A fourth wave would come later, born of a complete inventory that deserves its own story.

At the end of wave 3, everything was green: every family produced, checked, in palette. That is when I laid all the thumbnails side by side, and two defects came out at once: two defects that wave-by-wave production could not see.

The character that darkened as it turned

First defect: human luminance depended on facing. Each direction comes out of a separate generation, and my conversion script for humans only resized, where the wildlife one already normalized. Measured gap: 21 to 23 luminance points between the south view and the east view, across all twelve animations, while wildlife held within 1 point. In game, the character darkened as it turned.

The fix was gamma, not scaling. A linear scale corrects the average but clips: the east direction called for a 1.33 factor, and 15% of opaque pixels slammed into white, flattening the garment's modeling. Raising values to a power leaves black at 0 and white at 1: nothing can clip, and it is the midtones that rise, where all the material lives. A single gamma per direction, applied to the six frames of the cycle, brought the gap down to 0.4 points across 288 images. The target: 84, the level of the south view. The only one I had ever looked at and approved.

The boar was purple

Second defect, and the most instructive: the boar's average hue measured 319 degrees. That is magenta. The bear was at 7 degrees, a pinkish red, while the deer sits at 24, the rabbit at 22, the human at 22. A purple beast was wandering my crepuscular world, and I had never seen it.

The defect had survived the wildlife wave for a precise reason: I had checked the luminance and saturation of those two species, never their hue. The two measured quantities were good. The third was not measured. The fix is a uniform hue rotation toward 26 and 22 degrees, followed by a luminance catch-up, because a rotation shifts it mechanically: green weighs 0.587 in luminance while blue weighs only 0.114.

> Three quantities are enough to hold a sprite: luminance against its ground, saturation against the palette, hue against the ecosystem. But you need all three. An unmeasured quantity is a drifting quantity.

What the eye approves

I keep two things from this overhaul. First, the eye only approves what it looks at: I had approved the south view of the humans, and the three other directions drifted; I had approved two measurements of the boar, and the third was wrong. Second, the side-by-side layout is an instrument in itself: no isolated thumbnail confessed anything, and the full sheet confessed everything at once.

Repainting an entire game demanded nothing artistic in the sense I imagined. It was a job of doctrine and measurement: decide where each thing lives, then verify that it lives there. Taste served once, when the mockup was settled. Everything else was numbers.