docs(README): rewrite for v0.2 Rev 4 UI + drag-paint
This commit is contained in:
105
README.md
105
README.md
@@ -1,10 +1,16 @@
|
|||||||
# sporel-module-map-editor
|
# sporel-module-map-editor
|
||||||
|
|
||||||
Interactive map editor for v2 Sporel map files. Click-to-paint, vertical layer-chip overlay on the left edge, collapsible atlas+tile picker bottom-left.
|
Interactive map editor for Sporel `.map.json` files. v0.2 series ships
|
||||||
|
the Rev 4 UX architecture (see design paper
|
||||||
|
`design/2026-05-28-autotile-blob-styles-design.md` §11 in `sporel-meta`):
|
||||||
|
top toolbar with mode-switch + actions, right Layers side-panel, bottom
|
||||||
|
palette strip of material slot thumbnails, mouse drag-paint, and two
|
||||||
|
mutually-exclusive paint modes (Auto-Tile vs Direct).
|
||||||
|
|
||||||
## Run
|
## Run
|
||||||
|
|
||||||
Default — edit the module's in-place work map:
|
Default — edit the module's in-place work map (`maps/work.map.json`,
|
||||||
|
a 16×16 schema-v3 map bound to the `blob_rect_stone` material):
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bash scripts/run-map-editor.sh
|
bash scripts/run-map-editor.sh
|
||||||
@@ -16,31 +22,94 @@ With a target — copy a real map in, edit, copy back out:
|
|||||||
bash scripts/run-map-editor.sh ~/Projects/Sporel/sporel-modules/spine-prototype/maps/demo.map.json
|
bash scripts/run-map-editor.sh ~/Projects/Sporel/sporel-modules/spine-prototype/maps/demo.map.json
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Or via the install layer (per `install-reference.sh`):
|
||||||
|
|
||||||
|
```text
|
||||||
|
Doubleclick C:/Games/Sporel/bin/Sporel.exe → launcher → map-editor
|
||||||
|
```
|
||||||
|
|
||||||
## UI
|
## UI
|
||||||
|
|
||||||
- **Layer chips** (left edge, vertical): top-of-stack down. `Rf` at top toggles roof-edit mode; the other eight chips select the active layer.
|
- **Top toolbar** (full-width): `Auto-Tile`/`Direct` mode buttons (mutually
|
||||||
- **Left-click** = set active layer (or toggle roof mode)
|
exclusive, Tab toggles), `Save` (S), `Erase` (E), `Rotate` (R),
|
||||||
- **Right-click** = toggle layer visibility (Rf chip ignores right-click)
|
`Flip` (H), `Reset` (0), `Help` (I). Each button shows its hotkey
|
||||||
- **Atlas + tile picker** (bottom-left): collapsed chip shows the active tile. Click to expand; click again or outside to collapse.
|
label inline. The active mode is highlighted.
|
||||||
- **Status chip** (bottom-right): current mouse-cell coordinate plus a `*` when the map has unsaved changes.
|
- **Right Layers side-panel** (8 rows top-down: `canopy`, `upper_wall`,
|
||||||
|
`wall`, `lower_wall`, `topsurface`, `surface`, `subsurface`,
|
||||||
|
`foundation`). Per row: visibility eye + active marker + layer name.
|
||||||
|
- **Left-click name** → set active layer
|
||||||
|
- **Left-click eye** → toggle layer visibility
|
||||||
|
- **Right-click row** → also toggles visibility
|
||||||
|
- **Bottom palette strip**: 14 swatches (slots 1-14). Real tile
|
||||||
|
thumbnails rendered from the active atlas via
|
||||||
|
`maps.atlas_tile_uv`. Active slot has a gold border.
|
||||||
|
- **Left-click** → set active slot
|
||||||
|
- **Status chip** (bottom-left of palette band): mouse-cell, dirty flag
|
||||||
|
(`*` when unsaved), and current transform indicator
|
||||||
|
(`slot=N rot=N flip=N`) for Direct-mode awareness.
|
||||||
|
- **Auto-Tile-mode world overlay**: cell grid (1 px), vertex dots (4 px
|
||||||
|
squares), and a snapped-vertex highlight ring (green) at the nearest
|
||||||
|
vertex to the cursor.
|
||||||
|
- **Cheatsheet modal** (I): centered dim-overlay listing all hotkeys
|
||||||
|
+ LMB/RMB drag semantics.
|
||||||
|
|
||||||
|
## Modes
|
||||||
|
|
||||||
|
| Mode | LMB on canvas | RMB on canvas | Notes |
|
||||||
|
|---|---|---|---|
|
||||||
|
| **Auto-Tile** | Paints vertex at snap target — `maps.set_vertex(layer, vx, vy, true)`. Any-corner rule flips up to 4 surrounding cells to material; renderer derives slot/rot/flip from neighbour bitmask. | Clears vertex — `set_vertex(..., false)` | Transform controls ignored (slot is derived from neighbours). |
|
||||||
|
| **Direct** | Writes per-cell override — `maps.set_override(layer, x, y, {slot, rot, flip})`. Bare slot int when canonical (rot=0+flip=0). | Clears override — `maps.clear_override(layer, x, y)` | Honours active Rot/Flip from toolbar. Use to force-place a specific orientation that the auto-derived slot wouldn't pick. |
|
||||||
|
|
||||||
|
Both modes support **drag-paint**: hold LMB (or RMB) and stroke across
|
||||||
|
the canvas to apply the action at every hovered vertex/cell. UI hits
|
||||||
|
on the toolbar / side-panel / palette never enter drag-mode.
|
||||||
|
|
||||||
## Hotkeys
|
## Hotkeys
|
||||||
|
|
||||||
| Key | Action |
|
| Key | Action |
|
||||||
|---|---|
|
|---|---|
|
||||||
| `Left click` on map | Paint cell with active tile (or set roof flag in roof-mode) |
|
| `Tab` | Toggle mode (Auto-Tile ↔ Direct) |
|
||||||
| `E` | Erase the cell under the mouse |
|
| `I` | Show / hide cheatsheet |
|
||||||
| `R` | Cycle rotation 0 → 1 → 2 → 3 → 0 |
|
| `S` | Save current map to `work.map.json` |
|
||||||
| `S` | Save to disk (overwrites the work map) |
|
| `E` | Erase tile at mouse cell |
|
||||||
|
| `R` | Cycle rotation 0 → 1 → 2 → 3 → 0 (Direct-mode override) |
|
||||||
|
| `H` | Toggle flip 0 ↔ 1 (Direct-mode override) |
|
||||||
|
| `0` | Reset transform (rot=0, flip=0) |
|
||||||
| `Esc` | Quit |
|
| `Esc` | Quit |
|
||||||
|
| `LMB-drag` | Stroke-paint (mode-dependent) |
|
||||||
|
| `RMB-drag` | Stroke-clear |
|
||||||
|
|
||||||
## Limitations (v0.1.0)
|
## Headless / smoke
|
||||||
|
|
||||||
- Tile thumbnails in the picker render as gray placeholders with tile-IDs as text — lib-core.maps v0.4.0 does not expose per-tile UVs to Lua, so visual thumbnails are a v0.2.0 task.
|
`ci_frames = 30` in `manifest.module`. The editor reads
|
||||||
- Atlas list in the picker is purely informational; if a map declares multiple atlases, the active atlas is set from `state.lua` defaults at startup and cannot yet be switched via UI (v0.2.0 hit-tests inside the expanded picker).
|
`SPOREL_CI=1` and auto-exits after 30 frames so the smoke harness
|
||||||
- Engine bindings `engine.render.draw_rect_lines` and `engine.render.draw_line` are not yet registered — active-chip borders, hidden-layer strikethroughs, and the entity-slot divider will trigger runtime errors when their code paths execute. Adding the bindings is a small engine-side follow-up.
|
can run it without a window-close click.
|
||||||
- No undo/redo, no multi-tile brush, no entity placement, no heightmap editing — see the design spec §1 for the full out-of-scope list.
|
|
||||||
|
|
||||||
## Spec
|
```bash
|
||||||
|
SPOREL_CI=1 ./Sporel.exe --module=map-editor # exits with rc=0 after ~0.5 s
|
||||||
|
```
|
||||||
|
|
||||||
`docs/superpowers/specs/2026-05-23-sporel-module-map-editor-design.md` in the `sporel-meta` repo.
|
## Limitations (current scope)
|
||||||
|
|
||||||
|
- **Single-atlas palette**: the palette draws from `atlas_idx=0` only.
|
||||||
|
Multi-atlas selector is a future slice. Workaround: keep one material
|
||||||
|
atlas per map for now.
|
||||||
|
- **Single Flip flag**: design paper mentions Flip-H + Flip-V as
|
||||||
|
separate controls, but the override format only stores one `flip`
|
||||||
|
field; combined with `rot` (0-3) the single flip covers all 8 D4
|
||||||
|
orientations, so the second button would be redundant.
|
||||||
|
- **No modifier hotkeys**: `lib-core.input` doesn't expose modifier
|
||||||
|
combos, so Shift+R for CCW rotation isn't supported. Workaround:
|
||||||
|
press R three times.
|
||||||
|
- **No Decal / Entity sub-selectors**: Direct mode on non-terrain
|
||||||
|
layers is unimplemented (lands in `0.2.0d`).
|
||||||
|
- **No Material-Properties modal**: `base_color` re-bake trigger
|
||||||
|
+ tint editor are deferred (also `0.2.0d`).
|
||||||
|
- **No multi-vertex brush sizes / procedural fill / undo-redo** — see
|
||||||
|
design paper §11 "Out of scope" for the full list.
|
||||||
|
|
||||||
|
## Plan + spec
|
||||||
|
|
||||||
|
- Design paper: `docs/design/2026-05-28-autotile-blob-styles-design.md`
|
||||||
|
§11 in `sporel-meta`
|
||||||
|
- Plan: `docs/superpowers/plans/2026-05-28-map-editor-blob-v2.md`
|
||||||
|
|||||||
Reference in New Issue
Block a user