diff --git a/README.md b/README.md index 70b30ea..9ca9e59 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,35 @@ # lib-core.maps -Single tile-grid map implementation. Loads JSON map + tilemap files, registers maps by id, and provides tile-fetch + walkability + size queries with current-map sugar. +Multi-layer tile-grid map implementation with vertex-painted autotile +(blob-14), sparse per-cell overrides, packed-u32 GID legacy path, atlas +loading + UV resolution, walkability + sight-blocking queries, and a +v3 multi-layer render pipeline with opaque-ceiling cache. -**Version:** 0.2.0 -**Lib-ID:** lib-core.maps -**Requires:** (none) -**Tags:** maps, tile-grid, walkability, tilemap +**Version:** 0.5.4 +**Lib-ID:** lib-core.maps +**Requires:** (none) +**Tags:** maps, tile-grid, multi-layer, vertex-painting, autotile, blob-14, override, walkability, tilemap + +## Schema versions + +| Version | Highlights | +|---|---| +| v1 | Single-layer `tiles[]` + tilemap path. Loaded but auto-upgraded to v2 on `maps.load`. | +| v2 | Multi-atlas + multi-layer with packed-u32 GIDs (atlas_idx + tile_id + rotation). `set_cell_gid`, `save_to_disk`. | +| v3 | Per-layer `material` (atlas-alias), optional `vertices` ((W+1)·(H+1) grid), optional `overrides` ({"x:y": int OR {slot, rot, flip}}). Renderer derives slot/rot/flip from neighbour-bitmask blob-gating; overrides force-place specific orientations. | + +## Painting model (v3 autotile) + +- **Vertex grid**: (W+1)·(H+1) cells. Any-corner rule: cell (x,y) is + material iff any of its 4 corner vertices is painted. +- **Blob-gating + SLOT_LOOKUP**: each material cell's 8-bit + neighbour-bitmask (clockwise from N) is blob-gated (diagonals zeroed + unless both adjacent cardinals are set), then mapped to one of 14 + canonical slots × {0,1,2,3} rotation × {0,1} flip via a D4-orbit + table. 47 distinct gated bitmasks total. +- **Override sublayer**: sparse `{"x:y": slot}` or `{"x:y": {slot, rot, + flip}}`. Takes precedence over the bitmask-derived slot AND forces + material-presence on the cell. ## Topology @@ -20,6 +44,51 @@ graph LR ## API +> **Note:** the API section below was authored against v0.2.0 and is +> being progressively updated. Entries marked `[v0.x added]` are the +> additions since 0.2.0. See `init.lua` source for the full surface. + +### APIs added v0.3.0 — v0.5.4 (summary) + +- **v0.3.0** — atlas-baker integration: `load_textures(asset_aliases)` + rewrite for M.2 atlas format; height-field API; atlas-bootstrap + stub when tilemap JSON missing. +- **v0.4.0** — write-APIs for editors / procedural-gen: + - `set_cell_gid(layer_name, x, y, gid, map_id?)` + - `set_roof(x, y, value, map_id?)` + - `save_to_disk(map_id, path)` +- **v0.5.0a-e** — schema-v3 multi-layer terrain stack: + - 8 layer slots (`foundation`, `subsurface`, `surface`, `topsurface`, + `lower_wall`, `wall`, `upper_wall`, `canopy`) + - `LAYER_Z` + `LAYER_ORDER_TOP_DOWN` constants + - Vertex-painted autotile renderer (any-corner + blob-14 SLOT_LOOKUP) + - Empty-layer + opaque-ceiling caches for render-opt +- **v0.5.0d** — sparse override sublayer: + - `set_override(layer_name, x, y, slot_or_entry, map_id?)` + - `clear_override(layer_name, x, y, map_id?)` + - `get_override(layer_name, x, y, map_id?)` +- **v0.5.1** — override-entry format extension to `{slot, rot, flip}` + (object form, backwards-compat with bare integer). Auto-compacts to + bare int when canonical orientation (rot=0+flip=0). `tile.opaque` + flag consumed from atlas-baker v0.2.0 alpha-analysis. +- **v0.5.2** — public vertex-grid write APIs: + - `set_vertex(layer_name, vx, vy, painted, map_id?)` — any-corner + rule fills up to 4 cells; lazy-allocates grid on first paint + - `get_vertex(layer_name, vx, vy, map_id?) -> bool` +- **v0.5.3** — bugfix: `load_textures` now refreshes the + `atlas_by_alias` dict after replacing `m.atlases[i]`, fixing the + v3 vertex/material render path which was resolving through the + pre-load stub (no texture handle → MISSING_ASSET_COLOR fallback). +- **v0.5.4** — public atlas accessors for palette consumers: + - `atlas_diffuse_handle(atlas_idx, map_id?)` — raylib texture handle + - `atlas_tile_size_px(atlas_idx, map_id?)` — int, usually 64 + - `atlas_tile_uv(atlas_idx, slot, map_id?)` — `{x, y, w, h}` in + atlas pixel coords, or `nil`. Resolves slot via the same + `slot_NN_` name regex used internally by the renderer. + +### Original v0.2.0 entries + + ### `maps.load(path)` **Syntax:** `maps.load(path: string) -> string`