What to design. Each character is 5 frames at
16×16 pixels. The Saturn engine picks one frame per
render based on the player's facing direction (see
Player::Draw in src/Entities/Player.hpp):
- frame 0: facing east-ish (engine angle 66°–111°). Mirror-flipped to face west on the engine side — you only draw one side.
- frame 1: 3/4-view (engine angles 21°–66° and 111°–156°). Used for both NE and SE-ish angles via mirror.
- frame 2: head-on view (engine angles 336°–21° / 156°–201°). Used for both north and south facings via mirror.
- frame 3: opposite 3/4-view (engine angles 201°–256° / 291°–336°).
- frame 4: rear-quadrant view (engine angle 256°–291°).
The cleanest reference is the built-in Char 0 (catgirl)
sprites in the grid above — open it to see exactly what
each frame looks like. The template downloads default to
those sprites so you can paint over them.
Template format. One
custom character = one 1280×256 RGBA PNG (5 frames
horizontal, 256×256 per cell at 16× scale). Each Saturn
pixel is rendered as a 16×16 block so the download looks
crisp in any image viewer. The blank template starts
from the catgirl sprites so you have a real starting
point — paint over them.
Saturn pixel format.
VDP1 stores sprites in ARGB-1555 (5 bits each for R, G,
B; 1 bit for alpha). Your 8-bit-per-channel pixels are
quantized on import (top 5 bits kept). Alpha < 128 →
fully transparent; alpha ≥ 128 → fully opaque. There's
no alpha blending on hardware — pixels are either there
or they're not.
Editor recommendations.
Aseprite is ideal for pixel art. GIMP, Photoshop, or
Paint.NET also work. Disable smoothing / anti-aliasing
and use a 1-pixel pencil tool (or paint-bucket on the
16×16 blocks of the upscaled template). On import the
server samples one corner of each block to recover the
Saturn pixel, so any per-pixel anti-aliasing will be
sampled away unpredictably.
Originals are always
preserved. The built-in CHARS.PAK on
disk is never modified. Built-in characters are
read-only in the editor — clicking one shows
an enlarged preview plus a Clone button that
creates a new editable custom character pre-populated
with that built-in's frames. Custom characters can also
be cloned from each other.
In-game delivery (work in
progress). Custom characters live as JSON files
under webapp/custom_characters/ on the
editor server. Phase B (server) added the protocol
opcodes 0xC0..0xC6 and the listing/streaming
handlers. Phase C (Saturn-side download flow) and Phase
D (lobby integration + remote-player fallback) ship in
future builds — the editor catalog you build today will
be ready for those.