Creating pixel perfect video games

Preface

If you don't know what Pixel art is, cure has an amazing introduction.

Reading through it I was thinking why something similar didn't exists specifically for making video games. With Godot 4 just having come out, I figured now is the perfect time to compile the things you can do to make a game pixel perfect.

Not all tools are Pixel Perfect

Being a game designer, I've dealt with a lot of game engines and frameworks. Most of the games I've made and worked on have been pixel art games, so naturally I've gravitated towards tools that are more suited for it.

The reason I'm bringing this up first is because while you can make a pixel art game in Unreal or Unity, tools more suited for the task like Godot will help you achieve that pixel perfect look.

Screen Size

When making pixel art, you usually worry about the size of your canvas exactly once and at the very start.

When making a video game, it's a different story. Because you're canvas (a players' display) is no longer static, both it's resolution and aspect ratio vary from person to person so you can no longer just pick one size and expect it to look good for everyone. Godot has a good tutorial that introduces the problem of multiple resolutions and how handle it.

To setup your screen for a pixel perfect game you want to do the following:

  1. Set the base window size to the smallest viewport you intend to use. For example if you wanted to make a GBA styled game, you would pick 240x160. For a modern game, you usually want an integer factor of 1920x1080 like 640x360(3) or 128x72(15).
  2. Render the game at that small resolution and stretch to fit the display. In Godot that's achieved using Stretch Mode = Viewport and tretch Aspect =

Expand`. A parallel should exist no matter what engine or framework you're using... I hope.

Palette swap

Pixel art goes hand in hand with a colour palette, and the same way you stick to it when creating pixel art, you got to ensure that every pixel of your game sticks to it too.

At first you might be making all your assets using a single pallet, ensuring all your UI elements use the right colours too. As the game expands there's more and more to keep track of. What if you want some transparency, lighting, what if you decide to support multiple palettes, now you got to remake all your assets and somehow control all UI. What a pain!

What if there was a way to solve all your problems in one go?

There is and it's called palette swapping and is usually implemented as a screen shader.

shader_type canvas_item;
render_mode blend_disabled, unshaded;

uniform sampler2D palette: filter_nearest, repeat_disable;
uniform sampler2D SCREEN_TEXTURE: hint_screen_texture, filter_nearest;

void fragment() {
	vec2 uv = texture(SCREEN_TEXTURE, SCREEN_UV).rg;
	COLOR = texture(palette, uv);
}

Before I explain how the effect works, let me show you what the result looks like.

Screenshot of Godot using the palette shader

The principle behind palette swap is that you no longer use colours to represent RGBA channels directly. Instead you use them to represent UV coordinates for a lookup texture (a colour palette). This means that every colour on screen will get converted to a colour in the palette without exception.

aarthificial made a video that uses the same idea to create a different effect.

The downside of using palette swap is that all your assets need to be coloured correctly which is usually done manually. The way I deal with this is by using Aseprite's index color mode to create my art as usual, and then changing the palette to an export one which does the recolouring for me.

I've also create a python script that creates the export palettes for me.

Fonts