Mastodon
Table of Contents
Understanding Gameboy Graphics
If you you want to take a deep dive into graphics on the game boy, here's a tutorial explaining it more in depth.
Table of Contents

Gameboy Graphics: The Background, Window, and Sprites

Gameboy Graphics: The Background, Window, and Sprites

When it comes to gameboy graphics, there are 3 major components. The first 2 components are the window and background “layers”. The third major component are sprites. These 3 components make up all the graphics for all gameboy games. The data for each of these 3 components is stored in the Gameboy’s VRAM.

The following lines can be used to show or hide The Background, Window, or (all) sprites.

				
					// Show (all) Sprites, The Background, or the Window
SHOW_SPRITES;
SHOW_BKG;
SHOW_WIN;

// Hide (all) Sprites, The Background, or the Window
HIDE_SPRITES;
HIDE_BKG;
HIDE_WIN;
				
			

What is VRAM?

VRAM stands for “Video RAM”. Before we get into how to display backgrounds and sprites, the topic of VRAM must be shortly explained.

For Gameboy graphics, it is a essentially a variable collection of 8x8px tiles. There is a dedicated space in VRAM for sprites, and another dedicated space in VRAM for the background/window (they share this space). Both spaces can have a maximum of 256 tiles. The contents of these spaces can be changed at any time.

For ANYTHING to be displayed on screen, it must be stored in VRAM first. Everything you see on screen maps to a VRAM tile.

The Background & Window Layers

Gameboy games have 2 display “layers”. These layers are the window and the background. The window is always drawn over the background. They can both be turned on/off and/or moved, individually, freely. 

The background and window layers are tile maps, made of 8×8 sized tiles. Each layer is 32 tiles wide, and 32 tiles high. This makes their overall max size in pixels 256x256px. The background and window layers do not support transparency, and they occupy the same VRAM space. (This means that the window and background will use the same tiles). The background and window can be moved freely.

The Gameboy screen is 160px by 144px. The contents of the background and window will wrap around when they exceed the 256px mark vertically and/or horizontally. Here is an awesome video that explains more about the background and window on the Gameboy.

There are two main steps for showing something on the background/window. 

  1. Placing the image data into VRAM using the “set_bkg_data” function.
  2. Using the “set_bkg_tiles“/”set_win_tiles” to actually show those tiles on the background/window respectively
Image to VRAM to Background

Placing background/window tiles into VRAM

The background and window layers share 256 tiles in VRAM. Something important to note for gameboy graphics: For a tile to show on the background or window, it must be placed in the VRAM. The GBDK “set_bkg_data” function will place a given number of tiles in the VRAM space dedicated to the window/background. This function takes in 3 parameters.
  1. The first parameter is where in VRAM to start placing the tile.
  2. The second parameter is how many tiles to place in VRAM
  3. The Third parameter is a pointer to the actual tiledata. I have a tutorial on understanding the GBDK/Gameboy Tileformat

Usage of the “set_bkg_data” function looks like this:

				
					// Load & set our background data
set_bkg_data(0,178,LaroldsJubilantJunkyard_data);
				
			

The above code snippet sets 178 tiles (defined in the ‘LaroldsJubilantJunkyard_data‘ variable) in VRAM. These tiles will start at 0, and end at 177. This snippet ONLY put’s the tiles in VRAM, it does not actually place them on the background/window. The “set_win_tiles” and “set_bkg_tiles” functions are responsible for making tiles visible on the screen.

NOTE: Changing the tiles stored in VRAM will change what’s displayed on the screen immediately, and with un-predictable results if not planned.

Showing tiles on the background/window

The “set_bkg_data” function handles putting tiles in VRAM for the window and background. Now that we have our desired tiles in VRAM, we can place them on the background/window. To put these tiles on the background/window, we must use the “set_win_tiles” and “set_bkg_tiles” functions. These two functions will place tiles, from VRAM, onto the window and background layers respectively.
 
Here is an example of how they are used: ( NOTE: “set_win_tiles” is used the exact same way as “set_bkg_tiles” )
 
				
					
// The gameboy screen is 160px wide by 144px tall
// We deal with tiles that are 8px wide and 8px tall
// 160/8 = 20, and 144/8 = 18
set_bkg_tiles(0,0,20,18,LaroldsJubilantJunkyard_map);
				
			
These two functions can place a rectangle of tiles onto the window or background. They both take 5 parameters:
  1. The x position on the screen/background (In tiles, not pixels)
  2. The y position on the screen/background. (In tiles, not pixels)
  3. How many tiles wide the rectangle is.
  4. How many tiles tall the rectangle is.
  5. The list of which VRAM tiles to place. (The size of this list must be equal to the product of the previous two parameters)

The “Larold’s Jubilant Junkyard” splashscreen is 160 pixels high, and 144 pixels wide. In tiles it is 20 tiles wide, and 18 tiles high. This makes 360 non-unique tiles. When the duplicate tiles are removed, we are left with 178 unique tiles.

The previously used “LaroldsJubilantJunkyard_data” variable has the data for 178 unique tiles. These tiles are stored in VRAM. The “LaroldsJubilantJunkyard_map” variable has 360 values. Each value points to a specific tile in VRAM.

Moving the Background and Window layers

