On November 19, 2016 in San Francisco, CA the first annual Gen Jam (procedural generation jam) was hosted at the awesome indie co-working space GameNest. The idea was to spend a Saturday creating an art generator, a "thing that makes a thing" if you will.
I created a thing that made character sprites in the amazing style of Christopher "Oryx" Barrett's awesome Oryx Design Lab 16-bit Sprite Set. Have a look at some of the stuff it created:
So essentially I took the character sprites, broke them down into pieces, normalize their color palette, and implemented an algorithm to recombine them to create new unique sprites.
So I broke the source sprites up into pieces - helmets, heads, bodies, feet, weapons, etc and then selected those at random and stuck them back together. Then I changed the colors. Here is the main idea:
The original sprites I used as reference from the 16-bit Sprite Set look like this (the original set of sprites is MASSIVE, this is a small sample of 5):
Then the sprites were broken up into eight groups: the torso, head, helmet, shield, feet, hair, weapon, and bow. Then I used Photoshop to cut out the pieces and place them into separate files like this:
The idea here is to have a bunch of different heads, a bunch of different weapons, a bunch of different shields, etc and combine them at random.
I wanted to vary the colors in a way that respects the original care that went into the color palette, but also creates a lot of variety. The trick to this is to identify which colors were used on the different sprites, have them grouped together as a "color ramp," and select color ramps to re-color the sprite pieces at random.
In other words I went through and collected all the colors used for the skin tones, all the shades of green, blue, etc for cloth, all the colors used together for metals, and so on and placed them together in a palette file. A set of color ramps looks like this:
Then I took the sprites themselves and recolored them to use "input colors," colors which could be replaced by colors from a color ramp. So if I had 3 shirts colored blue, green and red what I would do is make them all red, add color ramps for blue, green, and red in the palette file, and have the algorithm replace the reds with colors from a randomly selected color ramp.
Here are some results:
Materials are substances being drawn such as cloth, leather, metal, flesh, gemstones, etc. I needed different color ramps for different materials because only certain colors looked natural for certain material types. The colors that look good for metal, for example, don't look right for skin tones and vice versa.
Additionally the variation between the colors in a ramp is different for different materials. Metal ramps for example vary a lot from light to dark within a ramp, whereas cloth does not.
The palette ended up having sets of color ramps for the following materials: primary cloth, secondary cloth, hair, skin, metal, wood, leather, gemstone, and dark accent color.
Here is the final palette:
Grouping is where you take a collection of inputs and declare certain inputs as working well together and others not so much. For example you could have "wizard sprites" and "warrior sprites," groups of sprites for different nations drawn with different aesthetic styles, good and evil groups, rich and poor groups, and so forth. This results in lots of options to generate sprites that are somewhat guided towards the aesthetic you want.
The whole shebang
So, to summarize I did the following:
- Broke a large collection of sprites into pieces: weapons, heads, torsos, etc.
- Changed the input colors to "standard" colors for the materials (5 shades of cloth, 5 shades of metal, 4 shades of skin tone, etc).
- Wrote an algorithm to select one of each of the pieces and draw them on top of each other
- Wrote an algorithm to change the "standard" colors to one of several sets of colors (called "color ramps") in the palette.
That's it! This creates thousands of unique and interesting sprites.
Github, Conclusion, and Thanks
You can visit my personal blog at http://davideyork.com where I post about procedural generation and indie game development.
You can download my code which implements this project on Github here. I wrote it in C# and it should be compatible with Unity. Note that I included a full palette and some sample images, but I didn't include all the original sprites or images created from the sprites from the 16-bit Sprite Set. You have to purchase those sprites from Christopher Barrett aka Oryx at Oryx Design Lab. They aren't separated into pieces, I did that myself. It's a massive sprite set and practically free, Oryx spent a ton of time on it and I recommend checking it out (no, I'm not getting paid to say this).