Vertex-grid write/read for the autotile painting path. The map-editor
0.2.0a Auto-Tile mode is the primary consumer; painting a single
vertex causes up to 4 surrounding cells to flip to material via the
any-corner rule. Coordinate-checks reject OOB writes; grid is lazily
allocated on first paint.
Three small follow-ups bundled into a single version bump:
1. Real tile.opaque consumption (cell_is_opaque_on_layer)
v0.5.0e shipped a slot-13 heuristic for vertex-painted layers
because the atlas-baker wasn't computing real opacity. Atlas-baker
v0.2.0 now sets tile.opaque via alpha-analysis (all-alpha-255
detection). Both vertex-painted and tiles[] paths now resolve the
actual slot and read its tile.opaque from atlas metadata. Pre-
v0.2.0 atlases without the flag report not-opaque (safe-
conservative: extra draws, no missed cells).
2. Manifest-schema patch (reserved fields, accept-but-ignore)
Type-checked acceptance of forthcoming manifest fields the
validator will need before consumers can ship them in real
manifests without breaking changes:
map-level: z_level (int), z_below (string)
per-layer: base_color (string #RRGGBB), tint_override (table),
collision_policy (table), traversal_modes (table),
foundation_mode (array)
Future slices (lib-core.maps v0.6 multi-z-level, lib-core.actor
movement-modes, etc.) wire the fields into actual behaviour.
3. Override format extension {slot, rot, flip} (design paper §15.1)
Override entries now accept EITHER a bare integer slot_id (compact
canonical-orientation form, backwards-compat with 0.5.0d) OR an
object `{slot, rot?, flip?}` for explicit-transform placement
(unblocks map-editor v0.2's Direct-mode Transform controls).
New normalize_override_entry helper converts disk-form to runtime
{slot, rot, flip}. Validator (validate_map_table_v3) type-checks
per-entry. set_override accepts either form and auto-stores as
compact (bare-int) when rot+flip both 0, object form otherwise —
minimises disk diff for the common canonical case. get_override
returns normalized form regardless of how the entry is stored.
draw_layer + cell_is_opaque_on_layer updated to read the
normalized form.
Closure-gate: milestone-check.sh ctest + test-all-modules GREEN.
SPOREL_CI=1 vagrant-skeleton rc=0 with 60 render_frame_ok; no
magenta-placeholders, no render-hook errors. Existing override-cells
(vagrant's 3 wall pillars) still render correctly through the new
normalize path; opaque-ceiling cache now reads real atlas data.
Consumer dep-bumps for v0.5.1 land in their own commits per repo:
sporel-lib-core.render, sporel-module-vagrant-skeleton, sporel-
module-map-editor[-test].
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three new public functions (set_cell_gid, set_roof, save_to_disk)
documented in the README alongside the existing read API. Purely
additive bump — existing consumers continue to compile and run
unchanged.
draw_layer now samples tile sub-rectangles from the atlas diffuse
texture via the ADR-0044 source-rect render primitive (13-arg
draw_sprite_transform). load_textures gains a walkable field in
tile-records (from atlas JSON) so gameplay queries work after the
tiles-dir is removed. load_tilemap falls back to an atlas-bootstrap
stub when the legacy tilemap JSON is absent, allowing maps.load to
succeed before load_textures is called. Texture loading uses pcall
to degrade gracefully in headless environments. Bumps lib version to
0.3.0 to flag the breaking change in tile-record shape (id is now
integer, name is the stable string identifier).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sprite-mode in draw_map:
- tilemap-tiles with texture atlas-id render via
engine.render.draw_sprite_transform with rotation pivot at tile center
- tiles without texture continue to render via draw_rect with color
(Phase 1 mode preserved)
Tile rotation:
- maps support an optional tile_rotations parallel array in the map
JSON with per-cell 90-degree rotation values (0/90/180/270)
- absent or nil entries default to 0 (no rotation)
- enables 9-segment tile reuse via rotation rather than per-orientation
sprites
New API:
- maps.load_textures(asset_aliases) resolves the current tilemap's
tile atlas-ids to texture-handles via the asset-lib indirection
(asset_aliases[tilemap.asset_pack] -> lib-id -> atlas.json lookup
per tile)
Schema additions:
- tilemap.asset_pack (alias-key, optional)
- tile.texture (atlas-id, optional)
- map.tile_rotations (parallel array, optional)
All existing Phase 1 color-only tilemaps render unchanged.
Pre-existing bug: split_namespaced_id used first-dot-split. For modules
with dotted IDs (e.g. lib-core.maps-test), this misclassified
'<dotted-module-id>.<tilemap-name>' as cross-lib reference.
Replaced with split_local_tilemap() that matches by exact current-
module-id prefix. Module-id can now have arbitrary dots.
Surfaced by P.3.1 reference test-module 'lib-core.maps-test' which
has a dotted module-id.