Map Editor
What This Tool Is
The map editor is a standalone popup app launched from the main content editor. It is not a thin form field sitting on top of map JSON. It owns its own state, controls, render loop, history stack, and save workflow, then syncs its results back into the host editor through API writes and postMessage events.
Menu Bar
Undo, redo, save, quick layer selection, and theme switching live here. This is the stable command layer.
Tools
The left tool panel hosts Information, Maps, History, Instances, Tiles, Layers, and prototype placement tabs.
Canvas
The main viewport is a tile-grid world with snapping, drag placement, context menus, zoom, pan, selection, and the minimap drawer.
Terminology and Mental Model
Naming
- Menu Bar - the top command strip.
- Tools - the left-side panel with tabs and lists.
- Canvas - the world viewport where tiles and instances are edited.
Authored entities
- Tile - a sprite-backed paintable map cell resource.
- Template - a reusable instance source used like a stamp.
- Instance - a placed or unplaced map-local entity created from a template by value, not by live linkage.
Layer numbering
Internal layer 0 is the anchored Background. The first user-facing non-background
paint layer is displayed as Layer 0, because its internal id is 1.
In short: Background is special, anchored at the bottom, and every other displayed layer name is offset by one.
Ownership boundary
- The host editor owns dataset loading, popup launch, and background refresh after save.
- The popup editor owns editing state, rendering, history, drag logic, and the final composed save payload.
Core Principles
Edit local, save explicit
The popup mutates local runtime state first. Nothing is persisted until Save writes maps and NPCs back through the API.
History is per map
Undo and redo belong to the active map, not the whole app. Branches are truncated if you edit after undoing.
Templates are stamps
Selecting a template keeps stamp mode active so repeated clicks place new instances. A created instance is then independent.
Rendering is viewport-first
The editor draws only what the current viewport needs, then uses cached preview surfaces for pan, zoom, scroll, and the minimap.
Background is optimized
The editor can compress fully implicit background rows so huge maps do not waste JSON storing the same map-wide fill repeatedly.
Prototype tabs are honest
Monsters, Triggers, Paths, and Transitions already share selector and folder UI, but placement logic is intentionally not claimed yet.