5 KiB
Space Taxi level .dat format (STL2)
A small custom binary format that stLevelLoad() reads at scene
boot. Output files land in examples/spacetaxi/generated/levels/
(from romToLevel.py for the 24 canonical C64 levels, or from
mkstlevel for hand-authored levels in assets/levels/*.txt). The
build copies them under DATA/levels/levelNN.dat in the runtime
asset bundle. All multi-byte fields are little-endian. No
compression; ~2 KB per level.
| Offset | Type | Field |
|---|---|---|
| 0 | 4 bytes | magic S T L 2 |
| 4 | u8 | nameLen (0..23) |
| 5 | char[N] | name (no NUL; max 23 chars) |
| 5+N | u8 | tileBankId |
| ... | u8 | musicId (UNUSED -- C64 gameplay is silent; see VERIFIED.md) |
| ... | u8 | bgColor (palette slot) |
| ... | u8 | borderColor (palette slot, also HUD-band fill) |
| ... | u8 | taxiSpawnTileX |
| ... | u8 | taxiSpawnTileY |
| ... | u8 | xAccel (horizontal thrust magnitude / frame) |
| ... | u8 | yAccel (vertical thrust magnitude / frame) |
| ... | i8 | xGrav (constant horizontal accel; side-wind on levels P, U) |
| ... | i8 | yGrav (constant vertical accel; anti-gravity on level K = -7) |
| ... | u8 | bgColor1 ($D022, VIC multicolor -- UNUSED) |
| ... | u8 | bgColor2 ($D023, VIC multicolor -- UNUSED) |
| ... | u8 | bgColor3 ($D024, VIC multicolor -- UNUSED) |
| ... | u8 | spriteMc0 ($D025, sprite multicolor -- UNUSED) |
| ... | u8 | spriteMc1 ($D026, sprite multicolor -- UNUSED) |
| ... | u8 | sprite0Color ($D027, cab fallback color) |
| ... | u8 | sprite1Color ($D028, flame fallback color) |
| ... | u8 | padCount (0..10) |
| ... | pad[] | padCount * 4 bytes: letter, tileX, tileY, tileW |
| ... | u8 | fareCount (0..16) |
| ... | fare[] | fareCount * 2 bytes: spawnPad, destPad |
| ... | u8[40*25] | tilemap (row-major, full 25 rows) |
| ... | u8[40*25] | colormap (row-major, palette slot per cell) |
Notes:
xAccel/yAccel/xGrav/yGravmirror the C64 per-level templates at$7D8F-$7D96. Side-wind levels P (xGrav = +4) and U (+2); the anti-gravity level K (yGrav = -7) makes the cab drift upward without input. SeeVERIFIED.mdfor the emulator-traced extracts.musicIdis preserved for format symmetry only; the C64 original has no gameplay music (only title/score-screen jingles).- The five VIC multicolor fields are preserved so the .dat is a
faithful byte-for-byte capture of the C64
$7D00-$7D08block. The port renders in single-color mode and ignores them at runtime. - Pads are 4 bytes (letter + 3 tile coords); there is no patience
byte on fares -- Space Taxi proper has no patience timeout, and the
emulator trace at
$71CE/$7213confirmed the only gating is the player-selectable fare target at the title screen.
Tile-index conventions (in the tilemap byte)
Indexes 0..255 reference the level's active tile bank. Reserved ranges:
| Range | Meaning |
|---|---|
| 0 | empty (sky / interior space; non-solid) |
| 1..63 | solid (walls, ceilings, support structures) |
| 64..127 | landing-pad surfaces (also solid; pad collisions live here) |
| 128..255 | decorative non-solid (lights, signs, animation frames) |
The engine's isSolidAt() uses this convention. If you redesign a
tile bank, keep the indexing consistent so the physics keeps working
without changes.
Authoring pipeline
- Author a 256-tile (or smaller) tile sheet as an indexed PNG. Each
tile is 8x8 px. Arrange in a grid; the bank loader assumes row-
major, tile-index =
ty * tilesPerRow + tx. Drop the PNG atexamples/spacetaxi/assets/tiles/tbank<N>.png. - The Makefile bakes per-target via
tools/assetbake/assetbake.py --type tile --target <port> tbank<N>.png tbank<N>.tbk. Output lands inexamples/spacetaxi/generated/<port>/tiles/and is staged into the runtime tree atbuild/<port>/.../DATA/tiles/. - Author each level layout in a text editor or grid tool, save as a
.dat per this spec. The helper
examples/spacetaxi/mkstlevelconverts from a human-readable text grid to .dat. The 24 canonical C64 levels are emitted bystuff/spacetaxi/romToLevel.pydirectly from a raw VICE dump of the original .prg.
Naming
Use the original game's level names as the name field (uppercase
ASCII, max 23 chars). The HUD displays this at the bottom-right of
the screen.