The Charset/Tile Editor is one editor with two sides, chosen for you by the active build target. On a Commodore 64, C128, or Plus/4 target its heading reads Charset Editor and it draws the character set a program uses for text and, with the Tilemap Editor, for character-mode graphics: all 256 glyphs of character memory, each 8 × 8 pixels, saved as an editable project or exported as a crustyBASIC include your program can install. On an Atari 8-bit or Atari 5200 target its heading reads Tile Editor and it draws 8 × 8 one-bit tile glyphs, saved as .atari8tiles.json in tiles/ and exported as a glyph array plus a _DEFINE_TILES helper.
This guide covers the editor on its own. For building a level out of those glyphs, see Help → Tilemap Editor Guide. The Atari Tile Editor section below covers the Atari side.
The heading follows the target in the active source file, and the side is not switchable by hand:
| Active target | Heading | What it edits | Saved as |
|---|---|---|---|
| C64, C128, Plus/4 | Charset Editor | A C64 character set: all 256 glyphs, standard or multicolour | .c64charset.json |
| Atari 8-bit, Atari 5200 | Tile Editor | 8 × 8 one-bit tile glyphs | .atari8tiles.json (in tiles/) |
| Any other target | The Tools entry is disabled | — | — |
A few words are used precisely throughout these docs: a glyph is the 8 × 8 shape data, a tile is a game-level ID that pairs a glyph with a colour, a tileset is a collection of glyphs, and a tilemap is the layout of tile IDs. The Tilemap Editor places tile IDs; this editor draws the glyphs they refer to.
.64c binary or .c64charset.json project.Charsets live in the project's charsets/ folder and are listed in the manifest's assets.charsets array. On its C64 side the editor is a C64-family tool: the palette it writes names VIC-II colour registers, so the same asset is expected on a C128 or Plus/4 as on a C64. There is no charset editor for NES (its characters are CHR patterns inside the NES Tilemap Editor), for Apple II, or for the other targets. On the Atari 8-bit and 5200 the same tool opens as the tile editor described below, and the Tools menu keeps the entry disabled for every target that is neither the C64 family nor those two.
The editor's title bar carries the open charset's own file name, so the asset you are drawing is never in doubt, and opening a charset seeds the Export dialog's file name from it:
| Open file | Export file | Symbols the include defines |
|---|---|---|
charsets/arabian_nights.c64charset.json |
arabian-nights.cbi |
C64_CHARSET_ARABIAN_NIGHTS, C64_CHARSET_ARABIAN_NIGHTS_INSTALL_CHARSET |
charsets/caverns.c64charset.json |
caverns.cbi |
C64_CHARSET_CAVERNS, C64_CHARSET_CAVERNS_INSTALL_CHARSET |
| A new or unopened charset | charset.cbi |
C64_CHARSET_CHARSET, C64_CHARSET_CHARSET_INSTALL_CHARSET |
The file name is the only naming input: the .c64charset.json project does not store a title, so the names a program writes are derived from the include file. Renaming the charset file and reopening it therefore renames the symbols. Type over the file name in the Export dialog when you want the array called something else — the help line under the field shows the symbols the current name produces before you export.
Choose the mode before you draw, because the two are different shapes and converting between them loses information:
| Standard | Multicolour | |
|---|---|---|
| Shape | 8 × 8 pixels | 4 × 8 fat pixels |
| Colours | Two: glyph colour and background | Four: background, colour 1, colour 2, and the cell colour |
| Brush values | Lit or clear | Background, colour 1, colour 2, cell colour |
| Palette editor | Not needed — the two colours come from the screen registers | Screen palette, saved with the project |
Switching mode converts all 256 glyphs at once, and there is no undo. Standard to multicolour keeps only whether each pixel pair was lit; multicolour to standard loses which of colours 1, 2, or 3 a cell used. Decide first, then draw.
$hex, or 0x values separated by commas or spaces and leave the field to apply them. Copy glyph bytes puts the same text on the clipboard for use in source.src/ that may be replaced, and the glyph range. The name is seeded from the charset's own file, and the help line under it shows the symbols that name will define. Choosing one of the existing includes also fills in the range that include installs, so replacing your own output reproduces it rather than re-basing its glyphs..c64charset.json in charsets/.Exporting over one of the project's own includes starts from the range that include already installs, read from the file, and the dialog says which include the numbers came from. That is what makes a re-export reproduce the include: the range decides which glyphs are written and which character codes they are stamped over, so inheriting it means an asset whose art sits at 96..132, or a tileset whose game code addresses the array from its first glyph, comes back as it was. Change the numbers and you move the glyphs deliberately.
A new include starts at the plain default: glyphs 64 to 127 on the C64, 0 to 15 on the Atari. That default exists for a reason: a charset include overwrites what it installs, and exporting all 256 glyphs would replace the letters and digits the ROM font still supplies. Exporting only the range you actually redrew keeps the ROM font for everything else, which is usually both smaller and safer. A font that replaces the whole character set — a demo gallery, say — wants the full 0..255.
The generated include starts with the asset marker, then one packed array, then C64_CHARSET_<NAME>_INSTALL_CHARSET, which:
CHARSET_COPY_DEFAULT to start from the machine's own font, andCHARSET_INSTALL_RANGE call.The glyphs live in a single array, CONST C64_CHARSET_<NAME>(<count × 8 - 1>) AS U8, eight bytes per glyph in character-code order. It is one array rather than one CONST per glyph because CHARSET_DEFINE is inlined at each call site: a constant and a call per glyph costs about 16 bytes of 6502 code for every 8 bytes of glyph data, which for a full font is over 4 KB of code per charset. On the C64 the runtime's charset buffer sits at $5000, and a handful of full fonts exported that way grows a program straight through its own font buffer, so the install overwrites the program. The packed array and one range call is 2 KB of data and a few bytes of code, whatever the size of the range.
The array is written sixteen bytes to a line, wrapped across lines. The compiler joins a wrapped constant back into one array, so the layout is only there to keep the file readable and diffable.
A multicolour charset also gets _COLOR_BACKGROUND, _COLOR_1, _COLOR_2, and _COLOR_CELL constants plus palette and colour-RAM routines, because those colours have to be written to the VIC-II as well. A standard charset emits no palette block — its two colours come from the screen registers your program already sets.
Include the generated .cbi from your game source and call the install routine during setup, for example C64_CHARSET_CAVERNS_INSTALL_CHARSET.
Four routes bring a charset in, and all four decode it the same way:
| Route | What it does |
|---|---|
| Open charset (header) | Reads a file you pick and loads it into the editor. |
| Import charset file (header) | The same file system import the drag-and-drop does: the picked file is copied into charsets/, recorded in the manifest's assets.charsets, and opened. Use this to bring a charset in from outside the project. |
| Drop a file on the editor | The desktop build imports it exactly like the Import button; in the browser preview it is parsed in place. A drop anywhere else on the window does the same. |
| Double-click in the Explorer | Opens a charset asset that is already in the project. |
| What | How it is handled |
|---|---|
.64c binary dump |
The two-byte load address is read and shown, then eight bytes per glyph are decoded. A shorter set is padded to 256 glyphs with blanks. |
.c64charset.json, .c64charset, .charset.json, .charset |
An editable project; it must contain exactly 256 glyphs. |
A binary is converted into an editable project rather than being edited in place, and the load address is not kept in the project. Importing from the Explorer or by dropping a file always decodes a binary as standard, while the editor's own Open charset decodes it in the mode you are currently in — so if you are importing a multicolour dump, set the mode first.
The parser reports three specific problems rather than failing silently: a file with no room for even one glyph, data that is not a whole number of eight-byte records, and more than 256 glyphs. A project that does not match the expected shape is reported as an invalid charset project.
There is no image import here. Glyphs are drawn, converted from a .64c, or generated as data.
On the Atari 8-bit and Atari 5200 targets the tool opens with the heading Tile Editor. It edits tile glyphs — the 8 × 8 pictures a game binds to tile IDs — rather than a text character set.
The drawing tools work as described above: pick a brush value, click or drag on the grid, and use Fill, Clear glyph, and Copy glyph. Save writes the set as .atari8tiles.json in the project's tiles/ folder, where the Explorer groups it with the tile maps. The project format is crustystudio-atari8-tiles and it carries a target field, so the editor knows which machine the asset belongs to. An asset saved under the earlier .atari8charset.json name and format still opens, and re-saving it keeps its current name. There is no PNG or other image import here, but a raw .64c glyph dump can be imported because its layout matches the Atari side exactly: eight bytes per glyph, one bit per pixel. Tile glyphs are drawn, imported from a .64c or a saved project, or generated as data.
Export writes a .cbi include into the project's src/ folder. It contains one packed glyph array — eight bytes per glyph, one bit per pixel — plus a ..._DEFINE_TILES(FIRST_TILE AS U8) PROC that emits TILE_DEFINE FIRST_TILE + n, ADDR <ARRAY> + n*8 for each glyph in the set.
There is deliberately no charset-install code and no palette code in an Atari export. On the Atari a tile's colour does not come from the glyph bytes: it is set in the game with TILE_COLOR id, fg, bg. The glyph array only says which pixels are lit, so the same glyph can be drawn in different colours at different tile IDs.
Glyph order must match tile-ID order. Glyph n in the asset is the glyph that _DEFINE_TILES binds to FIRST_TILE + n, so keep the pictures in the order the game expects.
A charset include records the machine it was generated for in its @crusty-asset marker (target=c64 or target=atari8), and an export refuses to replace a generated include that belongs to a different machine.
The Atari tile path is used with @OPTION TILE_BACKEND TILE_BITMAP and the TILE_DEFINE, TILE_COLOR, and TILE_PLOT calls. A small game might include the exported set and define its tiles like this:
@OPTION TILE_BACKEND TILE_BITMAP
@INCLUDE "player-tiles.cbi"
CONST PLAYER_TILE = 1
TILE_BEGIN 1, 1
<ARRAY>_DEFINE_TILES PLAYER_TILE
TILE_COLOR PLAYER_TILE + 0, 14, 0
TILE_COLOR PLAYER_TILE + 1, 12, 0
The @INCLUDE brings in the glyph array and the _DEFINE_TILES procedure, TILE_BEGIN 1, 1 starts the tile area the game will use, <ARRAY>_DEFINE_TILES PLAYER_TILE binds the set's glyphs to consecutive tile IDs starting at PLAYER_TILE, and each TILE_COLOR line gives one of those tiles its foreground and background colour. Nothing in the include writes a colour; the TILE_COLOR lines are what put colour on the screen.
| Target | Charset/Tile Editor |
|---|---|
c64, c128, plus4 |
Available as the Charset Editor. All three use the same C64-addressed output. |
atari800, atari5200 |
Available as the Tile Editor. 8 × 8 one-bit tile glyphs, exported as a glyph array plus a _DEFINE_TILES helper. |
vic20, mega65 |
Not offered, even though both are Commodore machines with their own character memory. |
nes |
Not offered. NES characters are 2bpp CHR patterns, edited in the NES Tilemap Editor. |
apple2 and the rest |
Not offered. |
Opening an existing charset or tile-glyph asset from the Explorer works regardless of the current target, because the saved asset records its own platform. A .c64charset.json asset stays C64-family data, and an .atari8tiles.json asset stays Atari data.
Standard-mode glyph values are shown through the project's palette, and a neutral default maps the lit colour to a dark grey. The brush swatch beside the tool list is a fixed amber for legibility. Switch to Multicolour, choose a brighter colour 1, and switch back if you want a different standard-mode appearance; the palette is kept across the mode change.
Check the warning under the Screen palette. A cell colour below 8 is stored by colour RAM but the VIC-II only shows it from 8 upwards; below that the cell is drawn as two-colour hi-res. Pick a colour from 8 to 15.
That is the generated-include check. Crusty Studio only replaces a .cbi that carries the @crusty-asset marker line with a matching kind; anything else is treated as hand-written source and left alone. A charset include also records the machine it was generated for (target=c64 or target=atari8), so an export refuses to replace a generated include that belongs to a different machine as well. Export to a different name, or remove the file yourself. The refusal is reported in Output, not in the editor.
A .64c decoded in the wrong mode is the usual cause. The editor's Open dialog decodes in the mode you are currently in; importing from the Explorer or by dropping always decodes as standard. Set the mode first, then import.
The project must contain exactly 256 glyphs, each 8 rows of 8 (standard) or 4 (multicolour) values in range. A hand-edited file with fewer glyphs will not load.
Draw a replacement for the glyphs your game actually uses — a cursor, a border, a HUD icon, or a set of glyphs for the Tilemap Editor — export only that range, include the result from main.cbs, and call the install routine at start-up. On the Atari side, bind the exported array to tile IDs with _DEFINE_TILES and give each tile its colour with TILE_COLOR.