Tilemap Editor - Technical Reference
Level: ⭐⭐⭐ Advanced
Quick Index
Engine Limits
⚠️ Limits Table
| Parameter | Limit | Description |
|---|---|---|
| MAX_TILE_WIDTH | 32 px | Maximum tile size |
| MAX_TILE_HEIGHT | 32 px | Maximum tile size |
| MAX_MAP_DIM | 255 tiles | Maximum map dimension |
| MAX_UNIQUE_TILES | 256 | Unique tiles per project |
| MAX_LAYERS | 8 | Layers per scene |
| MAX_SCREEN_WIDTH | 320 px | Screen width |
| MAX_SCREEN_HEIGHT | 240 px | Screen height |
| MAX_ANIMATIONS | 64 | Animations per scene |
| MAX_ANIMATION_FRAMES | 256 | Total frames |
| MIN_FRAME_COUNT | 1 | Minimum frames |
| MAX_FRAME_COUNT | 255 | Maximum frames |
| MIN_FRAME_DURATION | 1 | Minimum duration (ticks) |
| MAX_FRAME_DURATION | 255 | Maximum duration (ticks) |
Enforcement: Tile size, layer count, and animation limits are validated at edit time (project creation, add-layer, add-animation). At save, animations and player spawn positions are re-validated.
Screen Resolutions
Landscape:
- Maximum: 320×240 px
- Aspect ratio: 4:3
Portrait:
- Maximum: 240×320 px
- Aspect ratio: 3:4
File Formats
Project File
The editor stores projects in a single binary format (.pr32scene.bin, version 6). There is no human-readable JSON writer; the JSON object used inside the serializer only carries project metadata and per-tile attributes embedded in the binary container.
The "Use Binary Format" preference in File → Preferences only affects the file extension written to disk (.pr32scene.bin vs .pr32scene). The on-disk content is the same binary v6 container either way.
| Extension | Content |
|---|---|
.pr32scene.bin | Binary v6 container (default) |
.pr32scene | Legacy extension accepted for open; still binary v6 when saved |
Binary Format
The .pr32scene.bin format is a big-endian binary container (current version 6). Layout:
| Field | Size | Notes |
|---|---|---|
| MAGIC | 4 B | PR32 (big-endian 0x50523332) |
| VERSION | u16 | Current: 6 |
| FLAGS | u16 | Bit 0: COMPRESSION_ZLIB |
| tileSize | u8 | Tile size in px |
| reserved | 3 B | Padding |
| Metadata | u32 len + JSON | Project metadata (JSON embedded) |
| Tilesets | u16 count + entries | Per-tileset data |
| Scenes | u16 count + entries | Per-scene data; optional zlib-compressed layers; v6+: player spawn x/y |
The serializer targets byte-for-byte compatibility with the engine's binary project format (big-endian layout). Layer payloads can be zlib-compressed (flag bit 0).
Size & Performance
The binary format keeps projects compact and fast to load (single-format; there is no alternative JSON serialization to compare against).
Project Structure
File Structure
my_project/
├── my_project.pr32scene.bin # Project file (binary v6, default)
├── tile_flag_rules.json # Custom rules (optional)
└── assets/
└── tilesets/
├── tileset1.png
└── tileset2.pngThe file is stored as
.pr32scene.binby default. With "Use Binary Format" disabled it is written as.pr32sceneinstead (still binary v6 content). Only the extension changes.
Exported Files
output/
├── my_scene.h # Declarations + animations + palettes (multi-palette)
├── my_scene.cpp # Data (palettes, tiles, indices)
└── {namespace}_tilemap_palette.h # Shared palette (single palette mode)Animations are embedded in
my_scene.halongside their layer (<LAYER>_TILE_ANIMATIONS[]). There are no separate*_animations.h/.cppfiles.
Application Architecture
The Tilemap Editor is a native desktop application built with C++17 on SDL2 + ImGui + OpenGL 3.3. There is no Python/Tkinter runtime. The editor is distributed as a compiled binary within the Tool Suite.
Core Services
The editor's logic is organized into the following internal services (C++):
| Service | File (source) | Responsibility |
|---|---|---|
| ProjectService | tools/tilemap_module/project_service.{h,cpp} | Create / load / save projects, validate project name, manage tile flag rules |
| BinarySerializer | tools/tilemap_module/binary_serializer.{h,cpp} | Read/write .pr32scene.bin (v6, big-endian, optional zlib compression) |
| HistoryManager | tools/tilemap_module/history_manager.{h,cpp} | Bounded (100 entries) undo/redo stack with optional compression |
| AnimationValidator | tools/tilemap_module/core/animation_validator.{h,cpp} | Validate animations against engine limits (bounds, overlap, count, duration) |
| ExporterService | tools/tilemap_module/exporter_service.{h,cpp} | Gate C++ export behind a valid license; coordinate the native export pipeline |
| ExportOrchestrator | tools/tilemap_module/native_export/export_orchestrator.{h,cpp} | Multi-palette detection, image processing, palette analysis, tile dedup, C++ code generation |
| AutosaveService | tools/tilemap_module/autosave_service.{h,cpp} | Interval-based autosave |
| ToolManager | tools/tilemap_module/tool_manager.{h,cpp} | Active tool registry (Brush, Eraser, Rectangle, Pan, Pipette, Attribute, Anim) |
Note: These services are internal C++ modules compiled into the Tool Suite binary. They are not a public Python API and cannot be imported by external scripts. Automation should use the file formats described below or the external
pr32-sprite-compilerCLI (Sprite Compiler module).
Runtime Environment
| Item | Detail |
|---|---|
| Language / standard | C++17 |
| GUI framework | Dear ImGui (v1.92.8) |
| Windowing / GPU | SDL2 + OpenGL 3.3 (single window, DockSpace layout) |
| JSON | nlohmann/json v3.11.3 |
| SVG rasterization | lunasvg v3.1.0 |
| Native file pickers | portable-file-dialogs |
| Compression | zlib (.pr32scene.bin layer payloads) |
| Crypto | OpenSSL (SHA-256 checksum + AES-256-CBC) |
| Build system | CMake ≥ 3.20 |
C++ Export
Requirements
⚠️ Important: C++ export requires a valid license (Ed25519 v3 key, machine-bound). See License & Activation for full details.
- Without license, the Upgrade Required dialog appears when attempting to export
- Other features work without license
Export Options
| Option | Description | Recommended |
|---|---|---|
| C++ Namespace | Namespace for code | Project name |
| Color Depth (BPP) | Read-only; auto-detected (1/2/4) | Auto-detect |
| Store in Flash (ESP32) | Save to PROGMEM | ✅ Always |
| Legacy Format | Without Flash attributes | Compatibility only |
Export Mode
| Mode | Trigger | Generated |
|---|---|---|
| Single Palette | All layers use P0 | Shared palette |
| Multi-Palette | Any layer P1-P7 | Per-slot palettes |
Generated Files
Single Palette
// level1.h
static const uint16_t TILEMAP_PALETTE_DATA[] = { /* RGB565 */ };
extern pixelroot32::graphics::TileMap4bpp layer_foreground;
// level1.cpp
static const pixelroot32::graphics::Sprite4bpp TILESET_SPRITES[] = { /* tiles */ };
static const uint8_t LAYER_FOREGROUND_INDICES[] = { /* indices */ };The palette array is declared in the header; tiles and index data live in the
.cpp. The layer struct isTileMap,TileMap2bpp, orTileMap4bppdepending on the auto-detected BPP.
Multi-Palette
// level1.h
static const uint16_t PLATFORMS_PALETTE[16] = { /* RGB565 */ };
static const uint16_t STAIRS_PALETTE[16] = { /* RGB565 */ };
// level1.cpp
void init() {
setBackgroundCustomPaletteSlot(1, PLATFORMS_PALETTE);
setBackgroundCustomPaletteSlot(2, STAIRS_PALETTE);
}Engine Integration
Single Palette:
#include "level1.h"
level1::init();
renderer.drawTileMap(level1::layer_foreground, x, y);Multi-Palette:
#include "level1.h"
level1::init(); // Registers palettes
renderer.drawTileMap(level1::background, 0, 0);
renderer.drawTileMap(level1::platforms, 0, 0);Attributes/Flags:
// Query attributes
const char* type = level1::get_tile_attribute(0, x, y, "type");
// Query flags
uint8_t flags = level1::getTileFlags(0, x, y); // layer index, x, y
if (flags & TILE_SOLID) { /* collision */ }Animations:
level1::getForegroundAnimManager().step();
renderer.drawTileMap(level1::layer_foreground, x, y);Each animated layer exposes a
<LayerName>AnimManager(). A legacygetAnimManager()alias maps to the Details layer when present.
Data Formats
Palette
- Format: RGB565
- Size: 16 colors max
- Index 0: Transparent (multi-bpp)
Tiles
| BPP | Per Row | Colors |
|---|---|---|
| 1 bpp | 1 byte | 2 |
| 2 bpp | 2 bytes | 4 |
| 4 bpp | 4 bytes | 16 |
Index Map
- 1 byte per cell (
uint8_t) - Value -1 (editor) = Index 0 (export) = Empty
BPP Auto-Detection
| Real Colors (excl. transparency) | BPP | Maximum |
|---|---|---|
| ≤ 1 | 1 bpp | 2 |
| 2-4 total slots (incl. optional transparency) | 2 bpp | 4 |
| otherwise | 4 bpp | 16 |
totalSlots = realColors + (hasTransparency ? 1 : 0). 1bpp requires ≤1 real color; 2bpp when total slots ≤ 4; otherwise 4bpp.
Compatibility
Runtime
The Tilemap Editor is distributed as a pre-built native binary (part of the Tool Suite). No Python, Tkinter, or Pillow installation is required.
| Requirement | Detail |
|---|---|
| Operating system | Windows, Linux, macOS (per release) |
| GPU / Windowing | OpenGL 3.3 capable GPU; SDL2-based window |
| Storage | ~tens of MB for the app + generated assets |
| License | A valid Tool Suite license is required for C++ export |
Target Hardware
- ESP32 (PixelRoot32 engine)
- Flash: 4MB minimum recommended
- RAM: 520KB minimum
Glossary
| Term | Definition |
|---|---|
| ENGINE_LIMITS | Engine limit constants |
| ProjectModel | Project class |
| SceneModel | Scene model |
| LayerModel | Layer model |
| TileAnimation | Tile animation model |
| RGB565 | Color format (5+6+5 bits) |
| BPP | Bits per pixel |
| PROGMEM | ESP32 flash storage |
| Sprite4bpp | 4bpp sprite |
| TileMap | Exported tilemap structure |
Related Guides
- Quick Start - 5 minute guide
- Usage Guide - Essential features
- Advanced Guide - Advanced features
