Skip to content

Tile Maps

Building worlds from blocks

A tile map describes a level as a grid of numbers, each naming a small reusable picture. The NES stored one screen as 960 tile numbers and 64 bytes of colour; Commodore 64 programmers built maps from 4×4 blocks of characters; and games from Super Mario Bros. onwards squeezed levels further by storing larger blocks, or whole objects, instead of single tiles.

Super Mario Bros. had 8K for its graphics: every tile of scenery and every frame of every sprite. Shigeru Miyamoto told Satoru Iwata in 2010 that he managed the budget on the planning sheet itself, “making the greenery and clouds out of the same parts” and colouring them differently. The level data was just as tight. Toshihiko Nakago remembered that “1 block was 3 bytes, maybe 2, so if there were 20 bytes open, you could put in 10 blocks”, and Miyamoto kept asking for ten more.

That is the bargain a tile map makes. A level is not stored as a picture. It is a grid of small numbers, and each number names a picture that is stored once and reused wherever it is needed. Change a number and the world changes; point the same numbers at a different set of pictures and a grass level becomes an ice level. The same grid also tells the program what is solid, so drawing the world and colliding with it share one piece of data.

For how tile-based display hardware works, and which machines had it, see Tile-Based Graphics. This entry is about the map: how the numbers are laid out, and how games packed them.

Fast facts

  • The tile set: the pictures, usually 8×8 pixels. The NES holds 256 in each of its two 4K pattern tables; a Commodore 64 character set is 256 characters in 2K.
  • The map: one number per cell. One byte on the NES and C64; one 16-bit word on the Mega Drive, which also carries palette, flip and priority bits.
  • NES screen: 32×30 tiles, 960 bytes, plus a 64-byte attribute table for colour.
  • C64 screen: 40×25 characters, 1,000 bytes of screen memory.
  • Compression: most games stored bigger blocks (NES metatiles of 2×2 tiles; C64 blocks of, typically, 4×4 characters), and the map holds block numbers.

One NES screen

The NES picture chip, the PPU, has no bitmap mode at all. Its background is a nametable: 32 columns by 30 rows of tile numbers, 960 bytes, covering the 256×240-pixel screen. The console has 2K of video RAM, enough for two nametables, and the tile pictures themselves sit on the cartridge in two 4K pattern tables of 256 tiles each. A bitmap of one screen at the NES’s two bits per pixel would need 15,360 bytes. The nametable and its colour data need 1,024.

Each nametable starts at a fixed address, and the tile at a given row and column is found by arithmetic:

Code
$2000 + (row × 32) + col   ; row 0-29, col 0-31

The bottom-right tile of the first nametable is at $2000 + (29 × 32) + 31 = $23BF. The next 64 bytes, $23C0-$23FF, are its attribute table.

Colour by the 16-pixel square

The attribute table is where the NES’s tile maps get their shape. Each attribute byte covers a 32×32-pixel area, four tiles by four, and gives each 16×16 quarter two bits: a choice of one of four background palettes.

Code
bits 1-0: top-left     2×2 tiles
bits 3-2: top-right    2×2 tiles
bits 5-4: bottom-left  2×2 tiles
bits 7-6: bottom-right 2×2 tiles

Every 2×2 group of tiles therefore shares one palette of three colours plus the background colour. NESdev notes that most games answer this with metatiles of 16×16 pixels, the size of a Super Mario Bros. question-mark block, or 32×32, the width of that game’s pipes, so that the map lines up with the colour grid. A metatile is a small table entry: four tile numbers and a palette. The level map then holds metatile numbers, and one byte stands for four tiles and their colour.

The grid shows at the edges of a scrolling screen. Because the attribute areas are 16 pixels wide and the scroll moves one pixel at a time, a game scrolling across mirrored nametables cannot always change the colour of a column cleanly. NESdev gives Super Mario Bros. 3 as an example: a strip of wrong colours shows on the right of the screen.

Feeding the edge

Two nametables give 512 pixels of room, so a level wider than that has to be written in as the player moves. The program writes each new column of tiles into the off-screen part of the nametable just before it scrolls into view. The PPU’s control register has a setting that makes each write step down 32 bytes instead of along one, so a column goes in as a run of writes to one address. The work has to fit in vertical blanking, about 2,270 CPU cycles on an NTSC console, and NESdev notes that most games write no more than 64 bytes to the nametable in one frame. The NES pattern Feeding New Columns shows the routine.

The Commodore 64: map data and block data

The C64 has no nametable register to point at a map. Its text screen is 1,000 character codes in RAM, and a map is whatever the program makes of it. Lasse Öörni, who writes as Cadaver and wrote the Metal Warrior games, describes the usual layout in a Codebase64 article, calling it “the popular method of graphics encoding seen in for example SEUCK”: the map-data and block-data system, “sometimes the blocks are also called tiles”. He credits some of what he knew to Jukka Tapanimäki’s Finnish book on C64 game-making.

