I’ve been really busy with a few pieces of contract work over the Summer. Really glad to have had that as funds have been dwindling somewhat – and once that was over I decided to have some time off (something I rarely do unless I’m actually going away).
Anyway, back on it and decided to (not) ease myself in gently with a fairly mammoth task that’s been on my list for some time now – that of implementing alternate palettes.
I wanted to have ‘proper’ alternate palettes (not just throw some kind of tint over everything) and there seemed to be two ways I could have gone about this. 1) I could implement a shader to swap colours at runtime, drawing to an offscreen buffer and using that as the source for my sprites rather than the original, or 2) I could mess with the palette data in the 8bit PNGs as they’re loaded and re-instantiate the source images from the byte data each time the palette has changed.
I have already used the second approach in a J2ME game I produced a while ago so had a bunch of code to hand for swapping PNG palettes, however I decided to go for the first approach here for three main reasons – 1) Instantiating images from byte streams can be a drain on resources as it requires a lot of memory allocation and garbage collection, 2) I have had bad experiences with instantiating images from byte streams in some versions of MonoGame (see here) and 3) I was going to have to edit some of my existing shader code to cope with palette swapping anyway so figured I may as well do the whole thing in HLSL.
Before I even started on the shaders I had a lot of rationalisation of my sprite sheets to do in order to minimise the amount of images that need to be redrawn each time a palette swap takes place. I’ve decided to allow different palettes per sprite sheet and have therefore consolidated my sprite sheets into seven key components – player, enemies, pickups, terrain, floor, parallax and HUD. Each one can have a different palette applied as part of a palette ‘set’ though often multiple sheets will share the same palette.
Next I had to write the palette swap shader itself. I pass a palette image to the shader as a lookup table, the shader compares each colour being drawn to a reference palette and, if it matches, swaps the colour with the colour at the same index in the new palette.
This fairly straightforward approach seemed to work OK but I was getting some strangeness where colours weren’t always matching or were matching wrongly. This seemed to be almost random and I have no idea whether it was to do with MonoGame scaling the images or rendering into a different colour space or what. I fixed it by having my code find the closest matching colour in the reference palette rather than looking for a (more or less) exact match.
Once the basic palette swapping appeared functional I had to go through some of my existing shader code and edit this to cope with multiple palettes. Some shaders had colours from the original palette hard-coded in there (this was fairly easy to change) – others used algorithms for colour inversion and brightness that I was never entirely happy with (ever notice pixels going a bit yellow-y on some of the GIFs, particularly during the ‘teleport’ effect). I changed both these algorithms to only work from a strict colour index and now they work much better.
Lastly I had to go through all the particle effects (groan) and make sure the tints applied to them were from the appropriate palette. This was particularly time-consuming on weapons as I had to apply a different palette depending on whether the weapon was affiliated with the player or an enemy.
And, of course, I actually have to design some palettes. Not quite sure how I’m going to approach this in-game yet but I’ve included some examples of my initial attempts. I think I’m going to go for more subtle palettes (like the original) as the defaults and then include the more garish/extreme palettes as ‘one offs’ and/or player unlockables. With some of these I’m restricting the colours available to give an even more blocky/retro feel.
Dev Time: 5 days
Total Dev Time: approx 219.5 days

Restricted Palette – Grindhouse Film Posters / Russian Constructivism

Inspired By The Manual Artwork For Atari’s ‘Space Duel’ Arcade Machines

Inspired By The Manual Artwork For Atari’s ‘Gravitar’ Arcade Machines

Inspired By The Manual Artwork For Atari’s ‘Asteroids’ Arcade Machines

Inspired By The Original Tron Movie

Very Garish Palette Inspired By The Original Defender Arcade Game, By Far The Biggest Influence On Jetboard Joust