Chapter 03 @dirtytalk/spatial
Damage is a rectangle.
A scene is a tree of rects. When something changes, it marks the rect it dirtied, and the root turns those marks into the few regions worth repainting. This stage runs the real @dirtytalk/spatial.
01
A scene is rects.
Every widget is a SceneNode with bounds: x, y, width, height.
The outlines show them. Nothing is drawn by the library. It only knows where things are,
and insomni draws each tile into its own layer.
root.adoptChild(new Tile({ bounds })); 02
A change damages its own rect.
One tile just got hot. It called markDamaged('paint'), which defaults to its
own bounds. The dashed rect is that mark. The solid cyan rect is the region the root
handed the renderer: one rect in, one region out.
this.markDamaged('paint'); 03
A move damages old and new.
setBounds marks the rect the node left, so it gets erased, and the rect it
moved to, so it gets filled. The two do not overlap, so they stay two regions and the gap
between them is never touched.
tile.setBounds({ ...tile.bounds, x: next }); 04
Overlapping damage merges.
A tile heated and nudged a few pixels leaves three marks that cover nearly the same area. A rect folds into an earlier region when their bounding rect is no larger than both areas added together. Here three marks become one region. The tile far away stays its own region.
05
Past 16, one big rect.
Eight scattered changes make eight regions. Then twenty. Past MAX_REGIONS,
which is 16, the root gives up on tracking them one by one and collapses the frame to a
single bounding rect. Most of the screen repaints for a few changes. That is the cliff.
06
Only what touches repaints.
The paint walk skips every node whose bounds miss all the regions, so
painted counts tiles touching damage, not tiles changed. insomni scissors to
the same regions, so pixels follow too. Tracking off sets fullFrame:
everything repaints, every frame. Drag a tile, click one, scatter twenty, flip tracking,
and watch the numbers.
root.fullFrame = true; - damage rects
- –
- regions
- –
- painted
- – / –
- pixels
- – %
- CPU ms
- –
- GPU ms
- –
collapsed
This stage needs WebGPU. The reference page covers the same ground.
damage region