Domo 🐧 Soda-Powered Penguin
banner
domo-yoro.games
Domo 🐧 Soda-Powered Penguin
@domo-yoro.games
they/them |
indie dev, working hard on Soda-Powered Penguin!

steam: (WITH DEMO!)
http://sodapoweredpenguin.com

discord:
discord.gg/txpYqy7pyV

patreon:
https://www.patreon.com/sodapoweredpenguin

contact:
sodapoweredpenguin AT gmail.com
pssst..... hey... the Soda-Powered Penguin SAGE '25 demo is out now! the entire demo has been brought to a new visual standard thanks to @magipixel.bsky.social !!

#indiedev #gamedev
September 21, 2025 at 3:33 AM
maybe i'm milking it but i do think the 2025 version of this room looks infinitely better

#pixelart #indiedev #leveldesign
September 19, 2025 at 5:07 PM
i still can't believe how good all of the new art looks now, it's surreal

#pixelart #indiedev #gamedev
September 19, 2025 at 5:03 PM
texture sizes do have limits though, whether you're using the RGBA32 color format or just the single-color channel R8 color format.

so... how about we combine multiple R8 color indexed textures into a single RGBA32 texture?

each R8 texture could occupy a different color channel after all!
July 17, 2025 at 2:22 AM
once again, we'll turn to shaders to automate this process!

this is actually just the first part of the "Find and Replace All" shader- but instead of outputting a swapped color, we just output index "i" converted to a color!
July 17, 2025 at 2:07 AM
this raises a new question: how do we create these color-indexed textures?

doing it by hand is certainly not an option. like the original recolor-by-hand approach, you'd need to throw out your work and start again every time you make a change to the original image.
July 17, 2025 at 2:06 AM
since we only need one color index per pixel, we actually only need to use just one color channel- red- to store the color indices!

so, the shader to convert color indices back to RGBA colors should look something like this:
July 17, 2025 at 2:04 AM
the answer, as it turns out, is that the NES stores RGBA values externally! the 2-bit value is used as a position on the palette, allowing colors to be represented with less data!
July 17, 2025 at 1:58 AM
we'll iterate through this set of colors with index position "i".

1. if the color matches source color at position "i", then output the corresponding swap color at position "i".
2. if the color doesn't match, then add 1 to "i" and go back to step 1
July 17, 2025 at 1:46 AM
this enables changing any singular color on the sprite.

if we wanted to change more colors, we could chain the logic of this shader:
July 17, 2025 at 1:39 AM
so: shaders are the best tool to accomplish palette swapping! we'll start with a basic "Find and Replace" shader.

If the pixel's color matches the "source" color, then the shader will render the "swap" color instead of the original color.
July 17, 2025 at 1:38 AM
in short: shaders are GPU programs that use data from "materials" in order to render (draw) images!

here's the default shader most game engines have- and here's exactly where you see the "tint" color multiplication!
July 17, 2025 at 1:32 AM
since color component values can only be between 0.0 and 1.0, this means that the product of color multiplication will always result in something that's darker than either starting color.

this explains why "tint" never provides a satisfactory result!

(it is useful for transparency at least!)
July 17, 2025 at 1:26 AM