From aa9987b46b88cee533fa38e483b72d27ce28b7ba Mon Sep 17 00:00:00 2001 From: bQUARKz Date: Fri, 20 Mar 2026 07:44:40 +0000 Subject: [PATCH] align packer specs and loader --- docs/runtime/specs/04-gfx-peripheral.md | 28 +++++++++++-- docs/runtime/specs/15-asset-management.md | 48 +++++++++++++++++++++++ 2 files changed, 72 insertions(+), 4 deletions(-) diff --git a/docs/runtime/specs/04-gfx-peripheral.md b/docs/runtime/specs/04-gfx-peripheral.md index c9acb8b6..54863093 100644 --- a/docs/runtime/specs/04-gfx-peripheral.md +++ b/docs/runtime/specs/04-gfx-peripheral.md @@ -80,6 +80,9 @@ The graphical world is composed of: - characters - UI - effects +- `assets.pa` tile-bank payloads use a serialized representation distinct from runtime memory: + - serialized pixels are `4bpp` packed in payload order + - runtime memory may expand pixels to one `u8` palette index per pixel after decode ### 4.2 Layers @@ -413,16 +416,16 @@ Fixed rule: Each **Tile Bank** contains: -- Up to **256 palettes** +- **64 palettes** in runtime-facing v1 - Each palette has: - **16 colors** - - each color in **RGB565 (u16)** + - each color in **RGB565 (`u16`, little-endian in serialized assets)** Size: - 1 palette = 16 × 2 bytes = **32 bytes** -- 256 palettes = **8 KB per bank** -- 16 banks = **128 KB maximum palettes** +- 64 palettes = **2 KB per bank** +- 16 banks = **32 KB maximum palettes** --- @@ -449,6 +452,10 @@ Each tilemap cell contains: - `flip_x` - `flip_y` +Runtime-facing validity rule for v1: + +- `palette_id` values are valid only in the range `0..63` + #### Sprite Each sprite draw contains: @@ -460,6 +467,10 @@ Each sprite draw contains: - `flip_x`, `flip_y` - `priority` +Runtime-facing validity rule for v1: + +- `palette_id` values are valid only in the range `0..63` + --- ### 18.6. Color Resolution @@ -494,6 +505,9 @@ Tile Banks are "strong assets": - Tiles and palettes live together - Export/import always carries: - tiles + palettes +- In `assets.pa` v1, the serialized payload is: + - packed indexed pixels for the whole sheet + - followed by the palette table for the same bank - The hardware does not impose semantic organization: - grouping is the creator's decision - Tooling and scripts can create conventions: @@ -501,6 +515,12 @@ Tile Banks are "strong assets": - 16..31 = scenery - etc. +Runtime-facing v1 baseline: + +- sheet pixels are authored and resolved as indexed values `0..15` +- serialized tile-bank payload uses packed `u4` pixel indices +- runtime may materialize the decoded bank as expanded `u8` pixel indices plus palette table + --- ### 18.8. Metrics for Certification (CAP) diff --git a/docs/runtime/specs/15-asset-management.md b/docs/runtime/specs/15-asset-management.md index 85c69b5e..8c2af766 100644 --- a/docs/runtime/specs/15-asset-management.md +++ b/docs/runtime/specs/15-asset-management.md @@ -100,6 +100,53 @@ This table describes content identity and storage layout, not live residency. `offset` is relative to the start of the payload region inside `assets.pa`. +`size` is the serialized byte count stored in the payload region. + +`decoded_size` is the byte count of the materialized runtime bank after decode, not necessarily the same as the serialized payload size. + +`codec` identifies how the runtime must interpret the serialized payload slice before the asset becomes a resident bank. + +### 4.1 `TILES` asset contract in v1 + +For `BankType::TILES`, the runtime-facing v1 contract is: + +- `codec = RAW` +- serialized pixels use packed `u4` palette indices +- serialized palettes use `RGB565` (`u16`, little-endian) +- `palette_count = 64` +- runtime materialization may expand pixel indices to one `u8` per pixel + +`RAW` for `TILES` means there is no compression stage beyond deterministic reconstruction of the tile bank from its serialized payload. It does not require the serialized byte layout to be identical to the in-memory layout. + +Required `AssetEntry.metadata` fields for `TILES`: + +- `tile_size`: tile edge in pixels; valid values are `8`, `16`, or `32` +- `width`: full bank sheet width in pixels +- `height`: full bank sheet height in pixels +- `palette_count`: number of palettes serialized for the bank + +Validation rules for `TILES` v1: + +- `palette_count` must be `64` +- `width * height` defines the number of logical indexed pixels in the decoded sheet +- additional metadata may exist, but the runtime contract must not depend on it to reconstruct the bank in memory + +Serialized payload layout for `TILES` v1: + +1. packed indexed pixels for the full sheet, using `ceil(width * height / 2)` bytes; +2. palette table, using `palette_count * 16 * 2` bytes. + +The tile-bank payload therefore separates serialized storage form from runtime memory form: + +- serialized pixel plane: packed `4bpp` +- decoded pixel plane: expanded `u8` indices, one entry per pixel +- palette table: `64 * 16` colors in `RGB565` + +For `TILES` v1: + +- `size` must match `ceil(width * height / 2) + (palette_count * 16 * 2)` +- `decoded_size` must match `(width * height) + (palette_count * 16 * 2)` + ## 5 Banks and Slots The current runtime exposes bank types: @@ -151,6 +198,7 @@ For v1: - `OP_MODE` is derived from `codec`/CODEX; - explicit per-asset hinting is not part of the baseline contract. +- `TILES` with `codec = RAW` may still stage in memory before bank installation because runtime decode expands packed pixel indices into the resident representation. The runtime does not treat asset installation as implicit side effect.