# VoxelForge — design review: how do we get a cold whole view from ~2.5–4.6 s to ~1 s? You're reviewing a voxel terrain generator's performance architecture. **Read and reason only.** Don't edit, build, run tests, commit or stash. You may read any file in this repository and search the web. We've spent about 15 rounds finding and fixing hot spots, and the gains are shrinking. We want fresh eyes on the *approach*, not another micro-optimisation. Question our framing where it's wrong. ## The system (summary, so you don't have to rediscover it) **VoxelForge** is a UE5 plugin for underground density-field terrain. Generation lives in a standalone C++ library, "Core" (`Standalone/Core/`), that Unreal calls through an adapter (`Source/VoxelForge/Private/VoxelForgeCoreAdapter.cpp`). - **The field.** Density is a *function*, not stored data: negative = solid. Core voxels are 25 cm. Tiles hold 32³ voxels. - **Clipmap.** LOD0–8; each LOD doubles the voxel step. A "whole view" is about 2,250–2,850 tiles across all LODs around one camera. - **Meshing.** Marching cubes per tile (about 35³ samples per LOD0/1 tile with borders), plus normals and skirts. - **The world is a vertical stack of "strates".** Each is ceiling → content → bedrock, with its own generator: - SurfaceWorld (SW): heightfield, native path; - FloatingIslands (FI), TunnelNetwork (TN) and VerticalShafts (VS): the "legacy compiled-analytic" path. - **The owner's test world** stacks four of them: SW 512 m, FI 240 m, TN 128 m, VS 128 m tall. - **Passages.** Walkable, winding, natural-looking tunnels near (0,0) connect each strate to the next. They're carved by a shared "composer" that also adds support treads, boundary bands and mouth shaping. - **Multiplayer.** No geometry is replicated. Every peer regenerates from the seed, the layout and a diff of player edits. That's why peer determinism is mandatory. ## The goal and constraints - **Goal:** about 1 s cold whole view at any strate arrival on the owner's PC (Ryzen 5800X3D, 8 cores/16 threads, 7900 XTX). Streaming must stay smooth in VR (Quest 3) and at high travel speed. - **Must hold:** - peer determinism (same inputs → same world on every machine); - no visible quality regression; - passages stay walkable from arrival mouth to departure mouth (capsule, support and grade audits exist); - no game-thread hitches. - **Not required:** byte-identical output with earlier versions. The owner accepts that perf passes change the world's shape slightly, as long as every peer gets the same result and quality holds. (We have tended to treat hash equality as a gate anyway; it's a convenience, not a rule.) - **On the shelf, not a speed excuse:** a disk mesh cache is an accepted feature, but perf is judged cold. ## Measurements (owner world, measured on an i9-12900H with 8 workers, headless unless stated) **Whole view now** (it was 2.6 / 7.2 / 6.0 / 2.7 s a week ago): | Strate | Whole view | |---|---:| | SW | 2.4 s | | FI | 4.6 s | | TN | 4.3 s | | VS | 2.5 s | **In Unreal (SW arrival):** - Core work equals headless; - initial set ready at 3.74 s vs headless 2.41 s, the extra being scheduling; - walkable ring 0.4–1.8 s. **Where the time goes:** - **L73:** field evaluation inside grid fill is about 40 of FI's 46 worker-seconds (TN 33 of 39). LOD0/1 tiles evaluate about 44k density samples each. - **L74/L75:** sound whole-tile skip proofs now certify about 22–26% of tile visits. - Ceiling: 46–82% of LOD0–2 tiles are truly uniform, and 90–97% of samples lie in uniform 8³ blocks. - Dominant remaining veto: tiles crossing a strate boundary. - Legacy sub-tile (block) proofs were unsound once (missed passage wall/floor relief), then sound but slower than they saved. - **L76, per legacy sample:** - passage/support composer ≈ **1.05 µs**; - primitive scan ≈ 0.19 µs (0.25 primitive distance evaluations per sample, binned); - boundary band ≈ 0.06 µs; - noise ≈ 0.01 µs. **About 75% of field time is the passage composer, even far from passages.** - Per-tile passage culling was tried and changed 612 density samples / 24 mesh tiles. It was rejected only for breaking hash equality, which is a convenience, not a rule; nobody checked whether that change was harmless. **Tried and rejected:** - the native FI generator (fails passage walk audits on this plan); - deeper Unreal queues (done: 4.78 → 3.74 s). **Trap we fell into once:** a diagnostic hash mode silently disabled the skips and doubled the timings. Measure the production path. ## What to reason about (open; don't limit yourself to these) 1. **Is "evaluate a density function at ~44k points per tile, then march cubes" the right shape** for this world? Consider, for example: - sparse/hierarchical evaluation (octree or brick refinement driven by interval or Lipschitz bounds, as in libfive/Fidget/MPR-style implicit rendering); - reusing samples across nested clipmap LODs; - evaluating smooth large-scale terms coarsely and interpolating; - narrow-band evaluation near the surface only. 2. **The passages are a few winding tubes.** Why does every sample pay 1 µs for them? What representation would make "far from any passage" free and "near a passage" cheap? For example: - bake each passage once at plan time into a sparse distance/brick structure; - a spatial index of segments with a conservative distance early-out; - a per-tile passage candidate list built once. What would a correct per-tile culling need so that it doesn't change the result? And if it changes the result, how should we judge whether that change is acceptable? 3. **Which work is needed for "ready in 1 s"?** Maybe the target should be redefined: walkable ring first, progressive LOD refinement, far LODs from cheaper representations or impostors, fewer tiles. What do comparable engines do (Voxel Plugin, Teardown, Dreams, No Man's Sky, Minecraft-style streaming, Nanite-era voxel work)? 4. **Hardware.** 8 CPU cores plus a 7900 XTX that's mostly idle during load. An earlier GPU port was closed, and determinism across GPU vendors is a concern. Is there a deterministic way to use it, e.g. integer/fixed-point evaluation or a CPU-authoritative plus GPU-display split? Is SIMD (AVX2) evaluation of the legacy field realistic? 5. **Anything in our process or measurement** that hides the real bottleneck. ## How to work efficiently - **Trust the numbers above; don't re-measure or re-derive them.** Spend your effort on thinking. - **Read code only to check whether a specific idea fits.** Entry points: - `CODEMAP.md` (navigation) and `ARCHITECTURE.md` §8.10 (performance invariants); - `Standalone/Core/src/ShapeWorldInternal.h`: composer, `AnalyticDensityAt`, `ClassifyBoxDetailed`, passage terms; - `Standalone/Core/src/VoxelForgeCore.cpp`: tile generation and skips; - reports in `Standalone/Research/WorldAssemblerM3/`: `Linux73`–`Linux76`, `Research36`, and R38–R40 notes inside `Linux73/` and `Linux76/`. - **Use the web** for prior art and techniques, and cite them. - **Go broad first** (many approaches, one or two lines each), then deep on the best three. ## Output At most ~2,500 words, plain language, **ranked recommendations first**. For each of the top three: - what changes, and where in this codebase (file and function); - expected gain, with arithmetic from the numbers above; - what it risks: determinism, quality, walkability; - effort; - **a cheap experiment that would prove it wrong** before anyone builds it fully. Then the shorter list of other ideas, then any questions only the owner can answer (e.g. what "ready" must mean). Mark claims as [CODE] (read in this repo), [MEASURED] (from the numbers above), [PRIOR ART] (cited) or [INFERENCE].