Everything the next agent needs to run the Phase 2 optimisation loop on a machine that can launch the client: - analysis/client-perf/: LEVERS (ranked levers + corrections), BENCH-MATRIX (world, scenes, config IDs, blocks B0-B14 with decision rules), PLAYER-TUNING, SPAWN-TUNING, research briefs, the jar scanner and its output, observed default configs, and proposed-configs/ (build.py generates tiers and bench variants and fails on unknown keys; apply_variant.py applies a variant and merges options.txt). - analysis/client-perf/bench/onion-bench/: bench-world datapack (scene teleports, Create grid, mob pen, sound storm, 120 s teleport tour). - analysis/audit/: the static recipe/dependency audit, including gen_fixes.py, which generates the shipped Paxi datapack and was never tracked. - phase0/: per-machine measurement harness (Steam Deck, 7700K/1060, 6700K/1080 Ti). - .pi/journal.md: running work log; read it first. All of it is packwizignored, so nothing here ships to players.
107 lines
24 KiB
Markdown
107 lines
24 KiB
Markdown
# Research: Client rendering cost of the Create/Sable stack (r7)
|
||
|
||
Scope: Sable 2.0.5, Create Aeronautics bundled 1.3.2 (aeronautics 1.3.2 + simulated 1.3.2 + offroad 1.3.2), SSRD 1.8.7, Sable: Physics Compat 1.3.0, Create 6.0.10 + Flywheel 1.0.6 (jar-in-jar), Slice & Dice, Dragons Plus, Enchantment Industry — on 1.21.1 NeoForge, Sodium 0.8.13, Iris 1.8.14-beta.1, DH.
|
||
|
||
Tag legend: **VERIFIED** = confirmed against the exact pinned jars in this repo (bytecode/config inspection) or an official spec; **DOCUMENTED** = official issue tracker/changelog/mod page; **COMMUNITY** = reddit/user comments; **INFERENCE** = my reasoning.
|
||
|
||
## Summary
|
||
|
||
Sable does not have its own renderer — its only sub-level renderer (`SODIUM_REACHAROUND`) re-drives **Sodium's own chunk renderer once per sub-level** (own viewport, frustum, section meshing, layered draws), so each airship is effectively a small second terrain pass, and cost scales with *number of sub-levels × their meshed section count*, not with world render distance. The two biggest *client* levers are (1) shaderpacks: Flywheel's `indirect` **and** `instancing` backends both self-disable while a shaderpack is active (and this pack ships **no** Iris Flywheel Compat), dropping Create contraption rendering onto the vanilla block-entity path, and (2) per-frame pathological interactions (log spam on the render thread, per-tick sub-level-aware sound distance math) that produce the "FPS decays over 30–60 min" reports. Known FPS bugs in the trackers are mostly either fixed by our pinned versions (burner-sound degradation fixed in Aeronautics 1.3.0) or still open and unconfirmed on 2.0.5/1.3.2 (gradual decay while sub-levels exist).
|
||
|
||
## Findings
|
||
|
||
### A. How a Sable sub-level renders, and how it scales
|
||
|
||
1. **Sable's sub-level renderer is a Sodium "reach-around", not a separate engine.** `sable-client.toml` exposes exactly one renderer: `sub_level_renderer = "SODIUM_REACHAROUND"` (sole allowed value). Bytecode of `mixin/sublevel_render/impl/sodium/SodiumWorldRendererMixin` shows per sub-level: build a Sodium `Viewport` from the camera + sub-level container, `compileSections` (chunk mesh builds) honoring Sodium's `performance.chunkBuildDeferMode`/`PrioritizeChunkUpdates`, then draw via `ChunkRenderMatrices` + layered render types (`VeilRenderType.LayeredRenderType`) with `ShaderInstance.setDefaultUniforms`. Sub-levels also have their own frustum (`cullingFrustum`) and per-frame culling update. — **VERIFIED** (jar inspection; keys cross-checked in `analysis/client-perf/data/observed-default-configs/sable-client.toml`; Sodium integration also described in Sable's own README: https://github.com/ryanhcode/sable)
|
||
2. **Cost model.** Per frame each visible sub-level costs: one frustum+cull update, draws for all compiled sections in it (≈ ceil(blocks/16)³ worst case, typically the hull), plus matrix-only transform (movement itself is cheap — it's a pose, not a re-mesh). Re-meshing happens when blocks on the sub-level change (also piston/contraption edits). Scaling is roughly linear in *count of rendered sub-levels* and in *meshed section count per sub-level*, additive to normal world terrain cost; SSRD then decides how far away this pipeline runs. — **VERIFIED** (mechanism) / **INFERENCE** (exact per-sub-level ms; no public benchmark found)
|
||
3. **Sable patches the shader stack it runs on.** Sable 2.0.5 ships overrides of **Flywheel's internal shaders** (`assets/flywheel/flywheel/internal/*`, plus `light/flat.glsl`, `light/smooth.glsl`, `light/smooth_when_embedded.glsl`) so Create Flywheel visuals can be embedded in sub-levels; it has a `sublevel_render.fancy.ProgramMixin` and `compatibility.flywheel.ShaderSourcesMixin`. The *vanilla* core-shader override in the Sable stack is only `worldborder.*` from the nested Veil 4.3.2 jar (4 files) — the static scan's "sable overrides vanilla core shaders" is real but tiny in file count; the runtime shader patching (Veil/Flywheel) is the substantive interference surface. Iris compat exists explicitly (`SableIrisCompat`, `compatibility.iris.ExtendedShaderMixin`), and the pack additionally ships `irisveil-0.3.0` (Iris Veil Compat). — **VERIFIED** (jar inspection; static scan in `analysis/client-perf/data/jarscan-report.md`)
|
||
4. **Sable does not disable Sodium optimizations** — the opposite: it *requires* Sodium (SSRD hard-requires it too) and *reads* Sodium settings (`PerformanceSettings.chunkBuildDeferMode`, `PrioritizeChunkUpdates`) to decide how sub-level rebuilds are queued; it changes no `sodium-options.json` keys. Known Sodium visual conflicts with Sable were fixed over time ("Fix some visual issues with Sodium on AMD machines" in 2.0.0; "Update Sodium compatibility to 0.8.13 alpha" in 2.0.0). — **VERIFIED** (jar inspection) + **DOCUMENTED** (https://api.modrinth.com/v2/project/T9PomCSv/version)
|
||
5. **Client-cost toggles that exist in Sable 2.0.5** (all keys verified in `SableClientConfig` / observed defaults):
|
||
| key | default | perf relevance |
|
||
|---|---|---|
|
||
| `sub_level_dynamic_shading` | `true` | adds `dynamic_directional_shading` mixins into `ModelBlockRenderer`/`AmbientOcclusionFace`/`SectionCompiler` (meshing-side cost for sub-levels) |
|
||
| `sub_level_skylight_shadows` | `false` | if enabled, sub-levels cast world shadows — leave off |
|
||
| `sub_level_water_occlusion` | `true` | hooks `FogRenderer`/`GameRenderer`/`Camera` |
|
||
| `sub_level_snapshot_interpolation_delay_ticks` | `1.5` (0–100) | interpolation buffer, not render cost |
|
||
| `sub_level_renderer` | `SODIUM_REACHAROUND` | only value; no vanilla fallback to pick |
|
||
| `attempt_udp_networking` | `true` | client side of UDP movement channel (disabling = "worse performance and latency" per common-config comment) |
|
||
Common config (`SableConfig`): `sub_level_tracking_range` (network distance of sub-levels to players), `sub_levels_with_players_cannot_unload`, `sub_level_splitting*`, `disable_udp_pipeline`, `verbose_serialization_logging`. — **VERIFIED** (jar inspection). Community advice to raise tracking range to 1280 (default 320) is about *server→client streaming* of sub-levels, not client frame cost: **COMMUNITY** (https://www.reddit.com/r/CreateMod/comments/1tdil1p/limiting_sublevel_render_distance_in_sable/ — key name `sub_level_tracking_range` verified in jar)
|
||
|
||
### B. Known FPS issues / fixes in the Sable & Aeronautics trackers
|
||
|
||
6. **Render-thread log spam can collapse FPS near any sub-level (Sable #881, open).** A mod calling `getEntityLookedAt()` every frame produced huge AABBs against Sable's entity getter; Sable logged `Aborting entity get for abnormally large AABB` hundreds of times/sec, log4j ate ~75% of the render thread, 30→9–12 FPS. Root cause is the *triggering mod* (LegendarySurvivalOverhaul — **not in our pack**; only `legendary-tooltips` is, which does no entity lookups). Lesson for us: any per-frame entity/clip query mod can detonate on sub-levels; watch client logs for repeated Sable errors. — **DOCUMENTED** (https://github.com/ryanhcode/sable/issues/881)
|
||
7. **"FPS decays over 20–60 min while a sub-level exists" (Sable #1011, open; Simulated-Project #746/#1204).** Two distinct reported causes: (a) #1011 — gradual decay mitigated temporarily by F3+T (texture reload) or world rejoin, smells like a render-resource leak (Sable 1.2.2 era, unconfirmed on 2.0.5); (b) #746/#1204 — `BalloonBurnerSoundInstance` (`aeronautics:block.hot_air_burner.head`, `aeronautics:block.steam_vent.head`) re-played ~20×/s, each tick doing `distanceSquaredWithSubLevels → projectOutOfSubLevel → getContaining → getLocalPlot → getChunk/getBlockEntity` — hundreds of× vanilla cost; master volume 0 or blocking the two sound IDs stabilizes FPS. **Fixed upstream:** Aeronautics 1.3.0 changelog has "Fix performance degradation with Adjustable Burner sounds" → our 1.3.2 pin includes the fix. Caveat: 1.3.2 still contains `BalloonBurnerSoundInstance` with `distanceSquaredWithSubLevels` and `AeroSoundDistUtil.tickGlobalBurnerSound` — the sub-level-aware per-tick distance math is structurally still there, so treat "burners on many airships" as a known stressor. — **DOCUMENTED** (https://github.com/ryanhcode/sable/issues/1011, https://github.com/Creators-of-Aeronautics/Simulated-Project/issues/746, https://github.com/Creators-of-Aeronautics/Simulated-Project/issues/1204, https://api.modrinth.com/v2/project/oWaK0Q19/version) + **VERIFIED** (1.3.2 jar inspection)
|
||
8. **Iris shader artifacts with sub-levels — affects our exact stack (Iris #3164, open).** With Iris 1.8.14-beta.1 + Sable 2.0.x + Aeronautics 1.3.x + Sodium 0.8.13, physics structures render incorrectly *with shaders enabled*; artifact scales with structure size; any shaderpack; goes away with shaders off; specifically triggered by shader **real-time shadows** (Complementary/Miniature: disable shadows; Solas: disable SSAO). Root cause attributed to Veil; a community fix exists but is unmerged. Our `shaderpacks/` = **Complementary Reimagined + Makeup–Ultra-Fast**, i.e. the affected families (Makeup–Ultra-Fast is also named in SSRD #50 "SSRD not working with Shaders"). — **DOCUMENTED** (https://github.com/IrisShaders/Iris/issues/3164, https://github.com/RanoldStranold/SSRD/issues/50)
|
||
9. **Other tracker items (context, mostly visual or fixed):** sub-levels invisible behind DH LODs at distance when tracking range > view distance (Sable #376); "Visual bugs with Sodium" world-invisible report (Sable #331, older Sable); Iris tessellation-shader geometry invisible with Aeronautics (Simulated-Project #308); IFC + `flywheel:DEFAULT` → invisible/transparent cogs & shafts (iris-flw-compat #244); resource leak of Contraption Diagram fixed in Aeronautics 1.1.0. — **DOCUMENTED** (https://github.com/ryanhcode/sable/issues/376, https://github.com/ryanhcode/sable/issues/331, https://github.com/Creators-of-Aeronautics/Simulated-Project/issues/308, https://github.com/leon-o/iris-flw-compat/issues/244, https://api.modrinth.com/v2/project/oWaK0Q19/version)
|
||
|
||
### C. SSRD (1.8.7) — what it changes on the client
|
||
|
||
10. **Config surface:** a "Sub-Level Render Distance" **slider injected into Sodium's video settings** (below Simulation Distance); slider max is dynamically capped by your DH/Voxy LOD distance or the server maximum; server caps via `/gamerule ssrdMaxRenderDistance` (**default 128 chunks**) and `/gamerule ssrdForceloadLimit` (**default 2 per player**). SSRD 1.8+ **requires Sodium 0.8** (we have 0.8.13 ✓) and DH or Voxy on the client. — **DOCUMENTED** (https://modrinth.com/project/fJ183v3D)
|
||
11. **Cost & bugs:** raising the slider = more sub-levels rendered by the full Sable/Sodium pipeline at distance (frame cost scales with visible sections, culling still applies), plus server-side force-loading pressure. Known issues: sub-levels visible through LODs with certain shaderpacks (Modrinth warning), DH fade-out also fades sub-levels (#64), zoom glitching (#66), Colorwheel incompatibility (#62, closed), various forceload/unload bugs (mostly closed as of 1.8.7). Mixins confirm the hooks: `RenderSectionManagerMixin`, `SodiumConfigBuilderMixin` (the slider), `VanillaFrustumMixin`/`SodiumViewportMixin`, `RenderSystemFogMixin`, DH `DHShaderSourceMixin`/`FrameUniformsMixin`, plus visual-distance mixins on contraption/entity/block-entity visuals. — **DOCUMENTED** (https://modrinth.com/project/fJ183v3D, https://github.com/RanoldStranold/SSRD/issues?q=is%3Aissue) + **VERIFIED** (`SSRD-1.8.7-1.21.1.jar` mixin list)
|
||
12. **sablecompat** (`Sable: Physics Compat` 1.3.0) only provides tags for modded blocks — no rendering behavior. `Create Aeronautics: Compatibility` 1.1.3 likewise compat glue. Neither is a perf surface. — **DOCUMENTED** (https://modrinth.com/project/sZbcIrJb; jar metadata)
|
||
|
||
### D. Flywheel backend choice (Pascal NVIDIA vs Mesa RADV, with Iris)
|
||
|
||
13. **Backend IDs & requirements (Flywheel 1.0.6, verified in source + jar):** `flywheel:off`, `flywheel:instancing` (GL 3.3 + `ARB_shader_bit_encoding`; priority 500), `flywheel:indirect` (GL 4.6 + compute/DSA/`ARB_multi_draw_indirect`/SSBO/etc.; priority 1000 — GPU-driven culling with a depth pyramid + MDI; uses `GL_KHR_shader_subgroup`). `DEFAULT` picks the highest-priority *supported* backend, with a fallback log "Flywheel backend fell back from '{}' to '{}'". **Driver special-case: `Driver.INTEL` gets indirect priority 1** ("Intel has very poor performance with indirect rendering, and on top of that has graphics bugs") — irrelevant to our fleet (NVIDIA Pascal, AMD/Mesa RADV). Both Pascal (GTX 10xx) and Steam Deck RADV advertise GL 4.6 + the required ARBs, so **`DEFAULT` → `indirect` on all three machines when no shaders**. — **VERIFIED** (Flywheel `Backends.java` @ Engine-Room/Flywheel branch 1.21.1/dev, and bytecode in `create-1.21.1-6.0.10.jar` → nested `flywheel-neoforge-1.21.1-1.0.6.jar`)
|
||
14. **With a shaderpack active, both backends self-disable:** `supported() = … && !ShadersModHelper.isShaderPackInUse()` on *both* `instancing` and `indirect` → `DEFAULT` falls back to `flywheel:off` (vanilla block-entity path for all Create visuals). This is why the pack has no working Create-instancing under Iris. The documented fix is **Iris & Oculus Flywheel Compat (IFC)**: "Flywheel will disable its optimizations when you are using shaderpacks. This mod forces Flywheel's optimizations to be enabled… render Create's entities using Flywheel Instancing with shaderpack enabled… significantly improve fps" — IFC 2.3.x supports **Create 6.0.9 + Flywheel 1.0.6**, needs **Iris ≥ 1.8.1** (we have 1.8.14-beta.1 ✓); Create **6.0.10 is newer than the last tested 6.0.9** → verify before shipping. **Our pack does not include IFC.** — **VERIFIED** (Flywheel source) + **DOCUMENTED** (https://modrinth.com/mod/iris-flw-compat, https://github.com/leon-o/iris-flw-compat/issues)
|
||
15. **Driver risk notes for indirect:** AMD *Windows* has a confirmed driver crash in Flywheel's indirect path (`atio6axx.dll`, `glBindBuffersRange`/MDI; GPUOpen-Drivers #89, acknowledged in Create/Flywheel repos) — **does not apply** to our fleet (no AMD Windows machine; Steam Deck is Mesa RADV, which Flywheel explicitly detects as `Driver.MESA` and supports); Create #10191 reports indirect crashes with elevator pulleys on one user setup (fix: `instancing`), and some users report indirect crashes with Create 6 + certain setups. Pascal is generally the safest indirect platform; treat any "Create block crash" on a client as "switch `backend` to `flywheel:instancing` or `flywheel:off` first". — **DOCUMENTED** (https://github.com/GPUOpen-Drivers/AMD-Gfx-Drivers/issues/89, https://github.com/Creators-of-Create/Create/issues/10191, https://www.reddit.com/r/CreateMod/comments/1pogo4t/create_6_crashing_when_placing_a_block_other/)
|
||
16. **flywheel-client.toml (verified defaults in pack):** `backend = "DEFAULT"`, `limitUpdates = true` ("instance update limiting with distance" — keeps distant contraptions from updating instances; leave on), `workerThreads = -1` (0–4; parallelizes instance updates, needs restart; 4-core Zen2 Deck vs 8-thread 7700K/6700K → explicit `2` on Deck if update-thread contention shows up is a testable knob), `[flw_backends] lightSmoothness = "SMOOTH"` (values FLAT, TRI_LINEAR, SMOOTH, SMOOTH_INNER_FACE_CORRECTED; config comment: "**May have a large performance impact**" — SMOOTH adds per-vertex light interpolation in Flywheel's uber-shaders; FLAT is the cheap end; each value changes compiled shader permutations). — **VERIFIED** (`observed-default-configs/flywheel-client.toml`, `LightSmoothness.class` bytecode)
|
||
|
||
### E. Create contraption rendering cost & the addons
|
||
|
||
17. **Create 6 = Flywheel 1.0** (official changelog: "Now using Flywheel 1.0"); contraption/kinetic visuals are instances batched per material; `indirect` adds GPU culling+MDI so cost scales with *visible* instances, `instancing` costs CPU draw calls per material (fine for tens of contraptions, and it's what IFC re-enables under shaders). Without Flywheel (backend off, e.g. under shaders without IFC) every kinetic/contraption visual becomes a vanilla block-entity render — the classic "Create + shaders = CPU death" mode. — **DOCUMENTED** (https://wiki.createmod.net/users/changelogs/6.0.0) + **VERIFIED** (backend mechanics, above)
|
||
18. **Sable × Create integration adds its own frame mixins:** Sable 2.0.5 has 30+ `compatibility.create.*` mixins (ContraptionVisual, CarriageContraptionVisual, VisualizationEventHandler, flywheel Engine/RenderDispatcher/EmbeddedEnvironment/VisualManager mixins) so contraptions riding sub-levels render inside the sub-level pass with embedded lighting — contraptions on airships are therefore *both* Flywheel instances and embedded-environment draws; a big airship factory is the worst-case render target. — **VERIFIED** (`sable-neoforge.mixins.json`, jarscan: create-aeronautics 20 frame mixins, sable 127)
|
||
19. **Slice & Dice, Dragons Plus, Enchantment Industry:** no client-perf issue reports found in their trackers for 1.21.1/Create 6 (S&D mostly touches RenderLevelStage/Gui events per jarscan; no lag/fps issues surfaced). They add ordinary instance/BER content; cost scales with placed blocks like any Create addon. — **DOCUMENTED (absence of evidence)** — treat as "no known client perf issues found" for these three.
|
||
20. **Sound-adjacent sanity note:** Create 6.0.0 already caps boiler sounds ("Play at most four steam engine sounds at once per side"), but Aeronautics adds its own global sound instances; combined with Sable's sub-level-aware distance math (Finding 7) the sound engine is a real client-tick cost center on all machines — an easy benchmark axis (master volume 0 vs 100). — **DOCUMENTED** (https://wiki.createmod.net/users/changelogs/6.0.0) + Finding 7
|
||
|
||
## Top levers (ranked)
|
||
|
||
| # | Lever | Impact | Machine(s) | Risk | Confidence |
|
||
|---|---|---|---|---|---|
|
||
| 1 | Add **Iris Flywheel Compat 2.3.x** (test vs Create 6.0.10) or accept `flywheel:off` under shaders knowingly | **H** — restores GPU instancing for all Create visuals under shaders; without it shader users pay vanilla-BER cost for every cog/contraption | All, biggest on 7700K+1060 (CPU-bound) and Deck (4-core Zen2) | M — IFC lists Create 6.0.9 as last tested; visual glitches possible per iris-flw-compat #244 | High (Flywheel source-verified behavior + IFC docs) |
|
||
| 2 | In shaderpack settings, **disable real-time shadows/SSAO** (Complementary Reimagined, Makeup–Ultra-Fast) or accept #3164 artifacts | **H** — removes documented sub-level rendering corruption *and* shadow-pass cost; shadows are the confirmed trigger | All shader users | L — pure shader setting | High (Iris #3164 reproduces on our exact versions) |
|
||
| 3 | Keep **SSRD slider modest** (e.g. start at 8–16 chunks, not the 128-chunk server cap) and don't forceload broadly | **M–H** — directly bounds how many sub-level sections the per-sub-level Sodium pass draws; also server load | Deck (GPU/VRAM-limited) & 1060 6GB first | L — slider is the intended knob; gamerule cap on server | Medium-High (mechanism verified; magnitude unbenchmarked) |
|
||
| 4 | Prefer `flywheel:indirect` (DEFAULT) **without** shaders; only drop to `flywheel:instancing` on crash; consider `lightSmoothness = "FLAT"`/`TRI_LINEAR` on Deck if Flywheel shader cost shows in F1 | **M** — indirect = GPU-culled MDI; FLAT removes per-vertex light smoothing cost ("large performance impact" per config) | Deck (RADV) and 1060 for lightSmoothness; indirect OK on Pascal & RADV | L–M — changing lightSmoothness alters visuals (block light smoothing) | Medium-High (config semantics verified; perf delta unbenchmarked) |
|
||
| 5 | Keep `sub_level_skylight_shadows=false`, keep `limitUpdates=true`, keep UDP networking on; watch client logs for Sable "Aborting entity get" spam (Finding 6 class) | **M** — avoids enabling the shadow pass; avoids the documented render-thread log-stall class | All | L | High (defaults verified; #881 mechanism documented) |
|
||
| 6 | If gradual FPS decay reproduces on 2.0.5: test F3+T / master-volume-0 as diagnostics (sound-engine vs render-resource); keep an eye on Sable #1011 | **M** — separates the two documented decay causes cheaply before deeper profiling | All; 8GB-RAM 1080 Ti machine most sensitive to leaks | L — diagnostics only | Medium (both causes documented on adjacent versions; 1.3.2 fixed the burner one) |
|
||
|
||
## Open questions to verify by benchmark
|
||
|
||
1. ms/frame cost of **one** idle sub-level vs an identical static structure in the world (isolates the per-sub-level Sodium re-drive overhead), and the marginal cost of the 2nd, 3rd, 4th sub-level (linearity of Finding 2).
|
||
2. Cost of a **moving + rotating** sub-level with `sub_level_dynamic_shading=true` vs `false` (does rotation re-mesh? how often?) — deck vs 1060.
|
||
3. Frame cost of the **same airship under shaders with IFC on vs off** (instancing-merged vs vanilla-BER fallback) on 7700K/1060 and Deck.
|
||
4. `flywheel:indirect` vs `flywheel:instancing` vs `off` on **RADV/Steam Deck specifically** (Mesa GL4.6 MDI perf is the wildcard; also VRAM headroom vs the 1080 Ti's 8 GB-free-RAM host).
|
||
5. SSRD slider sweep (4/16/32/64 chunks) with DH LODs: frame-time and chunk-build queue behavior (Sable reads `chunkBuildDeferMode=ALWAYS` — does sub-level remeshing starve behind deferred world builds?).
|
||
6. Sound-engine axis: master volume 0 vs 100 near N burners/steam vents on 1.3.2 (residual per-tick `distanceSquaredWithSubLevels` cost, Finding 7).
|
||
7. Long-run decay test (45+ min, sub-levels present, #1011 class) on Sable 2.0.5 — does it still exist? Track client RAM/VRAM and F3+T recovery.
|
||
8. IFC 2.3.x × Create 6.0.10 × Iris 1.8.14-beta.1 compatibility spot-check (invisible cogs #244 class) before adding it to the pack.
|
||
|
||
## Sources
|
||
|
||
**Kept:**
|
||
- Sable repo/README (https://github.com/ryanhcode/sable) — primary source; mixin list & Sodium integration verified against jar
|
||
- Sable issues #881, #1011, #376, #331 (github.com/ryanhcode/sable) — documented FPS failure modes
|
||
- Simulated-Project #746 + #1204 (github.com/Creators-of-Aeronautics) — sound-engine FPS decay, spark profiles, bytecode-level root cause
|
||
- Aeronautics changelog API (https://api.modrinth.com/v2/project/oWaK0Q19/version) — "Fix performance degradation with Adjustable Burner sounds" in 1.3.0
|
||
- SSRD Modrinth page + GitHub issues (https://modrinth.com/project/fJ183v3D, https://github.com/RanoldStranold/SSRD/issues) — config/gamerules, Sodium-0.8 requirement, shader caveats
|
||
- Iris #3164 (https://github.com/IrisShaders/Iris/issues/3164) — repro on our exact version stack; shadow trigger
|
||
- Iris Flywheel Compat Modrinth page (https://modrinth.com/mod/iris-flw-compat) — shader-mode Flywheel behavior + IFC support matrix
|
||
- Flywheel `Backends.java` (raw.githubusercontent.com/Engine-Room/Flywheel/1.21.1/dev) — backend support conditions, Intel deprioritization
|
||
- GPUOpen-Drivers/AMD-Gfx-Drivers #89, Create #10191, r/CreateMod threads — driver-level indirect risks
|
||
- Create 6.0.0 changelog (https://wiki.createmod.net/users/changelogs/6.0.0) — Flywheel 1.0 baseline
|
||
- Local pinned-jar inspection: sable 2.0.5 (+ nested veil 4.3.2), create 6.0.10 (+ nested flywheel 1.0.6), aeronautics bundled 1.3.2, SSRD 1.8.7, observed default configs (`analysis/client-perf/data/observed-default-configs/`)
|
||
|
||
**Dropped:**
|
||
- Modders-of-Create/Create-Aeronautics #14 "Gradual drop in fps" (404 — repo/issue no longer resolvable; superseded by Simulated-Project #746/#1204)
|
||
- r/CreateMod "Limiting sublevel render distance in Sable" full thread (login-walled; snippet retained only as COMMUNITY corroboration; its `ticking_range` key name is stale — actual key verified as `sub_level_tracking_range`)
|
||
- mcmod.cn Flywheel page (secondary aggregator; its AMD-Windows advice superseded by GPUOpen issue #89)
|
||
- 9minecraft/deepwiki Flywheel articles (SEO/aggregator content, no unique facts)
|
||
|
||
## Gaps
|
||
|
||
- No public benchmark quantifies per-sub-level frame cost or scaling with count/size — the cost model in Finding 2 is mechanism-derived, not measured.
|
||
- Could not confirm whether Sable #1011 (gradual decay, F3+T-reset) still reproduces on Sable 2.0.5 — issue is open but filed against 1.2.2; no maintainer root-cause posted.
|
||
- IFC compatibility with Create **6.0.10** specifically (last tested 6.0.9) is unverified; nor is IFC × Sable 2.0.5 embedding (Sable overrides Flywheel shaders, IFC also patches them — interaction untested publicly).
|
||
- Shaderpack-specific behavior of *Makeup–Ultra-Fast* with SSRD (#50) and Complementary Reimagined with #3164 is reported for sibling packs (Makeup–Ultra-Fast plain, Complementary Unbound); Reimagined itself untested in those threads.
|
||
- Steam Deck (RADV) Flywheel-indirect reports are anecdotal in either direction; no RADV-specific issue was found, which is weak evidence of health, not proof.
|