• Register

Master deadly traps and savage hazards to slaughter your foes in turn-based tactical combat. Guile & Glory: Firstborn is the story of a world on the brink of ruin. A legion of nightmarish immortals sweeps across the land, slaughtering all who would oppose them. Blades shatter and arrows snap against the demonic flesh of the horde, and death follows in their wake. But as swords fail and kingdoms crumble, three heroes rise to challenge the darkness.

Post news Report RSS Shader Capers: Palette Swapping

This week we take a look at a how a simple palette-swap shader is used to retouch art and generate enemy variants in Firstborn.

Posted by on

I have always struggled with colour in pixel art. Get a shade wrong here or there and an otherwise aesthetically-pleasing image can end up looking terrible. This is especially problematic when you realize something is wrong with the palette for a character. You may have completed dozens of animations (or worse, payed someone else to produce them for you), only to find that your colours just don't look quite right. Well, with enough time and patience, as well as a bit of beefy editing software, you can fix it. But doing so takes time, potentially quite a lot of it, and time is a game developer's most precious resource. There has to be a better way...

Having run into this very problem earlier in the year, I set out to find a way of making sure that I wouldn't have to lose hours recolouring sprites in the future. As it turns out, there was a solution: shaders! Shaders allow for a remarkable level of control over what your game actually draws to the screen, and after a little research I discovered that setting up a palette-swap shader was actually pretty straightforward. But what exactly is palette-swapping?

Take a look at the gif above. Here you can see a few Firstborn undergoing some pretty radical changes in colour. This is a palette-swap shader at work. In Firstborn, each material that makes up a character (skin, metal, cloth etc.) is divided into six colours (two for outlines, two for shading, a base colour and a highlight). The shader takes the red, green and blue values of each of these colours, and replaces them with a new set of values, creating a new colour to replace the old. Success! Minor tweaks to the colour palette will do longer require me to rework a character's sprite sheets. But can we do anything else with palette-swapping?


Here are the regular enemies from the demo. These guys are savage, reptilian humanoids with a penchant for mayhem. The Archer, Drudge and Turtle are the most common and weakest enemies, and the player will be quite familiar with their unique silhouettes and capabilities after only few encounters. But now, let's introduce something new...


After a simple palette-swap, we have a new menace for the player to face. These are Bog Shades, fearsome undead variants of the basic enemies. By messing around with a few colours, we've turned savage lizard-people into dour shades bedecked in ancient silver. Why is this useful? Well, at a glance the player can see that these are similar to the enemies that they've faced before, but the drastically different palette hints that they have some additional capabilities.

So when should you palette swap, and when is an entirely new sprite called for? I have some thoughts in relation to Firstborn, based primarily on the concept of orthogonal unit differentiation. But that's a whole other topic, which I'll talk about in another post.

If you're looking to introduce a palette-swap shader into your project in GameMaker: Studio, community member Pixelated_Pope has a great example project that can help you get started. You can check it out here: Gmc.yoyogames.com

Thank you for reading, and I'll see you next week for another Firstborn development blog!

TL;DR

  • Updating colours in pixel art can be a pain

  • A palette-swap shader can help

  • Palette swaps can also be a great way of creating new variants of existing enemies

Post a comment

Your comment will be anonymous unless you join the community. Or sign in with your social account: