manifest.module
+ new dep on lib-asset.prototype-blob-geom v0.1.0 (companion lib
for the design paper's reference asset set + Python atlas-packer)
+ asset_aliases entry for blob_testbench (mixed 3-material atlas:
grass/stone/wood x 14 slots = 42 tiles) and blob_rect_stone
(single-material atlas for vertex-painted autotile)
- removed subterrain_tiles asset_alias (no longer used)
bumped lib-core.maps dep 0.4.0 -> 0.5.0
vagrant_test.map.json rewritten as native schema-v3 with three non-
empty terrain layers, exercising all renderer paths in a single map:
- surface (tiles[] path, multi-material via blob_testbench):
grass-solid floor across all 400 cells
14-wide x 3-tall showcase strip on rows 10-12 columns 2-15
displays every slot of every material the atlas ships (slot 0
through 13 x grass/stone/wood, ids 1..42 visible at a glance)
- topsurface (tiles[] path): 2x4 wood overlay decoration on rows
3-4 columns 2-5
- wall (vertex-painted autotile with blob_rect_stone material):
21x21 vertex grid; 80 vertices painted in a border-ring pattern
so the renderer's bitmask + 47->14 slot lookup produces the
visually-correct stone wall around the 18x18 interior; plus
3 interior pillars (cells 9:7, 7:15, 13:15) authored as
overrides with slot 0 (isolated), demonstrating that the
override sublayer can place truly-1-cell-isolated material
which the any-corner vertex rule alone cannot express
assets/tiles/vagrant_test.tilemap.json removed; under schema v3 the
engine resolves the palette directly from the atlas's tiles.atlas.json,
the standalone tilemap.json was unused (atlas-bootstrap stub path
took over since M.2).
Closure verifies SPOREL_CI=1 ./Sporel.exe --module=vagrant-skeleton
rc=0 with 60 render_frame_ok, both atlases load (no magenta-
placeholders), walkability rule (surface present + wall absent)
correctly treats border + pillars as non-walkable.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Asset-aliases now reference the three baked subterrain atlas-sets
(subterrain_player, subterrain_tiles, subterrain_world) rather than
the legacy indexed pack labels. The rig asset_pack updates to
subterrain_player and each bone gains a calibrated anchor offset.
Furniture-draw loads the subterrain_world atlas once and renders
via source-rect draw_sprite_transform. The map tilemap field updates
to subterrain_tiles to match the new atlas-id. Dep-bumps for
lib-core.maps 0.3.0, lib-core.puppet 0.5.0, and
lib-asset.prototype-subterrain 0.2.0. Replace r_lib.draw_map with
draw_map_pre/post_entities.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
13-bone humanoid rig (12 visible bones + 1 root) hand-ported from
substrate reference, mapped to PROTOTYPE asset-pack via asset_aliases
indirection (asset_pack: player). Bones use texture/z_order/scale/
anchor fields from the rig-format extension. Tracks split: lower for
legs + feet (walk animation), upper for root/body/head/shoulders/arms
(idle animation).
Animations:
- idle.anim.json: 2.0s loop on upper track, subtle body+head sway
- walk.anim.json: 0.6s loop on lower track, legs+feet cycle
Sprite-tilemap: 4-tile palette (floor_001-003 walkable, floor_004
as wall). Map content: 20x20 with wall-border and interior wall
blocks. tile_rotations parallel array exercises 90 and 180-degree
rotations on a handful of cells for visual rotation-pipeline
verification.
init.lua loads textures via asset_aliases lookup:
- maps.load_textures(aliases) resolves tilemap-tile atlas-ids
- puppet.load_rig(path, aliases) loads + resolves bone textures
- furniture textures preloaded at init (bed, bench, backpack) to
avoid first-frame load stutter; rendered via engine.render.
draw_sprite_transform in the draw hook
Camera follows puppet via per-frame camera.set_target. Headtrack:
head bone (look_at: true) rotates to face mouse world-position.
New SPOREL_CI=1 traces from render and init hooks:
- vagrant: render_frame_ok (per frame from render)
- vagrant: sprite_mode=on (once after first sprite-draw)
- vagrant: assets_loaded=14 (once after init: 7 puppet + 4 tile + 3 furniture)
Composer module: single-player character as puppet (humanoid 4-bone
rig: torso, head, leg_l, leg_r) at world (320, 240) on a 20x20
v0.1-format tilemap.
- WASD direct movement, normalized for diagonals, 120 px/s.
- Camera-chase via lib-core.camera target-provider (camera follows
puppet position frame-to-frame).
- Idle and walk keyframe animations: idle is a 2s torso-sway on the
upper track; walk is a 0.6s leg-cycle on the lower track.
- Animation-state transitions driven by movement input: walk while
WASD-active, idle when released.
- Headtrack: head bone (marked look_at: true in rig) rotates each
frame to face the mouse cursor's world position via
puppet.set_look_target.
- ESC -> launcher.
CI hooks (env-var-gated, no-op in normal play):
- SPOREL_CI=1: emits 'vagrant: frame_avg_ms=N' after 60 frames and
'vagrant: render_frame_ok' per frame from the render hook, then
engine.exit(0). Smoke stages consume these markers.