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.
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 I think it's not impossible to 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.
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:
240x160
. For a modern game, you usually want an integer factor of
1920x1080
like 640x360
(3) or 128x72
(15).Stretch Mode = Viewport
and Stretch Aspect =
Expand
. A parallel should exist no matter what engine or framework you're
using, I hope.Crisp 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?
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.rgb = texture(palette, uv).rgb;
}