Tilemap Editor Guide

The Tilemap Editor turns small, reusable graphics into level-building pieces. You edit the system's atomic tiles, assemble them into metatiles such as platforms or pickups, paint those metatiles into a map, and export the data for your game.

This guide covers the three supported tile workflows:

Not the Charset/Tile Editor. This tool edits map layouts — which tile IDs go where. The Charset/Tile Editor edits the 8 × 8 pictures themselves: the C64 charset glyphs and the Atari tile glyphs. Change a glyph there and every map cell that refers to it follows.

Before you begin

  1. Open a C64-family, NES or Atari 7800 project.
  2. Choose Tools → Tilemap Editor.
  3. Create a new tile map, or open an existing tile-map asset from the project explorer.
  4. Save regularly. In the desktop app, Save writes the tile map into the current project. A browser preview downloads a copy instead.

Tile maps live in the project's tiles/ folder and are listed in the manifest's assets.tilemaps array. The workshop keeps the map project separate from source code, so the same tile definitions can be reused by more than one game screen or include file.

Choose the right workflow

System Atomic tile Metatile Exported data
C64 An 8 × 8 glyph from the selected C64 charset A rectangle of charset glyphs, with collision and gameplay metadata Map, metatile definitions, collision, and gameplay roles
NES An 8 × 8 2bpp CHR pattern A rectangle of CHR tiles with one attribute palette CHR pattern data, nametable map data, and attribute bytes
Atari 7800 An 8 × 8 one-bit MARIA tile, drawn in the editor None — stamps are authoring sugar, expanded to tile IDs as you paint Tile pictures, the project's eight palettes, one map per screen with its palette runs, a collision table, and markers

C64 and NES paint with metatile IDs rather than individual tiles. That is what makes a platform, wall, or pickup easy to place consistently across a scrolling level. The Atari 7800 has no metatile layer: its map is one byte per tile, because that is exactly what the hardware reads, and a stamp gives you the same convenience without a second layer to render.

Shared workflow

The six steps below are common to all three editors. Where they say metatile, an Atari 7800 map uses a stamp instead, and its screens are one fixed tile area — see the 7800 section for what that changes.

1. Create or open a tile map

Use New Tile Map to create a blank project. Give it a name that describes the screen or level, such as scrolling-background or cave-level-01.

Use Open to load a saved tile-map JSON file. Assets already inside the project can also be opened from the explorer.

2. Build the atomic tiles

Atomic tiles are the smallest graphics the target hardware can draw:

3. Assemble metatiles

Select Metatile editor, create a metatile, choose its size, and fill each cell with an atomic tile. A 2 × 2 metatile is a useful starting point for a platform or block, while 1 × 1 is useful for a small pickup or decorative mark.

4. Add game meaning

The map renderer only needs the graphic arrangement, but your game also needs to know what a placed piece means. Use the available collision, role, or palette fields to keep this information beside the art.

5. Paint the map

Switch to Map canvas, select a metatile, and click or drag across the grid. Use Erase to remove cells. The map grid can be larger than the visible game screen, which is useful for scrolling levels.

6. Save and export

Save preserves the editable tile-map project. Export creates a .cbi include containing target-ready data. Include that file from your game source and use the generated constants and data tables in your renderer.

C64 Tilemap Editor

How C64 tiles work

Yes: for a C64 character-mode tile map, the atomic tiles come from the charset you load.

The C64 Tilemap Editor does not copy a second set of pixels into every map cell. Instead, it stores references to charset glyph numbers. The selected charset supplies the 8 × 8 pixel shapes, while the tile map stores which glyphs belong in each metatile and where those metatiles are placed.

This gives the workflow a useful separation:

If you change the selected charset, the previews update to show that charset's glyphs. If you edit a glyph in the Charset/Tile Editor, any metatile using that glyph will use the updated shape when the charset is loaded by the game. Keep the charset path stable when you want the tile map to continue referring to the same source.

C64 steps

  1. In the Loaded charset selector, choose the charset that supplies the background art.
  2. Browse the 256 glyphs in the glyph palette. Select a glyph to use it in the metatile editor.
  3. Switch to Metatile editor and choose a size such as 2 × 2.
  4. Click metatile cells to place the selected glyph.
  5. Give the metatile a useful name, such as Grass Platform, Coin, or Goal Flag.
  6. Set Collision and Gameplay role.
  7. Switch to Map canvas, choose the metatile, and paint the level.

C64 collision choices are Empty, Solid, One way, Ladder, and Hazard. Gameplay roles include Platform, Wall, Floor, Ceiling, Pickup, Checkpoint, Spawn, Goal, and Decoration.

The default C64 map is 40 × 25 metatiles, matching a standard character-mode screen when using 1 × 1 metatiles. Wider or taller maps are appropriate for scrolling games; the exported map remains a data source that your scrolling code can read as the camera moves.

C64 export

