I’m old enough to remember playing a GameBoy on the school playground, but I’ve not given the retro handheld much thought since then. It was only recently, when I came across the impressive WiFi GameBoy cartridge project from Sebastian Staacks—a project that is well-worth a look if you’re unfamiliar—that I became interested in the GameBoy again.
This led me to GBDK 2020, there’s also a repo for GBTD and GBMB that’s more up to date—a development kit for the GameBoy that enables you to write software for it in C, as opposed to Assembly—which was something that appealed to me tremendously, offering a fun way to cut my teeth on the language, as I’ve so far only got a little C++ under my belt, thanks to tinkering on various Arduino-based projects.
For my first attempt at developing something for the GameBoy, I wanted to keep it as simple as possible – both because GBDK 2020 is brand new to me and my knowledge of C is pretty limited. After no more than a few minutes thought, I figured what could be simpler than recreating my own logo, as a homage to the original GameBoy boot up screen? It certainly beats trying to whip up a working game on my first attempt.
The project in action
As you can see, it’s pretty simple—it scrolls my logo down the screen and stops it in the middle, just like the original GameBoy boot-up screen.

Some basic Gameboy concepts
As should be clear to anyone who read the opening of this article, I’m by no means an expert on any of this— in fact, it’s my first day—I’m just learning the ropes myself, so keep that in mind as I explain a couple of core concepts when it comes to rendering graphics on screen for the GameBoy.
- Graphics are made up of 8×8 tiles and are displayed on one of three separate layers—the background layer, the window (used for displaying things like lives, scores, etc.), and the sprite layer. The latter is where all the action takes place, and the layer we’ll focus on in this post.
- Obviously, single 8×8 tiles aren’t much use—so you’ll want to combine these into more complex sprites. Tiles that are combined to great game assets are referred to as “meta-sprites”, which is how I put together the logo graphic seen in the gif at the beginning of this post which shows the project in action.
- There are several limitations to keep in mind when designing graphics. In the case of this project, the most significant is the limit of number of tiles per line when using the sprite layer, which is 10—something I learnt the hard way, as my original tile map for the logo was made up of 22 tiles, which had to be remade.
Thankfully, for those of us just starting out—the GameBoy has one of the largest homebrew developer communities—meaning everything is incredibly well documented, which makes things much easier than some other retro handheld systems. For more info on how all this works, I’d highly recommend giving Rodrigo Copetti’s Gameboy architecture write-up a read.
There’s a ton of great content on Youtube about these topics—one such resource is the “Learn how to develop your own GameBoy games” playlist from GamingMonsters. In fact, for this project, Part 9 “Meta-Sprites” of the series was a great help—so if you’re looking to give this a go yourself, that would be an excellent place to start.
What you’ll need
For the purposes of this post, I’m going to assume that you at least have some programming background, and that you’ve already got an IDE setup and all that good stuff. So we’ll leave that out, and jump straight to specifics for GameBoy development.
GBDK 2020
The first thing you’ll need to do is download and setup GBDK 2020—for everything you need to get it up and running, I suggest heading over to the GBDK 2020 getting started guide, available as part of the projects developer docs.
GameBoy Tile Designer
This is a free program for windows which lets you easily create tile maps for use in your GameBoy games. You can download GameBoy Tile Designer from the project’s website.
A GameBoy Emulator
There are no shortage of GameBoy emulators to take your pick from—I went with BGB, which you can download from their website—but any GameBoy emulator will do.
Creating the graphics
Now that you’re all setup and ready to go, let’s start with creating the graphics you want to display on the GameBoy – in my case, it was my logo. For this, we’re going to use GameBoy Tile Designer as well as Gimp, to setup a reference image to make life easier on ourself.
The first thing I did was to open Gimp, setup a new canvas measuring 160px x 144px—the same size as the original GameBoy screen—added a grid, and changed the settings of the grid to 8 x 8, reflecting the tile size as mentioned earlier. I’m sure there are better ways to do this, but frankly, I just wanted a quick and dirty reference to help me draw out each of the respective tiles as quick and as easily as possible. It worked for me, but I’d definitely welcome any comments on better ways to get this done.

Once I had that, I opened the GameBoy Tile Designer and started creating my tiles—20 in total, spreading the logo over two lines. After I had my tiles created, I simply exported them, selecting the type as “GBDK C file”, into my project file. Apart from a rework due to encountering a limitation in the number of tiles per row, it was pretty easy to use.

