#Limits And Performance
#Hard-Coded Limits
| Limit | Value | Reason |
|---|---|---|
| Minimum grid columns/rows | Keeps Moore-neighborhood editing and topology behavior meaningful. | |
| Neighbor count range | to | Moore neighborhood has exactly neighbors. |
| Comparison margin | to | Margin is applied to neighbor counts. |
| Supported packing | , , , , , bits/cell | Fits cleanly into u32 words. |
| Render color lookup | tribes | Render palette buffer is sized for colors. |
| Max recording frame | Keeps individual recorded frames bounded. | |
| Recording chunk cap | Preferred chunk size before frame-size fallback. | |
| Staging ring size | buffers | Allows readback overlap while keeping VRAM bounded. |
| Max pending OPFS writes | Hard backpressure threshold. | |
| Pending OPFS write budget | Limits raw unsaved recording pressure. | |
| Pending compression budget | Limits queued compression pressure. | |
| Download chunk-mode threshold | Avoids very large in-memory normal exports. | |
| Snapshot streaming threshold | Switches large snapshots to streaming. | |
| Snapshot repack block | Bounded block size during streaming snapshot work. | |
| MP4 max dimension | Keeps video output inside practical encoder limits. | |
| MP4 small-grid reference | Upscales small grids to more useful video size. | |
| MP4 persisted FPS | to | Bounds user settings. |
| MP4 persisted bitrate | to | Bounds user settings. |
| Max combine inputs per row | Matches neighbor-scale logic and keeps generated rules bounded. | |
| Rule branches per WGSL chain | Avoids long chains to prevent reaching the shader chaining limit. | |
| Random seed | to | Keeps deterministic probability rolls inside unsigned -bit space. |
| Rule probability input | to | Percentage with up to decimal digits. |
| Brush density | to | Bounds density validation and shader selection percentage. |
| Brush selected tribe ID slots | Fixed brush uniform array size. |
#Device Limits
Some limits are not hard-coded by the app. They come from the WebGPU adapter selected by the browser, so they can change across devices, browsers, drivers, and power modes.
Two important limits for grid size are:
maxBufferSize: the largest individual GPU buffer that can be created.maxStorageBufferBindingSize: the largest storage-buffer range that can be bound for shader access.
The simulation frame must fit both constraints, so the effective maximum simulation frame size is:
See VRAM and packing for the frame-size formula and how packing affects these limits.
#Performance Tradeoffs
The largest costs are grid size, packing, rule complexity, recording, metrics, and export selection.
- Larger grids increase compute work and frame bytes.
- Lower bits per cell reduce memory and storage, but must still represent all tribes.
- More rules and complex selectors generate larger shaders and more branch/count work.
- Probabilistic rules add deterministic hash and threshold checks to generated simulation branches.
- Recording copies every captured frame and writes chunks to OPFS. Active recording runs batch ordered step/copy command pairs to reduce per-generation queue-submission overhead without dropping generations.
- Live metrics add GPU passes and readback.
- PNG, MP4, and offline metrics require scanning recorded frames.
- Max speed disables rendering so simulation work can dominate.
Non-recording high-throughput runs use adaptive batching. The grid-size tier is based on , clamped from through , and seeds the initial generation budget. After each GPU queue drain, the worker measures drain time and adjusts the next budget with bounded growth and shrink. Max speed and multi-generation step-forward target runs use a drain target because rendering is paused or transient. Fixed-speed catch-up uses a target so visible canvas updates remain responsive when the requested speed is higher than the device can sustain. Recording runs keep separate pacing because they must preserve every captured frame and honor recording backpressure. Recording batching improves small-frame overhead by submitting several ordered step/copy pairs together, but large backpressured recordings are still limited mainly by GPU readback, CPU copy, and OPFS write throughput.
#Failure Boundaries
The app logs and surfaces failures at lifecycle boundaries:
- WebGPU initialization and rebuild.
- GPU device loss.
- GPU validation/runtime errors.
- OPFS cleanup and recording persistence.
- Compression retries and deferrals.
- Snapshot load/save failures.
- Download preparation and worker export failures.
- Wake lock acquisition and release.
When effective recording usage reaches of the browser-reported storage quota estimate, the app pauses the simulation to preserve data. Effective usage is pending raw recording bytes plus compressed recording bytes plus reserved recording headroom. At , it pauses and disables recording so the user can save data and reset. Recording is also disabled whenever the remaining quota after pending, compressed, and reserved bytes is smaller than frame. The browser-reported quota estimate is approximate and may change as the browser manages storage. If an actual OPFS write still fails because the browser enforces a lower storage limit, recording is stopped and the app rolls back to the previous persisted frame instead of surfacing a GPU error.