The C64 include contains the metatile arrangements, map values, collision values, and gameplay-role values. Map cells refer to metatiles, and metatile cells refer to glyph numbers from the selected charset.

After exporting, include the generated .cbi file in the game source. Use its constants and tables when drawing the visible map and when deciding whether the player can stand on, climb, collect, or collide with a placed piece.

NES Tilemap Editor

How NES tiles work

NES background graphics are stored as 8 × 8 CHR patterns. Each pixel has one of four values, called 2bpp values 0 through 3; those values are the two CHR bitplanes, not fixed colours. The workshop presents 256 editable CHR patterns, the complete 64-entry NES PPU colour table, and four editable background sub-palettes.

The NES workflow has three layers:

  1. CHR tile editor — edit the 8 × 8 pattern.
  2. Metatile editor — arrange CHR tiles into a reusable piece and choose its attribute palette.
  3. Map canvas — place metatiles across the background map.

NES steps

  1. Open the CHR tile editor tab and select a pattern from the CHR palette.
  2. Choose pixel value 0, 1, 2, or 3, then click or drag over the 8 × 8 grid. The selected value sets the two bitplane bits in the CHR data.
  3. Switch to Metatile editor and choose the CHR tile for each cell.
  4. In Background palettes, choose any NES PPU colour index for each palette slot. Colour 0 is the universal background colour shared by all four palettes.
  5. Set the metatile's Attribute palette to palette 0, 1, 2, or 3.
  6. Switch to Map canvas, select the metatile, and paint the background.
  7. Set the map width and height in Map settings. NES maps may be up to 256 metatiles wide and 120 metatiles high.

The default NES map is 32 × 30 metatiles, which corresponds to one 256 × 240 nametable-sized screen when each metatile is 1 × 1. For a scrolling background, increase the width so the map extends beyond the first screen.

CHR range and sprites

The number of CHR patterns included in the exported CHR data is stored in the project, defaulting to 64 tiles ($00–$3F). There is no editor control for it: it changes only when you load a map project whose own chrStart/count says otherwise (and a map imported with a non-zero chrStart is re-saved from zero), so treat the range as fixed by the file you started from.

Keep the background range separate from the sprite range. The current Scroll Demo uses background tiles $00–$3F and sprites from $60, leaving a gap between them. If a metatile uses a tile outside the exported range, move that artwork into the exported background range or start from a project whose stored count is larger.

NES export

The NES include contains:

The export is the data source for your renderer. It does not automatically stream the map into the PPU or replace a project's existing TILE_FOR_WORLD logic. Your scrolling code still needs to copy the appropriate map values into nametable memory and update the attribute table as new columns or rows enter the camera view.

For a horizontal scrolling game, a typical flow is:

  1. Include the generated tile-map .cbi file.
  2. Call its generated CHR-loading procedure during setup.
  3. Copy the first 32 × 30 visible map cells into the nametable.
  4. As the camera advances, read the next map column or columns and stream them into the off-screen side of the nametable.
  5. Update the corresponding attribute bytes so the new area uses the metatile palettes selected in the workshop.

Atari 7800 Tilemap Editor

Opened from Tools → Tilemap Editor in an Atari 7800 project. This editor is not a port of the C64 or NES one: the hardware has no character generator and no tile table, so the model is smaller and stricter.

What a 7800 tile is

One screen is the tile area the display gives you: 40 × 24 tiles, each 8 × 8 pixels, one bit per pixel, in MARIA_320A. A tile shows one colour. It cannot carry that colour itself, so the display list colours it a row at a time (below).

Tile 0 is blank and cannot be drawn on. An undefined slot in the character bank reads as background, and that is what makes an empty map cell empty. A screen can use up to 256 tiles, numbered from that blank tile.

Palettes belong to the project

The chip has eight 3-colour palettes, and both tiles and sprites read them, so the table is one value for the whole project: it lives in the project manifest (<project>.crusty, under atari7800ColourRam — eight rows of a shared background entry plus three palette colours, with the older atari7800Palettes still read) and the Sprite Workshop edits the same table. Change a colour in either editor and every 7800 asset in the project is stamped with it.

A 320A tile shows entry 2 — the middle of the three. Entries 1 and 3 are still stored and exported because a 160-mode object uses all three, so put the colour you care about in the middle slot. Palette 0 is normally the tile and text colour for the rest of the screen; leave it alone unless you mean to change everything using it.

Palette runs, and the 26-byte row

A row of the map is not one palette: it is a sequence of runs, and the editor works them out from the palettes your tiles ask for. This is the number that decides whether a screen fits, because a row of the display list holds 26 bytes for tile and sprite objects together:

The Budget panel reports the busiest row, its byte cost and the sprite headroom left, and the canvas marks any row that needs more than one run with a colour band above it. Rows of a single palette stay clean.

Blank cells count towards the runs like any other cell, which is the one non-obvious rule here: the blank tile's palette decides the run structure of every row it appears in. Two consequences:

