Webtile includes a full CPC sprite editor alongside its tilemap editor. Sprites are stored as Firestore documents in aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/johnlobo/webtile/llms.txt
Use this file to discover all available pages before exploring further.
sprites subcollection under a project, and share the same Firebase Auth identity as the rest of your work. Each sprite captures everything the Amstrad CPC hardware needs to display it: a video mode, an ink palette mapping CPC hardware colour indices to ink slots, and one or more frames of pixel data expressed as ink indices.
Firestore location
Sprite documents live at:Sprite document fields
| Field | Type | Description |
|---|---|---|
name | string | Human-readable sprite name shown in the SPRITES menu. |
videoMode | number | CPC video mode: 0, 1, or 2. Controls colour depth and pixels-per-byte encoding. |
width | number | Sprite canvas width in sprite pixels. |
height | number | Sprite canvas height in sprite pixels. |
palette | number[] | Array of CPC hardware colour indices, one per ink slot. Length is determined by the video mode (16, 4, or 2 entries). |
frames | Array<{ pixels: number[] }> | Array of frame objects. Each frame stores a flat array of ink indices, one per pixel, in row-major order. |
createdAt | Timestamp | Firestore server timestamp set when the sprite is first created. |
updatedAt | Timestamp | Firestore server timestamp refreshed on every save. |
CPC video modes
The Amstrad CPC hardware supports three video modes that trade colour depth for horizontal resolution. Webtile honours these constraints in both the editor and the binary export.Mode 0
16 colours
2 pixels per byte (interleaved bit planes).
Default palette indices:
2 pixels per byte (interleaved bit planes).
Default palette indices:
[0, 26, 6, 18, 3, 11, 24, 15, 8, 20, 4, 2, 21, 5, 16, 13]Mode 1
4 colours
4 pixels per byte (interleaved bit planes).
Default palette indices:
4 pixels per byte (interleaved bit planes).
Default palette indices:
[0, 26, 6, 18]Mode 2
2 colours
8 pixels per byte (1-bit, simple).
Default palette indices:
8 pixels per byte (1-bit, simple).
Default palette indices:
[0, 26]palette array and the valid range of non-transparent ink indices — is determined entirely by the video mode chosen at sprite creation time.
Default palettes
When a new sprite is created,spriteService.js seeds the palette field from DEFAULT_PALETTES, a lookup keyed by video mode:
.pal file.
Ink indices and transparency
Pixel data in every frame is stored as a flat array of ink indices, not raw colours. An ink index is a zero-based slot number into the sprite’spalette array. The editor renders ink n by looking up palette[n] and mapping it to the corresponding CPC hardware RGB value.
Ink index 0 is always transparent. Pixels set to ink 0 are rendered as a checkerboard in the editor and exported as fully transparent in PNG exports. When encoding to CPC hardware byte format, index 0 produces a mask bit that marks the pixel as background. You can assign any CPC colour to
palette[0]; that colour choice affects the CPC hardware output but does not change the transparency behaviour in the Webtile editor.Frames
Each sprite document contains aframes array. Every element is a plain object with a single pixels key holding the flat ink-index array for that frame:
width × height. Frames are displayed as a strip in the right sidebar of the sprite editor. You can add or delete frames from the strip, and the built-in animation player cycles through them so you can preview motion without leaving the browser.
Listing vs. loading
listSprites returns summary objects only — id, name, videoMode, width, height, and updatedAt. The palette and frames fields (which can be large for multi-frame sprites) are not included in the listing. Full pixel data is only fetched when you explicitly open a sprite via loadSprite, which reads the complete document.
This two-stage approach keeps the SPRITES menu fast even for projects with many sprites.
Auto-save
Any pixel mutation in the sprite editor — including pencil strokes, flood fill, erase, paste, and flip operations — schedules an auto-save via a 1.5-second debounce. The save writesname, videoMode, width, height, palette, and frames to Firestore and updates updatedAt. The debounce is reset on every mutation, so rapid painting does not produce a burst of writes.
doubleWidth display
The sprite editor supports adoubleWidth toggle (keyboard shortcut D) that stretches each sprite pixel 2× horizontally. This simulates the aspect ratio of the Amstrad CPC’s Mode 0 display, where hardware pixels are twice as wide as they are tall. doubleWidth is a display-only setting stored in editor state; it does not alter the pixel data or the Firestore document.
PNG and palette import/export
PNG export
Renders the current frame at 1:1 resolution with a transparent background and downloads it as a PNG file.
PNG import
Scales an imported PNG to the sprite’s dimensions on an off-screen canvas, then quantises each pixel to the nearest ink slot in the current palette by Euclidean RGB distance. Pixels with alpha below 128 are mapped to ink 0 (transparent).
Palette export
Writes the current palette as a JASC-PAL
.pal file (JASC-PAL / 0100 / count / R G B per line).Palette import
Parses an imported JASC-PAL file and maps each RGB entry to the nearest of the 27 CPC hardware colours by Euclidean RGB distance.