The file gives an unsigned char of hexadecimal values, each row of eight representing a single tile. This then just needs to be included in your project’s main.c file. I’ve given the file below for reference, which contains the tiles for my logo.
logoText.c
unsigned char logoText[] =
{
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x1F,0x00,0x3F,
0x00,0x70,0x00,0xE0,0x00,0xC0,0x00,0xC0,
0x00,0xE0,0x00,0x71,0x00,0x3F,0x00,0x1F,
0x00,0x00,0x00,0x60,0x00,0x60,0x00,0x60,
0x00,0x60,0x00,0x60,0x00,0xE3,0x00,0xE3,
0x00,0xE3,0x00,0x63,0x00,0x63,0x00,0x63,
0x00,0xE3,0x00,0xC3,0x00,0x81,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,
0x00,0x06,0x00,0x06,0x00,0x06,0x00,0x06,
0x00,0x06,0x00,0x8E,0x00,0xFC,0x00,0xF8,
0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x18,
0x00,0x00,0x00,0x00,0x00,0x18,0x00,0x18,
0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,
0x00,0x18,0x00,0x18,0x00,0x18,0x00,0x18,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x3E,0x00,0xFF,
0x00,0xE3,0x00,0xC1,0x00,0xC1,0x00,0xC1,
0x00,0xC1,0x00,0xC1,0x00,0xC1,0x00,0xC1,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x87,
0x00,0x8E,0x00,0x8C,0x00,0x8C,0x00,0x8C,
0x00,0x8C,0x00,0x8E,0x00,0x87,0x00,0x83,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0xF0,0x00,0xF8,
0x00,0x1C,0x00,0x0C,0x00,0x0C,0x00,0x0C,
0x00,0x0C,0x00,0x1C,0x00,0xF8,0x00,0xF0,
0x00,0x00,0x00,0xC0,0x00,0xC0,0x00,0xC0,
0x00,0xC0,0x00,0xC0,0x00,0xFF,0x00,0xFF,
0x00,0xE1,0x00,0xC0,0x00,0xC0,0x00,0xC0,
0x00,0xC0,0x00,0xE1,0x00,0x7F,0x00,0x3F,
0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x06,
0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x86,
0x00,0xC6,0x00,0xC6,0x00,0xC6,0x00,0xC6,
0x00,0xC6,0x00,0xC6,0x00,0x86,0x00,0x06,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,
0x00,0x30,0x00,0x30,0x00,0x3F,0x00,0x3F,
0x00,0x30,0x00,0x30,0x00,0x30,0x00,0x30,
0x00,0x30,0x00,0x38,0x00,0x3F,0x00,0x1F
};
The code
There’s nothing too difficult here. The code is made up of just a handful of components—a struct to group the logo tiles together, a function to animate them, and a simple timer to control the speed and end of animation.
The whole project is made up of just three files—the tile data (logoTile.c), which we shared earlier—logo.c, which is the struct, and main.c. It’s all given below for anyone who’s interested and wants to play around with it themselves.
logo.c
#include <gb/gb.h>
struct DuinobitLogo {
UBYTE spriteids[20];
UINT8 x;
UINT8 y;
UINT8 width;
UINT8 height;
};
main.c
#include <gb/gb.h>
#include <stdint.h>
#include "logo.c"
#include "logoText.c"
#define FRAMES_TILL_ANIM_UPDATE 3
struct DuinobitLogo logo;
UBYTE spritesize = 8;
int frame_count = 0;
void moveLogo(struct DuinobitLogo* logo, UINT8 x, UINT8 y){
for(int i = 0; i < sizeof(logo->spriteids)/sizeof(logo->spriteids[0]); i += 2) {
move_sprite(logo->spriteids[i], x + ((spritesize*i)/2), y);
move_sprite(logo->spriteids[i+1], x + ((spritesize*i)/2), y + spritesize);
}
}
void setuplogo(){
logo.x = 46;
logo.y = 0;
logo.width = 80;
logo.height = 16;
for(int i = 0; i < sizeof(logo.spriteids)/sizeof(logo.spriteids[0]); i++) {
set_sprite_tile(i,i);
logo.spriteids[i] = i;
}
moveLogo(&logo, logo.x, logo.y);
}
void main(void)
{
set_sprite_data(0, 20, logoText);
setuplogo();
SHOW_SPRITES;
DISPLAY_ON;
while(1) {
frame_count++;
if (frame_count >= FRAMES_TILL_ANIM_UPDATE && logo.y < 72) {
logo.y += 2;
moveLogo(&logo, logo.x, logo.y);
frame_count = 0;
}
wait_vbl_done();
}
}
Summing it up and next steps
I had a lot of fun with this mini project—it’s a fun way to learn C and a welcomed change from the usual SEO automation stuff I share on this blog, that I put together in Node JS.
Sure, it’s basic—but it did help me pick up a handful of important concepts about game development for the gameboy, such as using meta sprites and learning how rendering graphics to the screen works. There’s certainly a lot more to learn, and I think the next step is to make a primitive game, learning about other core concepts, like collision detection, controls, scoring, and using the other graphic layers.
I’m also fairly interested in the hardware side of things, and while something like the WiFi cartridge is way beyond my current abilities, the EXT port doesn’t look quite so hard to interface with using interrupts, although of course it would be much slower. If I can come up with some interesting way to use it, I might look to create something there.
Thanks for reading! If you found it useful or have any tips and pointers for a newb like me, just getting started with GameBoy development, I’d love to hear from you in the comments.
Excellent stuff! I love GBDK and was fun reading through your code and write up here.
May I ask, why did you choose to use sprites instead of scrolling a background map? Just curious!
Hey Sean, thanks for the comment! You’re quite right – to just make and animate the logo the background layer makes more sense.
I went for the sprite layer as the bigger project is to make a space invaders type game, using the LED icon in my logo as the enemies and the letters of the logo as the defense bunkers. I’ll need to remake the latter though, given that they’ll need more spacing.
The funny thing is that for that I also have to do things the “wrong way”, as coming up against the 40 sprite limit means I’ll need to render the enemies on the background layer.
Nice! Looking forward to seeing more 🙂
Good Tutorial. I would recommend you look into PNG2Asset it’s a tool that comes with GBDK. It converts PNGs to the .c and .h files. It comes with GBDK-2020 now. I find it a better workflow than using GBTD and GBMB, because I can use modern spiriting tools like Aseprite.
One thing to note: You should update your link for GBDK or add an additional one. The GBDK-2020 github project has a repo for GBTD and GBMB thats more up to date. https://github.com/gbdk-2020/GBTD_GBMB
Great Stuff! It’s always cool to see more people jumping into the gameboy homebrew scene. LONG LIVE THE GAMEBOY!!
Thanks, I’ll take a look – it has to beat creating tiles by hand in the tile designer. I’ve also updated the GBDK link to the github repo, as per your suggestions.
Appreciate the feedback. I’ve been browsing through your site a fair bit, definitely makes life a little easier with all the great guides and info you’ve put out.