Frame cost and look, on the low-end box
- Low-end / older Windows iGPU box (§9), 1080p. Run the current release standalone, let
it reach steady state, capture
diagnostics.log. Report (a) fps holds ≥ 60 @ 1080p, and (b) steady-state working set + private commit. (This is Plan 0012 Phase 3, extracted; it also satisfies the identical Plan 0003 Phase 3 iGPU-60-fps carry-forward — same measurement.) - Second GPU vendor — Intel iGPU, if a box is available, 1080p. Same capture. The point is the footprint spread vs the AMD dev box — confirms whether the ~350 MB ceiling is AMD-specific.
- The dual-live dissolve budget, on the low-end box. Plan 0023 made every preset switch a
~1 s dissolve, and its governor re-renders the outgoing preset live as well whenever the two
presets hold independent GPU state and the smoothed frame time is under
DUAL_LIVE_BUDGET_MS(core/src/render/mod.rs, currently 18.0 — the code calls it “the number to calibrate on a low-end rig”, and no capture can speak to it because a headless run collects no frame times and so never upgrades). Two things to report, both with the overlay on (F3) so the p99 is visible: (a) pressSpacerepeatedly between light presets — does the frame time hold ≥ 60 fps through the dissolves, or does the governor’s threshold need to come down; (b) the heavy pair — dissolve an attractor preset into a reaction-diffusion one and back. That pair is the freeze fallback’s reason for existing; on this box it should either stay frozen (fine) or, if it upgrades, still hold the floor. (Plan 0023 Phase 4’s done-when and its budget-tuning risk, extracted at that plan’s close.) - The layered heavy pair (Plan 0076), on the low-end box, 1080p. A preset may now
compose a second scene (
[layer], ADR-0090), andFloorrenders both layers by design — a two-layer world must not lose half its content on weak hardware. The deliberately heavy pairing is an attractor main with a reaction-diffusion layer, at both joins (under, andoverwith a blend — theoverjoin adds a surface-sizedRgba16Floatoffscreen pair and one blend pass). With the overlay on (F3), load such a preset — the Plan 0076 close notes carry probe TOMLs, or write one frompresets/README.md— and report (a) whether fps holds ≥ 60 at 1080p for each join and (b) the p99 against the attractor preset alone. (Plan 0076 Phase 4’s measured numbers are dev-box hardware figures, not iGPU evidence; this line is where that evidence comes from. If it fails, the response is authoring guidance — heavy-plus-heavy pairings are an authoring responsibility per ADR-0090 — not a tier change.) - Trails at native resolution, on the low-end box, 1080p. Plan 0033 made the two post
stages size their internal grid from the render target instead of a fixed 1280x720
(ADR-0034). With
trailsactive that is now a full-resolutionRgba16Floatping-pong read and write every frame where it used to be a 720p one — roughly 2.25x the feedback bandwidth at 1080p. Plan 0045 raised it again: the accumulation was always float, but the stage’s composited output and the fold’s source were the surface format and are nowRgba16Floattoo (ADR-0046), so every hand-off between stages moved from 4 to 8 bytes a texel. Composite bandwidth roughly doubled on top of the 2.25x. NFR §1’s ≥ 60 fps @ 1080p floor is exactly the claim at risk, and no headless capture can speak to it: WARP timings say nothing about an iGPU’s memory bandwidth. Loadrose_trails— it bindstrailsaround 0.78 and is the shipped preset that exercises this path (fragment_kaleidocovers the fold). Let it settle with the overlay on (F3), and report (a) whether fps holds ≥ 60 and (b) the p99 against the same preset withtrails = 0. (Plan 0033’s stated main exposure, widened by Plan 0045. If it fails, lowerTierConfig::FLOOR.post_capincore/src/render/tier.rs— the constant moved there in Plan 0044 — and do not re-fix the grids.) - Working-set delta from the post stages, including mid-dissolve. Re-stated for the float
composite (Plan 0045). These numbers moved twice: Plan 0033 grew the composite from ~22 MB
per chain to ~50 MB at the cap by sizing the grids from the target, and Plan 0045 took that to
~66 MB by moving every intermediate to
Rgba16Float(8 bytes a texel, not 4). A dual-live dissolve holds two chains, so the transient peak is ~133 MB, and the worst case — dual-live, every stage on including bloom, ink on — is ~246 MB against NFR §12’s ~350 MB soft ceiling, which is mostly driver floor already. There is also a genuinely new surface-sized float buffer that exists on every frame regardless of preset: the tonemap’s input, 16.6 MB at 1080p. The full before/after table is in Non-functional requirements §12. Those figures are arithmetic from the texture descriptors, not a measurement. On the low-end box, report the steady-state working set with atrailspreset active, and again while holding down preset switches so a dissolve is live, against the same numbers withtrails = 0. Readrss_bytes, notgpu_bytes— the latter is a swapchain-only approximation (ADR-0008) that does not count the post stages’ offscreens, so it reads identically either way. Measured on the dev box after Plan 0033 landed:gpu_bytesunchanged at 16,588,800 (= 1920x1080 x 4 B x 2 — the swapchain exactly), andrss_bytesup only ~3 MB, because that box renders on a discrete GPU where the textures sit in VRAM and never enter the working set. That is exactly why this item needs the iGPU, where GPU memory is system memory — and why the doubled float footprint is unmeasured rather than known-harmless. (Plan 0033 Risks: “memory is a projection, not a measurement”. Same mitigation as above — the cap is one constant.) - Bloom on the low-end box, 1080p. Plan 0045 Phase 4 added a bright-pass, a blur pyramid
and a recombine as a third
PostStage. It is off by default (bloom_amount = 0skips the stage entirely — no offscreens, no pyramid, no pipelines), so an ordinary run on most of the library measures none of it. Loadstar_lantern— it is the shipped preset built for this stage and binds all three params (bloom_amountaround 0.95 rising on onset,bloom_threshold = 1.0,bloom_radiusaround 2.15), so no scratchRLX_PRESET_DIRis needed any more. When active the stage costs 4N passes atTierConfig::bloom_levels(Floor= 4,Rich= 6) plus its own grid-sizedbloom-srcoffscreen and the pyramid — 16.6 + ~11 ≈ 28 MB at the floor cap (NFR §12). Report (a) whether fps holds ≥ 60 @ 1080p with bloom active on top oftrails+ the fold, and (b) the p99 against the same preset withbloom_amount = 0. If it misses, the lever isTierConfig::FLOOR.bloom_levels— a capacity, not a look, so it is a smaller decision than the other levers on this page, but the halo does visibly shorten. (Plan 0045 Phase 6 measured the Rich side on the dev box’s discrete GPU. Bloom is not what is expensive there:star_lanternruns 164 fps, p99 8.2 ms windowed — comfortably inside a 60 Hz frame — againstattractor_clifford’s p99 19.9 ms andattractor_leviathan’s 19.0 ms on the same run, neither of which binds bloom at all. (Both attractor figures predate ADR-0140 and were taken at a flat 150 000 samples; see theRichcalibration item below.) So the cost that puts the heaviest shipped preset past a 60 Hz frame at Rich is the float composite plus the attractor, not this stage. Still owed on this page: the samestar_lanternrun at native fullscreen, theFloor-pinned sanity pass, and all of the low-end-box side.) - The reaction-diffusion present’s reconstruction cost, on the low-end box, 1080p. Plan 0033
replaced the RD present’s field sampling with a Catmull-Rom reconstruction to get the coral
look. The present pass now calls
sample_vfive times per fragment, each at nine bilinear taps — roughly 45 texture fetches per fragment, over the whole screen, every frame. It shipped unmeasured on hardware: the WARP figure first reported was retracted as run-to-run noise (the same suite timed 193.6 / 224.2 / 105.2 s across three runs), and a software rasterizer says nothing about an iGPU’s texture-unit throughput anyway. Loadreaction_reef(or anyreaction_*preset), let it settle with the overlay on (F3), and report (a) whether fps holds ≥ 60 @ 1080p and (b) the p99. If it fails, that is a user call, not an automatic revert. The reconstruction is one function in the RD present shader and reverting it is cheap, but it costs the coral look outright — so route a failure toarchitectwith the number, and let the look/perf tradeoff be decided rather than assumed. (Plan 0033 shipped this and never measured it; extracted at Plan 0035’s Phase 4.) - The swarm’s depth axis, on the low-end box, 1080p. Plan 0043 Phase 3 added per-particle
depth math and a fourth vertex attribute inside a loop that runs 10 000 times per frame.
Measured on the dev box over 5000 frames at 1920x1080: 1.03–1.09 ms/frame before,
1.56–1.58 ms after — about +0.5 ms. That is not fill rate (pinning the sprite scale flat
still measures 1.60), so it is the depth math plus the wider instance, and it will not shrink
on a slower box. Phase 3’s done-when named NFR §1/§9’s ≥ 60 fps @ 1080p floor as the
acceptance criterion and that floor was never measured — it is defined on this box.
Load
swarm_dense.toml(the highest visible density of the three survivors, and the one whosefield_freq ~5.2keeps the most particles resolving separately), let it settle with the overlay on (F3), and report (a) whether fps holds ≥ 60 and (b) the p99. If it fails, the lever isTierConfig::FLOOR.swarm_particles(core/src/render/tier.rs— the constant moved there in Plan 0044) — and per Plan 0043’s own risk bullet that is a look decision that routes back toarchitect, not a constant to quietly lower. (Plan 0043 Phase 3’s done-when, extracted at that plan’s close.) - The analytic field’s escape-time budget, on the low-end box, 1080p. Plan 0163 added
analytic_field, a fullscreen per-pixel loop whose cost isiterationsper pixel on every pixel of the set’s interior, and capped it per tier withTierConfig::FLOOR.field_iterations= 64 — a number taken from arithmetic, not a measurement (the field’s doc comment incore/src/render/tier.rscarries it). No shipped preset draws the system yet, so pointRLX_PRESET_DIRatdocs/examples/field/and loadescape_time.toml; then write the heaviest frame the cap allows beside it — the same file withzoom = "3",pan_x = "-0.2", so the set’s interior fills the window and every pixel runs all 64 steps. Overlay on (F3), report (a) whether fps holds ≥ 60 @ 1080p on both, and (b) the p99. Loadchladni.tomltoo: it is a closed form with no loop and should be the cheapest system in the engine, which is worth one line confirming. If the heavy frame misses, the lever isTierConfig::FLOOR.field_iterations— and lowering it changes what an escape-time preset looks like on this tier, not just how dense it is, so it routes toarchitectwith the number rather than being quietly lowered. (Plan 0163 Phase 4 set the cap without target hardware; this is where the measurement comes from.) - The cellular system at the Floor caps, on the low-end box, 1080p. Plan 0164 added
cellular, whose cost is one pass per generation over the grid — two forlarger_than_life, whose neighbourhood is summed as a row pass and a column sum — and capped it per tier withTierConfig::FLOOR.cellular_grid= 512 andcellular_radius= 6, both from arithmetic, not a measurement (their doc comments incore/src/render/tier.rscarry it). No shipped preset draws the system yet, so pointRLX_PRESET_DIRatdocs/examples/cellular/and loadlarger_than_life.toml; then write the heaviest frame the caps allow beside it — the same file withgrid = 512in its[cellular]table,radius = "6"andstep_rate = "60". Overlay on (F3), report (a) whether fps holds ≥ 60 @ 1080p on both, and (b) the p99. Loadlife_like.tomlandcyclic.tomltoo, which read eight neighbours and should cost a fraction of it. If the heavy frame misses, the levers arecellular_gridandcellular_radius— and lowering either changes what a preset looks like on this tier (a smaller grid draws every pattern larger; a smaller radius runs a different rule), so it routes toarchitectwith the numbers. (Plan 0164 Phases 3 and 5 set both caps without target hardware.) - The cellular system’s look, any box. Load the three files in
docs/examples/cellular/and say, for each, whether it reads as structure or as noise:life_like.tomlfor whether the fading wake carries the history,larger_than_life.tomlfor whether its blobs visibly travel,cyclic.tomlfor whether the spirals are visible as spirals and rotate. Also run one same-system dissolve between two cellular presets: two presets of one system share one scene, so the dissolve holds the outgoing picture still while the incoming one runs (ADR-0198), and on this system that shows as a frozen automaton fading out — say whether it reads as a defect. - The plexus system at the Floor caps, on the low-end box, 1080p. Plan 0235 added
plexus, whose cost is a pairwise test of every point on the CPU plus the fill of its lines, which an openaperturewidens. Its Floor caps —plexus_points600,plexus_edges6000,max_coc_px12 — were measured on the development box’s integrated GPU (under 4 ms a frame headless, release build), not on the low-end box. Load the shipped Synapse (cloud) and Storm Sea (sheet); then write the heaviest frame the caps allow beside them —docs/examples/plexus/sheet.tomlwithpoints = 600,link_distance = "0.6"andaperture = "24", the top of its declared range. Overlay on (F3), report (a) whether fps holds ≥ 60 @ 1080p on both, (b) the p99, and (c) what the standalone prints about the clamps. If the heavy frame misses, the levers are the three caps, and loweringplexus_pointsormax_coc_pxchanges what a preset looks like, so it routes toarchitectwith the numbers. - The plexus system’s look, any box. Load
cloud.tomlandsheet.tomlfromdocs/examples/plexus/and say, for each, whether the depth reads: whether lines visibly soften away from the focal plane, whether links fade in and out rather than popping as the points drift, and, on the sheet, whether the ripple reads as cloth rather than as a mesh rewiring. Then bindapertureto a live control and sweep it, and say whether a blurred line dims as it spreads rather than flaring.
Built from 13c7582 at version 0.158.0. This site tracks main and is not versioned per release.