All articles
•3 min read

Keeping color consistent across hundreds of skins

King Rabbit has hundreds of rabbit skins, rings, items and decorations, drawn over a decade. Each one looked fine on its own. Side by side, the wood was five different woods and the gold was three different golds. I built a small studio tool to fix it, and most of what I learned was about color, not pixels.

Measure color the way people see it

RGB and HSL lie about lightness. A yellow and a blue with the same HSL lightness look nothing alike. I moved everything to OKLab and its polar form, OKLCH, where equal steps in the numbers look like equal steps to a person. Every rule below is measured there.

A ramp is a set of rules, not a set of colors

The biggest shift was writing down what a good ramp is, so a tool can check it instead of me squinting. Every shared material palette follows the same five rules:

  • Even lightness. Neighboring steps are the same distance apart, so no two shades read as one and no jump stands out.
  • No near-duplicates. If two steps are almost the same color, one of them is wasted.
  • No pure black or white. The darkest step is a dark version of the material and the lightest a pale one, so outlines and highlights keep their color.
  • Hue shifts one way. Shadows lean cooler, highlights lean warmer, and the hue never zigzags back.
  • One saturation peak. Color is richest in the midtones and falls off toward both ends.

Greys skip the last two, since their hue is mostly noise. The rules run as a test, so a palette that breaks them fails before it reaches the game.

Share materials, not colors

Instead of every item carrying its own palette, items now point at shared materials: wood, stone, metal, gold, gems and elements. A key, a crate and a crown made of gold all use the same gold ramp. Fix gold once and every gold thing in the game follows.

It also makes reskins cheap. Turning a gold key into a wooden, stone or metal one is a remap from one ramp to another, not a redraw.

Remap by step and keep the shading

The idea that makes remapping work: every color in a sprite is a step on a ramp. To recolor, swap the ramp and keep the step. The third-darkest gold becomes the third-darkest wood. Shading, highlights and outlines land exactly where they were, because the structure never changed.

Rabbits go one level further. Each skin's colors are grouped by hue into roles, fur, belly and accent, and each role becomes its own ramp anchored on its most-used color. That's what lets one rabbit's fur colors move onto another rabbit's head with the shading intact.

One edit, every skin

Many skins are recolors of the same shape. The front of the head alone comes in about 300 distinct outlines, and most of them are shared by several skins. So an edit to one skin's head can be carried to every skin with the same outline, each in its own colors. Pixels the edit didn't touch stay as they are, and changed pixels take each skin's own version of the original color.

When the tool can't be sure, it flags instead of guessing. If the edit adds a color the original never had, or a skin uses several colors where the original had one, that skin goes to a human. A slightly lighter or darker version of an existing color is fine: each skin gets the same step in its own color.

Audit, then fix

Consistency is easier to keep than to create. A review page lists what's worth a look: near-miss shapes that are almost a shared outline, and palette outliers, such as a step darker than the one below it, steps that merge or are uneven, a hue jump, or a stray tint on a grey. One decision covers every skin that shares the problem.

What I learned

  • Measure color the way people see it. OKLab made every rule simple to state.
  • Write the rules down and test them. Taste is easier to keep when a tool can check it.
  • Think in ramps and roles. A color's step matters more than its exact value.
  • Flag, don't guess. Automation should handle the obvious cases and hand the rest to you.