Part Contents
Map data One byte per block, “so there can be 256 different blocks maximum”; each row stored in turn from the top, with the row length in a “map header”
Block data The character codes for each block, row by row; a 4×4 block is 16 bytes
Address tables The start address of every map row and every block, worked out in advance “to avoid any multiplication operations”

Öörni prefers 4×4 blocks: “the block size is always a tradeoff between memory use and the complexity of graphics that can be achieved. But for easy calculations, the block size should be a power of two.” With 4×4 blocks, one map byte stands for 16 screen characters.

Colour needs a decision too. A programmer called Achim sets out the choice on Codebase64: one colour for each tile is “very useful when you want to save rastertime for the main program, but is obviously less colourful”; one colour for each character is “more colourful, but needs more rastertime when it comes to colour RAM shifting”. The cost is real because the C64 scrolls in software past the first seven pixels. In Öörni’s words, “Shifting 1000 bytes (the whole screen) around takes more than half of the rastertime of a frame”, and the decoded blocks for the new edge come on top. Multidirectional Scrolling follows that work through.

Blocks were a choice, not a rule. Öörni points out that Chris Butler’s C64 versions of Commando and Ghosts’n Goblins stored the screens as plain character codes, “and do just fine by doing things this way”. At the other end, he mentions “blocks constructed of even smaller blocks like seen in Faery Tale Adventure”, which he never used himself but which “would allow scrolling huge maps around”.

The Mega Drive: a word per cell

The Mega Drive’s VDP has two scrolling background planes, Scroll A and Scroll B, and Sega’s Genesis Software Manual gives each cell of a plane’s pattern name table one 16-bit word. Eleven bits pick the pattern; the rest set priority, the palette line and horizontal and vertical flip. Flip bits let one tile serve as its own mirror image, and the priority bit lets a single cell of the background draw in front of low-priority sprites.

Collision from the same grid

The map that draws the world can also answer “what is here?”. Divide a pixel position by the tile size and the result is a cell in the map; for 8×8 tiles that is a shift right by three bits. A small table indexed by the tile or block number then says whether it is empty, solid, a platform that holds only from above, or something that hurts. One table lookup replaces checking pixels. Öörni used the same idea with his blocks: in Metal Warrior 3 the high byte of an object’s position is its block number, so the background collision lookup reads it directly. Tile Collision covers the technique.

Sources

  • Nintendo, Iwata Asks: Super Mario Bros. 25th Anniversary, Volume 5, “Original Super Mario Developers” (2010, web): page 3 (Nakago’s “1 block was 3 bytes, maybe 2”; Miyamoto on the 64-kilobit character memory), page 4 (Miyamoto’s “the greenery and clouds out of the same parts”). https://iwataasks.nintendo.com/interviews/wii/mario25th/4/2/
  • NESdev Wiki, pages “PPU”, “PPU nametables”, “PPU attribute tables”, “PPU pattern tables”, “PPU scrolling”, “PPU registers” and “Mirroring” (community reference, web, secondary): the 32×30 nametable and its addresses, the attribute byte layout, metatiles of 16×16 and 32×32 matched to Super Mario Bros.’ blocks and pipes, Super Mario Bros. 3’s colour strip, the 32-byte address step, the 2,270-cycle vertical blank, “most games do not write more than 64 bytes to the nametable per NMI”. https://www.nesdev.org/wiki/PPU_attribute_tables
  • Sega, Genesis Software Manual (1989–1992), p. 42: “Scroll pattern name”, one word per cell with priority, colour palette, V and H reverse bits and an 11-bit pattern generator number.
  • Lasse Öörni (Cadaver), “Multidirectional scrolling and the ‘game world’” (Rant 4), Codebase64 wiki (web, secondary): section 0 (the book and brother credits), section 1 (map data and block data, SEUCK, Commando and Ghosts’n Goblins, Faery Tale Adventure, map header and address tables, 4×4 blocks), section 2 (the cost of shifting the screen), section 3 (Metal Warrior 3’s block-number coordinates). https://codebase64.net/doku.php?id=base:rant4
  • Commodore 64 Programmer’s Reference Guide (Commodore Business Machines, 1982), p. 103: a character set of 256 characters of 8 bytes, “256*8=2K bytes of memory”.
  • Achim, “Decoding 4x4 tiles”, Codebase64 wiki (web, secondary): colour per tile against colour per character. https://codebase64.net/doku.php?id=base:decoding_tile_based_maps

See also

Checked. Verified against primary sources and signed off by a person.