Screens, stamps and markers

7800 export

Export writes one .cbi include into the project's src/. Its symbols are named after the include file, as the sprite include's are — lunar-levels-tilemap.cbi gives LUNAR_LEVELS_TILEMAP_INSTALL and LUNAR_LEVELS_TILEMAP_LEVEL_1_SHOW — while the tile constants come from the asset's own name.

It carries the tile pictures as CONST glyphs bound with TILE_DEFINE, the eight palettes as data with an INSTALL procedure, one map per screen with its palette runs and marker table, and a SHOW_<SCREEN> procedure per screen. A game needs:

@OPTION TILE_ACTIVE_COUNT 6          ' the number the include reports
@INCLUDE "my-map-tilemap.cbi"

PROC MAIN
    DISPLAY MARIA_320A
    TILE_BEGIN 1, 1
    MY_MAP_TILEMAP_INSTALL            ' palettes + tile bank, once
    MY_MAP_TILEMAP_LEVEL_1_SHOW       ' runs + map for that screen
ENDPROC

The include cannot set a compile option, so TILE_ACTIVE_COUNT is yours to set, and it must cover every tile ID the bank uses.

One writer of the palette registers. If the program also includes the Sprite Workshop's output, call the tile map's INSTALL and not the sprite include's <INCLUDE>_SET_PALETTES: two loaders write the same eight registers, and the sprite one writes its own three entries for every palette, so whichever runs last decides the colours.

What the 7800 editor does not do

Practical design advice

Troubleshooting

C64 previews are blank or incorrect

Choose a valid source in Loaded charset. The tile map needs a C64 charset for its glyph previews. If the art itself is wrong, open the source charset in the Charset/Tile Editor and check the glyph there.

NES art looks wrong after export

Check that every CHR tile used by a metatile is inside the range the project stores for exported CHR (64 patterns by default). Also confirm that the game uploads the generated CHR data at the exported CHR start, writes the exported PALETTE_DATA bytes to $3F00, and interprets the map as metatile IDs rather than raw CHR IDs.

NES colours change in large blocks

That is normally an attribute-table issue. The NES applies palette choices to attribute quadrants, not to every individual tile. Keep neighbouring artwork compatible with the palette boundaries, or split the design into metatiles whose palette transitions line up with the map's attribute grid.

A 7800 tile shows one colour instead of the three in its palette

That is the mode, not a bug. A 320A tile is one bit per pixel, and MARIA maps a lit pixel to entry 2 — the middle colour — of the palette the tile selects. Entries 1 and 3 are for 160-mode objects. Put the colour you want in the middle slot, and use a different palette rather than a different entry when you want another colour on a 320A screen.

A 7800 row's colours look wrong, or the budget panel flags a row

Rows, not tiles, carry colour on the 7800: the editor splits each row into palette runs and a row has 26 bytes of display list. A flagged row needs more runs than fit. Either make the tiles in it agree on a palette, or move the odd tiles to a different row. Remember that blank cells count too — the blank tile's palette decides the run structure of every row it appears in.

7800 tile colours and sprite colours fight each other

Two palette loaders are running. The sprite include's <INCLUDE>_SET_PALETTES and the tile map's INSTALL write the same eight registers, and the sprite one flattens every entry to the middle colour. Call the tile map's INSTALL and not the sprite loader.

The map is saved but I cannot find it

In the desktop app, look under the project's tiles/ folder. In a browser preview, Save downloads the project file; import that file into the desktop project when you want it to appear in the explorer.

My scrolling level only shows the first screen

Make the map wider than 32 NES metatiles, include the exported map data, and add the streaming step to the scrolling code. The workshop creates and exports the level data; the game code remains responsible for moving that data into the PPU as the camera advances.

The 7800 build stops with LEVEL_GROUND_1 is read before it is introduced

A game that kept its terrain as a height table (a value per column) alongside a 7800 tile map has had that table deleted or moved below the procedure that reads it. A tile map is drawing data only: it carries no collision for your game to fall back on, so a height table used by the collision test has to stay in the source and stay above its readers.

A 7800 screen is blank after export

Three things have to be true: @OPTION TILE_ACTIVE_COUNT must be set to the bank size the include reports, the include's INSTALL must be called once before any screen, and the screen itself is drawn by its SHOW procedure. Also check tile 0: it is deliberately never defined, so anything painted with it is background by design.

Next step

For an Atari 7800 screen, create a map, make the small bank a terrain game needs (a blank tile, a ground tile, the two or three tiles that matter), paint one 40 × 24 screen, watch the Budget panel read 10 of 26 bytes per row, add a marker or two, export the include, and call INSTALL then SHOW from your game.

For the NES scrolling demo, create a scrolling-background map, keep its background CHR range at $00–$3F, build a few 2 × 2 metatiles, make the map wider than one screen, export the include, and wire its CHR loader and map/attribute tables into the existing scroll renderer.