The background and window layers can be moved around freely. This is commonly used for scrolling effects. These two layers can moved by their corresponding “move_” and “scroll_” functions ( move_win,scroll_win,move_bkg,scroll_bkg).
 
These 4 functions all take 2 parameters. The first parameter is for horizontall movement/placing, the second is for vertical movement/placing. The “move_” functions will move the window/background to the location specified by it’s two parameters. The “scroll_” functions will nudge the window/background in direction specified by it’s two parameters.
Note: the values are negative. Increase the value to move your background/window to the
 
Here is an example code below:
				
					    // Move the window TO x-coordinate: 7, y-coordinate: -80
    move_win(7,80);

    // Move the background TO x-coordinate: 7, y-coordinate: -80
    move_bkg(7,80);

    // Move the window to the right 1 pixel, and down 3 pixels
    scroll_win(1,3);

    // Move the background to the right 1 pixel, and down 3 pixels
    scroll_bkg(1,3);
				
			
Larolds Jubilant Junkyard Splash Screen Moved
Splashscreen with move_bkg(7,80)
Getting Started With GBDK 2020 and BGB
Splashscreen at default background coordinates

In the comments I made sure to point out the difference that the “move_” functions will set the location of the background/window to the exact values specified. Where as the “scroll_” functions are used for nudging the background in a given direction.

The background  “wraps around”. Part of it will always be shown. Once a tile goes to far to one side, it will show up on the other side.

Simple HUD Strategy

If you recall, the window appears OVER  the background. Also, neither the window or the background can be transparent. This creates a certain problem. If Both are showing at the same location, the window will always cover the background (and often sprites too, unless explicitly positioned over the window).

The solution we see in many games is to move the window down or up, so only a part of it is showing.

Gameboy Graphics - Sprites

Sprites are different from the window/background layers. They represent smaller individual objects. These can be positioned above both window and background, BELOW both window and background, or between the two. Each “sprite” is 8 pixels in width. As for height, sprites can be 8 or 16 pixels high. A sprite can represent a single object on screen, or multiple sprites can combine to represent a single larger object on screen. Sprites can have their own unique per-pixel position. In addition, sprites can be flipped horizontally and vertically. Below are examples of things that are sprites are used for:

  • The Player
  • Enemies
  • Bullets & Projectiles
  • Powerups

The Gameboy supports a maximum of 40 sprite objects. Because of the 40 object limitation, different strategies must be used to achieve certain game design elements.

Placing sprite data into VRAM

Like with the window and background, before we can show a sprite on screen it’s data must be placed in VRAM. Just like the window/background layers have their own VRAM space, all sprites SHARE a chunk of VRAM space dedicated to them. 
 

To put tile data in VRAM for sprite objects we must use the “set_sprite_data” function. This function is exactly like the “set_bkg_data” function. The only exception is that it uses a different chunk of VRAM. This function takes in 3 parameters.

  1. The first parameter is where in VRAM to start placing the tile.
  2. The second parameter is how many tiles to place in VRAM
  3. The Third parameter is a pointer to the actual tiledata. I have a tutorial on understanding the GBDK/Gameboy Tileformat

The “set_sprite_data” does not target a specific sprite. The data it sets in VRAM is shared by all sprites. Example usage of the function looks like this:

				
					// Set 5 sprites (defined in 'PlayerSprite') in VRAM, starting at 0
set_sprite_data(0,5,PlayerSprite);
				
			
With that, we have 5 sprites set into VRAM that we can use freely. At this point in time, none of the 40 sprites have been used yet.

Assigning a sprite to VRAM tiles

Once  tile data has been set in VRAM, we can now assign a given tile (in VRAM) to a specific sprite. This is done with the “set_sprite_tile” function. This function has 2 parameters:
  1. Which sprite from 0 to 40
  2. Which tile in VRAM

Here is an example of using that function:

				
					// Set the first sprite (sprite 0) to use tile 0
set_sprite_tile(0,0);
				
			
This can be done multiple times with the same sprite and a different tile, Which is used for animations. With the sprite’s VRAM tile specified, we can now move the sprite around freely (on screen) using the “move_sprite” and “scroll_sprite” functions.

Moving your sprites around

Once a tile has been set for a sprite, we can use the “move_sprite” and “scroll_sprite” functions to change it’s location. These functions operate similar to the “move_bkg“, “move_win“, “scroll_bkg”, and “scroll_win” functions above. The “move_sprite” function moves a specific sprite to an exact location. The “scroll_sprite” function will nudge a sprite in the direction specified. These two functions both take 3 parameters:
  1. The index of the sprite (from 0 to 39)
  2. The horizontal value
  3. The vertical value
My Game Boy tutorials have a lot of C Programming. If you need help, here’s a book that may help you:
Who else is making Game Boy Games?

There are many individuals who are developing games for retro consoles. Here’s one you might like:

Black Castle

Created By: Userx07F

The times were dark and the kingdom was threatened by a black warlock. His evil magic brought disease and destruction to the land, but none of the king’s knights found the courage to fight him. One day a young knight appeared. He set out for the warlock’s black castle to free the kingdom from his tyranny.

Other Tutorials:

Sign-Up for the "Junkyard Newsletter" for more Game Boy news!

If you like Game Boy Game Development, subscribe to the Junkyard Newsletter. Stay up-to-date with all the latest Game Boy news. It’s free, and you can unsubscribe any time!