The Game Boy Advance from First Principles
A first-principles look at the GBA's hardware capabilities — modes, tiles, sprites, affine transformations — so you can start a weekend game knowing what fits and why.
On this page
The Game Boy Advance is a 2001 handheld with a 16.7 MHz ARM processor and 32 KB of RAM — less computing power than a modern thermostat. But it runs games that look and feel alive because the hardware is specialized: it has dedicated circuitry for scanning out tiles, sprites, and backgrounds at 60 frames per second. The trick is not speed. It is the right abstractions baked into silicon.
This article explains the GBA’s hardware model from the ground up: what the machine can do, why it does it that way, and how different game types map onto its capabilities. If you use a framework like Butano, the register calls are handled for you. The decisions that matter — which rendering mode to use, how many background layers you need, whether sprites are enough or you need affine transformations — come from understanding the hardware, not the framework.
The Hardware’s Mental Model
The GBA does not work like a modern game engine. Modern engines build a scene graph, run a render loop, and draw pixels to a framebuffer. The GBA works the other way around: it is always rendering. The Picture Processing Unit (PPU) continuously scans a fixed region of memory and outputs whatever it finds there, 60 times per second. Your job as a developer is to change what is in that memory before the next scan starts.
The memory is split into dedicated regions:
- Tile memory stores the 8x8 pixel graphics; each one is saved once and referenced by many positions.
- Tilemaps are grids of indices that say which tile goes where.
- Sprite memory (OAM) holds positions, tile indices, and flags for up to 128 hardware sprites.
- Palette memory holds the color tables. The GBA uses indexed colors, not direct RGB.
You do not draw anything. You configure. The PPU reads your configuration every frame.
The Modes (The Single Most Important Decision)
The GBA has six rendering modes. The mode determines what kind of backgrounds are available, how many layers you can use, and whether you work with tiles or raw pixels. Everything else follows from this choice.
Mode 0 — four tile layers, each scrollable independently. No rotation, no scaling. This is the workhorse for puzzle games, platformers, and any game that does not need perspective effects. Four layers means: a sky layer (scrolls slowly for parallax), a ground layer (scrolls with the player), a foreground layer, and an overlay for UI or shadows.
Mode 1 — three tile layers plus one affine layer. The affine layer supports rotation and scaling via a 2x2 transformation matrix. Useful for a single rotating element while keeping tile-based UI in the other layers.
Mode 2 — two affine layers. All backgrounds use affine transformations. This is where Mode 7 style effects live — pseudo-3D by updating the affine matrix each frame.
Modes 3-5 — bitmap modes. Instead of tiles, you write pixels directly to a framebuffer. Simpler conceptually, but more memory-intensive and slower. Useful for photo viewers or games that need per-pixel effects. Rarely the right choice for a game because you lose tile-level compression and hardware scrolling.
The rule: use tile modes unless you have a specific reason not to. Tiles are the GBA’s native format. Tiles compress memory (one tile used in 50 positions costs memory for one tile plus 50 indices), they scroll for free (change one scroll value to move an entire layer), and they leave CPU time for game logic rather than pixel pushing.
Tiles and Backgrounds
A tile is an 8x8 pixel image, stored in video memory as indexed colors. Instead of storing every pixel on screen, you store a set of tiles and then build maps from them. This is how the GBA gets detailed visuals out of 96 KB of video memory.
A tilemap is a 2D grid of tile indices. To render an outdoor scene, you store grass, tree, and rock tiles once, then build a map that references them by index. The map can be 32x32, 64x32, or 64x64 tiles depending on how much scrolling space you need.
Each background layer has three values you control: scroll, an optional affine matrix, and an enable flag.
- Scroll sets how far the layer has moved horizontally and vertically.
- Affine matrix (affine modes only) applies the 2x2 transformation to the layer.
- Enable turns the layer on or off.
To scroll a layer, you set new scroll values. The PPU picks up the change on the next scan.
Parallax is a natural consequence. Put a mountain range on background layer 0 and a foreground on layer 1. Scroll layer 0 at half the speed of layer 1, and the hardware handles the rest.
Sprites (OAM)
Sprites are hardware-managed movable objects. The GBA supports 128 sprites per frame, each 8x8 to 64x64 pixels, with independent position, tile assignment, palette, and flags.
The Object Attribute Memory (OAM) is a table of 128 entries. Each entry records where the sprite is, which tiles it uses, and a set of flags:
- Position (X, Y), where the sprite appears on screen.
- Tile index, the 8x8 tile a sprite starts from; larger sprites reference a block of tiles.
- Flags, such as horizontal/vertical flip, priority, palette bank, and affine flag.
To make a sprite move, you change its X and Y in the OAM table. The PPU picks up the new position on the next scan, and the sprite simply appears there at 60 FPS.
Affine sprites use a per-sprite 2x2 matrix for rotation and scaling around the sprite’s center. An affine sprite can spin, grow, and shrink without any CPU work beyond updating its matrix.
Invisible Ceilings
Three hardware limits shape every GBA game, and a framework like Butano won’t save you from them:
- Colors: 256 total, in fixed 16-color palettes (for tiles and sprites; bitmap modes use 15-bit direct color instead). Your art style is decided here — a sprite gets 15 colors plus transparency, so characters and scenes are designed to share palettes. The GBA’s colorful look comes from palette swaps, not from using more colors.
- Tiles and sprites share the same video memory. More detailed backgrounds mean fewer sprites, and vice versa. Budgeting that pool is a design decision you make before you draw anything, not a code problem to solve later.
- 32 sprites per scanline. You can place 128 sprites in a scene, but only 32 can appear on any single row of pixels. Crowd a busy screen and sprites silently vanish. If a boss fight suddenly loses an enemy, this is why.
Mode 7 and Affine Backgrounds
Mode 2 enables what most people call “Mode 7” — an affine background transformed by a 2x2 matrix that you update every frame. This is the technique behind the pseudo-3D effects in Mario Kart and F-Zero.
A 2x2 matrix controls rotation and scaling together. You tell it how much to rotate and how much to scale, and the PPU bends the entire background accordingly.
Airplane simulation. To simulate flying over a landscape, update the matrix each frame based on pitch and roll. Pitch compresses the horizon vertically. Roll tilts the horizon line. The background never moves; the transformation matrix is the illusion.
The Frame Loop
Every GBA game follows the same rhythm:
- Initialize hardware state — set the mode, load tile data, build tilemaps, configure sprites and palettes
- Loop: read input -> update game state -> update background scroll values and sprite positions -> wait for vsync -> repeat
The vsync is critical. The PPU scans the screen line by line, 60 times per second. If you update data while it is being read, you get tearing. Butano handles the vsync timing, but you own the budget: roughly 16.7 milliseconds per frame to do all your work before the next scan cycle.
Weekend Projects
The mode-first approach makes weekend projects straightforward because you pick the right mode and let the hardware do most of the work.
Puzzle game (Mode 0). One background layer for the grid, one for decoration. Sprites for cursor and pieces. D-pad input, buttons to swap or place. Game state fits in a small 2D array. Done in a day. The second day: timer, scoring, smooth swap animations.
Platformer with parallax (Mode 0). Three background layers: mountains at 0.25x scroll speed, terrain at 1x, foreground at 1.5x. Player and enemies as sprites. Tilemap collision — check which tile index is under the player’s feet. Hardware scrolls all layers simultaneously.
Airplane simulation (Mode 2). One affine background for the terrain. Update the 2x2 affine matrix each frame from flight dynamics. Sprites for cockpit instruments. No 3D engine — the illusion comes entirely from the affine transformation on a flat tilemap. The flight model can be as simple as you want; rendering cost is the same: one matrix update per frame.
Every project ends up constrained by the hardware rather than the code. The hardware tells you what is cheap (tile scrolling, sprite movement, affine transforms) and what is expensive (frequent tilemap updates, pixel-level effects). Design within the constraints, and the game mostly writes itself.