Buffer protocol / numpy views for ColorLayer and TileLayer #335

Closed
opened 2026-07-02 12:29:41 +00:00 by john · 0 comments
Owner

From the 2026-07-02 memory-model review. Additive API. Blocked by the bulk-edit convention decision (#328) -- these layers have dirty state that raw writes bypass.

Why the storage is already ready

  • ColorLayer: std::vector<sf::Color> (src/GridLayers.h:88) -- contiguous (h, w, 4) uint8 RGBA.
  • TileLayer: std::vector<int> (src/GridLayers.h:146) -- contiguous (h, w) int32, -1 = empty.

Both are per-layer SoA and contiguous across the whole grid (layer chunking is only in the render cache, chunk_textures/chunk_dirty at src/GridLayers.h:42-45, not in the data).

What needs the convention

Cell writes today go one-at-a-time through layer->at(x,y) + markDirty(x,y) (src/UIGridPoint.cpp:167-256, src/GridLayers.h:222-249); the only bulk ops are fill/fill_rect. A raw numpy write bypasses markDirty, so stale chunk textures would render. Implementation per whichever idiom wins: with layer.edit() as arr: marking dirty on exit, or view + mandatory layer.mark_dirty().

Payoff

Wave-function-collapse, LDtk post-processing, heightmap coloring, and agent observation extraction (tile indices + RGBA planes) all become single vectorized numpy expressions instead of Python per-cell loops.

Together with DiscreteMap and (post-#332) walkable/transparent planes, a gym-style observation is a stack of zero-copy planes assembled in a few lines -- see #55/#154.

From the 2026-07-02 memory-model review. Additive API. **Blocked by the bulk-edit convention decision** (#328) -- these layers have dirty state that raw writes bypass. ## Why the storage is already ready - `ColorLayer`: `std::vector<sf::Color>` (`src/GridLayers.h:88`) -- contiguous `(h, w, 4)` uint8 RGBA. - `TileLayer`: `std::vector<int>` (`src/GridLayers.h:146`) -- contiguous `(h, w)` int32, -1 = empty. Both are per-layer SoA and contiguous across the whole grid (layer chunking is only in the *render cache*, `chunk_textures`/`chunk_dirty` at `src/GridLayers.h:42-45`, not in the data). ## What needs the convention Cell writes today go one-at-a-time through `layer->at(x,y)` + `markDirty(x,y)` (`src/UIGridPoint.cpp:167-256`, `src/GridLayers.h:222-249`); the only bulk ops are `fill`/`fill_rect`. A raw numpy write bypasses `markDirty`, so stale chunk textures would render. Implementation per whichever idiom wins: `with layer.edit() as arr:` marking dirty on exit, or view + mandatory `layer.mark_dirty()`. ## Payoff Wave-function-collapse, LDtk post-processing, heightmap coloring, and agent observation extraction (tile indices + RGBA planes) all become single vectorized numpy expressions instead of Python per-cell loops. Together with DiscreteMap and (post-#332) walkable/transparent planes, a gym-style observation is a stack of zero-copy planes assembled in a few lines -- see #55/#154.
john closed this issue 2026-07-11 14:42:07 +00:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Reference
john/McRogueFace#335
No description provided.