#VRAM And Packing
#Packed Formats
Cell states are stored as integer tribe indexes packed into u32 words. Supported formats are , , , , , and bits per cell.
| Bits/cell | Cells/word | Word shift | Cell shift | Cell mask |
|---|---|---|---|---|
0x1 |
||||
0x3 |
||||
0xF |
||||
0xFF |
||||
0xFFFF |
||||
0xFFFFFFFF |
The smallest tight format for a tribe count is selected by state count thresholds: , , , , , then -bit fallback.
However, currently, only up to states are supported, so -bit and -bit packings are user-choice only.
#Frame Byte Size
A packed frame is a rectangular array of u32 words:
The same formula is used by grid-size validation, packing validation, snapshots, recording, and exports.
#VRAM Budget
The worker computes device simulation capacity as:
WebGPU does not expose the actual amount of GPU VRAM available to the browser. The displayed VRAM budget is therefore an estimate derived from WebGPU buffer limits and the engine's own buffer plan, not a direct hardware memory reading.
The WebGPU limits in the first line come from the selected adapter/device:
maxBufferSize: the largest individualGPUBufferthe device allows the app to create.maxStorageBufferBindingSize: the largest storage-buffer range the device allows a shader to bind and access in one binding.
The engine uses the smaller of the because a simulation frame must both exist as a buffer and be usable by the compute shader. If either limit is smaller than the requested packed frame, the grid cannot be supported in that packing format. This is why very large grids may need narrower packing or a row count reduced by even when the GPU still has free VRAM.
Simulation buffers use full packed grid buffers plus fixed overhead. Recording buffers use a chunk GPU buffer plus a staging ring:
The staging ring size is , so recording reserves chunk buffer plus staging buffers when recording is available.
VRAM classes shown by the app:
- Simulation: GPU memory for the current simulation buffers and fixed engine overhead.
- Recording: GPU memory for the recording chunk buffer and staging ring.
- Budget: an estimated budget derived from WebGPU buffer limits and the engine buffer plan, not actual physical VRAM.
#Why Packing Matters
Packing is a tradeoff between memory traffic, recording cost, shader work, and supported state count. Lower bits per cell reduce frame bytes, which helps larger grids fit WebGPU buffer limits, keeps recording available, lowers OPFS growth, and makes exports cheaper. As covered in the benchmark conclusions, this matters most while recording and once large grids become memory-traffic bound.
Higher bits per cell support more tribes and can avoid repacking when complex rulesets or snapshots require more states. They also simplify the shader's packing math because fewer cells share each u32 word. That can reduce overhead on smaller non-recording grids, where dispatch, scheduling, and browser/GPU pipeline overhead often matter more than raw frame size.