Compare commits

..
4 Commits
Author SHA1 Message Date
logan 611a1a5952 docs: client-perf analysis, bench harness and work journal
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.
2026-10-14 18:15:32 -04:00
logan d80f85b3f6 feat(config): moderate spawn tuning for Alex's Mobs, Fowl Play, Critters
Every visible entity multiplies the client render cost (vanilla, EMF/FA,
GeckoLib, ETF, dynamic lights) and the server tick. These cuts target only the
species that are heavy by weight x group size. Rare mobs keep their defaults.

- Alex's Mobs: halve 9 common weights (gazelle and capuchin herds, straddler,
  rocky roller, underminer, elephant, blobfish, mudskipper, caiman).
- Fowl Play: lower duck/goose/gull/sparrow weights and max group sizes
  (upstream #214, ~400 ducks on rivers, is still open in 1.2.3).
- Critters and Companions: about 40% off sea bunnies and the forest/lush bug
  rules. It does have a spawn config; configVersion 2 skips its v1->v2
  migration.

All three are partial files. NeoForge (TOML) and YACL 3.8.2 (JSON5) keep
defaults for missing keys. Shipped enforced from config/ because the server
reads them from this repo. Details and the B14 measurement plan:
analysis/client-perf/SPAWN-TUNING.md.
2026-10-14 18:14:50 -04:00
logan 5919955548 chore(analysis): archive finished reviews, drop stale duplicates
Move the completed 2026-09 candidate review (MODLIST-REVIEW/-GROUPS,
CANDIDATE-APPENDIX, PACK-CONTEXT), FINDINGS.md and the shipped FTB Chunks swap
write-up into analysis/archive/, with a README mapping their old paths. The
review's build pieces, subagent intermediates and Modrinth API dumps are
deleted: the assembled reports carry their content. MODLIST-GROUPS.md was a
byte-for-byte duplicate of analysis/groups-table.md.

Also: drop the now-pointless FINDINGS/MODLIST packwizignore lines (analysis/
covers the archive), and gitignore *.tar.gz so the 650 MB map-migration world
tarball can't be committed by accident.
2026-10-14 18:08:48 -04:00
logan a01bc3b2f1 feat(perf): ship client perf defaults via Default Options, add perf mods
Pack-side half of the client performance work (analysis/client-perf/).

- Add Default Options 21.1.8 (client). It copies config/defaultoptions/
  options.txt and extra/** into place only when the target is absent, so
  player changes are never clobbered. It is also client-only. packwiz
  `preserve` would also land these files in this repo's server config, which
  matters for DistantHorizons.toml [server]/[common] and SSRD's COMMON config.
- Seed provisional mid-tier defaults generated by
  analysis/client-perf/proposed-configs/build.py --ship: render distance 8,
  DH LOD radius 128 / SSAO off / 2 threads, EMF animation LOD 12, Flywheel
  TRI_LINEAR lighting, LambDynamicLights fast, SSRD 16 chunks, Sound Physics
  16 rays / 2 bounces plus per-tick caps on noisy Create sounds. All values
  are unmeasured; Phase 2 (BENCH-MATRIX.md) replaces them. ModernFix
  dynamic_resources is held back until bench block B6 passes.
- Add Sodium Extra 0.9.4, Reese's Sodium Options 2.2.4, BadOptimizations
  2.4.1 and Particle Core 0.3.3 (all client-side). Their declared ranges match
  the pins (Sodium 0.8.13, fzzy_config, Kotlin for Forge).
- Bump Puzzles Lib 21.1.62 -> 21.1.64 as a bugfix: 21.1.63 restores dropped
  access transformers. The event-cache change in 21.1.64 is Fabric-only.
2026-10-14 18:05:45 -04:00
131 changed files with 31093 additions and 9 deletions

No files matched your search

+4
View File
@@ -3,3 +3,7 @@ cache/
# Immersive Paintings player-upload cache (regenerated at runtime; see .packwizignore)
immersive_paintings_cache/
# Large or regenerable local artifacts
*.tar.gz
analysis/client-perf/proposed-configs/out/
+9 -2
View File
@@ -21,8 +21,6 @@ kubejs/
local/
# Authoring/review material - belongs in the repo, never in the pack
FINDINGS.md
MODLIST-*.md
analysis/
phase0/
ftbbackups3/
@@ -63,3 +61,12 @@ config/paxi/*
config/paxi/datapacks/*
!config/paxi/datapacks/onion-fixes
!config/paxi/datapacks/onion-fixes/**
# Client perf defaults (analysis/client-perf/proposed-configs/build.py --ship).
# Default Options copies them into place client-side, only when the target is absent.
!config/defaultoptions
!config/defaultoptions/**
# Server spawn tuning (analysis/client-perf/SPAWN-TUNING.md); partial files, the mods
# fill in defaults for every other key. Enforced: the server reads them from here.
!config/alexsmobs-common.toml
!config/fowlplay.json5
!config/crittersandcompanions-common.json5
+413
View File
@@ -0,0 +1,413 @@
# Onion MC — work journal
## Session 2026-10-06 — 60-mod expansion, integration review
### What this is
**Onion MC**, a curated Minecraft modpack managed with **packwiz**.
- Minecraft **1.21.1**, NeoForge **21.1.251**
- **209 mods** (was 149 four commits ago)
- packwiz lives at `~/go/bin/packwiz` — **not on PATH**
- Remote: `ssh://git.ljones.me:2222/logan/onion-mc.git`, branch `main`
- Commit style: Conventional Commits, imperative subject, body explains *why*
- The repo **doubles as a server directory** (`.packwizignore` excludes `libraries/`,
`world*/`, `logs/`, `crash-reports/`, `*.jar`, `run.sh`). Never blanket-un-ignore
anything there — you will index runtime junk.
### Environment (checked 2026-10-06)
- This machine is **NixOS**: no `java` on PATH; use `nix shell nixpkgs#jdk21` for
anything server-side. No server is installed in the repo yet (no `libraries/`,
`run.sh`, or NeoForge jar).
- Client = Prism instance `~/.local/share/PrismLauncher/instances/Onion MC/`. Its
pre-launch hook runs `packwiz-installer-bootstrap` against
`https://git.ljones.me/logan/onion-mc/raw/branch/main/pack.toml`, so launching it
pulls the pushed pack. Last launch (`logs/latest.log`) is **2026-09-24**, i.e.
before all five commits below — confirms the expansion has never been booted.
- `.pi/` is in `.packwizignore`, so this journal never ships.
### State
Five commits, all pushed to `main`, HEAD = `e36bff8`:
| Commit | Contents |
| --- | --- |
| `455e398` | 14 client-side mods + 12 libraries |
| `b6ebdb8` | 11 Farmer's Delight addons + 4 decoration + 4 pet/mob |
| `e371e51` | 15 gameplay/media/social |
| `387ee1e` | config policy change + PetProtect default |
| `e36bff8` | Akashic Tome whitelist config |
Verified after each stage: mod set matches intent exactly (nothing auto-added by
packwiz, nothing missing, nothing removed), `index.toml` hash matches `pack.toml`.
**Two configs ship** (new capability — see policy in gotchas):
- `config/petprotect.json`
- `config/akashictome-common.toml`
### Goal
A **working, well-integrated 209-mod pack**:
1. **Boots clean** on client and dedicated server — no mixin failures, no missing deps.
2. **No duplicate systems** — the pack has a history of removing them (FTB Chunks →
Open Parties and Claims; FTB Quests/Teams/XMod Compat deleted). New mods must not
reintroduce overlapping mechanics without a reason.
3. **No broken recipe chains** — every consumed item stays obtainable.
4. **Performance held** — Sodium, Iris, ImmediatelyFast, EntityCulling, ModernFix,
FerriteCore, Distant Horizons mandatory, C2ME/Noisium server-side, Dynamic FPS.
5. **Tested, not assumed** — nothing has been booted yet.
### Decisions made — do not relitigate without cause
**Excluded candidates:**
- `sable_beyond` — every 1.21.1 build is alpha; wide Create/Aeronautics sublevel-mass
mixin surface. Owner's call.
- `expanded-delight` — beta-only, built against FD 1.2.4 (pack runs 1.3.4); sweet
potato / cranberry / peanut / chili / cinnamon / salt duplicate kept mods.
- `hearth-and-harvest` — no per-crop config, so corn/peanut/cotton/salt/blueberry
dupes couldn't be trimmed. Dropping it also removed two cutting-board collisions
(wheat, sunflower).
- `display-delight` — zero risk but ~250 plate items incl. dishes from Delight mods
we don't run. Could be added any time.
**Rustic Delight dedupe declined.** Its flags are whole content-family switches:
- `enable_cotton` — only dupe partner was hearth-and-harvest (not added).
- `enable_coffee` — real dupe vs extradelight, but cascades into coffee-braised beef,
Haste potions, cherry-blossom/syrup chains.
- `squids_drop_calamari` — also strips calamari from creative tab and villager
trades; `enable_fried_foods` depends on it.
Remaining "duplicates" are tag-merged (`c:crops/coffee_beans` etc.) and benign.
**Kept after being flagged:**
- Grassier Grass — reported shader breakage is Rethinking Voxels-specific; issue
lists Complementary Reimagined (what we ship) as working. BSL bug is separate.
- Perception — OctoLib/ShatterLib is a maintained zero-dep lib; trails are particles,
shake is camera; jar has no shader/post-process assets.
### Open questions for the owner
1. **Potato cutting-board collision → needs a datapack loader.** Only real
unresolved defect. `c:crops/potato` + knife matches both
`extradelight:cutting/sliced_potato` (4×) and `moredelight:cutting/diced_potatoes`
(1×). Neither output is obtainable otherwise; they feed 4 and ~10 recipes. The
losing chain breaks permanently. Fix: rewrite both recipes to emit the combined
output via a datapack loader reading from `config/` (**Paxi** or **Global Packs**)
— a new mod, awaiting approval.
2. **Keep PetProtect?** With both protection flags off it only stops pets being
provoked into fights. Dropping it + config restores vanilla retaliation; Pet
Cemetery works alone.
3. **Keep `mystical-oak-tree`?** Costs Moonlight (2.3 MB) for a 1-in-280-chunk
feature — near-zero value on a pre-generated map. Offered to exclude.
4. **Rustic Delight coffee flag** — one line, if the second coffee should go.
5. **`display-delight`** — add later, or not.
### Known and potential conflicts
| Area | State |
| --- | --- |
| **PetProtect ↔ Pet Cemetery** | Resolved *only* by the shipped config. `isInvulnerableTo` gates on `prevent_pet_damage` alone, so disabling `prevent_pet_death` alone leaves pets immortal. Both flags `false`. Delete the config and Pet Cemetery is dead weight. |
| **extradelight recipe overrides** | 169 files under `data/farmersdelight/recipe/`, ~25 path-colliding with FD's own. Live, ungated. FD recipe book changes noticeably. |
| **Twilight Forest stripping (16 pairs)** | `farmers-cutting-twilight-forest` and `twilight-delight` both cut TF logs into `stripped_X` + `tree_bark`. Identical outputs — harmless. Pre-existing. |
| **Curios slot merging** | `artifacts`, `too-many-bows`, `tarotcards-remastered`, `mermod` define player slots, no `replace`. Should merge — **verify in game once**. |
| **Sophisticated Core disc handlers** | Verified clean: first-supports-wins, predicates disjoint. |
| **`dungeons_delight`** | **29 vanilla mixins** incl. `BlockBehaviourMixin`/`LevelRendererMixin`. Broadest surface added. Untested vs ModernFix/Sodium. |
| **`fowlplay` spawning** | ~13 bird species via `NaturalSpawnerMixin` — spawns in already-generated chunks. Watch tick time. |
| **`fishermans-haven`** | Lighthouse spacing 9/separation 6 (dense); several biome modifiers use **bare un-namespaced biome IDs** (may log errors / silently not spawn). Salt lakes in every biome via `neoforge:any`. |
| **`extradelight` legacy `forge/` biome modifiers** | Inert on NeoForge (working `neoforge/` copies exist). Harmless. |
| **`etched` ↔ `music-disc-maker`** | No code conflict (mixin points re-verified), but duplicate content: two blank discs, two boomboxes, two 9-disc albums, two recording pipelines. Design decision. |
| **Tag merges** | Several mods write the same `c:` crop tags (3 garlics, 3 peanuts, 3 salts, 2 corns…). Benign. **Bell pepper and citrus NOT merged** (`crops/bellpepper` vs `crops/bell_pepper`, `crops/lemon` vs `foods/fruits/lemon`). |
### Not verified — nothing has been booted
All findings are static analysis (jars, bytecode, data files, Modrinth API). Untested:
- Whether the pack **boots at all**, client *and* server.
- `dungeons_delight`'s 29 mixins vs the perf stack.
- Grassier Grass vs **Complementary Reimagined** and **MakeUp Ultra Fast** (MakeUp
untested by anyone).
- Whether Terralith biomes carry `#c:is_*` / `#minecraft:is_overworld` tags that
wild-crop/tree biome modifiers key off (generation density only).
- Whether `fishermans-haven`'s bare-ID biome modifiers parse.
- Whether `extradelight`'s inline-feature `neoforge:` biome modifiers place.
- Whether `extradelight`'s cookbook opens (ships `patchouli_books/cookbook2/` dirs but
**no `book.json`**). The item itself is real.
- `room-for-two` (beta; compat untested by author) and `petprotect` (beta).
- PetProtect edge case: logging out while downed may lose items (upstream #184,
1.19.2, never fixed).
- Curios slot merge rendering all four mods' slots.
### Method notes and gotchas
- **packwiz `side` quirk**: only client-only mods are special-cased; mods with
`client_side: unsupported` still get `side = "both"`. `petprotect` manually set to
`side = "server"` (as `c2me-neoforge` and `noisium` already were).
**`packwiz update` rewrites metafiles and resets these.**
- **Config policy is opt-in.** `.packwizignore` ignores `config/*` and
`defaultconfigs/*`; shipping a file needs `!config/<file>` at the **bottom** (last
match wins), after the blanket `*.json` rule.
- **Duplicate `version_number` traps**: `tarotcards-remastered`, `room-for-two`,
`too-many-bows` reuse version strings across 1.21.1 / 1.21.11 / 26.x. Pin exact
filenames by hand.
- **Undeclared deps on Modrinth**: `perception` → `shatterbyte-lib` (OctoLib),
`dungeons_delight` → `runiclib`. `mystical-oak-tree` → `moonlight` is declared in
the jar but not the API.
- **cdn.modrinth.com returns HTTP 501 to Range requests** — download whole jars.
`unzip` is not installed; use `python3 -c "import zipfile..."`.
- **`lodestonelib`** is the real slug; `lodestone` has no 1.21.1 build.
- `FINDINGS.md`, `MODLIST-GROUPS.md`, `MODLIST-REVIEW.md` are untracked,
packwizignored, and **~60 mods stale**. They hold the FTB-swap reasoning, OPAC
config decisions and the original per-mod compat audit — refresh, don't re-derive.
### Next steps, in order
1. **Boot the pack.** Client first (launch the Prism instance — it self-updates from
the pushed `pack.toml`), then the dedicated server.
2. Check logs for: missing deps, mixin apply failures, `fishermans-haven`
biome-modifier parse errors, anything referencing `dev/ftb/mods/ftbteams`
(soft-dep risk from the FTB removal).
3. Smoke-test: Grassier Grass + Complementary Reimagined, `dungeons_delight` mixins,
curios slots, Pet Cemetery death→collar loop.
4. Watch tick time and entity counts (fowlplay, fishermans-haven, mooblooms).
5. Bring open questions to the owner, potato collision first.
## Static audit 2026-10-06 (all 209 jars + vanilla + NeoForge data)
Scripts/output: `analysis/audit/` (jars cached in `/tmp/onion/jars`, ephemeral).
Deps clean (no missing/out-of-range/incompatible; lambdynlights_runtime is a
false positive — nested under META-INF/jars). No item-tag load failures.
Corrections to the handoff:
- Potato board collision is **3-way**: + `rusticdelight:potato_slices` (81
consuming recipes, board-only source). Vanilla `getRecipesFor` sorts by result
translation key, so `extradelight:sliced_potato` likely wins; rustic + moredelight
lose. moredelight diced potatoes/bread slices still reachable via Create saw.
- New: bread + knife → extradelight vs moredelight bread slice.
- rusticdelight tags `potato_slices` as `c:crops/potato` (re-cut/dupe loop);
veggiesdelight tags sweet potato there too. rustic coffee beans sit in both
`c:crops/coffee` and `c:crops/coffee/cooked`.
- extradelight *disables* 14 FD recipes (relocated to oven/mixing bowl/feast/
chiller — all still obtainable); FD beef_stew is rustic-live vs
extradelight-disabled → load order decides.
Crafting-grid collisions (one output uncraftable): dungeonsdelight vs
twilightdelight TF knives (×4); dungeonsdelight vs frightsdelight crates (×2);
extradelight vs fruitsdelight apple crate, vs hamsterpets cucumber crate; coffee
bag/sack/crate; comforts sleeping bag (vertical) vs handcrafted sheet; fishermans
worms can → own worm vs aquaculture worm. Pre-existing: handcrafted wood plate vs
17 TF drying racks; create vs TF copper nugget (tag-unified, harmless).
## Fix pass 2026-10-06 — pushed as `fc649b4` (on top of `e7d6691`)
- Added **Paxi** 5.1.3 (only dep YUNG's API, already present; injects packs at TOP).
- Datapack `config/paxi/datapacks/onion-fixes/` (43 files), generated by
`analysis/audit/gen_fixes.py` — edit the script, not the JSON. Shipped via a
dir-by-dir re-include chain at the bottom of `.packwizignore` (packwiz's
matcher needs negations *without* trailing slashes or it SkipDirs the parent).
- Re-audit with the pack on top: all real collisions gone. Remaining flags are
benign (dough shaping UI, mixing-bowl fluid variants, Aquaculture Delight
neptunium tiering, Create/TF copper nugget).
- Correction: rustic potato_slices has 3 direct consumers, not 81 (81 was via
the polluted `c:crops/potato` tag).
- `c:crops/potato` and `c:crops/coffee/cooked` now use `replace: true` — any
future mod adding to them must be added to gen_fixes.py.
- Orphaned on purpose (uncraftable, still uncraftable-from): dungeonsdelight TF
knives + crates, hamster cucumber crate, fruitsdelight apple crate. Consider
hiding them in JEI.
- Needs in-game check: `/datapack list` shows onion-fixes (pink), recipes in JEI.
- Rebased over upstream `0adfb6c` (Icy's Better Horses + Modonomicon, 212 mods);
re-audit clean. Note: Better Horses' modId is `icys_better_horses` but it
registers under `icys-better-horses` — the audit's absent-mod check flags it
falsely.
## Session 2026-10-14 — client performance analysis, Phase 1 (static baseline)
HEAD `aa1d273` (212 mods), unchanged. **Nothing committed, nothing changed in the
pack.** All output is in `analysis/client-perf/` (untracked; `analysis/` is
packwizignored).
### What exists now
- `analysis/client-perf/LEVERS.md` — **the deliverable**: ranked levers (Tier 1–3),
meta-levers, add/remove candidates, Phase 2 test order, corrections to the
subagent research. Read this first.
- `analysis/client-perf/README.md` — index and method.
- `scripts/jarscan.py` + `scripts/report.py` → `data/jarscan.json`,
`data/jarscan-report.md`. Parses class-file annotations for real `@Mixin` targets
and injector kinds, per-frame/tick event refs, atlas px (one frame per animated
texture), models, shaders, sounds and entities. It skips the Fabric-only nested
jars of multi-loader jars (DH, LambDynamicLights). Runs in ~35 s over
`/tmp/onion/jars` (ephemeral; refetch with `analysis/audit/fetch.py`; resource
and shader packs were also dropped there).
- `data/observed-default-configs/`: generated configs copied from the Prism
instance's last launch (2026-09-24, the older 110-mod pack). They are the
real-default reference (DH, Sodium, EMF, ModernFix, Flywheel, Sable, SPR…).
- `research/r1..r9-*.md`: nine subagent briefs with confidence tags and URLs.
### Key facts established (verified)
- 951 per-frame mixin classes (121 Overwrite/Redirect); top: Sable 127, Iris 114,
Controlify 84 (GUI), Sodium 48, EMF 42.
- Handcrafted + Chipped + Rechiseled = 58% of the block atlas and 62% of the 69k
models.
- Flywheel 1.0.x disables both GPU backends when *any* shaderpack is active
(checked in `Backends.java`). The pack has no Iris Flywheel Compat.
- DH defaults: LOD radius 256, SSAO and AA on, 2 worker threads. EMF
`animationFrameSkipDuringIrisShadowPass` is already true. ModernFix
`dynamic_resources` is off by default. Flywheel `lightSmoothness = SMOOTH`.
- Sable renders each sub-level by re-driving Sodium's chunk renderer.
`sub_level_skylight_shadows=false` by default; Iris #3164 (sub-level corruption
with shadows) is open.
- Chipped requires Athena and Rechiseled requires Fusion, so neither CTM engine is
removable. Lodestone is required *only* by Miner's Delight.
- Puzzles Lib 21.1.64 has an event-dispatch caching fix; the pack pins 21.1.62.
- Shaders and resource packs are opt-in in practice (the last launch had none
enabled). The pack ships no perf config, and JVM/heap is per-player Prism (old
instance: 8 GB, stock G1).
### Decisions pending (owner)
1. Delivery mechanism for tuned defaults: **Default Options** mod (Balm is already
present) vs packwiz `preserve = true` (semantics with `packwiz refresh`
unverified).
2. Shader policy: default off / opt-in per machine?
3. Server-side spawn tuning (Alex's Mobs #62, Fowlplay #214, Critters &
Companions datapack).
4. Removal candidates: Miner's Delight (drops Lodestone), Fowlplay, Charta, WATUT,
Emojiful.
5. Add candidates: Default Options, Sodium Extra + Reese's Sodium Options,
Particle Core, BadOptimizations; trials: Gnetum, Better Block Entities,
Flerovium, Super Resolution (Deck), Ixeris (P1), Iris Flywheel Compat.
### Next steps
- Phase 2 = benchmark per `LEVERS.md` §6 using the `phase0/` harness (P0 Deck, P1
7700K/1060, P2 6700K/1080 Ti with 8 GB RAM free). Capture the atlas size, heap and
startup time at baseline.
- Before benchmarking: the pack has never booted at this mod count (see the
2026-10-06 session), so do a boot/log check first.
- Free change regardless of benchmarks: bump Puzzles Lib to 21.1.64.
## Session 2026-10-14 (b) — client perf Phase 1b: delivery, staged configs, bench matrix
HEAD `aa1d273`, unchanged. **Nothing committed; zero tracked-file changes; no mods
added/removed.** All output is under `analysis/client-perf/` (untracked, packwizignored).
### Produced
- `proposed-configs/` — `build.py` generates player tiers (`out/T-default|deck|mid|high`)
and 32 bench variants (`out/C0`, `C1`, `dh-*`, `fw-*`, …) from same-version observed
defaults or source-verified templates. **The build fails if an override names a key
that isn't in the base**, so key confirmation is enforced. README §1 = M1 decision,
§2 = tier table, §3 = key provenance.
- `BENCH-MATRIX.md` — replaces LEVERS §6: bench world recipe, scenes S1–S6, JVM sets J0–J3,
blocks B0–B13 with decision rules and budget (~25 h machine time).
- `bench/onion-bench/` — datapack (pack_format 48): scene teleports, `/fill` Create grid
(2,304 kinetic BEs), mob pen, a 24-sounds/tick storm, and a 120 s teleport tour.
**Never run in game**: syntax unverified, and the S2 `/fill`-placed kinetic network may
need motors re-placed by hand (checklist in matrix §2).
- `PLAYER-TUNING.md` — tiers, heap/GC, shader and RP guidance, Deck env vars.
- `proposed-changes/puzzles-lib-21.1.64.patch` — `git apply --check` passes on HEAD.
It touches only `puzzles-lib.pw.toml` + index/pack hashes. A single-mod
`packwiz update puzzles-lib` does **not** reset the side fields on petprotect, c2me or
noisium; only those three are at risk, from bulk updates. Its only dependent is
HeldItemTooltips, range `[21.1.1,)`.
### Verified this session (don't re-derive)
- **packwiz `preserve`** (packwiz `ef87d96` = the installed binary; installer v0.5.14 =
the Prism jar): settable only by hand-editing `index.toml`. It survives refresh, content
change and unrelated `update` (tested). It is **silently dropped** if a refresh runs
while the file is absent or ignored. The installer writes the file only if it's absent.
A skipped file re-logs "invalidated" every launch, and removing a file the installer
wrote deletes the player's copy. Index files have no `side`, so they also land on the
server (this repo *is* the server dir).
- **Default Options 21.1.8**: copy-if-absent for `config/defaultoptions/options.txt`
(`key_` lines stripped) and `config/defaultoptions/extra/**`. Runs at `GameConfig.<init>`:
before NeoForge constructs mods (`ClientModLoader.begin` is inside `Minecraft.<init>`),
but after mixin bootstrap, so too late for `modernfix-mixins.properties`. Balm
`[21.0.39,)`; the pack has 21.0.66.
- Observed defaults come from the **same jar versions as the current pins** (DH 3.3.2,
Sodium 0.8.13, EMF 3.3.9, Create 6.0.10 / Flywheel 1.0.6, Sable 2.0.5, SPR 1.5.1).
All 172 DH values match `Config.java` @ 3.3.2, except DH `numberOfThreads`: the true
default is ceil(nproc/2) = **4** on the fleet (the observed 2 came from this 4-thread
box). `serverId` is per-install random and is stripped from shipped files.
- SSRD 1.8.7 config = `config/ssrd-common.toml` (COMMON; the server reads it too).
`physicsRenderDistance` defaults to 128, slider floor 16.
- LambDynamicLights 4.8.11 = `config/lambdynlights.toml`; `mode` is lowercase
off/fastest/fast/fancy; `[light_sources] entities`.
- SPR merges a partial `sound_rates.properties` over its generated defaults. Sounds over
the cap play without physics; they are not dropped.
- **Puzzles Lib 21.1.64 has no perf change on NeoForge**: `FabricEventFactory` isn't in the
NeoForge jar. The 62→64 diff is access transformers plus one class. LEVERS #14 is
corrected.
- r6's `-XX:ShenandoahGCMode=iu` aborts JDK 21 without UnlockExperimentalVMOptions
(tested). GenZGC and the brucethemoose G1 set parse cleanly.
### Owner decisions pending (presented 2026-10-14)
1. Approve **Default Options** as the delivery mechanism, plus enforced
`modernfix-mixins.properties`. This is a mod add plus 3 `.packwizignore` lines (drafted in
proposed-configs README §1).
2. Apply the Puzzles Lib patch (bugfix only).
3. Shader policy (B7 produces the data).
4. Server spawn tuning (Alex's Mobs / Fowlplay / Critters & Companions).
5. Removal candidates (Miner's Delight → Lodestone, Fowlplay, Charta, WATUT, Emojiful).
6. Add candidates (Sodium Extra + RSO, Particle Core, BadOptimizations; trials). These gate
B12.
### Next steps
1. Boot check (matrix §0). Nothing else can proceed until the pack boots.
2. Build the bench world on P2 (matrix §2); fix any datapack parse errors on `/reload`.
3. Run B0 → B13; write the winners into `build.py`; regenerate; then ship via the approved
mechanism. Existing players need the file-reset step in PLAYER-TUNING §1.
## Session 2026-10-14 (c) — owner decisions applied, pushed for the client machine
The owner answered the pending list; this session acted on it, committed, and pushed.
**The next agent works on a machine that can run the client.** This machine is NixOS with
no `java`, no client and no `unzip`. Those notes are machine-specific; check what the new
machine has.
### Owner decisions (2026-10-14), now settled
1. Delivery = **Default Options** (+ enforced `modernfix-mixins.properties` after B6).
Done.
2. Puzzles Lib → 21.1.64. Done (bugfix only).
3. Shaders: **opt-in** (already the case: packwiz downloads them, nothing enables them).
4. Spawn tuning allowed if not detrimental to gameplay. Done, moderate (below).
5. **Remove no mods.** LEVERS §5 is reference only.
6. Add any helpful mods. Added the five "Add" verdicts. Trials are left to bench B12b, and
the agent may add trial winners.
### Commits (all pushed to `main`; Prism instances self-update from it)
- `a01bc3b` feat(perf): Default Options + `config/defaultoptions/` (8 provisional
mid-tier files from `build.py --ship`); Sodium Extra 0.9.4, Reese's Sodium Options 2.2.4,
BadOptimizations 2.4.1, Particle Core 0.3.3 (all `side = "client"`; deps already present);
Puzzles Lib 21.1.64. **217 mods.**
- `5919955` chore: stale reviews archived to `analysis/archive/` (README maps old paths);
intermediates and API dumps deleted; `*.tar.gz` gitignored.
- `d80f85b` feat(config): spawn tuning, enforced partial files
`config/alexsmobs-common.toml`, `config/fowlplay.json5`,
`config/crittersandcompanions-common.json5`. See `analysis/client-perf/SPAWN-TUNING.md`.
- docs commit: `analysis/client-perf/` (minus the generated `out/`), `analysis/audit/`
(incl. `gen_fixes.py`, which builds the shipped Paxi datapack and was never tracked
before), `phase0/`, and this journal.
### Rules of the road for the iteration
- Change tuned defaults **only** through `analysis/client-perf/proposed-configs/build.py`
(`DEFAULT` / `DECK` / `HIGH`), then `build.py --ship`, then `~/go/bin/packwiz refresh`
(wherever packwiz lives on that machine), then commit.
- Shipped defaults are copy-if-absent. Changing them reaches **fresh installs only**;
existing players use PLAYER-TUNING §1.
- `modernfix-mixins.properties` ships only after B6 passes. Instructions are in the `SHIP`
comment in `build.py`.
- Any new mod: verify its NeoForge 1.21.1 build and its `neoforge.mods.toml` ranges against
the pins, check `side`, rerun B0. **More Culling is unusable**: its NeoForge build
declares `minecraft [1.21,1.21.1)`.
- `packwiz update` (bulk) resets the hand-set `side = "server"` on petprotect, c2me-neoforge
and noisium. A single-mod update is fine.
- On first boot, the mods re-save the partial spawn files in full. Don't commit those
expansions by accident (`git diff config/`).
- `sp-world.tar.gz` (650 MB, untracked, gitignored) is a world save from the map-migration
work. Leave it alone.
### Next steps
1. BENCH-MATRIX §0 boot check (now covers Default Options seeding, the RSO/SSRD video
screen, YACL spawn-config loading, and the Iris↔Sodium report).
2. Build the bench world (§2), then run B0 → B14. Write the winners into `build.py`, ship,
refresh, commit.
3. Report shader-policy data (B7) and any trial-mod verdicts (B12b) to the owner.
+1 -1
View File
@@ -4,7 +4,7 @@
and unit-tested; final step blocked on a copy of the server world save.
**Goal:** give each player a native Xaero's map covering, as closely as possible, exactly the terrain
they had revealed in FTB Chunks.
Confidence tags as in `FINDINGS.md`.
Confidence tags as in `analysis/archive/FINDINGS.md`.
---
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,265 @@
# Onion MC — candidate mods grouped for review
Every candidate grouped by what it is *for*, with what it brings, what it costs in dependencies, how much it changes gameplay, the verdict, and the thing to watch. **ADDED** = already added on the `mod-pack-additions` branch. **ALREADY-IN-PACK** = duplicate of an installed mod.
Verdict legend: **ADD** (ship in the core cohort) · **ADD-OPTIONAL** (good; taste/library decision) · **MAYBE** (test or design decision first) · **SKIP** (don't) · **ALREADY-IN-PACK** · **ADDED**. `New deps` lists required libraries not already in the pack (candidate deps marked).
## Shaders & render stack
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Iris Shaders** (`iris`) | Shader-pack loader compatible with existing OptiFine shader packs | — | Overhaul | ADDED | Already added on branch mod-pack-additions (see Post-review update) |
| **Iris Veil Compat** (`iris-veil-compat`) | Bridges the Veil rendering engine into Iris shaderpacks so Veil-rendered visuals (Aeronautics wings, glass panels, contrails) render correctly under a shaderpack; r… | Iris Shaders | None | ADDED | Already added on branch mod-pack-additions (see Post-review update) |
| **Veil** (`veil`) | developer tooling for advanced rendering — JSON-defined framebuffers, custom post-processing pipeline, full OpenGL shader support + shader injection, color themes/e… | — | None by itself | SKIP | rendering-engine tooling with no dependent mod in the pack, on the most fragile part of the stack |
| **Shine** (`shine`) | Shader-free visual effects: bloom, colored lighting, atmosphere, weather, particles, interactive details; in-game config screen | — | Client-cosmetic | MAYBE | confirmed Sodium 0.8.12 compatibility, but partial feature loss on that version, overlap with Subtle Effects, and a privileged positio… |
| **Grassier Grass** (`grassier-grass`) | Per-blade custom wind shader: grass leans and ripples with rolling gusts | — | Client-cosmetic | MAYBE | best-looking pick in the batch, but Sodium 0.8-alpha compatibility is unproven; gate on a crash/visual test |
| **Fog** (`fog`) | Complete fog revamp: start/end distance, cave fog that thickens with depth, weather- and time-based (sunset/moon-phase) fog colors, biome-tinted fog including modde… | MRU | Client-cosmetic | MAYBE | attractive but unproven next to DH/SSRD; only add after an in-game fog + DH visual test |
| **ATMOSPHERICS** (`atmospherics`) | Real-time per-biome customization of fog, sky, clouds, haze and stars with smooth biome transitions; day/night split, comets, star editing | — | Client-cosmetic | SKIP | visual upside not worth the risk on the Sodium+DH+SSRD stack; no shader-adjacent additions should ride on that axis per pack rules |
| **Immersive Winds** (`immersive-winds`) | Wind system driving particle rain/snow, rain-splash particles, and sway animation for grass, plants, lanterns, and fire | — | Client-cosmetic | SKIP | Sinytra-only NeoForge support is a red flag by pack policy, and Grassier Grass already covers sway if that's added |
| **Puddles & Floods** (`puddles-floods`) | Puddle blocks appearing from rain, dripping blocks, flowing water, splash potions, broken cauldrons, and melting snow; puddles combine into floods in low-lying terr… | Forgified Fabric API | Client-cosmetic | SKIP | Fabric-API-derived dependency (red flag) for a cosmetic payoff with real server tick cost; revisit only if the pack accepts Forgified… |
## Client ambience & visual FX
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **AAA Particles** (`aaa-particles`) | Library that loads Effekseer (`.efkefc`) particle effects; by default replaces the vanilla lightning effect with an Effekseer one | — | Client-cosmetic | SKIP | a library with no in-pack consumer; standalone value is only a lightning visual swap |
| **AAA Particles: World** (`aaa-particles-world`) | In-world Effekseer effects: restored world lightning, explosion effect replacement (default on since 1.0.2), loot beams (1.0.3) | AAA Particles | Client-cosmetic | SKIP | purely cosmetic addon whose required base (AAA Particles) is itself a skip |
| **Particle Effects** (`particle-effects`) | Unique textured particle visuals for every vanilla status effect | — | Client-cosmetic | ADD-OPTIONAL | pure client polish, zero server footprint |
| **Perception** (`perception`) | Immersive client visuals: projectile/entity trails and directional screen-shake triggered by loud sounds, explosions, fast movement (also aids threat localization) | — | Client-cosmetic | ADD-OPTIONAL | safe client ambience; optional enough that individual players could skip it |
| **Visuality: Reforged** (`visuality-forge`) | cosmetic particles — crystal sparkles, mob-hit particles, custom slime blobs, environmental particles | — | Client-cosmetic | ADD-OPTIONAL | safe client-only polish; consider whether Subtle Effects already covers the need |
| **Inventory Particles** (`inventory-particles`) | Data-driven particles on inventory items (dust for gunpowder/dyes, glow for luminous items, etc.), with physics/rotation customization | MossyLib | Client-cosmetic | MAYBE | pretty and unusually modded-item-friendly; fine as a client-side optional, but pure cosmetics |
| **Fancy World Animations [FWA]** (`fwa`) | Smooth open/close animations for doors, trapdoors, fence gates, levers, buttons, repeaters, cauldrons, composters, lecterns, campfires, chiseled bookshelves, vaults… | — | Client-cosmetic | ADD-OPTIONAL | strong client polish with a blacklist safety valve; verify against Sable/ImmediatelyFast rendering before shipping |
| **Cosy Critters & Creepy Crawlies** (`cosy-critters`) | Client-side ambient fauna: bird flocks that land high and scatter from entities/projectiles; tiny spiders emerging from cobwebs; moths around sky-exposed light bloc… | — | Client-cosmetic | ADD-OPTIONAL | cheap atmosphere for explorers; skip if the ambience budget is full |
| **Better Animations Collection** (`better-animations-collection`) | Re-animated vanilla mob models: wiggly ghast/squid tentacles, fluffy wagging wolf tails, flowing ocelot/cat tails, pig snout+ears, cow udder, chicken bills, etc., w… | Puzzles Lib | Client-cosmetic | ADD-OPTIONAL | pure atmosphere polish for one new library dep |
| **Immersive UI** (`immersive-ui`) | Animated UI: particle trail for carried items of non-common rarity, carried-item wiggle/scaling, smooth hotbar selector animation, floating matched container items | ShatterLib | OctoLib | Client-cosmetic | SKIP | two extra libraries for cosmetic overlap with Inventory Particles; poor value per pin |
| **Effectual** (`effectual`) | Atmospheric particles: breath steam in cold biomes, underwater bubbles (mouth/chests/pots), drip on exiting water, footprints + snow residue, cave dust, lava-adjace… | TLib | Client-cosmetic | MAYBE | duplicates Subtle Effects' niche and drags in a new lib; only add after an overlap audit, which the config-less pack model makes costly |
| **Blur+** (`blur-plus`) | Gaussian-blur shader behind all GUI backgrounds, with fade animations, ARGB gradient/colors, per-GUI exclusions and radius config | MidnightLib | Client-cosmetic | ADD-OPTIONAL | safe cosmetic; only bother if the pack wants GUI polish |
| **Camera Overhaul** (`cameraoverhaul`) | Client-side camera rotation effects: strafe/turn tilt, jump/fall pitch, explosion shake, idle sway; per-effect intensity config (0 disables) | — | Client-cosmetic | ADD-OPTIONAL | cheap and configurable, entirely a taste/accessibility call |
| **Cinematic Respawn** (`cinematic-respawn`) | Replaces the death screen with a cinematic camera + fade transition into respawn; optional auto-respawn and skippable animation; fully client-side | — | Client-cosmetic | ADD-OPTIONAL | pleasant, zero-risk client polish; taste call on auto-respawn |
| **Smart Particles** (`smart-particles`) | Distance-prioritized particle culling ("smart particle culling") plus camera/frustum culling of off-screen particles | — | Client-cosmetic | ADD-OPTIONAL | targeted client-side stabilizer with no server footprint; watch mixin overlap with ImmediatelyFast |
## World mechanics & hazards
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Burnt** (`burnt-basic`) | Persistent, spreading fire: lit blocks smolder → burn → leave burnt block variants (with charcoal drops), integrated wind system (read via flags), biome-aware burn… | — | Moderate | ADD-OPTIONAL | distinctive survival flavor with controls, but server-grief/tick cost means it's a taste call, not a default |
| **Burnt + Additions** (`burnt`) | Everything in `burnt-basic` plus: Flint Bow (flame arrows), Fire/Blaze Barrels (delayed blast + ignition), random structural collapse events, smoker→burnt-wood reci… | — | Moderate | MAYBE | the fuller variant is attractive but heavier; if fire flavor is wanted, choose this over basic deliberately (and still treat as option… |
| **Tree Physics** (`tree-physics`) | cutting a tree with Rooted Dirt beneath it assembles the trunk/canopy into a Sable physics sub-level and topples it realistically; crouch-chop opts out; building on… | — | Moderate | MAYBE | the most on-theme Sable use possible, but per-tree physics sub-levels on the Aeronautics stack demand a dev-server soak test before sh… |
| **Sable Beyond** (`sable_beyond`) | Create interop with Sable sublevels: mechanical arms interacting with sublevels, encased fans pushing/pulling sublevels, dynamic mass for fluid tanks/spouts/drains/… | — | Moderate | MAYBE | the most functionally attractive Aeronautics enhancement in the batch, but alpha software on the pack's most fragile stack; isolated t… |
| **Ragdoll Reactions** (`ragdoll-reactions`) | Players ragdoll in reaction to crashes, being run over, sharp direction changes, and explosions | Sable: Ragdolls | Minor | MAYBE | only alongside Sable: Ragdolls, and only after crash-testing with Aeronautics |
| **Sable: Ragdolls** (`sable-ragdolls`) | Physics-driven player ragdolls using Sable's physics system (H to tumble, Shift to get up) | — | Minor | MAYBE | fun, Sable-native, and unlocks two other candidates; test with Aeronautics before adopting |
| **Sable: Ragdoll Corpse** (`sable-ragdoll-corpse`) | On death, a fully simulated ragdoll corpse holding your entire inventory (items safe in an internal inventory) | Sable: Ragdolls | Minor | SKIP | Gravestone already owns this job; stacking two death-item systems on the Sable physics stack adds fragility for no new capability |
| **Lunar** (`lunar`) | Cycle of lunar events: Bad Omen Moon, Big/Tiny Moon (gravity changes), Blood Moon (harder mobs), Crimson Moon (nether mob spawning in Overworld), Hero/Miner Moon (b… | — | Moderate | MAYBE | fun server-wide content, but gravity/spawn events touching Aeronautics physics is an unquantified risk in this pack |
| **Celestria** (`celestria`) | Server-triggered, synced shooting stars at night (grant Luck; command-spawnable; client renders via a WorldRenderer mixin, with a client-only fallback mode for vani… | — | Minor | MAYBE | nice ambience, but stale build + WorldRenderer mixin on the Sodium/DH/Sable stack needs an in-pack smoke test first |
| **Mystical Oak Tree** (`mystical-oak-tree`) | A rare talking oak tree with 300+ written lore/joke/fact lines, trust mechanic, self-defense; "dynamically grabbed from the web" content | — | Minor | ADD-OPTIONAL | harmless flavor for a friends pack; nothing about it strains the stack |
## HUD & client UI
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Auto HUD** (`autohud`) | Dynamically hides HUD elements that aren't currently interesting (keybind toggle, per-element config); hides persistent status effects and shows remaining effect ti… | Fabric API | Client-cosmetic | ADD-OPTIONAL | Metadata Fabric-API dep is Fabric-build-only; native NeoForge build |
| **Armor Hud** (`armor-hud`) | HUD overlay showing each equipped armor piece with icons and color-coded durability bars (green/yellow/red/black thresholds) | — | Client-cosmetic | ADD-OPTIONAL | tiny, dependency-free HUD addition |
| **Immersive Armor HUD** (`immersive-armor-hud`) | Pixel-perfect 7×7 armor icons above the vanilla armor bar showing which armor pieces are worn and per-piece durability warnings | TxniLib | Client-cosmetic | ADD-OPTIONAL | cheap vanilla-style HUD upgrade; minor recency caveat |
| **Health Bars** (`new-health-bars`) | HUD health panel: mob name, health, armor, damage taken with animated bars | Puzzles Lib | Client-cosmetic (informational) | MAYBE | redundant with Jade unless the group wants damage numbers; if added, de-overlap with Jade deliberately |
| **Neat** (`neat`) | Minimalistic unit frames (health bars colored by HP %, armor, smite/arthropod attribute icons, stack grouping, team colors, toggle keybind) over entities | — | Client-cosmetic | ADD-OPTIONAL | mature, zero-risk combat readability; prefer over the Damage Indicator if choosing one |
| **JeremySeq's Damage Indicator** (`jeremyseqs-damage-indicator`) | Client-side directional damage arrow, floating damage text, text health bars for mobs, optional blood overlay | — | Client-cosmetic | MAYBE | harmless, but functionally redundant with Neat if both are added; pick one combat-info mod |
| **Advancement Plaques** (`advancement-plaques`) | Replaces advancement toasts with glowing plaques for Task/Goal/Challenge; configurable position, distance, whitelist; resource-pack customizable | — | Client-cosmetic | ADD-OPTIONAL | safe client polish on a dep already in pack; one test-instance check on the sound caveat |
| **GUI Effect Timer** (`gui-effect-timer`) | Countdown text (s/m/h/d abbreviations) inside status-effect HUD badges, updated per tick; color configurable; supports infinite/command-set effects | Collective | Client-cosmetic (informational) | ADD-OPTIONAL | tiny, safe, useful; effectively free once Collective is pinned for Followers Teleport Too |
| **Keybind Atlas** (`keybind-atlas`) | Client-side visual keyboard/mouse overlay showing every keybinding, color-coded assigned/unused/hidden, with source-mod attribution and in-overlay rebinding | — | None | ADD-OPTIONAL | genuinely useful in a pack this size, zero risk |
| **Distinct Potions** (`distinct-potions`) | Distinct bottle styles for greater/extended potions, distinct colors for awkward/mundane/thick base potions | Puzzles Lib | Client-cosmetic | ADD-OPTIONAL | cheap visual QoL; only worth it if the pack accepts pulling in Puzzles Lib for a single client mod |
| **Obscure Tooltips** (`obscure-tooltips`) | Fully animated tooltip styling: glowing borders, particle effects, rarity-adaptive ornaments, integrated 3D gear previews inside tooltips, smooth scrolling and line… | Fragmentum | None | MAYBE | attractive but redundant with Legendary Tooltips; only add after confirming they don't fight over tooltip rendering, or as a replaceme… |
| **Tooltip Overhaul** (`tooltip-overhaul`) | complete vanilla tooltip replacement — scrollable/wrapping tooltips, equipment comparison, pinned tooltips, 30+ frames, 37+ effects, animations, 3D item icons/previ… | — | Client-cosmetic | SKIP | collides with Legendary Tooltips; the pack should carry one tooltip restyler, and it already does |
| **Visual Workbench** (`visual-workbench`) | crafting tables retain items in the grid between crafts; ingredients + result rendered on top of the table; contents drop when broken | Puzzles Lib | Minor | ADD-OPTIONAL | popular, polished Fuzs mod; costs one small library |
| **Held Item Tooltips** (`held-item-tooltips`) | Rich info plate above the hotbar on item switch: enchantments, durability, potion effects, item attributes, map IDs, firework/banner/book details | Puzzles Lib | Client-cosmetic (informational) | ADD | low-risk, high-frequency QoL; library cost shared with other Puzzles-Lib picks |
| **GUI Compass** (`gui-compass`) | HUD text readout of direction + coordinates ("FXYZ"), shown only with a compass in inventory (default) | Collective | Client-cosmetic | MAYBE | harmless, but marginal over F3 and redundant if Field Guide (with Immersive Overlays) is added |
| **Better Third Person** (`better-third-person`) | Independent free-rotating third-person camera (full 360°), 8-direction movement without camera rotation, full item use in third person, vehicle/swim/elytra support… | — | Client-cosmetic | ADD-OPTIONAL | safe, popular camera QoL with no deps; just smoke-test it while piloting Aeronautics contraptions |
| **Dynamic Crosshair** (`dynamiccrosshair`) | Context-sensitive crosshair: hides/changes based on what is looked at, held item, and action; highly configurable with optional YACL config screen | Fabric API | Client-cosmetic | ADD-OPTIONAL | pure client polish, but must be tested against ImmediatelyFast and dropped if HUD glitches appear |
| **Emojiful** (`emojiful`) | Emojis in chat, including animated ones, with autocomplete and an emoji picker | — | Client-cosmetic | ADD-OPTIONAL | fun for a 10-player social server with zero gameplay footprint |
| **Quick Skin** (`quick-skin`) | In-game skin library GUI (import by username or drag & drop), Classic/Slim model swapping | — | Client-cosmetic | ADD-OPTIONAL | client nicety; preferred over SkinChanger (newer, GUI, more features) |
| **SkinChanger** (`skinchanger`) | `/skin set|clear` and `/cape set|clear` commands by username or URL, working on offline-mode servers; admin variants targeting other players | — | Client-cosmetic | SKIP | redundant with Quick Skin (GUI, HD skins, animated capes) and stale: last updated 2024-10-26 vs. Quick Skin's 2026-09-28 |
| **Akashic Tome** (`akashic-tome`) | A single "Book of Books" item (craft: book + bookshelf) that stores all mod documentation books and transforms into any of them; right-click menu to switch, sneak-r… | — | None | ADD-OPTIONAL | cheap, low-risk QoL that scales well with a 142-mod pack |
| **Field Guide** (`field-guide`) | Spyglass-based scanning of entities/blocks to unlock entries in a personal in-game encyclopedia | Item Descriptions, Immersive Overlays | Minor | ADD-OPTIONAL | excellent fit for a 10-player exploration pack; price of admission is two extra NeoForge libs |
| **Certain Questing Additions** (`certain-questing-additions`) | FTB Quests UI upgrades: entity rendering in quest descriptions/backgrounds, APNG image support, per-chapter shader-based backgrounds, hover/open/zoom animations, gl… | — | None | ADD-OPTIONAL | nice polish for a quested pack; harmless if dropped |
| **FindMe** (`findme`) | Hover an item in JEI and press Y to mark which nearby inventories contain it (cloud particles) | — | Minor | ADD | zero-dep, low-risk, high-frequency QoL |
| **Zume** (`zume`) | hold-to-zoom keybind (FOV zoom) with zoom-level increase/decrease keybinds; auto-reloading JSON5 config in the global `.minecraft` dir | — | None (view convenience; no gamepl… | ADD | zero-dep, zero-server, fills an obvious gap next to Sodium+DH distance viewing |
## Audio & music
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Sounds** (`sound`) | 170+ new/reworked SFX (UI, chat, item, block sounds); configurable per event and extensible via resource packs; spiritual successor to ExtraSounds/Auditory | MRU | Client-cosmetic | ADD-OPTIONAL | high polish, zero server footprint; costs one new small library |
| **Extreme sound muffler** (`extreme_sound_muffler`) | Client-side selective sound muffling via an inventory-button/keybind GUI with per-sound volume sliders | — | Client-cosmetic | ADD | zero-risk, zero-server-cost QoL that is actively maintained (3.56, 2026-09-22) |
| **Sounds Be Gone!** (`soundsbegone`) | Mute any vanilla/modded sound event from a "recently played" list, with unmute audit trail | — | Client-cosmetic (no gameplay chan… | ADD-OPTIONAL | tiny, safe, real accessibility value for a 10-player group |
| **Simple Music Control** (`simple-music-control`) | Halved delay between background music tracks, next-track keybind (default M), now-playing widget | — | Client-cosmetic | ADD | zero-risk client QoL whose only dependency is already present |
| **Now Playing** (`now-playing`) | Toast/hotbar popup announcing the current music track (background music and jukeboxes), with placement/timing/sprite resource-pack options | — | None | ADD-OPTIONAL | trivial, safe; most valuable if music-content mods are added |
| **More Music Discs** (`more-music-discs`) | Custom music discs (YouTube-sourced tracks, used with permission) found as chest loot, mob drops, or creative tab; loot-table injection fully configurable/disableab… | Deimos | None-Minor | ADD-OPTIONAL | cheap flavor; verify default disc-in-every-loot-pool density is wanted |
| **Net Music: Better Experience** (`net-music-play-list`) | Playlist items and a portable music player built on the "Net Music" mod; playlist discs for jukeboxes/CD burners | Net Music | None-Minor | SKIP | dependent on an absent streaming-music base mod with service/licensing baggage; poor fit |
| **VinURL** (`vinurl`) | custom music discs that download and play audio from YouTube/file-hosting URLs via jukebox; `/vinurl` commands; auto-downloads yt-dlp, deno, and FFmpeg binaries at… | Sinytra Connector, Forgified Fabric API, oωo (owo-lib) | Minor (custom music per player) | SKIP | Connector red flag, runtime binary downloads, and licensing minefield; not worth it for jukebox music |
| **Immersive Melodies** (`immersive-melodies`) | 7 instruments playing 25 bundled songs; custom melodies via in-game drag-and-drop or datapacks (MIDI/ABC) | — | Minor | ADD-OPTIONAL | fun multiplayer toy at essentially zero mechanical risk |
| **Even More Instruments!** (`evenmoreinstruments`) | Playable instruments: trombone, violin, keyboard, guitar, saxophone, koto, shamisen, pipa; all 16 note blocks as playable instruments | Genshin Instruments | Minor | SKIP | abandoned per its own README and requires Genshin Instruments, which the pack does not have |
| **cat_jam** (`cat_jam`) | Client-side animation: cats bob/jam to the rhythm of music discs, with per-disc routines | — | Client-cosmetic | ADD | tiny, client-only, documented compat with a mod already in the pack |
| **Etched** (`etched`) | Custom music discs burned from URLs (MP3, WAV, OGG, SoundCloud) via the Etching Table with label customization | — | Minor | ADD-OPTIONAL | great social toy for a small server; settle the URL-content policy first |
## Food & farming
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Chef's Delight - Farmer's Delight Villagers** (`chefs-delight`) | Two villager professions (Cook, Chef) trading FD food, plus village structures for them (cook/chef houses) | — | Minor (if it worked) | SKIP | 1.21.1 build is bound to FD Refabricated, which conflicts with the pack's existing Farmer's Delight |
| **Expanded Delight** (`expanded-delight`) | Farmer's Delight expansion: new crops, blocks, workstations and more, added "gradually" on top of the base mod | — | Moderate | ADD-OPTIONAL | strongly on-theme and the best-covered addon for Display Delight, but accept the author-declared beta instability or wait for stable |
| **More Delight (for Farmer's Delight)** (`more-delight`) | Extra Farmer's Delight meals and ingredients, bread-slice sandwiches, toast, wooden/stone knives | Delight Lib | Minor | ADD-OPTIONAL | safe, on-theme content; the Delight family is already large, so it's cumulative rather than filling a gap |
| **Miner's Delight** (`miners-delight`) | Farmer's Delight cave-food addon: cave carrots (new crop + gossypium flower), bat/silverfish snacks, copper pot and copper cup cooking utensils, cave-themed meals | Lodestone | Minor | ADD-OPTIONAL | strong thematic fit with the Delight family, but the author's own beta warning plus a new library dep argue for wait-and-see |
| **Dungeon's Delight** (`dungeons_delight`) | Monster Pot cooking station (heated by spawner-like blocks) producing Monster Foods | — | Moderate | ADD-OPTIONAL | thematically perfect next to the pack's existing Delight collection; sanity-check the new effect types against Apotheosis stacking |
| **Barbeque's Delight [Forge/NeoForge]** (`barbeques-delight-forge`) | Grills + skewer cooking loop (place → smoke cue → sneak-flip → collect; burning on failure), ingredients basin crafting of skewers | — | Minor | ADD-OPTIONAL | frictionless fit with the existing Delight stack |
| **Fright's Delight** (`frights-delight`) | 56 horror-themed Farmer's Delight foods/drinks/candies crafted from hostile-mob drops (rotten flesh, spider eye, ghast tear, slime, cobweb, wither/soul berries) | — | Minor | ADD-OPTIONAL | fits the pack's Delight collection; horror theme is a taste call |
| **Veggies Delight** (`veggies-delight`) | 7 new vegetables (bell pepper, broccoli, cauliflower, garlic, sweet potato, turnip, zucchini) + forageable dandelion leaf; temperature-based wild veggie worldgen; v… | — | Minor | ADD-OPTIONAL | low-risk content that deepens the pack's largest content family |
| **Fruits Delight** (`fruits-delight`) | 17 fruits (peach, mango, lychee, durian, …) with unique per-fruit processed-food effects (Strength+Rage Aura, Night Vision, Healing Aura, walk-on-ice, eat-when-full… | — | Moderate | ADD | big, popular (2.2M downloads) FD expansion that plugs into two pack pillars (Create, Terralith) |
| **Rustic Delight** (`rustic-delight`) | New crops: bell peppers (red/yellow/green), coffee, cotton, with wild spawns (e.g., jungle wild bell peppers/coffee) | — | Minor | ADD | textbook fit: same-dependency addon for an existing content pillar |
| **Cultural Delights** (`cultural-delights`) | New world-cuisine crops: avocado, eggplant, cucumber, corn, beans, cinnamon | Cook's Collection | Moderate | ADD-OPTIONAL | on-theme food content, but it requires adopting Cook's Collection and the Delight shelf is already crowded |
| **Hearth and Harvest** (`hearth-and-harvest`) | New farmable crops, some with unique growth mechanics, plus new interactive food/resource crafting systems | — | Moderate | ADD-OPTIONAL | solid FD-family expansion; coordinate corn overlap with Haunted Harvest before adding both |
| **Haunted Harvest** (`haunted-harvest`) | Trick-or-treating: baby villagers wear 9 mask types, walk at night, collect candy from adult villagers (with witch interactions and egg-throwing on refusal); candy-… | Moonlight Lib | Minor | MAYBE | charming, but adds a lib, modifies villager AI, and double-buys corn with Hearth and Harvest |
| **Overweight Farming** (`overweight-farming`) | Rare "overweight" super-crops (beets/carrots/potatoes/beans) with boosted yields, moonlight growth bonus, straw hat (breeding twins/triplets), peeling/waxing/melon-… | — | Minor | ADD-OPTIONAL | small, self-contained farming charm |
| **AlcoCraft+** (`alcocraft`) | Brewing keg with 10+ beer recipes (hops, sugar, apples, water) | — | Minor | ADD-OPTIONAL | small, self-contained fun; no flags |
| **Fishing Real** (`fishing-real`) | Fish hooked as items spawn as live entities instead (salmon → live salmon, etc.) | — | Minor | ADD-OPTIONAL | cheap, fun, low-risk; worth a small datapack pass to include Aquaculture species |
| **FishingOverhaul** (`fishingoverhaul`) | Reel-in minigame: fish circles a bar; right-click inside the catch region to land loot; crit region doubles loot | — | Minor | ADD | declared Aquaculture 2 compat makes this a natural pack fit |
| **Fisherman's Haven** (`fishermans-haven`) | Fishing expansion: new rods, traps and nets that catch multiple fish at once | — | Moderate | ADD-OPTIONAL | no deps, distinct fishing mechanics that complement Aquaculture 2; accept the niche overlap deliberately |
| **Farmer's Knives** (`farmers-knives`) | Farmer's Delight knives in many modded materials — for mods actually in this pack that means The Twilight Forest (Ironwood, Fiery, Steeleaf, Knightmetal) plus a cop… | — | Minor | ADD-OPTIONAL | cheap thematic glue whose payoff is real but limited to Twilight Forest materials since the other supported tool mods aren't in the pa… |
| **Display Delight** (`display-delight`) | Placeable 3D food blocks for every Farmer's Delight (+ addon) food; placed foods are neither block entities nor entities (explicitly lag-friendly) | — | Minor | ADD | direct, low-risk upgrade to the pack's food-and-decor identity |
| **Create: Factory** (`create-factory`) | Create-themed foods: rolls, waffles, apples and related items/recipes; optional extra recipes when Create: Confectionery or Ecologics are present | — | Minor | ADD-OPTIONAL | harmless, but the food family is already the pack's most crowded content lane; low marginal value |
| **Delightful Creators** (`delightful-creators`) | Farmer's Delight ↔ Create automation bridge: new fluids for soups, stews and sauces; mixer recipes to produce them; bowl filling from fluids | — | Moderate | MAYBE | pick one FD↔Create bridge; Slice & Dice is already installed and proven, so this needs a deliberate "both approaches" decision |
| **Berry Good** (`berry-good`) | Berry QoL: bush placement moved to "pips" so bushes aren't placed accidentally; other simple berry-use improvements (excerpt details only the placement change) | Blueprint | Minor | SKIP | an entire additional library dependency (Blueprint) for one minor placement QoL; revisit only if the pack adopts Team Abnormals mods w… |
| **Abnormals Delight** (`abnormals-delight`) | Farmer's Delight integration for Team Abnormals mods: FD cabinets in every Abnormals wood type, Duck/Deer meat cuts, cake slices alongside Neapolitan | Blueprint | Minor (and in this pack, near-zer… | SKIP | required Blueprint dep plus an ecosystem (Team Abnormals) the pack doesn't run; mostly dead content |
| **ExtraDelight** (`extradelight`) | Kitchen workstations: Oven (3×3 slow-baking), Dough Shaping Station, Mixing Bowl, Mortar & Pestle, Drying Rack, Melting Pot (solids→fluids), Chiller (fluids→solids) | — | Moderate | ADD-OPTIONAL | the meatiest Delight addon in the batch and a natural kitchen-tier progression; confirm the block-entity load on the dedicated server… |
## Create & technology
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Create: Bells & Whistles** (`bellsandwhistles`) | 36 decorative/utility Create blocks: station platforms, headlights, "Metro" casing/panel/window palette, andesite/brass/copper grab bars & bogie steps & door steps… | — | Minor | ADD-OPTIONAL | strong deco value for a Create pack; verify blocks behave on Aeronautics contraptions first |
| **Create: Design n' Decor** (`create-design-n-decor`) | Create-focused QOL decoration: block variants (multiple crushing-wheel variants), containers, and extra factory-styled deco blocks | — | Minor | ADD-OPTIONAL | safe factory decoration; nice with the pack's Chipped/Rechiseled angle |
| **Create: Teleporters** (`create-teleporters`) | Create-styled teleportation: TP Links with a configurable range, plus entity and item teleporters in multiple sizes | — | Moderate | ADD-OPTIONAL | clean fit for Create logistics with no flagged conflicts; decide whether the pack wants dimensional play |
| **Create: Structures Arise** (`create-structures-arise`) | 28 new Create-themed worldgen structures scattered across the world | — | Moderate | ADD-OPTIONAL | strong fit for a Create + exploration pack, but it thickens an already structure-saturated worldgen stack with no config knobs shipped |
| **Create Waystones Recipes** (`create-waystones-recipes`) | Replaces all Waystones crafting recipes with Create-style (machine/mechanical) recipes and rebalances them; pairs with an optional texture/GUI resource pack | — | Minor | ADD-OPTIONAL | safe; a deliberate progression/taste decision for the questbook rather than a technical one |
| **Create: Sophisticated Backpacks Compat** (`create-sophisticated-backpacks-compat`) | A curated set of Create machine recipes for Sophisticated Backpacks items/components, enabling automation of key SB components inside Create factories (only "carefu… | — | Minor | MAYBE | plausible value, but check for recipe collisions with the official Create Integration already in the pack before committing |
| **Create: Dynamic Lights** (`create-dynamic-lights`) | Dynamic lighting for moving Create contraptions (client-side light via Sodium-family dynamic lights), plus an optional server-side "light block" mode that places re… | Sodium Dynamic Lights | Client-cosmetic | SKIP | redundant with LambDynamicLights, wrong rendering stack assumptions (Embeddium/Rubidium), and its niche is better covered (or delibera… |
| **Create Sable Dynamic Lights** (`create-sable-dynamic-lights`) | Dynamic-light support for Create contraptions and Sable sub-levels (moving contraptions/sub-levels actually illuminate surroundings, incl. on Aeronautics ships) | Sodium Dynamic Lights | Client-cosmetic | SKIP | requires a second dynamic-lights engine that duplicates LambDynamicLights and couples to the fragile Sodium/Sable version pin |
| **CreateBetterFps** (`createbetterfps`) | FPS optimization for Create scenes ("up to 50%" with a shaderpack, 7→35 fps with 512 waterwheels) via Sodium API usage and backface culling | — | None | MAYBE | Iris + Sodium now in pack, so unblocked in principle, but it patches Create's code on the Aeronautics/Sable stack - test first |
| **Sophisticated Inventory Interactions** (`sophisticated-inventory-interactions`) | Search field inside vanilla/modded container GUIs; sort modes (name/mod/count/tags) | — | Minor (pure inventory-management… | MAYBE | good mod, but it replaces rather than stacks with Client Sort; pick one container-sorting solution |
| **Sophisticated Item Actions** (`sophisticated-item-actions`) | Keybind highlights nearby storages containing the held/hovered/JEI-bookmarked item (green exact / blue type match) | — | Minor (inventory-flow QoL, Terrar… | ADD-OPTIONAL | genuinely new capability that plays well with the Sophisticated + JEI stack already in the pack |
| **Sophisticated Sorter** (`sophisticated-sorter`) | Sophisticated Core sort buttons on most regular container screens (name/mod/count/tags modes) | — | Minor | SKIP | redundant with Client Sort in-pack and with Sophisticated Inventory Interactions in this same batch; side metadata is also "unknown" f… |
| **Refined Storage - JEI Integration** (`refined-storage-jei-integration`) | JEI ↔ Refined Storage recipe transfer for Crafting Grid and Pattern Grid, incl. autocrafting tasks from JEI preview | Refined Storage | None in this pack | SKIP | dead weight without Refined Storage |
## Decoration & building
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Beautiful Campfires** (`beautiful-campfires`) | Wood-themed campfire variants (birch, etc.) so the crafted wood determines appearance; vanilla campfire recipe restricted to oak; includes the fire-type variants (r… | — | Minor | ADD-OPTIONAL | cheap cosmetic polish; document the oak-only recipe change in pack notes |
| **Sooty Chimneys** (`sooty-chimneys`) | Brick, Cobblestone, Mud Brick, Stone Brick, Iron, Copper, and Terracotta chimneys emitting smoke | — | Minor | ADD-OPTIONAL | safe, charming builder content with negligible cost |
| **Items Displayed [NeoForge]** (`items-displayed-forge`) | Sneak-right-click placement of items (sherds, smithing templates, ingots, etc.) as world-facing 3D models; craftable "Item Display" stand rotatable to any angle, va… | — | Minor | ADD-OPTIONAL | safe builder content that fits the pack's decoration mods |
| **Too Many Paintings!** (`too-many-paintings`) | 50+ new paintings including famous artworks (Van Gogh, da Vinci); works in existing worlds | — | Client-cosmetic (placed paintings… | ADD-OPTIONAL | zero-dep cosmetic content, safe on both sides |
| **Portfolio** (`portfolio`) | 100+ paintings by artist Yapetto across 10 themed catalogues (Still Life, Void Manor, Death, Rana, Far Lands, Anchor, Giant, Elemental, Cloud Cuckoo, Keeping Up) | — | Client-cosmetic | ADD | zero-dependency pure content that fills an empty decorative niche |
| **Display Case** (`displaycase`) | A decorative single-item display block; clicking with honeycomb stops the spin (axe unwaxes) | — | Client-cosmetic | MAYBE | fine in isolation, but choose between this and Fetzi's Displays (same batch) rather than shipping both display systems |
| **Fetzi's Displays** (`fetzis-displays`) | Glass cloches in 16 colors, katana stands, and wall holders with item-name plaques | — | Client-cosmetic | MAYBE | good feature set but redundant with Display Case (batch) + Handcrafted; pick one display system for the pack |
| **Gallery** (`gallery`) | Icon textures for all painting variants; right-click-with-painting GUI to search/select variants | Blueprint | Client-cosmetic (decorator QoL) | MAYBE | nice decorator QoL but drags in the Blueprint library for a niche feature |
| **Spooky Doors** (`spooky-doors`) | horror-game door behavior for all doors — drag to half-open/peek, slam by fast drag, run-into to open, creak sound set; Honeycomb/Ghast Tear toggle | — | Minor | ADD-OPTIONAL | small, charming, Balm-based and low-risk |
| **Boatload** (`boatload`) | Boats with chests, boats with furnaces, large boats, and boats with banners | Blueprint | Minor | ADD-OPTIONAL | pleasant water QoL, but chest-boat overlap with vanilla makes it low-value; needs Blueprint |
| **Supplementaries** (`supplementaries`) | Vanilla+ block set: jars, signposts, faucets, weather vanes, spring launchers, sconces, planters, lights, decoration + automation | Moonlight Lib | Moderate | ADD-OPTIONAL | Create conflict issues all closed; NeoForge-first. Needs Moonlight Lib; smoke-test |
| **Accents** (`accents`) | Dyeable cosmetic accessories (hats, back items, e.g. partial-coloring Top/Pirate Hat) with small situational stat bonuses (e.g. Sheathed Katana +5% damage worn on b… | Fragmentum | Minor | ADD-OPTIONAL | low-risk cosmetic+minor-stat layer; costs one new library dep |
## Mobs & wildlife
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Animal Garden - Porcupine** (`animal-garden-porcupine`) | Tamable/breedable porcupines spawning in forests (JSON-configurable spawn tags); quill damage to nearby attackers; apple taming, sweet-berry breeding/healing, incre… | — | Minor | ADD-OPTIONAL | tiny, dependency-free, fits the existing tameable-mob theme |
| **Fowl Play** (`fowlplay`) | ~13 bird species (hawks, gulls, ravens, crows, ducks, geese incl. swan/emden variants, songbirds, penguins) with realistic flight, sounds, and ecosystem behavior; s… | SmartBrainLib | Minor | ADD-OPTIONAL | strong ambience fit for the pack's mob roster; costs one AI lib |
| **Companions!** (`companions-mod`) | 10 tamable companion creatures with abilities, hostile mobs with unique skills, new weapons, a boss; Small/Great Essence economy (Great Chalice, Soul Furnace, fille… | Knight Lib | Moderate | MAYBE | decent content but redundant with the existing mob roster and it drags in a new library; only if the pack wants more combat-pet content |
| **Hybrid Aquatic** (`hybrid-aquatic`) | Large marine mob roster: new fish species, sharks, crustaceans, critters, otters, nautiluses, and a new miniboss | Hybrid API [HAPI], Biolith | Major | ADD-OPTIONAL | biggest content win in this batch; gate on a worldgen + Aquaculture overlap test because of the two new library pins |
| **Alex's Mobs Continued** (`alexs-mobs-continued`) | Unofficial continuation of Alex's Mobs: the full ~116-mob roster (grizzly bears, tigers, gorillas, sharks, orcas, soul vultures...), taming/breeding/mounts/bucketin… | CodxLib | Overhaul (if it *replaced* the ex… | SKIP | direct duplicate of an existing pack mod; would only ever be a 1:1 swap project |
| **Friends&Foes - Flowery Mooblooms (Forge/NeoForge)** (`friends-and-foes-flowery-mooblooms-forge`) | One moobloom cow variant per flower (allium, sunflower, lilac, etc.) | — | Minor | ADD-OPTIONAL | cheap flavor that slots into an installed mod; skip only if moobloom density is unwanted |
| **Pet Cemetery** (`pet-cemetery`) | Dead pets drop Pet Collars; use a charged Respawn Anchor to revive them as Zombie pets (tankier, curable) or Skeleton pets (faster, unrecoverable) with stat tradeof… | Blueprint | Minor | ADD-OPTIONAL | emotionally valuable on a friends server; verify modded-pet support first |
| **PetProtect** (`petprotect`) | Server-side protection toggles for tamed mobs in PvP: prevent pet player-damage, pet death, pet attacks on players; owner-damage, creative, and totem-effect options… | — | Minor | ADD | tiny, dependency-free, and directly prevents grief/accident on a 10-player PvP-capable server full of tamed mods' pets |
| **Mob Lassos** (`mob-lassos`) | Craftable lassos to carry mobs in inventory: golden (land), aquatic, diamond (no timer), emerald (villagers via contract), hostile (target below 50% HP, bites carri… | Puzzles Lib | Minor-Moderate | ADD-OPTIONAL | useful QoL; check boss exclusion config before shipping to a pack with Apotheosis |
| **Realm RPG: Fallen Adventurers** (`realm-rpg-fallen-adventurers`) | 50+ treasure-bearing skeleton types generating across biomes and dimensions, dropping ores, materials, food, gear, and enchanted books | — | Minor | ADD-OPTIONAL | easy exploration flavor; note the 1.21.1 build dates to 2025-01 (aging but stable, 2.3M downloads) |
| **Spawn** (`spawn-mod`) | Overworld wilderness overhaul: new biomes, many animal mobs with variants, ambience, mechanics | Teal Lib | Major | MAYBE | substantial content but collides with the pack's curated worldgen and mob roster; needs Teal Lib and dedicated testing before inclusion |
| **Mermod** (`mermod`) | Magical necklace (Curios-style accessory) that transforms the wearer into a merperson in water (per description; details on wiki, not README) | — | Minor | ADD-OPTIONAL | small, cheap, fits the pack's exploration theme; low information confidence due to thin README |
| **Punchy! x Tiny Takeover** (`tiny-takeover-x-punchy`) | Carry baby mobs in first person with dedicated animations (crouch + right-click; "I" key playful animation) | — | Minor | MAYBE | verify whether Punchy/Tiny Takeover base mods are actually required and that the NeoForge build is real before adding |
| **Environmental** (`environmental`) | New overworld biomes: Blossom Woods, Pine Barrens, Marshes | Blueprint | Moderate | MAYBE | its content substantially duplicates what Terralith + Alex's Mobs already deliver, and it requires pulling in Blueprint for a single m… |
| **Primal** (`mod-primal`) | Wilderness-immersion content released in "Hunters" (1.0) and "Hunt & Gather" (1.1) updates; further specifics are deferred to an external wiki that the README itsel… | — | unknown | MAYBE | sparse documentation; inspect the wiki and jar contents before committing |
| **Pixelmon** (`pixelmon`) | Every Pokémon Gen 1–9 (1000+) with handmade models/animations, plus battling, trading, breeding | — | Overhaul | SKIP | total-conversion-scale content that steamrolls the pack's identity, worldgen, and mob budget |
## Combat, gear & magic
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Too Many Bows** (`too-many-bows`) | 38 unique bows with special abilities; new attributes (Bow Draw Speed, Bow Damage, Ranged Weapon Damage) | — | Moderate | ADD-OPTIONAL | strong synergy with Better Combat and Curios already in the pack |
| **Reliquary Reincarnations** (`reliquary-reincarnations`) | Magical utility items: Coin of Fortune (item/XP magnet), Interdiction Torch (pushes mobs), Mob Charms (per-mob-type ignore), Sojourner's Staff (torch staff), Void T… | — | Moderate | ADD-OPTIONAL | content-rich and maintained, but demands a balance pass against Apotheosis/Artifacts |
| **More Relics** (`more-relics`) | 25+ relics (accessory items with unique/evolved forms, e.g. Tyrant Mask, Whispering Amulet evolution chains) distributed across structure chests | ShatterLib | OctoLib, Relics | Moderate | SKIP | needs a missing base mod + two libraries, carries self-documented version-pin fragility, and duplicates the Artifacts niche the pack a… |
| **Relics: Arcane Abilities** (`arcane-abilities`) | Dungeons containing three relic artifacts: Fate Beacon (structure finding + teleport marks), Shadow Lantern (darkness abilities: blinding, invisibility, time manipu… | — | Moderate | SKIP | its own README requires Relics + Hammer Lib (missing); would need both plus a balance review to reconsider |
| **Dream Relics** (`dream-relics`) | Curios-integrated accessories: necklaces/rings/bracelets/special items with abilities (damage scaling vs missing/target health, multi-jump boots, XP-granting grail) | — | Moderate | MAYBE | duplicate niche vs Artifacts with Apotheosis balance implications; needs a curation pass before adding |
| **TarotCards: Remastered** (`tarotcards-remastered`) | 22 Major Arcana cards found only in loot chests (buried treasure, shipwrecks, dungeons), each granting a passive buff while carried; dedicated Curios slot; deck com… | — | Minor | ADD-OPTIONAL | clean fit for an exploration/loot pack; explicitly team-aware |
| **Skillcloaks** (`skillcloaks`) | Curios back-slot cloaks from villager trades (colored sacks from master-tier villagers): Agility, Attack, Construction (teleport to spawn), Cooking, Crafting (porta… | — | Minor | ADD-OPTIONAL | solid Curios content on an existing dependency; consider adding Lucent for the full feature set |
| **Ars Elixirum** (`ars-elixirum`) | Free-form elixir brewing: ingredients with seed-dependent alchemical properties, player-authored/saveable/shareable recipes (recipe books on lecterns) | Fragmentum | Moderate | ADD-OPTIONAL | deep alchemy content with one new library dep; confirm in testing that it doesn't hard-require anything beyond Fragmentum |
| **Ars Ocultas** (`ars-ocultas`) | Ars Nouveau ↔ Occultism compatibility: spirits usable from Containment Jars, 7×7 auto item-processing around jars, item-capability piping into jars (pipes/hoppers/s… | Occultism | Moderate if Occultism were presen… | SKIP | required dependency Occultism is absent from both the pack and this batch |
| **Estrogen** (`estrogen`) | Estrogen Pill → "Girl Power" effect enabling a dash movement ability (+ hidden abilities); Estrogen Patches worn in their own Curios-style slots | Cynosure | Moderate | SKIP | meme-toned content whose headline feature alters player movement near a fragile physics stack, and which costs two extra pieces (Cynos… |
| **Create: Estrogen** (`create-estrogen`) | The Create module of the Estrogen mod: a Centrifuge multiblock/machine for new fluid processing recipes, plus custom package (Create packager) shipping recipes; JEI… | Estrogen | Moderate | MAYBE | can't be evaluated in isolation (dep is a batch candidate), self-declared in-development, and tone may not fit the pack; decide togeth… |
| **Small Ships** (`small-ships`) | Medieval sailable ships (R to open/close sail, W/S speed), biome-temperature speed bonuses, ship inventory | — | Moderate | MAYBE | appealing content, but a beta build with old updates parked next to Aeronautics/Sable physics; needs a dedicated compat test or should… |
## Exploration & worldgen
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Dynamic Trees** (`dynamictrees`) | Trees as growing multiblock structures: seeds self-plant, trees grow biome/temperature/rainfall-dependently, grow around obstacles, die in darkness | — | Major | SKIP | a transformative tree overhaul whose coverage against the pack's 10+ worldgen mods is unverified and which demands config curation the… |
| **Spawn Animations** (`spawn-animations`) | hostile mobs dig out of the ground or poof into existence when spawning (works for zombies, skeletons, creepers, endermen, etc.); server-side, command-driven settin… | Quilted Fabric API (QFAPI)…, Fabric API | None | MAYBE | mild flourish; if wanted, use the datapack form to dodge the Fabric dep chain rather than the mod |
| **Spawn Animations Compats** (`spawn-animations-compats`) | datapack adding Spawn Animations support to 50+ modded mobs (Enderman Overhaul, Deeper and Darker, The Graveyard, Galosphere, etc.) | Spawn Animations | None | SKIP | only meaningful if Spawn Animations is added, and its supported mob list barely overlaps this pack |
| **Loot Journal: Pickup Notifier** (`loot-journal`) | Animated item/XP pickup notifications with smart stacking, rare-find highlights, nearby-player pickup tracking, themes, and in-game config | Fragmentum | Client-cosmetic | ADD-OPTIONAL | nice HUD polish; in-game config means no shipped-config maintenance |
| **Traveler's Titles** (`travelers-titles`) | RPG-style fade-in titles when entering biomes/dimensions; Waystone-named region titles (1.18+ Forge/NeoForge), custom sounds via resource pack, dimension/biome blac… | — | Client-cosmetic | ADD | cheap, polished, and it makes the pack's giant curated worldgen legible to players |
| **Death Count** (`death-count`) | A per-player death counter displayed in the tab player list | — | Minor | ADD-OPTIONAL | harmless novelty for a 10-player server, though equally achievable with a one-line vanilla scoreboard datapack |
| **Chalk** (`chalk-mod`) | Craftable chalk (calcite / loot) that draws arrow/dot/symbol marks on block faces; dyeable 16 colors; glowstone/glow-ink glowing marks; chalk box for storing/select… | — | Minor | ADD | cheap, self-contained, fills a real gap for cave exploration |
## Social, sleep & death
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Comforts** (`comforts`) | Sleeping bags (portable bed that doesn't set spawn) and hammocks (sleep day→night), 16 colors + dyeing; optional config mechanics (well-rested, sleepiness, break ch… | — | Minor–Moderate | ADD | staple adventure QoL, well-maintained, no dependency cost |
| **Sleep Tight** (`sleep-tight`) | Sleep overhaul: hammocks (day rest), night bags (spawn-less temporary beds), dream essence, home-bed rewards, slower early-game sleep progression | Moonlight Lib | Moderate | ADD-OPTIONAL | popular, well-scoped sleep rework; requires adding Moonlight Lib and choosing between it and Room For Two rather than stacking blindly |
| **Room For Two** (`room-for-two`) | Multiple players sharing one bed; >2 players stack; camera faces your sleeping direction; `/sleeppos [front|back|left|right]` preference | — | Minor | ADD-OPTIONAL | harmless fun at BETA maturity; pick it OR Sleep Tight's ecosystem, and test if both |
| **PlayerRevive** (`playerrevive`) | A 60-second post-death window in which friends can revive you instead of a hard respawn | — | Moderate | ADD-OPTIONAL | strong social fit, but it rebalances death and needs a Gravestone interplay check |
| **Incapacitated** (`incapacitated`) | Downed state between life and death: crawling, bleed-out timer, 3 downs before true death (configurable); lava and similar causes bypass instantly | — | Major | MAYBE | great co-op mechanic but changes core death rules; needs owner sign-off plus a Gravestone interaction test |
| **Death Knell** (`death-knell`) | 35+ new death messages, including circumstance-specific ones (cookie-weapon kills, axe dismemberment) and generic variants | — | Client-cosmetic | ADD | zero-risk flavor whose deps are already installed |
| **Charta** (`charta`) | Card-game system: 3 games (Crazy Eights, "Fun", Solitaire), card tables in 3 sizes for up to 8 players, decks found in village/dungeon loot, in-game tutorials; API… | — | Minor | ADD-OPTIONAL | charming multiplayer flavor, zero risk if unused |
| **Mino++** (`minopp`) | Playable Uno-style card game: placeable table, scroll-wheel card selection, bot players (`/summon minopp:mino_auto_player`, bot config requires YACL), rule variants… | — | Minor | ADD-OPTIONAL | charming social content with no risk surface; pure taste call |
| **Piggyback** (`piggyback`) | Replaces the default sit-on-head player mechanic with a piggyback-style ride (right-click a crouching player with an empty hand) | Faewulf's Lib | Minor | ADD-OPTIONAL | harmless co-op fun, but requires adding Faewulf's Lib to the pack |
| **What Are They Up To (Watut)** (`what-are-they-up-to`) | in-world indicators when other players are typing (speed-animated), GUI-activity visuals (hand clicking at a screen), idle/sleeping player visuals, and Zz idle mark… | CoroUtil | Minor | ADD-OPTIONAL | genuinely fun on a small friend group; costs one small library |
| **Open Parties and Claims** (`open-parties-and-claims`) | Chunk claiming + forceload, player parties, party chat, admin controls, permission-API integration (FTB Ranks, LuckPerms), explicit FTB Teams and Xaero's map integr… | — | Overhaul of base-protection/socia… | SKIP | direct duplicate of FTB Chunks + FTB Teams; would only make sense as a wholesale replacement, which contradicts the installed FTB Ques… |
| **Welcome Screen** (`welcome-screen`) | one-time welcome screen on first world/server join and update-"what's new" screens, fully customizable via FancyMenu | FancyMenu, Necronomicon API | None | SKIP | 2-3 new dependencies for a screen a server MOTD/pin note can replace |
| **Early Bedtime** (`early-bedtime`) | Server-side configurable earlier sleeping threshold (default 1000 ticks / ~50s sooner) | TxniLib | Minor | SKIP | solves a shader-specific problem this shaderless pack doesn't have, at the cost of adopting TxniLib |
| **Horror messages** (`horror-messages`) | A random horror chat message ("Help me", "Behind you", binary "LEAVE") broadcast to all players every 10–15 minutes | — | None | SKIP | chat-spam gimmick; only defensible if the pack deliberately becomes a horror pack |
## Server, admin & performance
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **BlueMap** (`bluemap`) | Reads world files and generates 3D maps of the whole surface, viewable in a browser via its own built-in web app | — | None | ADD-OPTIONAL | genuinely useful for a small dedicated server, but it's ops overhead (webserver, ports, configs) rather than content |
| **Better Compatibility Checker** (`better-compatibility-checker`) | Replaces the default loader server-list compatibility check with modpack project-ID/version comparison, showing tick/X for players adding the pack's server | — | None | MAYBE | only earns its slot if the build pipeline commits to updating its config each release |
| **Let Me Despawn** (`lmd`) | Lets mobs that picked up/equipped items despawn naturally (dropping the items first), with configurable exclusion list and live `/letmedespawn add|remove` commands;… | Almanac | Minor | ADD | clear server-side perf win for a 10-player mob-dense pack; add Almanac with it |
| **More Culling** (`moreculling`) | Client-side culling changes for multiple render categories (per description/wiki: e.g. leaves, block-entity type cases) to cut rendered geometry | — | None | MAYBE | plausible FPS gain, but redundant-adjacent to Entity Culling and unvetted against the pack's fragile rendering core; test in isolation… |
| **BadOptimizations** (`badoptimizations`) | Client micro-optimizations: skip lightmap texture re-uploads when nothing affecting brightness changed; gate debug renderers (bees/game events/gametest/villager AI)… | — | None | SKIP | marginal, hard-to-measure gains on a stack that already covers these areas (constraint 6); not worth extra mixin surface for a ~4% syn… |
| **AsyncParticles** (`asyncparticles`) | Client particle optimizations: GPU-accelerated particle vertex rendering, async particle ticking, particle culling, async light cache | — | None (pure client optimization) | SKIP | a named crash interaction with in-pack C2ME that the pack cannot pre-configure, plus beta render-layer mixins against the fragile Sabl… |
| **Followers Teleport Too** (`followers-teleport-too`) | Non-sitting pets (wolves/cats) near the player teleport along with them on any teleport | Collective | Minor | ADD-OPTIONAL | clear QoL win with Waystones for ~10 players; costs one shared lib |
| **Waystones Teleport Pets** (`waystones-teleport-pets`) | pets teleport alongside players using Waystones without needing a lead attached | — | Minor QoL for pet owners | ADD | tiny, targeted, and fixes a real annoyance for a 10-player server full of tamed pets |
| **Carry On + Create Aeronautics Compat** (`carryon-aeronautics-compat`) | Patches Carry On so blocks can be picked up from Aeronautics/Sable simulated contraptions | Carry On | Moderate (when it applied); effec… | SKIP | self-declared obsolete (fix upstreamed to Carry On 2.2.6+), base mod absent, documented server-hang known issue |
| **Carry On Extend** (`carry-on-extend`) | Shift+Q to throw the entity/block you are currently carrying (Carry On add-on) | Carry On | Minor | SKIP | dead on arrival without Carry On; revisit only if the pack adopts Carry On itself |
## Already in pack (duplicates)
| Mod | What it brings | New deps | Impact | Verdict | Watch-out |
| --- | --- | --- | --- | --- | --- |
| **Aquaculture 2** (`aquaculture`) | (duplicate entry) — 30+ biome-specific fish, neptunium gear, hooks/bait/line rods, tackle box, fish fillets and fishing loot | — | Moderate (as installed) | ALREADY-IN-PACK | exact duplicate of the existing Aquaculture 2 entry |
| **Aquaculture Delight** (`aquaculture-delight`) | (duplicate entry) — Farmer's Delight × Aquaculture 2 compatibility: fish dishes, Neptunium knife, knife cross-compat, cooking pot/cutting board recipes | — | Minor (as installed) | ALREADY-IN-PACK | exact duplicate of the existing Aquaculture Delight entry |
| **Apothic Combat** (`apothic-combat`) | (duplicate entry) — Compatibility between Apotheosis and Better Combat: registers two-handed Better Combat weapons as HEAVY_WEAPON; removes the Entity Reach attribu… | — | Major (as installed) | ALREADY-IN-PACK | duplicates the pack's existing Apothic Combat entry |
| **Ars Creo** (`ars-creo`) | (duplicate entry) — Ars Nouveau × Create addon: Starbuncle Wheel (SU generation), spell/timer turrets on contraptions, Source Jars as contraption parts | — | Moderate (as installed) | ALREADY-IN-PACK | duplicate of the existing Ars Creo entry; the "missing dep" line is a dead-ID artifact, not a real gap |
| **Create Aeronautics: Compatibility** (`create-aeronautics-compatability`) | (per README) Fixes for mods that break on Sable sub-levels/physics ships: Etched, WATERFrAMES, Alex's Mobs + Alex's Caves (pathfinding RAM/OOM fix), Another Furnitu… | — | Moderate | ALREADY-IN-PACK | duplicates the existing "Create Aeronautics: Compatibility" entry in the pack list; do not add a second copy |
| **Nature's Compass** (`natures-compass`) | (Duplicate entry) Biome-locating compass with searchable GUI, HUD info, config blacklists | — | N/A | ALREADY-IN-PACK | byte-for-byte duplicate of the existing Nature's Compass entry; drop from the candidate list |
| **Separate Sable Render Distance** (`ssrd`) | (duplicate) — Sable physics objects rendering beyond view distance with Distant Horizons/Voxy; Sodium-menu sub-level render distance slider; server-friendly `/ssrd… | — | None | ALREADY-IN-PACK | duplicate of the pack's existing SSRD entry; exclude from the candidate list |
| **Sophisticated Backpacks Create Integration** (`sophisticated-backpacks-create-integration`) | Lets Sophisticated Backpacks sit on Create contraptions with all upgrades (Pickup, Magnet, Filter, Void) functional while in motion | — | Minor (already shipped; storage a… | ALREADY-IN-PACK | exact duplicate of the pack's own Sophisticated Backpacks Create Integration entry |
| **Sophisticated Storage Create Integration** (`sophisticated-storage-create-integration`) | Sophisticated Storage barrels/chests/shulker boxes usable on Create contraptions (trains, gantries, flywheels) with upgrades, tier upgrades, and Storage Tool functi… | — | Minor (already shipped) | ALREADY-IN-PACK | exact duplicate of the pack's own Sophisticated Storage Create Integration entry |
@@ -0,0 +1,688 @@
# Onion MC — Candidate Modlist Review
**Pack:** Onion MC 0.1.0 — Minecraft 1.21.1 / NeoForge 21.1.251 (packwiz)
**Candidates reviewed:** 189 minetest/mod links (mods, plugins, datapacks) supplied by the operator
**Existing pack:** 142 tracked entries (133 Modrinth + 9 CurseForge)
**Date:** 2026-09-29 (post-review update: see Section 0)
---
## 0. Post-review update — new commits and the `mod-pack-additions` branch
After the first pass of this review, the remote was fetched and two things changed the premises:
**A. New commits on `origin/main`** (local `main` was 2 commits behind):
- `be07001` — **Clumps** added (XP-orb merging, `side = both`): cuts XP-orb entity count, entity packets
and server tick cost. Low-risk, standard server-perf mod; no conflict with anything reviewed here.
- `25b3f78` — C2ME runtime `cache/` untracked from the pack index (housekeeping).
**B. Branch `mod-pack-additions`** (2 commits ahead of the local `main`; **not merged**, and checked
out in a separate worktree at `~/.herdr/worktrees/onion-mc/mod-pack-additions`). It adds:
| Added | Detail |
| --- | --- |
| **Iris Shaders** | `iris-neoforge-1.8.14-beta.1+mc1.21.1`, `side = client` |
| **Iris Veil Compat** | `irisveil-0.3.0.jar` — bridges Veil (embedded in Sable) through Iris so Create Aeronautics visuals render correctly under shaders |
| **Aeronautics Iris Fix** | CurseForge `aero-shadow-fix-2.1.0.jar` — third-party fix for Create Aeronautics balloon envelopes rendering as ghost artifacts under Iris |
| **Shaderpacks** | Complementary Reimagined r5.9.3, MakeUp Ultra Fast 9.5f |
| **Resourcepacks** | Motschen's Better Leaves 9.6, Fresh Animations: Extensions v1.8.1 |
**What this changes in this report:**
- The **"no shaders" premise is retired**. Onion MC is moving to Iris + a curated shader list, with two
purpose-built compat patches for the exact Aeronautics/Iris problems `FINDINGS.md` flagged.
- **`iris` and `iris-veil-compat` move from SKIP to `ADDED`** — they are now pack content.
- **`createbetterfps` moves from SKIP to MAYBE.** Its blocker was *"1.21.1 needs Sodium and Iris"*;
with Iris now present it is technically unblocked, but it patches Create's code directly and benefits
only shader scenes, so it must be tested against the Aeronautics/Sable stack before shipping.
- **Shader-adjacent candidates get a second look**: `shine`, `grassier-grass`, `fog`, and
`ATMOSPHERICS` now sit next to a real shader pipeline. `shine`/`grassier-grass` (Sodium terrain
shaders) become more relevant; `fog`/`ATMOSPHERICS` (sky/fog rewrites) now conflict with the
shaderpacks' own fog/sky, so their SKIP/MAYBE verdicts stand for a stronger reason.
- **Residual risk is not zero.** The fix chain is `iris` + `iris-veil-compat` + `aeronautics-iris-fix`,
and `aeronautics-iris-fix` is a small third-party CurseForge patch (~2.6K downloads, present in ~11
modpacks). Known Aeronautics/Iris issues beyond balloon shadows exist (e.g. heat-particle rendering
has a separate fix mod). Treat the Aeronaautics-under-shaders combination as **verified-in-progress**,
and keep the `phase0/` measurement plan for shader on/off before/after.
- Sections below are otherwise unchanged, except where marked **(updated)**.
---
## 1. Executive summary
**Every one of the 189 candidates has a 1.21.1 NeoForge-compatible build.** Nothing on the list is
blocked by version availability. The real filters are **dependency cost**, **overlap**, and a small
number of **hard conflicts**.
Headline result:
| Verdict | Count |
| --- | --- |
| **ADD** — clear, low-risk win | **18** |
| **ADD-OPTIONAL** — good, but a taste/librarary decision | **88** |
| **MAYBE** — needs an in-pack test or a design decision first | **36** |
| **SKIP** — conflict, dead dependency, duplication, or wrong stack | **36** |
| **ALREADY-IN-PACK** — duplicate of an installed mod | **9** |
| **ADDED** — already on `mod-pack-additions` | **2** |
The single most useful finding is that **the candidate list is dominated by "more of what the pack
already has"**. Onion MC already runs five Farmer's Delight addons, a full Create stack, ~20 structure
mods, a large mob roster, and a saturated client-performance stack. Most candidates are another Delight
addon, another decoration mod, another HUD mod, or another culling/perf mod. Adding all the safe ones
would bloat the pack and its library surface without changing the shape of the game.
**Recommended core: 20 mods + 2 libraries** (Section 4). Everything else is either a deliberate
expansion choice, a test-first item, or a skip.
The second finding is **dependency economics**. The candidates would collectively drag in **~25 new
NeoForge library mods** (`Puzzles Lib`, `Moonlight Lib`, `Blueprint`, `Fragmentum`, `Collective`,
`Almanac`, `Delight Lib`, `Lodestone`, `SmartBrainLib`, `Coralib`, `Faewulf's Lib`, `Teal Lib`, etc.).
Several are shared by multiple candidates, so the sane strategy is to **pick one or two content
families and pay for the libraries those need** — not to adopt candidates piecemeal.
The third finding is that a **few candidates are actively dangerous** in this specific pack: anything
that needs **Iris/shaders** (the pack deliberately has none; Create Aeronautics and SSRD both
document Iris rendering issues), anything **Fabric-only via Sinytra Connector**, a **second dynamic
lights engine** next to LambDynamicLights, and a **second claim/party system** next to FTB.
See the risk register in Section 8.
---
## 2. How this review was produced (and how much to trust it)
- **Deterministic data (high confidence).** All 189 links were resolved through the **Modrinth API v2**
— project metadata, loader/side support, every 1.21.1 build, and the **required-dependency graph**
of the selected 1.21.1 NeoForge build. The existing pack was read directly from its 142 `.pw.toml`
files. Counts, loader support, version availability and required dependencies in this report are
machine-derived, not guessed.
- **README/feature analysis (medium-high confidence).** Each candidate's Modrinth README was used as
the primary source for what it adds and for author-declared compatibility notes. Where the README
was silent, the assessment says so.
- **Compatibility claims (medium confidence).** Named conflict claims come from mod READMEs, official
issue trackers, or the pack's own `FINDINGS.md`. They are cited in the detailed appendix and should
be re-tested in a dev instance before shipping — a closed issue or a fixed version can invalidate any
of them.
- **Where this report is uncertain** it says `unknown`, `unverified`, or lists a test gate. Treat the
verdict as a prior, not a guarantee.
### Corrections applied after validation
The bulk research pass was independently checked on the highest-impact claims. Three corrections were
made; the full per-mod appendix retains the corrected view:
1. **`veil` — the "no consumer mod" rationale was wrong.** Veil is **embedded inside Sable**
(`embedded` dependency in Sable's own metadata), which is why `iris-veil-compat` exists. The verdict
is still **SKIP**, but the correct reason is *"Veil is already jar-in-jar inside Sable; adding it
standalone is a duplicate/conflict on the fragile render stack"* — not "nothing uses it".
2. **`autohud` — the Fabric-API "red flag" was a metadata artifact.** The README explicitly scopes the
Fabric API requirement to the Fabric build; the NeoForge build is native. Verdict raised from MAYBE
to ADD-OPTIONAL.
3. **`supplementaries` — the Create conflict is stale.** All three cited issues (Create #7405,
Create #9755, Supplementaries #1436) are **closed**, and both mods are now ~18 months newer. Verdict
raised from MAYBE to ADD-OPTIONAL, with a Create smoke test still recommended.
---
## 3. Baseline: what the pack is, and what that implies
From `FINDINGS.md`, `pack.toml`, `index.toml` and the `phase0/` tuning docs, the decision-relevant
facts are:
| Fact | Consequence for candidate screening |
| --- | --- |
| **Shaders: now being added via `mod-pack-additions`** — Iris + shaderpacks + two compat patches (see Section 0); previously none by design. | Iris, `iris-veil-compat` and the shaderpacks are now pack content. Shader-adjacent candidates are re-evaluated in Section 0; sky/fog rewrites now also conflict with the shaderpacks themselves. |
| **Fragile render core:** Sodium `0.8.13` + Distant Horizons + SSRD + Sable's intrusive mixins. Sodium is version-pinned by Sable (≥ 0.8.12-alpha.2). | Any mod that hooks the sky/fog/weather/terrain render path or couples to a Sodium version is test-first at best. |
| **Create + Sable + Aeronautics is the highest-risk component.** Five Sable compat patches already exist. | Create addons and anything touching player/block physics (gradient, ragdolls, tree physics, ships) need a dev-server test. |
| **Client-perf stack is saturated:** Sodium, Lithium, ModernFix, FerriteCore, EntityCulling, ImmediatelyFast, Dynamic FPS, AllTheLeaks, C2ME, Noisium. | Additional generic perf/culling mods have small marginal gains and add mixin surface. |
| **No configs shipped.** `.packwizignore` excludes `config/*` except one FTB Chunks file. | Candidates that require config curation (Burnt, More Music Discs, Lunar, Celestia, Sleep Tight, Worldgen structure tuning) carry a maintenance cost the pack does not currently pay. |
| **Worldgen is curated and already dense:** Terralith + Tectonic + Incendium + Nullscape + Towns and Towers + When Dungeons Arise + 9 YUNG's mods + Explorify + Sparse Structures. | Biome-adding and structure-adding candidates meet a stack that is already at the "loading" end and already uses Sparse Structures to tame it. |
| **Content pillars:** Farmer's Delight (+5 addons), Create, Aquaculture 2, Apotheosis, Sophisticated Storage/Backpacks, Waystones/Gravestone/Lootr, Alex's Mobs/Caves, Ars Nouveau, Twilight Forest. | The best candidates are those that *plug into* a pillar with the same dependencies, not those that start a new one. |
| **~10-player dedicated server matters as much as the client.** | Server-side candidates (`lmd`, PetProtect, claim mods, structure mods, BlueMap) are judged on TPS/ops cost, not just fun. |
| **A dedicated Create Aeronautics compatibility mod is installed** and explicitly patches `Sleep Tight` and `Etched` among others. | Those two candidates have a positive, author-provided compatibility signal for the Sable stack. |
---
## 4. Recommended core — add these
Chosen for **value ÷ risk**: high player-facing value, no hard conflicts, and either zero new
libraries or one small, widely-used library. This is the set I would ship as a first cohort.
| # | Mod | What it adds | Anchor / relationship | Gameplay impact | New libs | Compat notes |
| --- | --- | --- | --- | --- | --- | --- |
| 1 | **Supplementaries** (`supplementaries`) | Large Vanilla+ block set: jars, signposts, faucets, spring launchers, sconces, planters, rope, lights, decoration + light automation | Decoration family (Chipped/Handcrafted/Rechiseled); NeoForge-first project | **Moderate** | **Moonlight Lib** | Old Create 1.21.1 conflicts all closed; smoke-test with Create. Also unlocks Sleep Tight/Haunted Harvest. |
| 2 | **Let Me Despawn** (`lmd`) | Mobs that picked up gear despawn naturally (dropping the gear first) | Server perf next to Lithium/ModernFix; does **not** replace the chunk engine | Minor (server **perf gain**) | **Almanac** | Directly helps a mob-dense Apotheosis/Alex's Mobs server. Check affixed-mob drops. |
| 3 | **Comforts** (`comforts`) | Sleeping bags (no spawn-set) + hammocks (skip day); dyeable | Expedition QoL next to Waystones/Gravestone | Minor | none | 22.9M downloads, current 1.21.1 NeoForge build. |
| 4 | **Traveler's Titles** (`travelers-titles`) | RPG biome/dimension entry titles; Waystones region titles; Twilight Forest built in | Exploration family | Client-cosmetic | none (YUNG's API in pack) | Makes the curated Terralith/Tectonic world legible. |
| 5 | **Zume** (`zume`) | Hold-to-zoom keybind with adjustable zoom levels | Client utility; no zoom mod in pack | Client-cosmetic | none | Zero server footprint. |
| 6 | **FindMe** (`findme`) | Hover an item in JEI, press Y to locate it in nearby inventories | JEI + Sophisticated Storage loop | Minor | none (Architectury in pack) | High-frequency QoL for a storage-heavy pack. |
| 7 | **Sophisticated Item Actions** (`sophisticated-item-actions`) | Keybind-highlight nearby storages holding an item; deposit/restock without opening GUIs | Sophisticated Core/Backpacks/Storage + JEI | Minor | none | Fills a real gap; JEI-aware. |
| 8 | **Chalk** (`chalk-mod`) | Dyeable chalk marks on block faces (glow variants) + chalk box | Navigation next to Waystones/compasses/Ping Wheel | Minor | none | Fills the cave-marking niche nothing else covers. |
| 9 | **PetProtect** (`petprotect`) | Server toggle: tamed mobs can't be hurt/killed by players in PvP | Pet family | Minor (server policy) | none | Cheap grief insurance on a friends server. |
| 10 | **Waystones Teleport Pets** (`waystones-teleport-pets`) | Pets follow you through Waystones without a lead | Direct **Waystones** addon | Minor | none | Server-side. |
| 11 | **Extreme Sound Muffler** (`extreme_sound_muffler`) | Per-sound volume/mute GUI + ranged "anchor" muffling | Client audio control over AmbientSounds + Sound Physics + Create noise | Client-cosmetic | none | Client-only; complements (doesn't replace) Sound Physics Remastered. |
| 12 | **Simple Music Control** (`simple-music-control`) | Halved music delay, next-track key, now-playing widget | Client audio QoL | Client-cosmetic | none (Fzzy Config in pack) | Zero risk. |
| 13 | **Held Item Tooltips** (`held-item-tooltips`) | Info plate on item switch: enchants, durability, effects, shulker previews | Complements Enchantment Descriptions + Legendary Tooltips (different surface) | Client-cosmetic | **Puzzles Lib** | Puzzles Lib also unlocks Visual Workbench / Distinct Potions / Mob Lassos. |
| 14 | **Display Delight** (`display-delight`) | Placeable 3D models of every Delight food (no block entities — lag-friendly), food plates | **All five** installed Delight addons | Minor | none | README lists explicit compat with Ocean's/End's/Aquaculture Delight. |
| 15 | **Fruits Delight** (`fruits-delight`) | 17 fruits, 90 fruit foods, jam/jello cauldrons, 18 plants/14 fruit trees | Farmer's Delight; author-claimed **Create + Terralith** compat | **Moderate** | none | 2.2M downloads; plugs into two existing pillars. |
| 16 | **Rustic Delight** (`rustic-delight`) | Bell peppers, coffee (Speed/Haste), cotton, pancakes, fried foods | Farmer's Delight | Minor | none | Textbook same-dependency addon. |
| 17 | **Cat Jam** (`cat_jam`) | Cats bob to music discs, with per-disc routines | Client charm; **Alex's Mobs** discs explicitly supported | Client-cosmetic | none | Client-only, oldest-but-stable build. |
| 18 | **Death Knell** (`death-knell`) | 35+ situational death messages | Flavor | Client-cosmetic | none (Prickle + Bookshelf in pack) | Zero risk, deps already installed. |
| 19 | **Portfolio** (`portfolio`) | 100+ paintings in 10 themed catalogues | Decoration family | Client-cosmetic | none | Ships as mod or datapack; zero deps. |
| 20 | **FishingOverhaul** (`fishingoverhaul`) | Reel-in fishing minigame with crit regions and per-fish tuning | **Aquaculture 2** (README states compat) | Minor | none | Changes the fishing interaction, not progression. |
**Bundle cost:** 20 mods, 2 new libraries (`Moonlight Lib`, `Almanac`), one of which (`Moonlight Lib`)
unlocks further candidates later. No config maintenance. No server-render risk. Nothing here touches
Sodium, DH, Sable, Create physics, or worldgen.
**Runner-up core picks** (equally safe, pick if the theme appeals): **Sounds** (`sound`, +MRU) for
170+ upgraded SFX; **Particle Effects** and **Perception** for client ambience; **Distinct Potions**
(+Puzzles Lib, already paid for by Held Item Tooltips); **GUI Effect Timer** (+Collective);
**Neat** for mob health bars; **Advancement Plaques** (Iceberg already in pack); **Visual Workbench**
(+Puzzles Lib).
---
## 5. Strong optional additions, by content family
These are all defensible `ADD-OPTIONAL`s. Use them to steer the pack deliberately, not to accumulate.
### 5.1 Farmer's Delight expansion (the pack's most crowded lane)
Farmer's Delight already has 5 addons. Adding more is cumulative, not gap-filling.
| Mod | What it adds | New libs | Notes |
| --- | --- | --- | --- |
| **Expanded Delight** | More crops/workstations; best-covered by Display Delight (37 foods) | none | Author-declared **beta**. |
| **ExtraDelight** | 7 kitchen workstations (oven, chiller, melting pot…), cookware | none | Block-entity heavy; confirm server load. |
| **Miner's Delight** | Cave-food addon (cave carrots, copper pot/cup) | **Lodestone** | Author-declared **beta**. |
| **More Delight** | Sandwiches, toast, stone/wood knives; Create-compatible | **Delight Lib** | Safe, low marginal value. |
| **Dungeon's Delight** | Monster Pot, inverted "monster effects", Rotbulb crop | none | Check effect stacking with Apotheosis. |
| **Barbeque's Delight** | Grill/skewer loop + seasonings | none | Frictionless. |
| **Fright's Delight** | 56 horror foods from mob drops, cursed berries | none | Horror theme is a taste call. |
| **Veggies Delight** | 7 vegetables, temperature-based wild spawns, village Depot Houses | none | Low-risk; village structures are additive. |
| **Hearth and Harvest** | Crops, corn mazes, salt caverns, ranching utilities | none | Corn overlaps Haunted Harvest — pick one. |
| **Haunted Harvest** | Trick-or-treating villagers, pumpkin carving, corn | **Moonlight Lib** | Shares Moonlight with Supplementaries. |
| **Cultural Delights** | Avocado/eggplant/cucumber/corn/beans/cinnamon, world cuisine | **Cook's Collection** | Extra lib for one addon. |
| **Delightful Creators** | Second FD↔Create automation bridge (fluids/soups) | none | **Overlaps the installed Slice & Dice** — deliberate "both routes" decision. |
### 5.2 Create expansion (test every one against Aeronautics/Sable)
| Mod | What it adds | New libs | Notes |
| --- | --- | --- | --- |
| **Create: Bells & Whistles** | 36 deco/utility blocks (platforms, headlights, train grab bars) | none | Decorative; smoke-test on contraptions. |
| **Create: Design n' Decor** | Create-styled deco/variant blocks | none | Active maintenance; low risk. |
| **Create: Teleporters** | TP links, entity/item teleporters, pocket-dimension portal | none | Adds a dimension; independent of worldgen. |
| **Create: Waystones Recipes** | Replaces Waystones recipes with Create machine recipes | none | Progression design decision. |
| **Create: Factory** | Create-themed foods | none | Crowded food lane; low value. |
| **Create: Structures Arise** | 28 Create-themed worldgen structures | none | Thickens an already structure-saturated worldgen stack. |
| **Create: Sophisticated Backpacks Compat** | Third-party recipe pack for SB components | none | Likely partial **recipe overlap** with the installed official integration — check JEI. |
### 5.3 Decoration & building
**Items Displayed**, **Beautiful Campfires**, **Sooty Chimneys**, **Too Many Paintings**, **Spooky Doors**,
**Boatload** (+Blueprint), **Display Case** / **Fetzi's Displays** / **Gallery** (+Blueprint, *pick one
display system*), **Etched** (music discs from URLs — note: **Create Aeronautics Compat explicitly
patches Etched**, a positive signal; content-policy caveat), **Accents** (+Fragmentum).
### 5.4 HUD, client polish & ambience
**Neat** (prefer over **JeremySeq's Damage Indicator** — pick one mob-info mod), **Armor HUD** or
**Immersive Armor HUD** (+TxniLib), **Advancement Plaques**, **AutoHUD**, **GUI Effect Timer** (+Collective),
**Keybind Atlas**, **Blur+** (+MidnightLib), **Distinct Potions** (+Puzzles Lib), **Emojiful**,
**Quick Skin** (prefer over SkinChanger), **Sounds Be Gone**, **Now Playing** (+Deimos for discs),
**Loot Journal** (+Fragmentum), **Particle Effects**, **Perception**, **Smart Particles**,
**Better Animations Collection** (+Puzzles Lib), **Visuality: Reforged**, **Better Third Person**,
**Camera Overhaul**, **Cinematic Respawn**, **Mermod**, **Piggyback** (+Faewulf's Lib),
**Cosy Critters**, **Fancy World Animations** (blacklist safety valve exists).
### 5.5 Mobs, combat & gear
**Fowl Play** (+SmartBrainLib), **Animal Garden – Porcupine** (zero deps), **Hybrid Aquatic**
(+Hybrid API + Biolith; big ocean overhaul — gate on a worldgen/Aquaculture test), **Realm RPG: Fallen
Adventurers** (explicit Twilight Forest support), **Reliquary Reincarnations** (needs a balance pass vs
Apotheosis/Artifacts), **Too Many Bows** (explicitly recommends Better Combat + Curios, both in pack),
**Skillcloaks** (Curios), **TarotCards: Remastered** (team-aware via FTB Teams), **Mob Lassos**
(+Puzzles Lib; check boss exclusion), **Friends&Foes – Flowery Mooblooms** (same author as installed F&F),
**Pet Cemetery** (+Blueprint; verify modded-pet support), **Animal Garden**, **Dream Relics** (balance overlap with Artifacts).
### 5.6 Social & minigames
**Immersive Melodies**, **Charta**, **Mino++**, **Watut** (+CoroUtil), **PlayerRevive** (Gravestone
interplay test), **Incapacitated** (changes core death rules — owner sign-off).
### 5.7 Sleep
**Sleep Tight** (+Moonlight Lib; **explicitly patched by the installed Create Aeronautics Compat**, a
positive signal; adds bedbugs/nightmares), **Room For Two** (beta; pick **one** of these two).
### 5.8 Server / admin
**BlueMap** (web map — ops overhead: port, web server, bStats opt-out; async to the server thread),
**Followers Teleport Too** (+Collective; overlaps Waystones Teleport Pets — pick one),
**Better Compatibility Checker** (only if the pack pipeline will update `bcc-common.toml` each release).
### 5.9 Fishing & food extras
**Fishing Real** (fish spawn as live entities; defaults cover vanilla only — needs datapack JSONs for
Aquaculture species), **Overweight Farming**, **AlcoCraft+**, **Create: Factory**.
---
## 6. Full master table (all 189 candidates)
Verdicts and one-line rationale per candidate. `MAYBE` = test-first or a design decision. The detailed
**Adds / Relationship / Missing deps / Compatibility / Perf** breakdown for every mod is in the
appendix (`analysis/assess/chunk*.md`, consolidated in `analysis/CANDIDATE-APPENDIX.md`). The same
candidates grouped by purpose with a **“what it brings”** column are in **`MODLIST-GROUPS.md`**.
> **(updated)** `iris` and `iris-veil-compat` are now `ADDED` (branch), and `createbetterfps` is now
> `MAYBE` — see Section 0.
### ADD (18)
| Mod | Impact | Rationale |
| --- | --- | --- |
| **cat_jam** (`cat_jam`) | Client-cosmetic | tiny, client-only, documented compat with a mod already in the pack. |
| **Chalk** (`chalk-mod`) | Minor | cheap, self-contained, fills a real gap for cave exploration. |
| **Comforts** (`comforts`) | Minor–Moderate | staple adventure QoL, well-maintained, no dependency cost. |
| **Death Knell** (`death-knell`) | Client-cosmetic | zero-risk flavor whose deps are already installed. |
| **Display Delight** (`display-delight`) | Minor | direct, low-risk upgrade to the pack's food-and-decor identity. |
| **Extreme sound muffler** (`extreme_sound_muffler`) | Client-cosmetic | zero-risk, zero-server-cost QoL that is actively maintained (3.56, 2026-09-22). |
| **FindMe** (`findme`) | Minor | zero-dep, low-risk, high-frequency QoL. |
| **FishingOverhaul** (`fishingoverhaul`) | Minor | declared Aquaculture 2 compat makes this a natural pack fit. |
| **Fruits Delight** (`fruits-delight`) | Moderate | big, popular (2.2M downloads) FD expansion that plugs into two pack pillars (Create, Terralith). |
| **Held Item Tooltips** (`held-item-tooltips`) | Client-cosmetic (informational). | low-risk, high-frequency QoL; library cost shared with other Puzzles-Lib picks. |
| **Let Me Despawn** (`lmd`) | Minor | clear server-side perf win for a 10-player mob-dense pack; add Almanac with it. |
| **PetProtect** (`petprotect`) | Minor | tiny, dependency-free, and directly prevents grief/accident on a 10-player PvP-capable server full of tamed mods' pets. |
| **Portfolio** (`portfolio`) | Client-cosmetic | zero-dependency pure content that fills an empty decorative niche. |
| **Rustic Delight** (`rustic-delight`) | Minor | textbook fit: same-dependency addon for an existing content pillar. |
| **Simple Music Control** (`simple-music-control`) | Client-cosmetic. | zero-risk client QoL whose only dependency is already present. |
| **Traveler's Titles** (`travelers-titles`) | Client-cosmetic. | cheap, polished, and it makes the pack's giant curated worldgen legible to players. |
| **Waystones Teleport Pets** (`waystones-teleport-pets`) | Minor QoL for pet owners. | tiny, targeted, and fixes a real annoyance for a 10-player server full of tamed pets. |
| **Zume** (`zume`) | None (view convenience; no gameplay ch | zero-dep, zero-server, fills an obvious gap next to Sodium+DH distance viewing. |
### ADD-OPTIONAL (88)
| Mod | Impact | Rationale |
| --- | --- | --- |
| **Fisherman's Haven** (`fishermans-haven`) | Moderate | no deps, distinct fishing mechanics that complement Aquaculture 2; accept the niche overlap deliberately. |
| **Accents** (`accents`) | Minor | low-risk cosmetic+minor-stat layer; costs one new library dep. |
| **Advancement Plaques** (`advancement-plaques`) | Client-cosmetic. | safe client polish on a dep already in pack; one test-instance check on the sound caveat. |
| **Akashic Tome** (`akashic-tome`) | None | cheap, low-risk QoL that scales well with a 142-mod pack. |
| **AlcoCraft+** (`alcocraft`) | Minor | small, self-contained fun; no flags. |
| **Animal Garden - Porcupine** (`animal-garden-porcupine`) | Minor | tiny, dependency-free, fits the existing tameable-mob theme. |
| **Armor Hud** (`armor-hud`) | Client-cosmetic. | tiny, dependency-free HUD addition. |
| **Ars Elixirum** (`ars-elixirum`) | Moderate | deep alchemy content with one new library dep; confirm in testing that it doesn't hard-require anything beyond Fragmentum. |
| **Auto HUD** (`autohud`) | Client-cosmetic. | Metadata Fabric-API dep is Fabric-build-only; native NeoForge build. |
| **Barbeque's Delight [Forge/NeoForge]** (`barbeques-delight-forge`) | Minor | frictionless fit with the existing Delight stack. |
| **Beautiful Campfires** (`beautiful-campfires`) | Minor | cheap cosmetic polish; document the oak-only recipe change in pack notes. |
| **Better Animations Collection** (`better-animations-collection`) | Client-cosmetic. | pure atmosphere polish for one new library dep. |
| **Better Third Person** (`better-third-person`) | Client-cosmetic. | safe, popular camera QoL with no deps; just smoke-test it while piloting Aeronautics contraptions. |
| **BlueMap** (`bluemap`) | None | genuinely useful for a small dedicated server, but it's ops overhead (webserver, ports, configs) rather than content. |
| **Blur+** (`blur-plus`) | Client-cosmetic | safe cosmetic; only bother if the pack wants GUI polish. |
| **Boatload** (`boatload`) | Minor | pleasant water QoL, but chest-boat overlap with vanilla makes it low-value; needs Blueprint. |
| **Burnt** (`burnt-basic`) | Moderate | distinctive survival flavor with controls, but server-grief/tick cost means it's a taste call, not a default. |
| **Camera Overhaul** (`cameraoverhaul`) | Client-cosmetic | cheap and configurable, entirely a taste/accessibility call. |
| **Certain Questing Additions** (`certain-questing-additions`) | None | nice polish for a quested pack; harmless if dropped. |
| **Charta** (`charta`) | Minor | charming multiplayer flavor, zero risk if unused. |
| **Cinematic Respawn** (`cinematic-respawn`) | Client-cosmetic | pleasant, zero-risk client polish; taste call on auto-respawn. |
| **Cosy Critters & Creepy Crawlies** (`cosy-critters`) | Client-cosmetic | cheap atmosphere for explorers; skip if the ambience budget is full. |
| **Create Waystones Recipes** (`create-waystones-recipes`) | Minor | safe; a deliberate progression/taste decision for the questbook rather than a technical one. |
| **Create: Bells & Whistles** (`bellsandwhistles`) | Minor | strong deco value for a Create pack; verify blocks behave on Aeronautics contraptions first. |
| **Create: Design n' Decor** (`create-design-n-decor`) | Minor | safe factory decoration; nice with the pack's Chipped/Rechiseled angle. |
| **Create: Factory** (`create-factory`) | Minor | harmless, but the food family is already the pack's most crowded content lane; low marginal value. |
| **Create: Structures Arise** (`create-structures-arise`) | Moderate | strong fit for a Create + exploration pack, but it thickens an already structure-saturated worldgen stack with no config knobs shipped. |
| **Create: Teleporters** (`create-teleporters`) | Moderate | clean fit for Create logistics with no flagged conflicts; decide whether the pack wants dimensional play. |
| **Cultural Delights** (`cultural-delights`) | Moderate | on-theme food content, but it requires adopting Cook's Collection and the Delight shelf is already crowded. |
| **Death Count** (`death-count`) | Minor | harmless novelty for a 10-player server, though equally achievable with a one-line vanilla scoreboard datapack. |
| **Distinct Potions** (`distinct-potions`) | Client-cosmetic | cheap visual QoL; only worth it if the pack accepts pulling in Puzzles Lib for a single client mod. |
| **Dungeon's Delight** (`dungeons_delight`) | Moderate | thematically perfect next to the pack's existing Delight collection; sanity-check the new effect types against Apotheosis stacking. |
| **Dynamic Crosshair** (`dynamiccrosshair`) | Client-cosmetic | pure client polish, but must be tested against ImmediatelyFast and dropped if HUD glitches appear. |
| **Emojiful** (`emojiful`) | Client-cosmetic | fun for a 10-player social server with zero gameplay footprint. |
| **Etched** (`etched`) | Minor | great social toy for a small server; settle the URL-content policy first. |
| **Expanded Delight** (`expanded-delight`) | Moderate | strongly on-theme and the best-covered addon for Display Delight, but accept the author-declared beta instability or wait for stable. |
| **ExtraDelight** (`extradelight`) | Moderate | the meatiest Delight addon in the batch and a natural kitchen-tier progression; confirm the block-entity load on the dedicated server before committing. |
| **Fancy World Animations [FWA]** (`fwa`) | Client-cosmetic | strong client polish with a blacklist safety valve; verify against Sable/ImmediatelyFast rendering before shipping. |
| **Farmer's Knives** (`farmers-knives`) | Minor | cheap thematic glue whose payoff is real but limited to Twilight Forest materials since the other supported tool mods aren't in the pack. |
| **Field Guide** (`field-guide`) | Minor | excellent fit for a 10-player exploration pack; price of admission is two extra NeoForge libs. |
| **Fishing Real** (`fishing-real`) | Minor | cheap, fun, low-risk; worth a small datapack pass to include Aquaculture species. |
| **Followers Teleport Too** (`followers-teleport-too`) | Minor | clear QoL win with Waystones for ~10 players; costs one shared lib. |
| **Fowl Play** (`fowlplay`) | Minor | strong ambience fit for the pack's mob roster; costs one AI lib. |
| **Friends&Foes - Flowery Mooblooms (Forge/NeoForge)** (`friends-and-foes-flowery-mooblooms-forge`) | Minor | cheap flavor that slots into an installed mod; skip only if moobloom density is unwanted. |
| **Fright's Delight** (`frights-delight`) | Minor | fits the pack's Delight collection; horror theme is a taste call. |
| **GUI Effect Timer** (`gui-effect-timer`) | Client-cosmetic (informational). | tiny, safe, useful; effectively free once Collective is pinned for Followers Teleport Too. |
| **Hearth and Harvest** (`hearth-and-harvest`) | Moderate | solid FD-family expansion; coordinate corn overlap with Haunted Harvest before adding both. |
| **Hybrid Aquatic** (`hybrid-aquatic`) | Major | biggest content win in this batch; gate on a worldgen + Aquaculture overlap test because of the two new library pins. |
| **Immersive Armor HUD** (`immersive-armor-hud`) | Client-cosmetic. | cheap vanilla-style HUD upgrade; minor recency caveat. |
| **Immersive Melodies** (`immersive-melodies`) | Minor | fun multiplayer toy at essentially zero mechanical risk. |
| **Items Displayed [NeoForge]** (`items-displayed-forge`) | Minor | safe builder content that fits the pack's decoration mods. |
| **Keybind Atlas** (`keybind-atlas`) | None | genuinely useful in a pack this size, zero risk. |
| **Loot Journal: Pickup Notifier** (`loot-journal`) | Client-cosmetic | nice HUD polish; in-game config means no shipped-config maintenance. |
| **Mermod** (`mermod`) | Minor | small, cheap, fits the pack's exploration theme; low information confidence due to thin README. |
| **Miner's Delight** (`miners-delight`) | Minor | strong thematic fit with the Delight family, but the author's own beta warning plus a new library dep argue for wait-and-see. |
| **Mino++** (`minopp`) | Minor | charming social content with no risk surface; pure taste call. |
| **Mob Lassos** (`mob-lassos`) | Minor-Moderate | useful QoL; check boss exclusion config before shipping to a pack with Apotheosis. |
| **More Delight (for Farmer's Delight)** (`more-delight`) | Minor | safe, on-theme content; the Delight family is already large, so it's cumulative rather than filling a gap. |
| **More Music Discs** (`more-music-discs`) | None-Minor | cheap flavor; verify default disc-in-every-loot-pool density is wanted. |
| **Mystical Oak Tree** (`mystical-oak-tree`) | Minor | harmless flavor for a friends pack; nothing about it strains the stack. |
| **Neat** (`neat`) | Client-cosmetic | mature, zero-risk combat readability; prefer over the Damage Indicator if choosing one. |
| **Now Playing** (`now-playing`) | None | trivial, safe; most valuable if music-content mods are added. |
| **Overweight Farming** (`overweight-farming`) | Minor | small, self-contained farming charm. |
| **Particle Effects** (`particle-effects`) | Client-cosmetic | pure client polish, zero server footprint. |
| **Perception** (`perception`) | Client-cosmetic | safe client ambience; optional enough that individual players could skip it. |
| **Pet Cemetery** (`pet-cemetery`) | Minor | emotionally valuable on a friends server; verify modded-pet support first. |
| **Piggyback** (`piggyback`) | Minor | harmless co-op fun, but requires adding Faewulf's Lib to the pack. |
| **PlayerRevive** (`playerrevive`) | Moderate | strong social fit, but it rebalances death and needs a Gravestone interplay check. |
| **Quick Skin** (`quick-skin`) | Client-cosmetic | client nicety; preferred over SkinChanger (newer, GUI, more features). |
| **Realm RPG: Fallen Adventurers** (`realm-rpg-fallen-adventurers`) | Minor | easy exploration flavor; note the 1.21.1 build dates to 2025-01 (aging but stable, 2.3M downloads). |
| **Reliquary Reincarnations** (`reliquary-reincarnations`) | Moderate | content-rich and maintained, but demands a balance pass against Apotheosis/Artifacts. |
| **Room For Two** (`room-for-two`) | Minor | harmless fun at BETA maturity; pick it OR Sleep Tight's ecosystem, and test if both. |
| **Skillcloaks** (`skillcloaks`) | Minor | solid Curios content on an existing dependency; consider adding Lucent for the full feature set. |
| **Sleep Tight** (`sleep-tight`) | Moderate | popular, well-scoped sleep rework; requires adding Moonlight Lib and choosing between it and Room For Two rather than stacking blindly. |
| **Smart Particles** (`smart-particles`) | Client-cosmetic | targeted client-side stabilizer with no server footprint; watch mixin overlap with ImmediatelyFast. |
| **Sooty Chimneys** (`sooty-chimneys`) | Minor | safe, charming builder content with negligible cost. |
| **Sophisticated Item Actions** (`sophisticated-item-actions`) | Minor (inventory-flow QoL, Terraria-st | genuinely new capability that plays well with the Sophisticated + JEI stack already in the pack. |
| **Sounds** (`sound`) | Client-cosmetic. | high polish, zero server footprint; costs one new small library. |
| **Sounds Be Gone!** (`soundsbegone`) | Client-cosmetic (no gameplay change; p | tiny, safe, real accessibility value for a 10-player group. |
| **Spooky Doors** (`spooky-doors`) | Minor | small, charming, Balm-based and low-risk. |
| **Supplementaries** (`supplementaries`) | Moderate | Create conflict issues all closed; NeoForge-first. Needs Moonlight Lib; smoke-test. |
| **TarotCards: Remastered** (`tarotcards-remastered`) | Minor | clean fit for an exploration/loot pack; explicitly team-aware. |
| **Too Many Bows** (`too-many-bows`) | Moderate | strong synergy with Better Combat and Curios already in the pack. |
| **Too Many Paintings!** (`too-many-paintings`) | Client-cosmetic (placed paintings are | zero-dep cosmetic content, safe on both sides. |
| **Veggies Delight** (`veggies-delight`) | Minor | low-risk content that deepens the pack's largest content family. |
| **Visual Workbench** (`visual-workbench`) | Minor | popular, polished Fuzs mod; costs one small library. |
| **Visuality: Reforged** (`visuality-forge`) | Client-cosmetic. | safe client-only polish; consider whether Subtle Effects already covers the need. |
| **What Are They Up To (Watut)** (`what-are-they-up-to`) | Minor | genuinely fun on a small friend group; costs one small library. |
### MAYBE (36)
| Mod | Impact | Rationale |
| --- | --- | --- |
| **Better Compatibility Checker** (`better-compatibility-checker`) | None. | only earns its slot if the build pipeline commits to updating its config each release. |
| **Burnt + Additions** (`burnt`) | Moderate | the fuller variant is attractive but heavier; if fire flavor is wanted, choose this over basic deliberately (and still treat as optional). |
| **Celestria** (`celestria`) | Minor | nice ambience, but stale build + WorldRenderer mixin on the Sodium/DH/Sable stack needs an in-pack smoke test first. |
| **Companions!** (`companions-mod`) | Moderate | decent content but redundant with the existing mob roster and it drags in a new library; only if the pack wants more combat-pet content. |
| **Create: Estrogen** (`create-estrogen`) | Moderate | can't be evaluated in isolation (dep is a batch candidate), self-declared in-development, and tone may not fit the pack; decide together with the Estrogen entry. |
| **Create: Sophisticated Backpacks Compat** (`create-sophisticated-backpacks-compat`) | Minor | plausible value, but check for recipe collisions with the official Create Integration already in the pack before committing. |
| **CreateBetterFps** (`createbetterfps`) | None | Iris + Sodium now in pack, so unblocked in principle, but it patches Create's code on the Aeronautics/Sable stack - test first. |
| **Delightful Creators** (`delightful-creators`) | Moderate | pick one FD↔Create bridge; Slice & Dice is already installed and proven, so this needs a deliberate "both approaches" decision. |
| **Display Case** (`displaycase`) | Client-cosmetic | fine in isolation, but choose between this and Fetzi's Displays (same batch) rather than shipping both display systems. |
| **Dream Relics** (`dream-relics`) | Moderate | duplicate niche vs Artifacts with Apotheosis balance implications; needs a curation pass before adding. |
| **Effectual** (`effectual`) | Client-cosmetic | duplicates Subtle Effects' niche and drags in a new lib; only add after an overlap audit, which the config-less pack model makes costly. |
| **Environmental** (`environmental`) | Moderate | its content substantially duplicates what Terralith + Alex's Mobs already deliver, and it requires pulling in Blueprint for a single mod. |
| **Fetzi's Displays** (`fetzis-displays`) | Client-cosmetic | good feature set but redundant with Display Case (batch) + Handcrafted; pick one display system for the pack. |
| **Fog** (`fog`) | Client-cosmetic. | attractive but unproven next to DH/SSRD; only add after an in-game fog + DH visual test. |
| **Gallery** (`gallery`) | Client-cosmetic (decorator QoL). | nice decorator QoL but drags in the Blueprint library for a niche feature. |
| **Grassier Grass** (`grassier-grass`) | Client-cosmetic. | best-looking pick in the batch, but Sodium 0.8-alpha compatibility is unproven; gate on a crash/visual test. |
| **GUI Compass** (`gui-compass`) | Client-cosmetic. | harmless, but marginal over F3 and redundant if Field Guide (with Immersive Overlays) is added. |
| **Haunted Harvest** (`haunted-harvest`) | Minor | charming, but adds a lib, modifies villager AI, and double-buys corn with Hearth and Harvest. |
| **Health Bars** (`new-health-bars`) | Client-cosmetic (informational). | redundant with Jade unless the group wants damage numbers; if added, de-overlap with Jade deliberately. |
| **Incapacitated** (`incapacitated`) | Major | great co-op mechanic but changes core death rules; needs owner sign-off plus a Gravestone interaction test. |
| **Inventory Particles** (`inventory-particles`) | Client-cosmetic. | pretty and unusually modded-item-friendly; fine as a client-side optional, but pure cosmetics. |
| **JeremySeq's Damage Indicator** (`jeremyseqs-damage-indicator`) | Client-cosmetic | harmless, but functionally redundant with Neat if both are added; pick one combat-info mod. |
| **Lunar** (`lunar`) | Moderate | fun server-wide content, but gravity/spawn events touching Aeronautics physics is an unquantified risk in this pack. |
| **More Culling** (`moreculling`) | None | plausible FPS gain, but redundant-adjacent to Entity Culling and unvetted against the pack's fragile rendering core; test in isolation or skip. |
| **Obscure Tooltips** (`obscure-tooltips`) | None | attractive but redundant with Legendary Tooltips; only add after confirming they don't fight over tooltip rendering, or as a replacement. |
| **Primal** (`mod-primal`) | unknown | sparse documentation; inspect the wiki and jar contents before committing. |
| **Punchy! x Tiny Takeover** (`tiny-takeover-x-punchy`) | Minor | verify whether Punchy/Tiny Takeover base mods are actually required and that the NeoForge build is real before adding. |
| **Ragdoll Reactions** (`ragdoll-reactions`) | Minor | only alongside Sable: Ragdolls, and only after crash-testing with Aeronautics. |
| **Sable Beyond** (`sable_beyond`) | Moderate | the most functionally attractive Aeronautics enhancement in the batch, but alpha software on the pack's most fragile stack; isolated testing and backups are mandatory. |
| **Sable: Ragdolls** (`sable-ragdolls`) | Minor | fun, Sable-native, and unlocks two other candidates; test with Aeronautics before adopting. |
| **Shine** (`shine`) | Client-cosmetic. | confirmed Sodium 0.8.12 compatibility, but partial feature loss on that version, overlap with Subtle Effects, and a privileged position on the fragile rendering stack. |
| **Small Ships** (`small-ships`) | Moderate | appealing content, but a beta build with old updates parked next to Aeronautics/Sable physics; needs a dedicated compat test or should pass. |
| **Sophisticated Inventory Interactions** (`sophisticated-inventory-interactions`) | Minor (pure inventory-management QoL). | good mod, but it replaces rather than stacks with Client Sort; pick one container-sorting solution. |
| **Spawn** (`spawn-mod`) | Major | substantial content but collides with the pack's curated worldgen and mob roster; needs Teal Lib and dedicated testing before inclusion. |
| **Spawn Animations** (`spawn-animations`) | None | mild flourish; if wanted, use the datapack form to dodge the Fabric dep chain rather than the mod. |
| **Tree Physics** (`tree-physics`) | Moderate | the most on-theme Sable use possible, but per-tree physics sub-levels on the Aeronautics stack demand a dev-server soak test before shipping. |
### SKIP (36)
| Mod | Impact | Rationale |
| --- | --- | --- |
| **AAA Particles** (`aaa-particles`) | Client-cosmetic. | a library with no in-pack consumer; standalone value is only a lightning visual swap. |
| **AAA Particles: World** (`aaa-particles-world`) | Client-cosmetic. | purely cosmetic addon whose required base (AAA Particles) is itself a skip. |
| **Abnormals Delight** (`abnormals-delight`) | Minor (and in this pack, near-zero). | required Blueprint dep plus an ecosystem (Team Abnormals) the pack doesn't run; mostly dead content. |
| **Alex's Mobs Continued** (`alexs-mobs-continued`) | Overhaul (if it *replaced* the existin | direct duplicate of an existing pack mod; would only ever be a 1:1 swap project. |
| **Ars Ocultas** (`ars-ocultas`) | Moderate if Occultism were present; in | required dependency Occultism is absent from both the pack and this batch. |
| **AsyncParticles** (`asyncparticles`) | None (pure client optimization). | a named crash interaction with in-pack C2ME that the pack cannot pre-configure, plus beta render-layer mixins against the fragile Sable/Create stack; revisit only if particle load measurably hurts cli |
| **ATMOSPHERICS** (`atmospherics`) | Client-cosmetic. | visual upside not worth the risk on the Sodium+DH+SSRD stack; no shader-adjacent additions should ride on that axis per pack rules. |
| **BadOptimizations** (`badoptimizations`) | None. | marginal, hard-to-measure gains on a stack that already covers these areas (constraint 6); not worth extra mixin surface for a ~4% synthetic-FPS delta per the author's own screenshots. |
| **Berry Good** (`berry-good`) | Minor. | an entire additional library dependency (Blueprint) for one minor placement QoL; revisit only if the pack adopts Team Abnormals mods wholesale. |
| **Carry On + Create Aeronautics Compat** (`carryon-aeronautics-compat`) | Moderate (when it applied); effectivel | self-declared obsolete (fix upstreamed to Carry On 2.2.6+), base mod absent, documented server-hang known issue. |
| **Carry On Extend** (`carry-on-extend`) | Minor | dead on arrival without Carry On; revisit only if the pack adopts Carry On itself. |
| **Chef's Delight - Farmer's Delight Villagers** (`chefs-delight`) | Minor (if it worked) | 1.21.1 build is bound to FD Refabricated, which conflicts with the pack's existing Farmer's Delight. |
| **Create Sable Dynamic Lights** (`create-sable-dynamic-lights`) | Client-cosmetic | requires a second dynamic-lights engine that duplicates LambDynamicLights and couples to the fragile Sodium/Sable version pin. |
| **Create: Dynamic Lights** (`create-dynamic-lights`) | Client-cosmetic | redundant with LambDynamicLights, wrong rendering stack assumptions (Embeddium/Rubidium), and its niche is better covered (or deliberately declined) elsewhere. |
| **Dynamic Trees** (`dynamictrees`) | Major | a transformative tree overhaul whose coverage against the pack's 10+ worldgen mods is unverified and which demands config curation the pack explicitly does not ship. |
| **Early Bedtime** (`early-bedtime`) | Minor | solves a shader-specific problem this shaderless pack doesn't have, at the cost of adopting TxniLib. |
| **Estrogen** (`estrogen`) | Moderate | meme-toned content whose headline feature alters player movement near a fragile physics stack, and which costs two extra pieces (Cynosure + separate Create module) for weak fit. |
| **Even More Instruments!** (`evenmoreinstruments`) | Minor | abandoned per its own README and requires Genshin Instruments, which the pack does not have. |
| **Horror messages** (`horror-messages`) | None | chat-spam gimmick; only defensible if the pack deliberately becomes a horror pack. |
| **Immersive UI** (`immersive-ui`) | Client-cosmetic. | two extra libraries for cosmetic overlap with Inventory Particles; poor value per pin. |
| **Immersive Winds** (`immersive-winds`) | Client-cosmetic. | Sinytra-only NeoForge support is a red flag by pack policy, and Grassier Grass already covers sway if that's added. |
| **More Relics** (`more-relics`) | Moderate | needs a missing base mod + two libraries, carries self-documented version-pin fragility, and duplicates the Artifacts niche the pack already covers. |
| **Net Music: Better Experience** (`net-music-play-list`) | None-Minor | dependent on an absent streaming-music base mod with service/licensing baggage; poor fit. |
| **Open Parties and Claims** (`open-parties-and-claims`) | Overhaul of base-protection/social sys | direct duplicate of FTB Chunks + FTB Teams; would only make sense as a wholesale replacement, which contradicts the installed FTB Quests/Chunks/Teams chain. |
| **Pixelmon** (`pixelmon`) | Overhaul | total-conversion-scale content that steamrolls the pack's identity, worldgen, and mob budget. |
| **Puddles & Floods** (`puddles-floods`) | Client-cosmetic | Fabric-API-derived dependency (red flag) for a cosmetic payoff with real server tick cost; revisit only if the pack accepts Forgified Fabric API. |
| **Refined Storage - JEI Integration** (`refined-storage-jei-integration`) | None in this pack | dead weight without Refined Storage. |
| **Relics: Arcane Abilities** (`arcane-abilities`) | Moderate | its own README requires Relics + Hammer Lib (missing); would need both plus a balance review to reconsider. |
| **Sable: Ragdoll Corpse** (`sable-ragdoll-corpse`) | Minor | Gravestone already owns this job; stacking two death-item systems on the Sable physics stack adds fragility for no new capability. |
| **SkinChanger** (`skinchanger`) | Client-cosmetic. | redundant with Quick Skin (GUI, HD skins, animated capes) and stale: last updated 2024-10-26 vs. Quick Skin's 2026-09-28. |
| **Sophisticated Sorter** (`sophisticated-sorter`) | Minor. | redundant with Client Sort in-pack and with Sophisticated Inventory Interactions in this same batch; side metadata is also "unknown" for both sides. |
| **Spawn Animations Compats** (`spawn-animations-compats`) | None. | only meaningful if Spawn Animations is added, and its supported mob list barely overlaps this pack. |
| **Tooltip Overhaul** (`tooltip-overhaul`) | Client-cosmetic. | collides with Legendary Tooltips; the pack should carry one tooltip restyler, and it already does. |
| **Veil** (`veil`) | None by itself | rendering-engine tooling with no dependent mod in the pack, on the most fragile part of the stack. |
| **VinURL** (`vinurl`) | Minor (custom music per player). | Connector red flag, runtime binary downloads, and licensing minefield; not worth it for jukebox music. |
| **Welcome Screen** (`welcome-screen`) | None. | 2-3 new dependencies for a screen a server MOTD/pin note can replace. |
### ALREADY-IN-PACK (9)
| Mod | Impact | Rationale |
| --- | --- | --- |
| **Apothic Combat** (`apothic-combat`) | Major (as installed) | duplicates the pack's existing Apothic Combat entry. |
| **Aquaculture 2** (`aquaculture`) | Moderate (as installed). | exact duplicate of the existing Aquaculture 2 entry. |
| **Aquaculture Delight** (`aquaculture-delight`) | Minor (as installed). | exact duplicate of the existing Aquaculture Delight entry. |
| **Ars Creo** (`ars-creo`) | Moderate (as installed). | duplicate of the existing Ars Creo entry; the "missing dep" line is a dead-ID artifact, not a real gap. |
| **Create Aeronautics: Compatibility** (`create-aeronautics-compatability`) | Moderate | duplicates the existing "Create Aeronautics: Compatibility" entry in the pack list; do not add a second copy. |
| **Nature's Compass** (`natures-compass`) | N/A | byte-for-byte duplicate of the existing Nature's Compass entry; drop from the candidate list. |
| **Separate Sable Render Distance** (`ssrd`) | None | duplicate of the pack's existing SSRD entry; exclude from the candidate list. |
| **Sophisticated Backpacks Create Integration** (`sophisticated-backpacks-create-integration`) | Minor (already shipped; storage automa | exact duplicate of the pack's own Sophisticated Backpacks Create Integration entry. |
| **Sophisticated Storage Create Integration** (`sophisticated-storage-create-integration`) | Minor (already shipped). | exact duplicate of the pack's own Sophisticated Storage Create Integration entry. |
### ADDED (2)
| Mod | Impact | Rationale |
| --- | --- | --- |
| **Iris Shaders** (`iris`) | Overhaul | Already added on branch mod-pack-additions (see Post-review update). |
| **Iris Veil Compat** (`iris-veil-compat`) | None | Already added on branch mod-pack-additions (see Post-review update). |
## 7. Skip list — the 36 I would not add, by reason
### 7.1 Render-stack violations (updated)
**`Iris Shaders` and `Iris Veil Compat` are no longer skips — they are now `ADDED` on the
`mod-pack-additions` branch (Section 0).** The entries below remain rejected.
| Mod | Reason |
| --- | --- |
| **ATMOSPHERICS** | Rewrites sky/fog/cloud rendering. It already clashed with the Sodium + DH + SSRD axis and warned about Sodium *"Improved Transparency"*; now it also fights the shaderpacks' own sky/fog. |
| **Veil** | Already **embedded inside Sable**; adding it standalone duplicates the render engine. |
| **Fog** | Fog/sky coverage the newly added shaderpacks already provide; Distant Horizons compatibility is an open upstream question. |
**(updated)** The previously listed `Iris Shaders`, `Iris Veil Compat` and `CreateBetterFps` moved:
`iris`/`iris-veil-compat` to **ADDED**; `CreateBetterFps` to **MAYBE** (its blocker was *"1.21.1 needs
Sodium and Iris"*, and Iris is now present, but it patches Create's code on the Aeronautics/Sable stack).
`Shine` and `Grassier Grass` stay **MAYBE**; both are Sodium-coupled and now also sit next to a real
shader pipeline.
### 7.2 Fabric-only / Sinytra Connector dependency (hard)
| Mod | Reason |
| --- | --- |
| **Immersive Winds** | README: *"NEOFORGE REQUIRES SINYTRA TO RUN, ALL MOD FILES ARE FABRIC."* |
| **VinURL** | Sinytra + Forgified Fabric API + owo-lib, **and** it auto-downloads and executes `yt-dlp`/`deno`/`FFmpeg` at runtime — supply-chain and licensing exposure on the server. |
| **Puddles & Floods** | Requires Forgified Fabric API for a cosmetic puddle effect with real rain-driven tick cost. |
### 7.3 Dead dependency / missing base mod (hard)
| Mod | Reason |
| --- | --- |
| **Ars Ocultas** | Requires **Occultism**, absent from pack and list. |
| **Carry On Extend** | Requires **Carry On**, absent. |
| **Carry On + Create Aeronautics Compat** | Author-declared **obsolete** (fix upstreamed to Carry On 2.2.6+); base absent; documented server-hang on picking up players onto contraptions. |
| **Net Music: Better Experience** | Requires **Net Music**, an external NetEase streaming service with login/licensing baggage. |
| **Refined Storage – JEI Integration** | Requires **Refined Storage**, absent — the pack uses Sophisticated Storage. |
| **Relics: Arcane Abilities** | README requires **Relics + Hammer Lib** (contradicting its metadata); both absent. |
| **Even More Instruments!** | Author has **retired** the project; requires **Genshin Instruments**, absent. |
| **AAA Particles / AAA Particles: World** | A library with no consumer mod in this pack; the addon depends on the skipped base. |
| **Spawn Animations Compats** | Only meaningful with Spawn Animations, and its supported mob list barely overlaps this pack (Alex's Mobs is not on it). |
### 7.4 Duplication — the pack already owns this (hard)
| Mod | Duplicates |
| --- | --- |
| **Alex's Mobs Continued** | The installed **Alex's Mobs (Unofficial Port)** — same mod/ID namespace; only a 1:1 swap is possible. |
| **Open Parties and Claims** | **FTB Chunks + FTB Teams** (and FTB Quests assumes that ecosystem). Two claim systems = split protection logic. |
| **Sable: Ragdoll Corpse** | **Gravestone** (which already ships Sable + Curios compat) — two death-item systems on the physics stack. |
| **SkinChanger** | **Quick Skin** (newer, GUI, HD skins); SkinChanger is stale (2024-10). |
| **Sophisticated Sorter** | **Client Sort** (installed). Three-way overlap with Sophisticated Inventory Interactions. |
| **Tooltip Overhaul** | **Legendary Tooltips** — the pack should carry one tooltip restyler. |
| **Create: Dynamic Lights** / **Create Sable Dynamic Lights** | **LambDynamicLights** (installed) — a second dynamic-lights engine; both also assume Embeddium/Rubidium or Sodium Dynamic Lights and recommend the banned shader stack. |
| **Chef's Delight** | Its 1.21.1 builds target **Farmer's Delight Refabricated**, a colliding reimplementation of the installed Farmer's Delight. |
### 7.5 Wrong shape for this pack — scale, worldgen, or marginal value
| Mod | Reason |
| --- | --- |
| **Pixelmon** | Total-conversion scale (1000+ entities, its own structures/economy); its README recommends a dedicated Pixelmon pack. Would steamroll the pack identity, worldgen and mob budget. |
| **Dynamic Trees** | Transformative tree overhaul with unverified coverage across 10+ worldgen mods and no config shipped. |
| **Estrogen / Create: Estrogen** | Meme content; movement-dash mechanic near the Sable physics stack; needs Cynosure + the Create module. |
| **More Relics** | Needs the absent Relics base + two libs; self-documented version-pin fragility; duplicates the Artifacts niche. |
| **AsyncParticles** | Documents a C2ME crash (in-pack) that needs a config edit; beta render-layer mixins against the Sable/Create axis. A candidate for a later test, not now. |
| **BadOptimizations** | Marginal gains on an already-saturated client perf stack; author's own screenshots show ~4%. |
| **Welcome Screen** | Three new libraries (FancyMenu + Necronomicon + Better Compatibility Checker) for a cosmetic first-join screen. |
| **Horror messages** | Chat-spam gimmick; tone mismatch with the pack. |
| **Immersive UI** | Two libraries for cosmetic overlap with Inventory Particles. |
| **Early Bedtime** | Solves a shader-only darkness problem this pack does not have; costs TxniLib. |
| **Abnormals Delight / Berry Good** | Require **Blueprint** for content that is inert (no Team Abnormals mods) or tiny. |
| **Sophisticated Sorter / SkinChanger** | (See duplication above.) |
---
## 8. Swap candidates — is replacing an installed mod justified?
Yes, for a small number of pairs — but the bar is higher than "the new one is shinier". A swap is only
worth it when the candidate is **(a) strictly more capable or better maintained, (b) no worse against
the fragile stack** (Sodium/DH/SSRD/Sable/Create), and **(c) safe for existing worlds** (entity/item
IDs, already-generated chunks, claims, quest data). Otherwise the incumbent wins by default.
The newly fetched branch is itself an example of a justified swap: the pack's "no shaders" stance was
replaced only because purpose-built compatibility patches (`iris-veil-compat`, `aeronautics-iris-fix`)
neutralised the specific blocker.
| Installed mod | Candidate replacement | Case for swapping | Case against | Recommendation |
| --- | --- | --- | --- | --- |
| **Alex's Mobs (Unofficial Port)** | **Alex's Mobs Continued** | Actively-maintained continuation, same content, deliberately Citadel-free (bundles what it needs); removes reliance on an unofficial port. | Two forks of one mod: entity/item IDs and NBT may differ, so an in-place swap can orphan tamed mobs/items. Citadel still needed by Alex's Caves. | **Evaluate on a world copy.** Best maintenance swap on the list, not urgent. |
| **Client Sort** | **Sophisticated Inventory Interactions** | Built on Sophisticated Core (installed); adds GUI search, container↔player transfer, remembered searches; deepens an existing pillar. | Newer/less proven; keybind and sort-button overlap; sorts containers, not the whole UI. | **Plausible upgrade — test UI collisions.** Do not also add Sophisticated Sorter. |
| **Legendary Tooltips** | **Obscure Tooltips** | Animated styling plus in-tooltip 3D gear previews — a real capability gain. | Adds Fragmentum; per-frame cost; coexistence unverified, so it must be a *swap*, never a stack. | **Swap-or-keep, never both.** |
| **LambDynamicLights** | **Sodium Dynamic Lights + Create Sable Dynamic Lights** | Would light moving Create contraptions and Aeronautics sub-levels, which LambDynamicLights does not. | SDL is coupled to the exact Sodium alpha Sable pins, and the Create mods assume Embeddium/Rubidium or the shader ecosystem. Trades a stable engine-agnostic mod for a version-fragile one. | **Do not swap now.** Revisit if contraption lighting becomes a pain point. |
| **Gravestone (+ Sable/Curios compat)** | **Sable: Ragdoll Corpse** | Novel physics-corpse recovery, Sable-native. | Gravestone is proven and already Sable/Curios-patched; two death-item systems risk item-loss precedence bugs on the physics stack. | **Keep Gravestone.** |
| **FTB Chunks + FTB Teams** | **Open Parties and Claims** | More granular party/claim permissions; LuckPerms/FTB Ranks hooks. | Wholesale replacement breaks FTB Quests/Teams and FTB's permission model; two claim systems cannot coexist. | **Keep FTB.** |
| **Client Sort** | **Sophisticated Sorter** | Sophisticated styling. | Less proven, unknown side metadata, duplicates Client Sort *and* Sophisticated Inventory Interactions. | **No** — if replacing, choose Sophisticated Inventory Interactions. |
| **Slice & Dice** | **Delightful Creators** | Different FD↔Create automation flavor (fluids/soups vs sequenced assembly). | Slice & Dice is installed and proven; running both duplicates recipes and clutters JEI. | **Only as a deliberate flavor swap**, never alongside. |
| **EntityCulling** | **More Culling** | — | Different scope (entities vs block/other culling); complementary, not alternatives. | **Not a swap.** |
| *(no skin mod installed)* | **SkinChanger vs Quick Skin** | — | — | If adding one, **Quick Skin** (newer, GUI, HD skins, animated capes). |
**Swap mechanics note:** packwiz makes the file change trivial, but the risk lives in the world. For any
swap that touches registered content (Alex's Mobs, dynamic lights, death handling), test on a **copy of
the live world** and diff entity/item IDs. Structural swaps (claim system, sorting UI, tooltip layer)
mostly affect client UI and are lower risk, but still change player muscle memory.
---
## 9. Dependency economics and the collision map
### 9.1 New libraries the candidates would introduce
Ordered by how many candidates each unlocks. **Bold** = recommended if you adopt that family.
| Library | Unlocks | Recommendation |
| --- | --- | --- |
| **Puzzles Lib** | Held Item Tooltips, Visual Workbench, Distinct Potions, Health Bars, Mob Lassos, Better Animations Collection | Buy once — high value |
| **Moonlight Lib** | Supplementaries, Sleep Tight, Haunted Harvest | Buy once — high value; also a Supplementaries prerequisite |
| Blueprint | Environmental, Pet Cemetery, Gallery, Boatload, Berry Good, Abnormals Delight | Only if you adopt several |
| Fragmentum | Accents, Ars Elixirum, Obscure Tooltips, Loot Journal | Only if you adopt several |
| Collective | Followers Teleport Too, GUI Compass, GUI Effect Timer | Cheap; bundle or skip |
| **Almanac** | Let Me Despawn | Buy (core pick) |
| MRU | Sounds, Fog | Cheap; pairs well |
| TxniLib | Early Bedtime, Immersive Armor HUD | Only if adopting |
| Delight Lib / Lodestone / Cook's Collection / Deimos / SmartBrainLib / CoroUtil / Faewulf's Lib / Teal Lib / MidnightLib / TLib / MossyLib / Knight Lib | one Delight/utility candidate each | Weigh individually |
| Item Descriptions + Immersive Overlays | Field Guide | Two libs for one mod |
| Hybrid API + Biolith | Hybrid Aquatic | Gate on a worldgen test |
| Sable: Ragdolls | Ragdoll Reactions (and the skipped corpse mod) | Only with Aeronautics crash-testing |
| Sinytra Connector + Forgified Fabric API | VinURL, Immersive Winds, Puddles & Floods | **Avoid** |
### 9.2 Candidate-vs-candidate collisions (pick one)
- **Mob health UI:** Neat vs JeremySeq's Damage Indicator
- **Tooltip restyler:** Obscure Tooltips vs existing Legendary Tooltips (prefer existing)
- **Display furniture:** Display Case vs Fetzi's Displays (+ existing Handcrafted)
- **Corn crop:** Hearth and Harvest vs Haunted Harvest
- **Grass sway:** Grassier Grass vs Immersive Winds (Immersive Winds is Fabric-only — Grassier Grass wins)
- **Carried-item particles:** Immersive UI (skipped) vs Inventory Particles
- **HUD coordinates:** GUI Compass vs Field Guide's Immersive Overlays dependency
- **Pet teleport:** Waystones Teleport Pets vs Followers Teleport Too
- **Container sorting:** Client Sort (installed) vs Sophisticated Inventory Interactions / Sophisticated Sorter
- **Sleep overhaul:** Room For Two vs Sleep Tight
- **Fire flavor:** Burnt vs Burnt + Additions (never both)
- **FD↔Create bridge:** Slice & Dice (installed) vs Delightful Creators
### 9.3 Test-first items (not rejections — gates)
| Candidate | Gate |
| --- | --- |
| Supplementaries | Create 6.0.10 smoke test (old conflicts are closed) |
| CreateBetterFps | Iris now present, but it patches Create directly — test on the Aeronautics/Sable stack |
| Grassier Grass | Sodium 0.8.12/0.8.13-alpha compatibility; custom terrain shader; interaction with shaderpacks |
| Fog | Distant Horizons/SSRD visual test (upstream DH issue history); shaderpack fog already covers this |
| Shine | Sodium 0.8.12+ confirmed, but partial feature loss on the pinned alpha |
| More Culling | Rendering-core test next to EntityCulling/Sable/DH |
| Tree Physics | Dev-server soak test; per-tree Sable physics sub-levels |
| Sable Beyond | Alpha software; backup + crash-test with Aeronautics |
| Ragdoll Reactions / Sable: Ragdolls | Crash-test with Aeronautics before adopting the cluster |
| Lunar | Gravity/spawn events vs Create Aeronautics physics + Apothic Spawners |
| AutoHUD | Confirm the NeoForge jar's real dependency list (metadata artifact) |
| Spawn Animations | Confirm NeoForge jar deps; prefer the datapack form |
| Hybrid Aquatic | Terralith/Tectonic/Lithostitched worldgen + Aquaculture loot overlap |
| Dream Relics / Reliquary / Too Many Bows | Balance pass vs Apotheosis + Artifacts |
| PlayerRevive / Incapacitated | Gravestone interplay; owner sign-off on death-rule changes |
---
## 10. Adoption plan
**Phase A — Core cohort (this is the recommendation).** Add the 20 mods in Section 4 plus
`Moonlight Lib` and `Almanac`. Expected result: a noticeably richer QoL/exploration/decor layer,
one clear server-perf gain (`lmd`), zero new render/physics risk, no config maintenance.
**Phase B — Pick one expansion family.** Choose **one** of: (a) Farmer's Delight expansion, (b) Create
decoration, (c) client ambience, (d) mobs/combat gear. Adopt its shared library and 3–6 mods. Run a
`/spark health` baseline before and after.
**Phase C — Test-first candidates on a dev server.** Take the Section 9.3 gates one at a time, one
variable per run, with backups. Promote only what survives.
**Phase D — Server infrastructure.** Decide on BlueMap (ops cost) and the FTB Chunks tuning already
recommended in `FINDINGS.md`; neither is urgent game content.
**Never / not without a rewrite:** Sinytra-Connector dependency chains, a second dynamic-lights engine,
and a second claim system. (Shaders are no longer on this list — the pack has adopted them with purpose-
built compat patches; see Section 0.)
---
## 11. Appendix — detailed per-mod assessments
The full per-candidate breakdown (Adds / Relationship / Missing deps / Gameplay impact /
Compatibility / Perf cost / Verdict, with citations where web sources were used) is retained:
- Raw per-chunk assessments: `analysis/assess/chunk01.md` … `chunk07.md`
(27 mods each, 189 total). `analysis/CANDIDATE-APPENDIX.md` consolidates these and carries a
corrections note (Section 2).
- **Grouped decision table (start here for “which should I add?”): `MODLIST-GROUPS.md`** — every
candidate by purpose, with what it brings, new deps, gameplay impact, verdict and the watch-out.
- Machine-readable candidate data: `analysis/summary.json` (title, side, loaders, 1.21.1 build,
required deps, in-pack flag) and `analysis/verdicts.json`.
- Research digest used for the assessments: `analysis/chunks/chunk*.md`,
`analysis/raw/projects.json`, `analysis/raw/versions.json`.
- Pack context given to the reviewers: `analysis/PACK-CONTEXT.md`.
### Confidence legend used throughout
- **High** — read from Modrinth/loader metadata, the mod's own README, or the pack's own files.
- **Medium** — inferred from the README, or a compatibility claim from a third-party source.
- **Unknown/unverified** — evidence absent; the report says so rather than guessing.
@@ -0,0 +1,73 @@
# Onion MC — pack context for candidate-mod assessment
## Target platform
- Minecraft **1.21.1**, **NeoForge 21.1.251** (packwiz). Loader = NeoForge. Forge-only mods
generally work; Fabric-only mods do **not** work without Sinytra Connector (a red flag).
- Mixed **client + dedicated server** pack (~10 players). Server performance matters as much
as client FPS.
- Existing pack: ~142 mod entries (133 Modrinth + 9 CurseForge).
## Existing mods (titles, for compatibility reasoning)
3D Skin Layers, Adorable Hamster Pets, Alex's Caves (Unofficial Port), Alex's Mobs (Unofficial
Port), AllTheLeaks, AmbientSounds, Apotheosis (+ Apothic Attributes, Apothic Category Compat,
Apothic Combat, Apothic Enchanting, Apothic Spawners), AppleSkin, Aquaculture 2, Aquaculture
Delight, Architectury API, Ars Creo, Ars Nouveau, Ars Nouveau's Flavors & Delight, Artifacts,
Athena, BaguetteLib, Balm, Better Combat, Bookshelf, Chipped, Chunky, Citadel (unofficial port),
Client Sort, Cloth Config, Collapsible Groups, Controlify, Create, Create Aeronautics, Create
Aeronautics: Compatibility, Create: Dragons Plus, Create: Enchantment Industry, Create Slice &
Dice, CreativeCore, Cristel Lib, Critters and Companions, Curios API, Distant Horizons, Duper's
Auto Walk, Dynamic FPS, EMF (Entity Model Features), Emotecraft, Enchantment Descriptions, End's
Delight, Entity Culling, ETF (Entity Texture Features), Explorer's Compass, Explorify, Exposure,
Farmer's Cutting: Twilight Forest, Farmer's Delight, FerriteCore, Friends&Foes, FTB Backups 3,
FTB Chunks, FTB Library, FTB Quests, FTB Teams, FTB XMod Compat, Fusion, Fzzy Config, Geckolib,
Gravestone (+ Sable & Curios compat), Handcrafted, Iceberg, ImmediatelyFast, Incendium, Jade,
Jade Sable Compat, JEI, Kotlin for Forge, LambDynamicLights, Legendary Tooltips, Lithium,
Lithostitched, Lootr, Macaw's (Bridges/Doors/Lights/Roofs/Windows), MezzConfig, ModernFix,
Mouse Tweaks, Mowzie's Mobs, Nature's Compass, Noisium, Nullscape, Ocean's Delight, Patchouli,
Ping Wheel, Placebo, playerAnimator, Prickle, Prism, Rechiseled (+ Chipped), Resourceful Lib,
Sable, Sable Physics Compat, SSRD, Sodium, Sophisticated Backpacks (+ Create Integration),
Sophisticated Core, Sophisticated Storage (+ Create Integration), Sound Physics Remastered,
spark, Sparse Structures, Subtle Effects, SuperMartijn642's Config/Core Lib, Tectonic, Terralith,
The Twilight Forest, Tiny Dragons, Towns and Towers, Twilight's Flavor & Delight, Waystones
(+ Sable), When Dungeons Arise, Wings Of Fire, YACL, YUNG's API + 9 YUNG's structure mods,
C2ME, Noisium.
## Hard constraints / known landmines (do not contradict these)
1. **No shaders.** `Create Aeronautics` README says it has visual issues with **Iris**; SSRD also
warns certain Iris packs cause rendering issues. The pack deliberately has no Iris/Oculus.
2. **Sodium must stay >= 0.8.12-alpha.2.** `sable` declares older Sodium incompatible.
3. **Create declares `radium` and `palladium` incompatible.** Never add them. Avoid server-perf
mods that wholesale replace the chunk/lighting engine in ways Lithium/ModernFix already cover.
4. **SSRD requires Sodium + Distant Horizons**, and DH must be >= 1.8.7 for SSRD (already).
5. **Sable is self-described as "incredibly intrusive", mixin-heavy, prone to compat issues.**
Treat any mod that touches Create/Sable rendering or physics as high-risk.
6. Client perf stack already includes: Sodium, Lithium, ModernFix, FerriteCore, EntityCulling,
ImmediatelyFast, Dynamic FPS, AllTheLeaks, C2ME, Noisium, EMF/ETF, Distant Horizons. Assume
overlap when a candidate is another perf/culling/memory mod.
7. Pack ships **no configs** except one FTB Chunks client file (`.packwizignore` excludes
`config/*`), so any candidate that needs config editing is a maintenance cost.
8. `sky/weather/render`-engine replacements (Veil, Iris, shaders) sit on the most fragile part of
the stack (Sodium + DH + Sable).
## Existing content families a candidate may enhance or duplicate
- **Farming/food:** Farmer's Delight + Ars Delight, Aquaculture Delight, End's Delight, Ocean's
Delight, Twilight's Flavor & Delight, Farmer's Cutting: Twilight Forest.
- **Create:** base Create + Aeronautics + Dragons Plus + Enchantment Industry + Slice & Dice, plus
Sophisticated Backpacks/Storage Create integrations.
- **Aquaculture 2** already present.
- **Exploration:** Terralith, Tectonic, Incendium, Nullscape, Towns and Towers, When Dungeons
Arise, 9 YUNG's mods, Explorify, Sparse Structures.
- **Mobs:** Alex's Mobs/Caves, Mowzie's Mobs, Friends&Foes, Critters and Companions, Tiny Dragons,
Wings of Fire, Adorable Hamster Pets.
- **QoL/HUD:** AppleSkin, Jade, JEI, Client Sort, Mouse Tweaks, Ping Wheel, Nature's Compass,
Explorer's Compass, Waystones, Gravestone, Lootr, Controlify, Emotecraft, 3D Skin Layers,
Enchantment Descriptions, Legendary Tooltips, Subtle Effects, Rechiseled/Chipped/Handcrafted.
- **Apotheosis** governs affixes, spawners, enchanting, bosses, world tiers.
- **Better Combat x Apotheosis Compat** (apothic-combat) is already installed — it disables the
attack-range attribute and makes the attack-range affix inert.
## Deliverable requested from the subagent
A per-mod structured assessment. Be evidence-based: use the supplied Modrinth README excerpt as
the primary source; use `web_search`/`read_url` only to resolve genuine uncertainty (notable
incompatibilities, hard dependencies, whether a mod is abandoned, whether it conflicts with
anything in the existing list). Never invent compatibility claims. Mark confidence.
+671
View File
@@ -0,0 +1,671 @@
# Onion MC - Configuration, Compatibility & Performance Review
**Pack:** Onion MC 0.1.0 - Minecraft 1.21.1 / NeoForge 21.1.251 - 146 mods (packwiz; 141 Modrinth + 5 CurseForge)
**Scope:** options and settings that improve inter-mod behaviour, performance, or are useful to the
players and the server administrator.
> **Snapshot note.** The mod-list statistics in section 1 were measured against an earlier pack
> revision (140 entries). The pack has since changed: **FTB Chunks was replaced by Open Parties and
> Claims + Xaero's World Map/Minimap**, the rest of the FTB suite that depended on it (**FTB Quests,
> FTB Teams, FTB XMod Compat**) was removed, Iris/shaders landed upstream, and Clumps/C2ME/Noisium were
> added. Sections 3.3 and 7.1 have been updated for these; section 1's counts have not been re-run.
---
## How to read this document
Every claim is tagged with a confidence level, because "a Reddit comment said so" and "I read the
mod's config source" are not the same thing.
| Tag | Meaning |
| --- | --- |
| **VERIFIED** | Read from the mod's own jar metadata, upstream source code, or bundled default config. |
| **DOCUMENTED** | Stated in official project docs (Modrinth/GitHub/wiki/NeoForge docs). |
| **COMMUNITY** | User reports (Reddit, forums). Directionally useful, not authoritative. |
| **INFERENCE** | My reasoning from the above. |
Methods used: Modrinth API (project + version metadata for all 131 Modrinth-tracked mods), extraction
of all 131 mod jars (reading `META-INF/neoforge.mods.toml` for dependencies, sides and declared
incompatibilities), upstream source/config files on GitHub/GitLab, and official documentation.
> **Section 8 lists what is still unverified.** Nothing there should be acted on as fact.
---
## 1. Pack state - it is in good shape
This matters because it means the work here is **tuning, not repair**. There is no fire to put out.
### 1.1 Integrity - VERIFIED
| Check | Result |
| --- | --- |
| Version validity (every pinned version supports 1.21.1 + NeoForge/Forge) | **129 / 131 OK** |
| Unsatisfied required dependencies | **0** |
| `side` flags that disagree with Modrinth's authoritative client/server support | **0** |
| Mods that would be wrongly installed on a dedicated server | **0** |
- The two non-"release" pins are **Incendium** and **Sound Physics Remastered**, both tagged
`alpha` on Modrinth. For Incendium that is normal (Stardust Labs datapacks); for Sound Physics
Remastered 1.5.1 it is currently the *only* 1.21.1 NeoForge build.
- Libs that look "missing" are correctly bundled via jar-in-jar: `apollib` (inside Tectonic and
Lithostitched), `flywheel` + `ponder` (inside Create), `atmosphere` (Slice & Dice),
`sablecompanion` (Sable), `mezz_config` (JEI), `Registrate` (Create/Ars Delight/Twilight Delight).
- The 16 client-only mods carry `side = "client"`, so `packwiz-installer -s server` will exclude them.
**The server mod list is already correct - do not hand-prune it.**
### 1.2 Version currency - VERIFIED
108 / 131 pins are the newest 1.21.1 NeoForge build. The 23 that are behind are mostly trivial patch
bumps, with three worth a decision:
| Mod | Pinned | Newest 1.21.1 | Note |
| --- | --- | --- | --- |
| Terralith | 2.5.8 | **2.6.2** | Minor bump. **New worlds only** - see section 2.4. |
| Apotheosis | 8.8.0 | 8.9.0 | Feature release. |
| Sophisticated Storage | 1.5.91 | 1.6.0 | Minor bump. |
Also available: **NeoForge 21.1.252** (pack pins .251). The 21.1.x line is the 1.21.1 LTS branch and
still receives fixes, so a patch bump is low-risk if you want bugfixes.
### 1.3 Declared incompatibilities - VERIFIED
These are asserted by the mods' own metadata. They are not opinions.
| Mod | Declares incompatible | In pack? |
| --- | --- | --- |
| `create` | `radium`, `palladium` | No [OK] - **never add Radium** |
| `sodium` | `embeddium` (any version) | No [OK] - **never add Embeddium** |
| `sable` | `scalablelux`, `sablecompanion` > 1.6.0 | No [OK] |
| `distanthorizons` | `ssrd` <= **1.8.6** | 1.8.7 [OK] - **one release clear of a hard break** |
| `geckolib` | `geckoanimfix` | No [OK] |
| `cristel-lib` | `t_and_t` <= 1.13.3 | 1.13.11 [OK] |
### 1.4 Hard version constraints - do not break these
**VERIFIED** from mod metadata. These are the version pins that are load-bearing:
1. **Sodium must stay >= `0.8.12-alpha.2+mc1.21.1`.** `sable` declares every Sodium below that
incompatible. Current 0.8.13 is fine. *Downgrading Sodium breaks Create Aeronautics.*
2. **SSRD must stay >= 1.8.7.** Distant Horizons declares SSRD <= 1.8.6 incompatible.
3. **`create-enchantment-industry` requires Create >= 6.0.10** and `create_dragons_plus` >= 1.11.9.
The pack sits *exactly* on both minimums, so Create cannot be downgraded.
4. **`ssrd` requires `sable` and `sodium`** (`sodium` at `side=CLIENT`, so the dedicated server is
unaffected).
5. **Towns and Towers must stay > 1.13.3** (cristel-lib constraint).
---
## 2. Where the server load actually comes from
Four cost centres dominate, in rough order of impact. Everything in section 3 maps to one of these.
1. **Worldgen & structure density** - this pack stacks Terralith + Tectonic + Incendium + Nullscape +
Towns and Towers + When Dungeons Arise + nine YUNG's mods + Explorify. Structure-heavy worldgen is
the classic cause of chunk-generation spikes and stutter while players explore.
2. **Apotheosis spawners and entities** - Apotheosis spawners can manufacture mob counts far beyond
vanilla, and spawner-spawned mobs are *deliberately prevented from despawning*.
3. **Create + Sable physics** - Create Aeronautics runs a physics pipeline. Sable's own README calls
itself "an incredibly intrusive mod" that "makes extensive use of mixins" and is "prone to many
compatibility issues". This is the highest-risk component in the pack.
4. **OPAC claim force-loading + offline chunk loading** - per-player force-loaded chunks that tick
even when nobody is online.
---
## 3. Server tuning
### 3.1 Structure density - the single biggest lever
**Sparse Structures is already in the pack and already active.** - DOCUMENTED/VERIFIED
- Config file: **`config/sparsestructures.json5`** (confirmed in `Constants.java`:
`Path.of("config", "sparsestructures.json5")`).
- **`spreadFactor` - default `2`.** This multiplies structure spacing globally: >1 = rarer,
1 = untouched, <1 = more common. So the pack is *already* halving structure frequency versus
default. Good default; raising it is the cheapest TPS win available.
- **`customSpreadFactors`** - array of `{ "structure": "namespace:name", "factor": n }`. The value
may be a **structure set** or a **structure name**; using a structure name modifies the whole set
it belongs to.
- `/dumpstructuresets` dumps every structure set to a file - use this to get real names instead of
guessing.
- **Changes require a full game restart.**
- Source: <https://github.com/MaxenceDC/sparsestructures> (`sparse-structures-default-config.json5`)
Suggested next step - push the expensive/oversized structure sets harder than the global 2x:
```json5
{
"spreadFactor": 2,
"customSpreadFactors": [
{ "structure": "minecraft:mansion", "factor": 2 }
// run /dumpstructuresets, then add entries for the dungeons_arise:*
// and t_and_t:* sets with factor 3-4
]
}
```
> **Caveat (INFERENCE):** I have not verified the exact `dungeons_arise` / `t_and_t` structure-set
> names. Use `/dumpstructuresets` on the server to obtain them rather than copying names from the web.
**Chunky** (in pack) is the other half: pregenerate so players don't force live generation.
DOCUMENTED - commands are `/chunky radius <n>`, `/chunky world <dim>`, `/chunky center`, `/chunky start`,
`/chunky pause`, `/chunky continue`. See section 3.4 for the Chunky <-> Distant Horizons interaction, which
matters here.
### 3.2 Apotheosis - entity accumulation
**VERIFIED** by reading the config source of Apothic Spawners 1.21 branch.
Config file: **`config/apothic_spawners.cfg`** - section `[general]`:
| Key | Default | Notes |
| --- | --- | --- |
| **`Entity Despawn Delay`** | **600** | Ticks that spawner-spawned mobs are *prevented from despawning* after spawning. Range 0-24000. |
| `Spawners Drop Empty` | false | Clears stored entity when broken. |
| `Capturing Drop Chance` | 0.005 | Per-level spawn-egg drop chance. |
| `Spawner Silk Level` | 1 | Silk touch level needed; -1 disables. |
| `Spawner Silk Damage` | 100 | Durability damage per spawner harvested. |
`Entity Despawn Delay` is the lever most people miss. At the default 600 ticks, every spawner keeps
its output alive for 30 seconds regardless of mobcap pressure. On a server with several upgraded
spawners this is a steady entity tax. **Lowering it to 0-100 is a direct, low-risk TPS improvement**
and is unlikely to be noticed by players (vanilla spawners have no such protection).
> Note: this config surface is *small*. In Apotheosis 8.x the spawner **modifiers** (spawn range,
> delay, count, ...) are **datapack-driven**, not config-driven. So you cannot cap spawner throughput
> from the config file alone - `Entity Despawn Delay` plus the loot-table/datapack layer is what you
> have.
Config file: **`config/apotheosis/apotheosis.cfg`** - sections and keys (defaults in parentheses), all **VERIFIED**:
> **Note the directory.** Apotheosis's module configs are *not* in the config root: `configDir` is
defined as `<config>/apotheosis` (`ApothicAttributes.java`, line 58), and `getConfigFile(p)` returns
`<config>/apotheosis/<p>.cfg`. The one exception is Apothic Spawners, which uses Placebo's
`Configuration(String)` constructor and therefore lands at the config root as
`config/apothic_spawners.cfg`. Do not go looking for `config/apotheosis.cfg` - it does not exist.
| Section | Key | Default |
| --- | --- | --- |
| `bosses` | `Boss Spawn Cooldown` | 3600 ticks (3 min) |
| `bosses` | `Boss Announcement Range` | vanilla spawn distance + 12 blocks |
| `bosses` | `Curse Boss Items` / `Boss Auto-Aggro` / `Boss Glowing On Spawn` | false / false / true |
| `worldgen` | **`Generation Dimension Whitelist`** | `["overworld"]` |
| `spawners` | `Spawner Value Chance` | 0.11 |
| `affixes` | `Cleave Players`, `Disable Quark Tooltips for Affix Items`, `Torch Placement Item` | false / true / `minecraft:torch` |
| `augmenting` | `Upgrade Sigil Cost` / `Upgrade Level Cost` / `Reroll Sigil Cost` / `Reroll Level Cost` | 2 / 225 / 1 / 175 |
| `potion_charms` | `Restrict Charms to Curios` | false |
| `quality_of_life` | `Enable Item Linking`, `Item Linking Cooldown`, `Enable Equipment Comparisons` | true / 100 / true |
| `flair` | `Enable Affix Item Effects` | true (clientside) |
| `world_tiers` | `Enable Manual World Tier Changes` | true |
Two worth acting on:
- **`Boss Spawn Cooldown`** (3600): invading bosses are among the most expensive things Apotheosis
spawns. Raising this is a legitimate, cheap difficulty/load dial.
- **`Generation Dimension Whitelist`** = `["overworld"]`: Apotheosis worldgen currently only runs in
the Overworld. This pack has Twilight Forest, plus Incendium's Nether and Nullscape's End. If you
want rogue spawners/boss dungeons there you must add the dimension IDs - and understand that doing
so *increases* worldgen cost.
Related configs, same pattern (`config/apotheosis/apothic_attributes.cfg`,
`config/apotheosis/apothic_enchanting.cfg`, and `config/apotheosis/name_generation.cfg`):
- `apothic_attributes.cfg` -> `[combat_rules]` holds the damage formulas as **editable expressions**
(`Protection Formula`, `A-Value Formula`, `Armor Formula`, `Armor Toughness Formula`,
`Negative Armor Factor`=0.015). These are how you retune Apotheosis combat *without* a mod - useful
because Apotheosis's armour model is the thing players most often call "broken" in a pack with
Better Combat. `[general] Hidden Attributes` controls what shows in the attributes GUI (supports
namespace wildcards and `!` negation entries).
- `apothic_enchanting.cfg` -> `[client]` `Sculkshelf Noise Chance` = **200** (1-in-200 chance per
*client tick* to play a sculk shelf sound; `0` disables). Minor client perf/noise lever.
### 3.3 Open Parties and Claims - force-loading and ticking
**Replaces FTB Chunks** (removed 2026-09-30 in favour of Open Parties and Claims + Xaero's
World Map/Minimap; see `analysis/FTB-CHUNKS-SWAP.md`). Everything below is the OPAC equivalent of the
tuning this section used to document for FTB Chunks.
**DOCUMENTED** - OPAC's main config lives **inside the world save**, not the pack:
| File | Purpose |
| --- | --- |
| `world/serverconfig/openpartiesandclaims-server.toml` | Main server config (limits, protection, forceloading, party backend). |
| `world/serverconfig/openpartiesandclaims-*` | Global "player configs" (default player config, server-claim, expired-claim, wilderness). |
| `<server dir>/config/openpartiesandclaims-server.toml` | Reported location on Fabric/Quilt only. |
**Warning - stop the server before editing.** The README is explicit: the server may overwrite your
changes otherwise. Do **not** assume the file the server generated matches any list here; read the
generated file, which carries inline `# Default:` comments for every key.
**Easiest route for an admin:** in-game, the mod UI is bound to `'` by default. Claim/party commands
are `/oclaims`, `/oparties`, `/opac` and `/opm` (party chat). Server-wide options are still edited in
the file, not the UI.
**`defaultconfigs/` and packwiz cannot help here** - the file is in the world save, so it cannot be
shipped at all. See section 7.1.
Keys and defaults - **DOCUMENTED where the project's own issue quotes or README state them**, else
flagged:
| Key | Default | Why it matters |
| --- | --- | --- |
| `maxPlayerClaims` | 500 | Per-player claim cap. Same as FTB Chunks' `max_claimed_chunks`, so no capacity loss on the swap. Overridable via the `xaero.pac_max_claims` permission. |
| `maxPlayerClaimForceloads` | low/0 - **verify** | Per-player forceload cap. **This pack sets it to 25** (matching FTB Chunks' old `max_force_loaded_chunks`); the stock default is not 25, so leaving it unset silently removes forceloading. Overridable via `xaero.pac_max_forceloads`. |
| `claims.forceload.offlineForceload` | **verify** (documented as "true" in a 2021 issue, so possibly stale) | Force-loaded chunks stay loaded while the owner is **offline**. This is the OPAC equivalent of FTB Chunks' `chunk_load_offline`, and the same farms-vs-TPS trade applies: 25 forceloads x ~10 players is potentially 250 chunks ticking around the clock. |
| `primaryPartySystem` | built-in | **Left at OPAC's built-in default** - FTB Teams was removed along with FTB Quests, so the built-in system is now the only one. Pointing this at `ftbteams` would be a no-op that logs missing-mod noise. |
| `staticFakePlayers` | - | Position-bound fake players for automation (miners, auto-clickers). The analogue of FTB Chunks' `fake_players`. |
| `playerConfigurablePlayerConfigOptions` / `opConfigurablePlayerConfigOptions` | - | Which options players (and OPs) may change in their own config. Adding a key to these arrays is what exposes it - e.g. `claims.forceload.offlineForceload` is not player-changeable until listed. |
| protection exception lists | - | `forcedBlockProtectionExceptionList`, `forcedEntityProtectionExceptionList`, `itemUseProtectionExceptionList`, plus the optional per-claim groups. This is OPAC's answer to FTB Chunks' protection; modded blocks/entities that misbehave go here. |
**Recommended starting point for a ~10-player server:** keep `maxPlayerClaims = 500`,
`maxPlayerClaimForceloads = 25` (decided 2026-09-30), leave `primaryPartySystem` at the built-in
default, and take a deliberate decision on `claims.forceload.offlineForceload` - it is the same straight
farms-vs-TPS trade FTB Chunks' `chunk_load_offline` was, with a larger blast radius now that each player
may forceload 25 chunks.
**Reliability caveat - COMMUNITY (open upstream issues).** OPAC force-loading has a recurring "marked
the chunk but it does not actually stay loaded" failure mode with issues open at the time of writing
(#855, #927, plus #237/#528 further back). Because this pack's farm design leans on offline
force-loading, verify per-player forceloading on a staging world *before* trusting it, and re-test
after each OPAC bump.
Sources: <https://github.com/thexaero/open-parties-and-claims> (README: config locations, permission
nodes, `primaryPartySystem`, `staticFakePlayers`), <https://modrinth.com/mod/open-parties-and-claims>
(commands, keybind, FAQ; also states the mod is in beta),
<https://github.com/thexaero/open-parties-and-claims/issues/228> and
<https://github.com/thexaero/open-parties-and-claims/issues/731> (default keys and the
`offlineForceload` description), <https://github.com/thexaero/open-parties-and-claims/issues/855>
(force-loading reliability).
### 3.4 Distant Horizons - decide deliberately, and mind Chunky
**DOCUMENTED** - Distant Horizons has real server-side support and it is opt-in. From the official
"Server Owners" wiki:
- **DH >= 2.3 is required on a server**; older builds crash. The pack's 3.3.2 is fine.
- **"Using the same version / build on both the server and the client is strongly preferred."**
- Server support only engages if **"Distant Generation" is enabled on both server and client**;
the same applies to every toggle with a server-side counterpart.
- DH is **optional on both sides** - vanilla clients can still connect. So marking it optional in the
pack is correct and safe.
- Default settings need **>= 500 KB/s (4 Mbit/s)** per client. If players see "Timed out" kicks, lower
their client bandwidth settings.
- **"Pre-generating LODs is highly recommended to avoid performance issues."**
- **Warning: Chunky interaction:** *"Running Chunky will also generate & update LODs, but it's not
recommended to rely on this behavior for pre-generation. LODs and chunks are independent, and by
loading a lot of chunks quickly you risk overloading DH and ending up with a lot of holes. Either
use DH's pre-generation, or temporarily disable the mod entirely."*
**This pack has both Chunky and DH.** If you pregenerate with Chunky, expect DH LOD holes. Use
`/dh pregen` instead, or disable DH while Chunky runs.
Server-side config keys (use `/dh config <key>`; the command prints the current value, description and
the config file path, which is the reliable way to find the file):
| Setting | Purpose |
| --- | --- |
| `common.threadPreset` | CPU load preset for DH's worker threads. |
| `common.maxDataTransferSpeed` | Per-player bandwidth cap. |
| `generation.mode` | Set to `INTERNAL_SERVER` to generate chunks alongside LODs. |
| `generation.requestRateLimit` | Requests/second cap. |
| `generation.maxRequestDistance` | Per-player generation radius. |
| `generation.nSized` | Experimental: generate LODs directly at the required size. |
| `generation.bounds.x` / `.z` / `.radius` | Global generation area restriction (disabled while `radius` is 0). |
| `realTimeUpdates.playerDistance` | How far chunk updates are converted to LOD pushes. |
| `syncOnLoad.rateLimit` / `syncOnLoad.maxRequestDistance` | Login-time sync throttling. |
| `levelKeyPrefix` | **Required if several servers share a proxy** - set a unique string. |
Also: pregenerate **beyond the world border** if you use one, or clients will show LOD holes at the edge.
**Avoid running `/dh pregen` on a server people are actively playing on.**
Source: <https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/5-server-owners/Server-Owners>
### 3.5 Diagnosing lag: spark is already installed
**DOCUMENTED** - `spark` 1.10.124 is in the pack, so no setup is needed. Per spark's own docs, ~30
seconds of profiling is enough for useful results.
Admin workflow:
- `/spark tps` - accurate TPS.
- `/spark health` - TPS, tick durations (min/avg/max), CPU usage, GC activity. **Start here.**
- `/spark profiler start --timeout 60` - sample the server; then `/spark profiler stop`.
Target specific threads with `--thread`, and record only slow periods to cut noise.
- Use GC figures from `/spark health` to decide heap/GC flags rather than guessing.
- On Linux x86_64 spark uses async-profiler via `perf_events`, which gives better results than the
fallback `ThreadMXBean` engine - worth knowing when comparing reports.
Docs: <https://spark.lucko.me/docs>
---
## 4. Client tuning and cross-mod conflicts
### 4.1 The SSRD -> Distant Horizons -> Sodium chain
**VERIFIED/DOCUMENTED.** SSRD ("Separate Sable Render Distance") is a *client rendering* addon that
exists to decouple Sable's sub-level render distance from the normal one.
- SSRD's own README: **"Distant Horizons or voxy AND Sodium MUST be installed on the Client!"**
- **Versions 1.8 and up REQUIRE Sodium 0.8.** The pack has Sodium 0.8.13 [OK] and SSRD 1.8.7 [OK].
- **But Distant Horizons is marked `optional = true, default = false` in the pack.**
**INFERENCE:** any player who leaves DH disabled gets a non-functional SSRD. Either ship DH by
default, or mark SSRD optional alongside DH so the two travel together.
- SSRD has **server-side gamerules**:
- `/gamerule ssrdMaxRenderDistance` - default **128** chunks (server-wide cap).
- `/gamerule ssrdForceloadLimit` - default **2** per player for `/ssrd forceload`.
- `/ssrd forceload` does not require op but respects that cap.
- SSRD README also warns: *"Certain Iris shader packs cause rendering issues."*
### 4.2 EntityCulling will break Ars Nouveau's spell visuals
**DOCUMENTED** - EntityCulling's README: *"Client-side entities, commonly used by magic mods for
animations, may not behave as expected. Whitelist the relevant entities via the config screen for tick
culling and/or entity culling."*
**INFERENCE:** this pack has Ars Nouveau, which uses client-side entities for spell/projectile visuals,
plus Create Aeronautics (Sable) and several mob mods with custom animations. EntityCulling has a wide
whitelist surface and its config screen supports per-entity toggles - expect to need it. EntityCulling
is a solid win in general (it is one of the biggest client FPS wins on busy servers), so whitelist
rather than remove.
### 4.3 Should you add shaders? Probably not yet
**DOCUMENTED**, two independent blockers:
1. **Create Aeronautics 1.1.3 README:** *"Aeronautics currently has visual issues when used with
**Iris Shaders**."*
2. **SSRD README:** certain Iris shader packs cause rendering issues.
Combined with the fact that the pack contains **no shader mod at all** (no Iris/Oculus) and that DH +
Sodium + Sable already form a tight, version-sensitive trio, adding shaders introduces a new
compatibility axis in exactly the most fragile part of the pack. **INFERENCE: leave shaders out** unless
you are willing to own that debugging surface.
### 4.4 Tectonic - optional terrain knobs
**VERIFIED** from Tectonic v3 config source. File: **`config/tectonic.json`** (DOCUMENTED via the
official changelog: "Added a proper config to the mod version at config/tectonic.json"). Keys and
defaults:
| Group | Key | Default |
| --- | --- | --- |
| `general` | `mod_enabled` / `snow_start_offset` | true / 128 |
| `global_terrain` | `vertical_scale` / `increased_height` / `lava_tunnels` | 1.125 / **false** / true |
| `continents` | `ocean_offset` / `continents_scale` / `erosion_scale` / `ridge_scale` | -0.8 / 0.13 / 0.25 / 0.25 |
| `continents` | `underground_rivers` / `river_lanterns` / `flat_terrain_skew` / `rolling_hills` / `jungle_pillars` | true / true / 0.1 / true / true |
| `islands` | `enabled` / `noise_scale` | true / 0.11 |
| `oceans` | `ocean_depth` / `deep_ocean_depth` / `monument_offset` / `remove_frozen_ocean_ice` | -0.22 / -0.45 / -30 / false |
| `biomes` | `temperature_multiplier` / `temperature_scale` / ... | 1.0 / 0.25 / ... |
Note `increased_height` is already `false` - good. It raises the build/generation ceiling to **y640**,
which is a meaningful worldgen and memory cost. **Do not enable it on a server.**
The Tectonic wiki (<https://github.com/Apollounknowndev/tectonic/wiki/Config>) explains every option;
the in-game mod-menu config screen shows them with tooltips.
---
## 5. Terralith + Tectonic - the combination is correct
**DOCUMENTED**, and this is a commonly-messed-up setup, so it's worth confirming it's right:
- Terralith's README: *"Terralith is **fully compatible with the mod version of Tectonic**."*
- Tectonic's README: *"Tectonic has a special version with Terralith compatibility. **This version is
shipped in the mod version of Tectonic**, but it is available as a standalone datapack
[Terratonic]."*
- Terralith's README: *"If you are using the **datapack** versions, you must use **Terratonic
instead** of Tectonic."*
The pack has **both as mods**, so the Terralith-compat layer is already active.
**Do not add Terratonic** - it is for the datapack route and would conflict.
### 5.1 Terralith updates require a new world
**DOCUMENTED** - Terralith's README: *"It is **not recommended to add Terralith to an existing world**
- reset yours first, or use a new world."*
Also relevant: *"In 2.6.0, the **mod** version of Terralith relies on **Lithostitched** as a required
dependency."* The pack has Terralith **2.5.8** and **already ships Lithostitched 1.8.0**, so the
eventual 2.6.x update is dependency-safe. **But it is a worldgen change - new worlds only.**
**INFERENCE / worth checking:** if the live server world predates the addition of Terralith (the pack
added it recently), terrain seams and abrupt biome transitions are expected and are not a bug.
---
## 6. Cross-mod notes worth knowing
### 6.1 Apothic Combat silently disables the attack-range affix
**DOCUMENTED** - from the Apothic Combat README (the "Better Combat x Apotheosis Compat" mod):
The problem it solves: Apotheosis adds a "Heavy Weapon" category (loosely like Better Combat's
two-handed weapons, but unrelated), and **Apotheosis/Forge treat attack range as an entity attribute**
that grows with gems and affixes, while **Better Combat defines attack range as an immutable weapon
property** in its own JSON format - so they cannot both work.
What the compat mod does:
- Registers all two-handed Better Combat weapons automatically as `HEAVY_WEAPON` for Apotheosis.
- **"Removes the Entity Reach Attribute from all weapons, and makes the attack range affix
nonfunctional."**
**Player-facing consequence:** any gem/affix investment in attack range does nothing in this pack.
That is a legitimate thing to tell players, and if you want, the README notes that *disabling the
Apotheosis Attack Range affix from appearing at all* is possible via datapack.
Source: <https://modrinth.com/mod/apothic-combat>
### 6.2 Apotheosis enchanting vs other enchanting overhauls
**COMMUNITY.** The well-known Apotheosis enchanting-table conflict is with **Quark**, which is *not* in
this pack, so that specific issue does not apply. No verified conflict with Ars Nouveau's enchanting
was found. Flagging only that both touch the enchanting system; if you see an enchanting-table UI
problem, test with Apothic Enchanting disabled first.
### 6.3 Lootr - exact keys, and one gotcha
**DOCUMENTED** - file **`config/lootr-common.toml`**. Lootr **must be installed on both client and
server** (its FAQ is explicit). Selected keys and defaults:
| Key | Default | Notes |
| --- | --- | --- |
| `disable_break` | false | Prevents breaking Lootr containers except sneaking in **creative**. |
| `blast_resistant` | false | Makes Lootr containers explosion-proof. |
| `decay_all` | false | **All** chests decay after first open (overrides the per-list options). |
| `decay_value` | 6000 | Ticks for a decaying container to decay (5 min). |
| `decay_dimensions` / `decay_modids` / `decay_loot_tables` | `[]` | Targeted decay. |
| `refresh_all` | false | **All** chests refresh after first open. |
| `refresh_value` | 24000 | Ticks to refresh (20 min). |
| `refresh_dimensions` / `refresh_modids` / `refresh_loot_tables` | `[]` | Targeted refresh. |
| `convert_wooden_chests` / `convert_trapped_chests` / `convert_mineshafts` | true | Conversion scope. |
| `convert_quark` | true | Quark isn't in this pack; harmless. |
| `skip_unloaded` | true | Skip containers in unloaded chunks (queued for later). |
| `maximum_age` | 3600 | How long a container may sit in the conversion queue (180x20 ticks). |
| `loot_modid_blacklist` / `loot_table_blacklist` / `dimension_blacklist` / `dimension_whitelist` | `[]` | Exclusions. |
| `power_comparators` | true | Comparators output 1 - **important for trap-based structures**; `false` makes traps fire on load. |
| `report_unresolved_tables` | false | Log unresolved loot tables. |
| `randomise_seed` | true | Warning: see caveat below. |
| `vanilla_textures` | false | Client-side; hides Lootr textures. |
Two things to flag:
- **Warning: `randomise_seed`'s documentation is contradictory** in the official wiki - the Forge section
and the Fabric section describe opposite behaviours. **Do not change this key on the strength of the
wiki alone**; test on a scratch world first.
- **Warning: Structure blacklists do not work on 1.21.1.** The wiki states plainly: *"structure blacklists
are not functional outside of 1.16.5 due to tagging and holder changes."* So `decay_structures` and
`loot_structure_blacklist` are dead keys here. Don't waste time on them.
Lootr interacts with the pack's structure mods (When Dungeons Arise, the nine YUNG's mods) and with
Apotheosis loot tables by converting their chests. If a specific structure's loot behaves oddly, the
`loot_table_blacklist` / `loot_modid_blacklist` route is the supported fix - not the structure keys.
### 6.4 Known compatibility risks to keep on the radar
- **Sable / Create Aeronautics** - self-described as highly intrusive and mixin-heavy. If you get a
weird crash or a visual bug you can't explain, **test with Sable removed first**. The five Sable
compat addons in the pack (`sablecompat`, `aeronauticscompat`, `gravestone_sable_compat`,
`waystonessable`, `sablejade`) exist precisely because it needed patching.
- **Create declares `radium` and `palladium` incompatible** - this rules out the most obvious
"add more server performance mods" candidates. See section 7.
---
## 7. Config mechanics - how to actually apply any of this
This is the part that decides whether the rest of the document is usable.
**DOCUMENTED** (NeoForge config docs) - three locations, and they behave differently:
| Location | Scope | Synced to clients? |
| --- | --- | --- |
| `config/` | Global, both sides | Depends on config type |
| `world/serverconfig/` | **Per-world override** of `SERVER`-type configs | Yes - server wins |
| `defaultconfigs/` | Seeds new worlds | n/a |
- `SERVER`-type configs are **synced from server to client** and can be overridden per world in
`world/serverconfig/`. `STARTUP` / `COMMON` / `CLIENT` are **not synced**.
- Server configs are only editable via the in-game screen on a local world; they are greyed out on a
multiplayer server - so on a real server you edit the files.
- **The Apotheosis stack is the exception:** those are Placebo `.cfg` files under
`config/apotheosis/` (+ `config/apothic_spawners.cfg`) and are **not** NeoForge `SERVER`-type
configs, so they are not synced and not per-world. They're plain global files you edit directly.
**This also means `defaultconfigs/` will not seed them** - see 7.1.
### 7.1 The pack currently cannot ship server configs
**VERIFIED** - `.packwizignore` contains:
```
config/
defaultconfigs/
```
So **every** config is excluded from the pack index. Consequences:
- None of the tuning in section 3 can be delivered to players or to a fresh server via the pack as it stands.
- A fresh server generates stock defaults for everything.
This is a cleaner end state than before: the only config the pack used to ship was the FTB Chunks
minimap client file, and it left with FTB Chunks (section 3.3).
**Recommendation (INFERENCE):** if you want these settings to be part of the pack rather than tribal
knowledge, un-ignore the specific files you care about (a `!config/<path>` rule alongside the `config/`
ignore) and/or use `defaultconfigs/` for per-world `SERVER`-type defaults.
**Caveat - the systems this document tunes are mostly unreachable from packwiz.**
- **OPAC** keeps its main config in `world/serverconfig/`, inside the world save. Not shippable, ever.
- the **Apotheosis stack** uses Placebo `.cfg` files, which `defaultconfigs/` does not seed.
The one exception now worth knowing: **Xaero's** server-side settings live in `<server dir>/config/xaero/`
(`world-map`, `minimap`), so a `!config/xaero/*` rule *would* let the pack ship enforced map profiles
if that is ever wanted. Those configs also register the status effects that block non-modded clients,
so shipping them has a real consequence - see the Xaero's pages before doing it.
Note the `.packwizignore` also excludes `*.json` globally, which would also exclude
`config/tectonic.json` even if `config/*` were relaxed. It needs an explicit `!` rule.
### 7.2 Installing on the server
**DOCUMENTED** - use the server side flag so client-only mods are skipped:
```
java -jar packwiz-installer-bootstrap.jar -g -s server <pack-url>
```
`-g` disables the optional-mods GUI, `-s server` downloads only server-side mods. Because every
`side = "client"` flag in this pack is already correct (section 1.1), this produces a correct server mod list
automatically.
---
## 8. Prioritised recommendations
Ordered by value / risk. **P0 items are the ones I'd do first.**
| # | Pri | Change | Where | Evidence |
| --- | --- | --- | --- | --- |
| 1 | **P0** | Set `Entity Despawn Delay` to `0`-`100` (from 600) | `config/apothic_spawners.cfg` -> `[general]` | VERIFIED source |
| 2 | **P0** | Decide `claims.forceload.offlineForceload` (true = farms run while owners are offline, costs TPS); set `maxPlayerClaimForceloads` to 25 | OPAC server config, `world/serverconfig/openpartiesandclaims-server.toml` | DOCUMENTED |
| 3 | **P0** | Leave `primaryPartySystem` at the built-in default (FTB Teams is gone; pointing it at `ftbteams` is a no-op) | OPAC server config | VERIFIED |
| 4 | **P0** | Fix SSRD/DH mismatch: ship DH by default, or mark SSRD optional with it | `mods/*.pw.toml` | VERIFIED + DOCUMENTED |
| 5 | **P0** | Whitelist Ars Nouveau (and Sable/Create) entities in EntityCulling | client config screen | DOCUMENTED |
| 6 | P1 | Raise `spreadFactor` for the expensive structure sets via `customSpreadFactors` (use `/dumpstructuresets`) | `config/sparsestructures.json5` | VERIFIED source |
| 7 | P1 | Cap SSRD via `/gamerule ssrdMaxRenderDistance` (default 128 chunks) | server command | DOCUMENTED |
| 8 | P1 | Pregenerate with `/dh pregen`, **not** Chunky, or disable DH while Chunky runs | server | DOCUMENTED |
| 9 | P1 | Raise `Boss Spawn Cooldown` above 3600 if invader load is heavy | `config/apotheosis/apotheosis.cfg` -> `[bosses]` | VERIFIED source |
| 10 | P1 | Establish a `/spark health` -> `/spark profiler` baseline before and after changes | server | DOCUMENTED |
| 11 | P1 | Un-ignore the specific configs you want shipped (or adopt `defaultconfigs/`) | `.packwizignore` | VERIFIED |
| 12 | P2 | Consider NeoForge 21.1.251 -> 21.1.252 | `pack.toml` | VERIFIED |
| 13 | P2 | Tell players the attack-range affix is inert (Apothic Combat) | player comms | DOCUMENTED |
| 14 | P2 | Decide on the 23 outdated pins (Terralith 2.6.2 is **new-world only**) | `mods/*.pw.toml` | VERIFIED |
| 15 | P2 | Leave `increased_height: false` in Tectonic; never add Embeddium/Radium/shaders | various | VERIFIED/DOCUMENTED |
| 16 | P2 | Set `levelKeyPrefix` if you ever run multiple servers behind a proxy | DH server config | DOCUMENTED |
---
## 9. Not verified / open questions
Listed so nobody mistakes absence of evidence for evidence of absence.
1. **Client-side performance options not yet reviewed in depth** - Distant Horizons' client quality/
thread presets, ImmediatelyFast, Dynamic FPS, EMF/ETF, Fusion/Athena, Legendary Tooltips, Prism.
These are very likely fine at defaults; DH's client quality preset is the one worth player guidance.
2. **Missing server-side performance mods not yet assessed** - ServerCore, Noisium, Clumps,
Connectivity, Packet Fixer, ThreadTweak on NeoForge 1.21.1, and whether each overlaps with the
already-installed Lithium/ModernFix/FerriteCore/AllTheLeaks. **Note Create's declared
incompatibility with Radium and Palladium**, which removes two candidates. Do not add anything here
without checking for overlap with Lithium and ModernFix first.
3. **Create / Sable / Aeronautics config surface** - not yet read from source. SSRD and the Sable
gamerules in section 4.1 are the only Sable-family settings verified so far.
4. **FTB Backups 3** config keys (interval, retention, compression) - not yet verified. Relevant to
disk/IO on the server.
5. **Waystones, GraveStone, Sophisticated Storage/Backpacks, Curios, Artifacts** config keys - not yet
verified.
6. **JVM flags / heap sizing** for this pack size - not yet researched. Use `/spark health` GC data
(section 3.5) to decide empirically rather than copying generic flags.
7. **`server.properties` / gamerule tuning** (view-distance vs simulation-distance, entity cramming,
mobcaps, `network-compression-threshold` for large modded packets) - not yet verified.
8. **Exact `dungeons_arise` / `t_and_t` structure-set names** - use `/dumpstructuresets`.
9. **Lootr `randomise_seed` semantics** - the official wiki contradicts itself; test before changing.
10. **The 5 CurseForge-sourced mods** (FTB Backups 3, FTB Library, AllTheLeaks, Collapsible Groups,
Twilight Forest) could not be version-checked by packwiz for currency without a CurseForge API key.
The FTB Chunks swap plus the later FTB suite removal cut this blind spot from nine mods to five.
---
## Appendix A - Verified config file paths
| Mod | File | Format |
| --- | --- | --- |
| Tectonic | `config/tectonic.json` | JSON |
| Sparse Structures | `config/sparsestructures.json5` | JSON5 |
| Apotheosis (adventure) | `config/apotheosis/apotheosis.cfg` | Placebo CFG |
| Apothic Attributes | `config/apotheosis/apothic_attributes.cfg` | Placebo CFG |
| Apothic Spawners | `config/apothic_spawners.cfg` (config root - see note in section 3.2) | Placebo CFG |
| Apothic Enchanting | `config/apotheosis/apothic_enchanting.cfg` | Placebo CFG |
| Apotheosis name generation | `config/apotheosis/name_generation.cfg` | Placebo CFG |
| Open Parties and Claims | `world/serverconfig/openpartiesandclaims-server.toml` (main server config - inside the world save) plus `openpartiesandclaims-*` player configs alongside it | TOML |
| Xaero's World Map / Minimap | server-side: `config/xaero/world-map`, `config/xaero/minimap`; client map + waypoint data under the instance `xaero/` directory | TXT / binary |
| Lootr | `config/lootr-common.toml` | TOML |
| Distant Horizons | use `/dh config <key>` to print the path | TOML |
## Appendix B - Sources
- Modrinth API v2 (`/project/{id}`, `/version/{id}`, `/project/{id}/version?game_versions=["1.21.1"]`) - pack inventory, sides, incompatibilities, version currency.
- All 131 mod jars - `META-INF/neoforge.mods.toml` (dependencies, sides, declared incompatibilities).
- Apotheosis stack config source: `Shadows-of-Fire/Apotheosis@1.21`, `Apothic-Spawners@1.21`, `Apothic-Attributes@1.21`, `Apothic-Enchanting@1.21`, `Placebo@1.21`.
- Sparse Structures: `MaxenceDC/sparsestructures@1.21` (`Constants.java`, `sparse-structures-default-config.json5`).
- Tectonic: `Apollounknowndev/tectonic@v3` (`config/state/ConfigState.java`), Tectonic wiki `/wiki/Config`, official changelog for `config/tectonic.json`.
- NeoForge config docs: <https://docs.neoforged.net/docs/misc/config/>
- Distant Horizons server owners wiki: <https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/5-server-owners/Server-Owners>
- OPAC README and Modrinth page (config locations, permission nodes, `primaryPartySystem`, `staticFakePlayers`, commands, beta status): <https://github.com/thexaero/open-parties-and-claims>, <https://modrinth.com/mod/open-parties-and-claims>
- OPAC default keys and `offlineForceload` semantics (issue quotes): <https://github.com/thexaero/open-parties-and-claims/issues/228>, <https://github.com/thexaero/open-parties-and-claims/issues/731>
- OPAC force-loading reliability reports: <https://github.com/thexaero/open-parties-and-claims/issues/855>, <https://github.com/thexaero/open-parties-and-claims/issues/927>
- Xaero's World Map / Minimap server-side config locations and modpack terms: <https://modrinth.com/mod/xaeros-world-map>, <https://modrinth.com/mod/xaeros-minimap>
- Lootr wiki: <https://github.com/LootrMinecraft/Lootr/wiki/Lootr-Configuration>
- spark docs: <https://spark.lucko.me/docs>
- Modrinth/CurseForge project pages and READMEs for Sable, Create Aeronautics, SSRD, Terralith, EntityCulling, Apothic Combat, FerriteCore, Lithium, Chunky.
File renamed without changes.
+21
View File
@@ -0,0 +1,21 @@
# Archive
Finished or superseded work, kept for its reasoning. It is **not maintained**: mod counts
and verdicts reflect the pack at the time each file was written. Paths inside these files
refer to their original locations.
| File | Was at | What it is |
| --- | --- | --- |
| `FINDINGS.md` | `/FINDINGS.md` | Config / compat / performance review of the 146-mod pack (2026-10-01): OPAC config decisions, per-mod compat notes. About 70 mods stale. |
| `FTB-CHUNKS-SWAP.md` | `analysis/` | FTB Chunks → OPAC + Xaero's swap. Shipped `1d02bf1`. |
| `2026-09-candidate-review/MODLIST-REVIEW.md` | `/MODLIST-REVIEW.md` | The 189-candidate mod review behind the 60-mod expansion (assembled report) |
| `2026-09-candidate-review/MODLIST-GROUPS.md` | `/MODLIST-GROUPS.md` | Same review grouped by purpose (was duplicated as `analysis/groups-table.md`) |
| `2026-09-candidate-review/CANDIDATE-APPENDIX.md` | `analysis/` | Per-mod detail for that review |
| `2026-09-candidate-review/PACK-CONTEXT.md` | `analysis/` | The pack brief given to the reviewers |
Deleted in the 2026-10-14 cleanup:
- the review's build pieces (`report-part*.md`, `master-table.md`, `groups-table.md`) and
intermediates (`chunks/`, `assess/`, `*.json`, `candidates.txt`);
- `analysis/raw/` (Modrinth API dumps);
- `analysis/audit/*.out` (rerun the scripts);
- the applied Puzzles Lib patch.
+25
View File
@@ -0,0 +1,25 @@
import pickle,json,collections,re
A=pickle.load(open("active.pkl","rb"));act=A["active"];tc=A["tagcache"]
prod=collections.defaultdict(list); cons=collections.defaultdict(set)
tagsof=collections.defaultdict(set)
for t,s in tc.items():
for i in s: tagsof[i].add(t)
for rid,(jar,j) in act.items():
r=json.dumps(j.get("result",""))+json.dumps(j.get("results",""))+json.dumps(j.get("output",""))
for m in set(re.findall(r'"(?:id|item)": "([^"]+)"',r)): prod[m].append(rid)
body=json.dumps({k:v for k,v in j.items() if k not in("result","results","output")})
for m in re.findall(r'"item": "([^"]+)"|"id": "([^"]+)"',body):
cons[m[0] or m[1]].add(rid)
for m in re.findall(r'"tag": "([^"]+)"',body): cons["#"+m].add(rid)
def info(i):
c=set(cons[i])
for t in tagsof[i]: c|=cons["#"+t]
return len(prod[i]),len(c),sorted(prod[i])[:6]
for i in """extradelight:bread_slice moredelight:bread_slice extradelight:sliced_potato moredelight:diced_potatoes rusticdelight:potato_slices
dungeonsdelight:fiery_knife twilightdelight:fiery_knife dungeonsdelight:ironwood_knife twilightdelight:ironwood_knife dungeonsdelight:knightmetal_knife twilightdelight:knightmetal_knife dungeonsdelight:steeleaf_knife twilightdelight:steeleaf_knife
frightsdelight:poisonous_potato_crate dungeonsdelight:poisonous_potato_crate frightsdelight:rotten_tomato_crate dungeonsdelight:rotten_tomato_crate
handcrafted:wood_plate twilightforest:oak_drying_rack comforts:sleeping_bag_red handcrafted:red_sheet
adorablehamsterpets:cucumber_crate extradelight:cucumber_crate_item fruitsdelight:apple_crate extradelight:apple_crate
rusticdelight:coffee_beans_bag extradelight:coffee_bean_sack extradelight:coffee_cherry_crate
fishermans_haven:worm aquaculture:worm create:copper_nugget twilightforest:copper_nugget twilightdelight:rainbow_ice_cream twilightdelight:refreshing_ice_cream twilightdelight:twilight_ice_cream""".split():
print(i, *info(i))
+144
View File
@@ -0,0 +1,144 @@
import pickle,json,collections,sys
sys.setrecursionlimit(10000)
exec(open("recipes.py").read().split("# ---------- active recipes")[0].split("# ---------- resource-level")[0]) # imports only
A=pickle.load(open("active.pkl","rb")); active=A["active"]; tagcache=A["tagcache"]
exec(open("recipes.py").read().split("# ---------- ingredients ----------")[1].split("# ---------- active recipes")[0].replace("resolve(","R("))
def full(x): return x if ":" in x else "minecraft:"+x
def R(t): return tagcache.get(t,set())
def ns(x): return x.split(":")[0]
EMPTY=frozenset(["<empty>"])
def shaped(j):
pat=j.get("pattern"); key=j.get("key",{})
if not pat: return None
g=[]
for row in pat:
r=[]
for ch in row:
if ch==" ": r.append(EMPTY)
else:
s=ing(key.get(ch))
if s is None: return None
r.append(s)
g.append(tuple(r))
return tuple(g)
def mirror(g): return tuple(tuple(reversed(r)) for r in g)
def inter(a,b): return bool(a&b)
def grid_match(a,b):
return len(a)==len(b) and len(a[0])==len(b[0]) and all(inter(x,y) for ra,rb in zip(a,b) for x,y in zip(ra,rb))
def bip(a,b):
if len(a)!=len(b): return False
match={}
def tr(i,seen):
for k in range(len(b)):
if k in seen or not inter(a[i],b[k]): continue
seen.add(k)
if k not in match or tr(match[k],seen): match[k]=i; return True
return False
return all(tr(i,set()) for i in range(len(a)))
def out(j):
try: return result(j)
except Exception: return str(j.get("result"))[:80]
groups=collections.defaultdict(list)
for rid,(jar,j) in active.items(): groups[j.get("type","?")].append((rid,jar,j))
print({k:len(v) for k,v in sorted(groups.items(),key=lambda x:-len(x[1]))[:40]})
res=collections.defaultdict(list)
def report(kind,a,b,same):
res[(kind,same)].append((a,b))
# --- crafting: shaped vs shaped, shapeless vs shapeless, shaped vs shapeless ---
SH=[]; SL=[]
for rid,jar,j in groups["minecraft:crafting_shaped"]:
g=shaped(j)
if g: SH.append((rid,g,out(j)))
for rid,jar,j in groups["minecraft:crafting_shapeless"]:
l=[ing(x) for x in j.get("ingredients",[])]
if None in l or not l: continue
SL.append((rid,l,out(j)))
idx=collections.defaultdict(set)
for i,(rid,g,o) in enumerate(SH):
for it in g[0][0]: idx[(len(g),len(g[0]),it)].add(i)
pairs=set()
for i,(rid,g,o) in enumerate(SH):
for gg in (g,mirror(g)):
for it in gg[0][0]:
for k in idx[(len(g),len(g[0]),it)]:
if k>i and grid_match(gg,SH[k][1]): pairs.add((i,k))
for i,k in pairs:
a,b=SH[i],SH[k]; report("shaped",(a[0],a[2]),(b[0],b[2]),a[2]==b[2])
idx=collections.defaultdict(set)
for i,(rid,l,o) in enumerate(SL):
for it in set().union(*l): idx[(len(l),it)].add(i)
pairs=set()
for i,(rid,l,o) in enumerate(SL):
small=min(l,key=len)
for it in small:
for k in idx[(len(l),it)]:
if k>i and bip(l,SL[k][1]): pairs.add((i,k))
for i,k in pairs:
a,b=SL[i],SL[k]; report("shapeless",(a[0],a[2]),(b[0],b[2]),a[2]==b[2])
# shaped vs shapeless (shapeless matches any arrangement with same nonempty cells)
for rid,g,o in SH:
cells=[c for r in g for c in r if c is not EMPTY]
for it in cells[0]:
for k in idx[(len(cells),it)]:
if bip(cells,SL[k][1]): report("shaped~shapeless",(rid,o),(SL[k][0],SL[k][2]),o==SL[k][2])
# --- single-input processing types ---
def single(j):
x=j.get("ingredient")
if x is None and isinstance(j.get("ingredients"),list) and len(j["ingredients"])==1: x=j["ingredients"][0]
return ing(x) if x is not None else None
for t in ["minecraft:smelting","minecraft:blasting","minecraft:smoking","minecraft:campfire_cooking"]:
L=[(rid,single(j),out(j)) for rid,jar,j in groups[t]]
L=[x for x in L if x[1]]
idx=collections.defaultdict(list)
for i,(rid,s,o) in enumerate(L):
for it in s: idx[it].append(i)
seen=set()
for it,ix in idx.items():
for a in ix:
for b in ix:
if a<b and (a,b) not in seen:
seen.add((a,b)); report(t,(L[a][0],L[a][2]),(L[b][0],L[b][2]),L[a][2]==L[b][2])
# cutting board
def tool(j):
t=j.get("tool")
if isinstance(t,dict) and t.get("type","").endswith("ability"): return ("ability",t.get("action") or t.get("item_ability"))
s=ing(t); return ("items",s)
def tools_overlap(a,b):
if a[0]!=b[0]: return False
return a[1]==b[1] if a[0]=="ability" else inter(a[1] or frozenset(),b[1] or frozenset())
for t in [k for k in groups if k.endswith(":cutting")]:
L=[]
for rid,jar,j in groups[t]:
s=ing(j.get("ingredients"));
if s: L.append((rid,s,tool(j),out(j)))
idx=collections.defaultdict(list)
for i,x in enumerate(L):
for it in x[1]: idx[it].append(i)
seen=set()
for it,ix in idx.items():
for a in ix:
for b in ix:
if a<b and (a,b) not in seen and tools_overlap(L[a][2],L[b][2]):
seen.add((a,b)); report(t,(L[a][0],L[a][3],sorted(L[a][1])[:2] if len(L[a][1])>2 else sorted(L[a][1])),(L[b][0],L[b][3]),L[a][3]==L[b][3])
# multi-ingredient machine types (exact multiset w/ overlap): cooking pots, mixers etc
GENERIC=[k for k in groups if not k.startswith("minecraft:") and not k.endswith(":cutting")]
for t in GENERIC:
L=[]
for rid,jar,j in groups[t]:
x=j.get("ingredients") or ([j["ingredient"]] if "ingredient" in j else None)
if not isinstance(x,list): continue
l=[ing(y) for y in x]
if None in l or not l or any(len(s)==0 for s in l): continue
extra=json.dumps({k:j.get(k) for k in ("container","tool","heatRequirement","heat_requirement","processing_time","fluid","inputFluid") if k in j},sort_keys=True)
L.append((rid,l,out(j),extra))
idx=collections.defaultdict(set)
for i,(rid,l,o,e) in enumerate(L):
for it in set().union(*l): idx[(len(l),it)].add(i)
for i,(rid,l,o,e) in enumerate(L):
for it in min(l,key=len):
for k in idx[(len(l),it)]:
if k>i and L[k][3]==e and bip(l,L[k][1]):
report(t,(rid,o),(L[k][0],L[k][2]),o==L[k][2])
pickle.dump(dict(res),open("coll.pkl","wb"))
for (kind,same),l in sorted(res.items()):
print(f"## {kind} {'SAME-OUTPUT(dup)' if same else 'CONFLICT'}: {len(set(map(str,l)))}")
+42
View File
@@ -0,0 +1,42 @@
import pickle,re
D=pickle.load(open("data.pkl","rb")); mods=D["mods"]
mods.setdefault("minecraft",[dict(jar="base",version="1.21.1",deps=[],nested=False)])
def vt(v): return [int(x) if x.isdigit() else x for x in re.split(r'[.\-+_]',v)]
def cmp(a,b):
a,b=vt(a),vt(b)
for x,y in zip(a,b):
if x==y: continue
if type(x)==type(y): return -1 if x<y else 1
return -1 if isinstance(x,str) else 1
return (len(a)>len(b))-(len(a)<len(b))
def inrange(v,r):
r=r.strip()
if not r or r=="*": return True
for part in re.findall(r'[\[\(][^\]\)]*[\]\)]',r) or [None]:
if part is None: return cmp(v,r)>=0
lo,_,hi=part[1:-1].partition(",")
if "," not in part:
if cmp(v,lo)==0: return True
continue
ok=True
if lo.strip(): c=cmp(v,lo.strip()); ok&= c>0 or (c==0 and part[0]=="[")
if hi.strip(): c=cmp(v,hi.strip()); ok&= c<0 or (c==0 and part[-1]=="]")
if ok: return True
return False
# duplicate modids among top-level jars
for mid,l in mods.items():
top=[x for x in l if not x["nested"]]
if len(top)>1: print("DUP-MODID",mid,[x["jar"] for x in top])
for mid,l in sorted(mods.items()):
e=[x for x in l if not x["nested"]] or l
for d in e[0]["deps"]:
t=str(d.get("type",d.get("mandatory") and "required" or "optional")).lower()
if d.get("mandatory") is True: t="required"
did=d.get("modId"); side=d.get("side","BOTH")
if t not in("required","incompatible","discouraged"): continue
if did not in mods:
if t=="required": print("MISSING",mid,"->",did,d.get("versionRange"),side)
continue
v=mods[did][0]["version"]; r=d.get("versionRange","")
if t=="required" and not v.startswith("$") and not inrange(v,r): print("VERSION",mid,"->",did,"needs",r,"have",v)
if t in("incompatible","discouraged") and (not r or inrange(v,r)): print(t.upper(),mid,"->",did,r,"have",v)
+29
View File
@@ -0,0 +1,29 @@
import pickle,collections,re,json
D=pickle.load(open("data.pkl","rb")); A=pickle.load(open("active.pkl","rb")); tc=A["tagcache"]
models=D["models"]
name={}
for k,v in D["lang"].items():
_,ns,p=k.split("."); name.setdefault(ns+":"+p,v[0][1])
spec=collections.defaultdict(set)
for t,s in tc.items():
if t.startswith("c:") and "/" in t and len(s)<=8:
for i in s: spec[i].add(t)
new=set("""extradelight moredelight rusticdelight dungeonsdelight frightsdelight fruitsdelight minersdelight veggiesdelight overweight_farming barbequesdelight fishermans_haven fowlplay etched music_disc_maker too_many_bows mermod tarotcards chalk charta comforts petcemetery friendsandfoes""".split())
def norm(n): return re.sub(r'[^a-z]','',n.lower())
by=collections.defaultdict(set)
for i,n in name.items():
if i in models and isinstance(n,str) and "spawn_egg" not in i and not i.startswith(("sophisticated",)):
by[norm(n)].add(i)
# also group by registry path
for i in models:
p=i.split(":")[1]
if len(p)>3: by["path:"+p].add(i)
seen=set()
for k,s in sorted(by.items()):
nss={i.split(":")[0] for i in s}
if len(nss)<2 or "minecraft" in nss or not (nss&new): continue
key=frozenset(s)
if key in seen: continue
seen.add(key)
s=sorted(s); common=set.intersection(*[spec.get(i,set()) for i in s])
print(("UNIFIED " if common else "SPLIT ")+name.get(s[0],s[0])+": "+", ".join(s)+((" via "+",".join(sorted(common))) if common else ""))
+48
View File
@@ -0,0 +1,48 @@
import zipfile, io, json, tomllib, re, pickle, os, glob
def lenient_json(b):
s=b.decode("utf-8-sig",errors="replace")
try: return json.loads(s)
except Exception:
s2=re.sub(r'//[^\n]*','',s); s2=re.sub(r',(\s*[}\]])',r'\1',s2)
try: return json.loads(s2)
except Exception: return None
mods={} # modid -> dict(jar, version, deps, nested)
files=[] # (jar, path, json) for data recipe/tags + lang
lang={}; models=set(); errors=[]
def walk(z, jarname, nested=False):
names=z.namelist()
for t in ("META-INF/neoforge.mods.toml","META-INF/mods.toml"):
if t in names:
raw=z.read(t).decode("utf-8",errors="replace")
try: m=tomllib.loads(raw)
except Exception as e: errors.append((jarname,"toml",str(e))); m={}
for md in m.get("mods",[]):
mid=md.get("modId"); ver=str(md.get("version"))
if ver.startswith("${"):
mf=z.read("META-INF/MANIFEST.MF").decode(errors="replace") if "META-INF/MANIFEST.MF" in names else ""
mm=re.search(r'Implementation-Version: *(\S+)',mf); ver=mm.group(1) if mm else ver
deps=m.get("dependencies",{}).get(mid,[])
mods.setdefault(mid,[]).append(dict(jar=jarname,version=ver,deps=deps,nested=nested,file=t))
break
for n in names:
if n.startswith("META-INF/jarjar/") and n.endswith(".jar"):
try: walk(zipfile.ZipFile(io.BytesIO(z.read(n))), jarname+"!"+n.split("/")[-1], True)
except Exception as e: errors.append((jarname,n,str(e)))
elif n.startswith("data/") and n.endswith(".json"):
p=n.split("/")
if len(p)>=4 and (p[2] in("recipe","recipes") or (p[2]=="tags" and p[3] in("item","items","block","blocks"))):
j=lenient_json(z.read(n))
if j is None: errors.append((jarname,n,"badjson"))
files.append((jarname,n,j))
elif n.startswith("assets/") and n.endswith("lang/en_us.json"):
j=lenient_json(z.read(n))
if isinstance(j,dict):
for k,v in j.items():
if k.startswith(("item.","block.")) and k.count(".")==2: lang.setdefault(k,[]).append((jarname,v))
elif n.startswith("assets/") and "/models/item/" in n and n.endswith(".json"):
p=n.split("/"); models.add(p[1]+":"+"/".join(p[4:])[:-5])
jars=["base_minecraft.jar","base_neoforge.jar"]+sorted(glob.glob("jars/*.jar"))
for j in jars: walk(zipfile.ZipFile(j), os.path.basename(j))
pickle.dump(dict(mods=mods,files=files,lang=lang,models=models,errors=errors),open("data.pkl","wb"))
print(len(mods),len(files),len(lang),len(models),len(errors))
for e in errors[:20]: print(e)
+21
View File
@@ -0,0 +1,21 @@
import tomllib, hashlib, os, glob, shutil, urllib.request, concurrent.futures as cf
P="/home/logan/Development/onion-mc/mods"
srcs=[os.path.expanduser("~/.local/share/PrismLauncher/instances/Onion MC/minecraft/mods"),"/tmp/fd/jars"]
def h(p): return hashlib.new
def one(f):
t=tomllib.load(open(f,"rb")); fn=t["filename"]; d=t["download"]; out=f"jars/{fn}"
def ok(p):
hh=hashlib.new(d["hash-format"]); hh.update(open(p,"rb").read()); return hh.hexdigest()==d["hash"]
if os.path.exists(out) and ok(out): return fn,"cached"
for s in srcs:
p=os.path.join(s,fn)
if os.path.exists(p) and ok(p): shutil.copy(p,out); return fn,"local"
url=d.get("url")
if not url: return fn,"NOURL "+str(t.get("update"))
req=urllib.request.Request(url.replace(" ","%20"),headers={"User-Agent":"onion-mc-audit"})
open(out,"wb").write(urllib.request.urlopen(req,timeout=120).read())
return fn,"dl" if ok(out) else "BADHASH"
with cf.ThreadPoolExecutor(8) as ex:
for fn,s in ex.map(one,sorted(glob.glob(P+"/*.pw.toml"))):
if s not in("cached","local","dl"): print(s,fn)
print(len(os.listdir("jars")))
+107
View File
@@ -0,0 +1,107 @@
"""Generate config/paxi/datapacks/onion-fixes from the audit findings.
Run from repo root after extract.py has built /tmp/onion/data.pkl."""
import json, os, pickle, shutil, copy
D = pickle.load(open("/tmp/onion/data.pkl", "rb"))
orig = {}
for jar, p, j in D["files"]:
orig.setdefault(p, {})[jar.split("-")[0]] = j
OUT = "config/paxi/datapacks/onion-fixes"
shutil.rmtree(OUT, ignore_errors=True)
def write(path, obj):
f = os.path.join(OUT, path)
os.makedirs(os.path.dirname(f), exist_ok=True)
with open(f, "w") as fh:
json.dump(obj, fh, indent=2); fh.write("\n")
def recipe(rid, obj):
ns, p = rid.split(":")
write(f"data/{ns}/recipe/{p}.json", obj)
def disable(rid):
recipe(rid, {"neoforge:conditions": [{"type": "neoforge:false"}]})
def src(path, mod):
return copy.deepcopy(orig[path][mod])
write("pack.mcmeta", {"pack": {"pack_format": 48,
"description": "Onion MC cross-mod recipe/tag fixes"}})
KNIFE = {"tag": "c:tools/knife"}
def cut(ing, out, n):
return {"type": "farmersdelight:cutting", "ingredients": [ing],
"result": [{"item": {"id": out, "count": n}}], "tool": KNIFE}
# 1. Potato: one board recipe per input, chained so each mod keeps its yield.
# potato -> 2 rustic slices (rustic's recipe, untouched)
# rustic slice -> 2 extradelight sliced potato (4/potato, as before)
# 2 rustic slices -> 1 moredelight diced potatoes (1/potato, as before;
# moredelight's Create saw recipe still gives 2/potato)
recipe("extradelight:cutting/sliced_potato",
cut({"item": "rusticdelight:potato_slices"}, "extradelight:sliced_potato", 2))
disable("moredelight:cutting/diced_potatoes")
recipe("onion:diced_potatoes_from_potato_slices", {
"type": "minecraft:crafting_shapeless", "category": "misc",
"ingredients": [{"item": "rusticdelight:potato_slices"}] * 2,
"result": {"id": "moredelight:diced_potatoes", "count": 1}})
# Slices are not whole potatoes (dupe loop via stews / re-cutting).
write("data/c/tags/item/crops/potato.json", {"replace": True, "values": [
"minecraft:potato", "veggiesdelight:sweet_potato",
{"id": "#forge:crops/potato", "required": False}]})
# 2. Bread: extradelight's slice wins; moredelight's sandwiches use c:bread_slices.
# Widen extradelight's input to c:foods/bread so cauliflower bread still slices.
r = src("data/extradelight/recipe/cutting/bread_knife.json", "extradelight")
r["ingredients"] = [{"tag": "c:foods/bread"}]
recipe("extradelight:cutting/bread_knife", r)
disable("moredelight:cutting/bread_slice")
# 3. Coffee: raw rustic beans are not roasted beans; crates use their own items.
write("data/c/tags/item/crops/coffee/cooked.json", {"replace": True, "values": [
"extradelight:coffee_beans", "rusticdelight:roasted_coffee_beans"]})
for rid, item in [("extradelight:coffee_cherries_to_block", "extradelight:coffee_cherries"),
("extradelight:coffee_beans_to_block", "extradelight:coffee_beans")]:
ns, p = rid.split(":")
r = src(f"data/{ns}/recipe/{p}.json", "extradelight")
r["ingredients"] = [{"item": item}] * 9
recipe(rid, r)
# 4. Twilight Forest knives: twilightdelight owns them; drop dungeonsdelight's copies.
for k in ["fiery_knife", "fiery_iron_knife", "ironwood_knife", "knightmetal_knife", "steeleaf_knife"]:
disable(f"dungeonsdelight:integration/twilightforest/crafting_table/{k}")
# 5. Crates: keep one crafting recipe per crate (uncrafting recipes untouched).
disable("minecraft:poisonous_potato_crate") # dungeonsdelight's; frightsdelight keeps it
disable("minecraft:rotten_tomato_crate") # dungeonsdelight's; frightsdelight keeps it
disable("fruitsdelight:apple_crate") # extradelight keeps it
disable("adorablehamsterpets:cucumber_crate") # extradelight's accepts any c:crops/cucumber
# 6. Handcrafted sheets: shapeless 3 wool collided with Comforts' vertical
# sleeping bags; make sheets a horizontal row.
COLORS = "white orange magenta light_blue yellow lime pink gray light_gray cyan purple blue brown green red black".split()
for c in COLORS:
r = src(f"data/handcrafted/recipe/{c}_sheet.json", "handcrafted")
recipe(f"handcrafted:{c}_sheet", {"type": "minecraft:crafting_shaped",
"category": r.get("category", "misc"), "key": {"#": r["ingredients"][0]},
"pattern": ["###"], "result": r["result"]})
# 7. Handcrafted wood plate (any 3 slabs in a row) shadowed all TF drying racks.
r = src("data/handcrafted/recipe/wood_plate.json", "handcrafted")
r["pattern"] = ["##"]
r["result"]["count"] = 2
recipe("handcrafted:wood_plate", r)
# 8. Fisherman's Haven worms can: one recipe, plus 1:1 worm conversions.
disable("fishermans_haven:recipe_worms_aquaculture")
for a, b in [("fishermans_haven:worm", "aquaculture:worm"), ("aquaculture:worm", "fishermans_haven:worm")]:
recipe(f"onion:{b.split(':')[0]}_worm_from_{a.split(':')[0]}_worm", {
"type": "minecraft:crafting_shapeless", "category": "misc",
"ingredients": [{"item": a}], "result": {"id": b, "count": 1}})
# 9. Twilight Delight ice creams need Neapolitan (absent): gate instead of log errors.
for k in ["rainbow_ice_cream", "refreshing_ice_cream", "twilight_ice_cream"]:
r = src(f"data/twilightdelight/recipe/{k}.json", "twilightdelight")
r = {"neoforge:conditions": [{"type": "neoforge:mod_loaded", "modid": "neapolitan"}], **r}
recipe(f"twilightdelight:{k}", r)
# 10. Beef stew: rustic replaces it, extradelight disables it -> load-order roulette.
# Pin rustic's version so the cooking pot recipe always exists.
recipe("farmersdelight:cooking/beef_stew",
src("data/farmersdelight/recipe/cooking/beef_stew.json", "rusticdelight"))
print("ok")
+161
View File
@@ -0,0 +1,161 @@
import pickle,json,collections,re,itertools
D=pickle.load(open("data.pkl","rb"))
mods=set(D["mods"])|{"minecraft","c","neoforge"}
files=D["files"]
# ---------- resource-level overrides ----------
byres=collections.defaultdict(list)
for jar,path,j in files: byres[path].append((jar,j))
legacy=collections.Counter()
for path,l in byres.items():
p=path.split("/")
if p[2]=="recipes" or (p[2]=="tags" and p[3] in("items","blocks")): legacy[l[0][0]]+=1
# ---------- tags ----------
def is_tag_path(p): return p[2]=="tags" and p[3]=="item"
tagdefs=collections.defaultdict(list) # tag -> [(jar, values, replace)]
for path,l in byres.items():
p=path.split("/")
if not is_tag_path(p): continue
tag=p[1]+":"+"/".join(p[4:])[:-5]
for jar,j in l:
if not isinstance(j,dict): continue
tagdefs[tag].append((jar,j.get("values",[]),j.get("replace",False)))
items=set()
for k in D["lang"]:
_,ns,pa=k.split("."); items.add(ns+":"+pa)
items|=D["models"]
def ns(x): return x.split(":")[0] if ":" in x else "minecraft"
def full(x): return x if ":" in x else "minecraft:"+x
tagcache={}; tagissues=[]
def resolve(tag,stack=()):
if tag in tagcache: return tagcache[tag]
if tag in stack: return set()
out=set()
for jar,vals,rep in tagdefs.get(tag,[]):
if rep: out=set()
for v in vals:
req=True
if isinstance(v,dict): req=v.get("required",True); v=v.get("id")
if not isinstance(v,str): continue
if v.startswith("#"):
t=full(v[1:])
if req and t not in tagdefs: tagissues.append((tag,jar,v,"missing-tag"))
out|=resolve(t,stack+(tag,))
else:
v=full(v)
if v not in items:
if req: tagissues.append((tag,jar,v,"missing-item" if ns(v) in mods else "missing-mod-item"))
continue
out.add(v)
tagcache[tag]=out; return out
for t in list(tagdefs): resolve(t)
# ---------- conditions ----------
unknown_cond=collections.Counter()
def cond(c):
if isinstance(c,list): return all(cond(x) for x in c)
t=c.get("type","")
if t in("neoforge:mod_loaded","forge:mod_loaded"): return c.get("modid") in mods
if t in("neoforge:not","forge:not"): return not cond(c["value"])
if t in("neoforge:and","forge:and"): return all(cond(x) for x in c["values"])
if t in("neoforge:or","forge:or"): return any(cond(x) for x in c["values"])
if t in("neoforge:item_exists","forge:item_exists"): return full(c["item"]) in items
if t in("neoforge:tag_empty","forge:tag_empty"): return not resolve(full(c["tag"]))
if t in("neoforge:true","forge:true"): return True
if t in("neoforge:false","forge:false"): return False
unknown_cond[t]+=1; return True
# ---------- ingredients ----------
def ing(x):
"""-> frozenset of items, or None if unknown type"""
if x is None: return frozenset()
if isinstance(x,str):
return frozenset(resolve(full(x[1:]))) if x.startswith("#") else frozenset([full(x)])
if isinstance(x,list):
s=set()
for y in x:
r=ing(y)
if r is None: return None
s|=r
return frozenset(s)
if isinstance(x,dict):
if "item" in x and isinstance(x["item"],str): return frozenset([full(x["item"])])
if "tag" in x: return frozenset(resolve(full(x["tag"])))
if "id" in x and "count" in x and isinstance(x["id"],str): return frozenset([full(x["id"])])
if "ingredient" in x: return ing(x["ingredient"])
t=x.get("type","")
if t in("neoforge:compound",): return ing(x.get("children"))
if t=="neoforge:components": return ing(x.get("items"))
if "items" in x: return ing(x["items"])
if t=="neoforge:difference":
b=ing(x.get("base")); s=ing(x.get("subtracted"))
return None if b is None or s is None else b-s
if t=="neoforge:intersection":
ch=[ing(c) for c in x.get("children",[])]
if None in ch or not ch: return None
return frozenset(set.intersection(*map(set,ch)))
return None
def result(j):
r=j.get("result")
if r is None: return None
if isinstance(r,str): return (full(r),1)
if isinstance(r,dict):
i=r.get("id") or r.get("item")
if isinstance(i,dict): i=i.get("id") or i.get("item")
return (full(i) if isinstance(i,str) else str(i), r.get("count",1))
if isinstance(r,list):
return tuple(sorted(result({"result":(e.get("item",e) if isinstance(e,dict) else e)}) + ((e.get("chance",1),) if isinstance(e,dict) else ()) for e in r))
return str(r)
# ---------- active recipes (last jar wins per path; note collisions) ----------
active={}; overrides=[]; missingrefs=[]
for path,l in byres.items():
p=path.split("/")
if p[2]!="recipe" or not path.endswith(".json"): continue
rid=p[1]+":"+"/".join(p[3:])[:-5]
live=[]
for jar,j in l:
if not isinstance(j,dict): continue
c=j.get("neoforge:conditions")
if c is not None and not cond(c): continue
live.append((jar,j))
if len(live)>1:
uniq={json.dumps(j,sort_keys=True) for _,j in live}
if len(uniq)>1: overrides.append((rid,[jr for jr,_ in live]))
if live: active[rid]=live[-1]
# cross-mod overrides of another namespace's recipes (single providing jar from other mod)
owner={}
for m,l in D["mods"].items():
for x in l: owner.setdefault(x["jar"].split("!")[0],set()).add(m)
foreign=collections.defaultdict(list)
for rid,(jar,j) in active.items():
n=ns(rid)
if n not in owner.get(jar,set()) and jar not in("base_minecraft.jar",) and n not in("c",):
foreign[(jar,n)].append(rid)
# ---------- unknown refs in active recipes ----------
def refs(o,acc):
if isinstance(o,dict):
for k,v in o.items():
if k in("item","id","tag") and isinstance(v,str) and k!="type": acc.append((k,v))
else: refs(v,acc)
elif isinstance(o,list):
for v in o: refs(v,acc)
return acc
for rid,(jar,j) in active.items():
if j.get("type","").startswith(("neoforge:","forge:")) and "conditional" in j.get("type",""): continue
for k,v in refs({kk:vv for kk,vv in j.items() if kk not in("neoforge:conditions",)},[]):
if k=="tag": continue
if ":" in v and ns(v) not in mods and not v.startswith("#"):
missingrefs.append((rid,jar,v)); break
pickle.dump(dict(active=active,tagcache=tagcache,items=items),open("active.pkl","wb"))
print("== legacy (pre-1.21 'recipes/' or 'tags/items/') files, inert ==")
for k,v in legacy.most_common(): print(f" {k}: {v}")
print("== recipe path collisions with differing content (load order decides) ==",len(overrides))
for r,js in overrides: print(" ",r,js)
print("== jars overriding another namespace's recipes ==")
for (jar,n),l in sorted(foreign.items(),key=lambda x:-len(x[1])): print(f" {jar} -> {n}: {len(l)} e.g. {l[:3]}")
print("== active recipes referencing items from absent mods (will fail to load) ==",len(missingrefs))
for x in missingrefs[:80]: print(" ",x)
print("== tag issues (required entry missing => whole tag fails to load) ==")
seen=set()
for t,jar,v,k in tagissues:
if (t,v) in seen: continue
seen.add((t,v)); print(" ",k,t,"<-",v,"from",jar)
print("== unknown condition types (assumed true) ==",dict(unknown_cond))
print("active recipes",len(active))
+190
View File
@@ -0,0 +1,190 @@
# Phase 2 benchmark matrix
This replaces `LEVERS.md` §6. It is meant to run without judgement calls: every config is a
generated directory, every scene is a datapack function, and every block ends in a decision
rule. The measurement protocol and machine prep are in `../../phase0/P{0,1,2}-*.md`
(uncapped, vsync off, p99 frametime + 1 % low, 15 s warm-up discarded, 3 runs, one variable
per comparison). This file adds what phase0 leaves open: the world, the scenes, the configs
and the order.
Machines: **P0** Steam Deck · **P1** 7700K + GTX 1060 6 GB (Windows) · **P2** 6700K + 1080 Ti,
~8 GB free RAM.
---
## 0. Prerequisite: boot check
The pack has never booted at its current size: 217 mods after `a01bc3b` added Default
Options, Sodium Extra, Reese's Sodium Options, BadOptimizations and Particle Core. Before
any timing, launch once and check `latest.log` for:
- missing deps and mixin apply failures;
- `fishermans-haven` biome-modifier errors;
- `ftbteams` references;
- Default Options' `Populated … with default options` lines (proves the seeding works);
- no YACL "Failed to deserialize" lines for `fowlplay` or `crittersandcompanions`
(spawn tuning, `SPAWN-TUNING.md`);
- a working Sodium video-settings screen (Reese's Sodium Options replaces it; SSRD injects a
slider into it).
r5 also flags a reported Iris 1.8.14-beta.1 ↔ Sodium 0.8.13 mixin incompatibility on
NeoForge 1.21.1, with a third-party "Iris-Sodium Compat" patch on CurseForge. Check for it
with a shaderpack enabled. **If the pack doesn't boot cleanly, fix that first. Bisect the
five new mods before anything older.**
## 1. Fixed inputs
| Input | Value |
| --- | --- |
| Pack | one commit, recorded in every row (`git rev-parse --short HEAD`). The Puzzles Lib bump goes in before B0 if approved, never mid-matrix. |
| Bench instance | a **separate** Prism instance per machine with the packwiz `PreLaunchCommand` **removed**, so it can't self-update mid-matrix. Mods are copied from a normal install of the recorded commit. |
| Java | Temurin 21 on all three (phase0). Check `java -XX:+UseShenandoahGC -version` works (needed for J3). |
| World | `bench-world-v1.zip`, built once on P2 (§2), sha256 recorded, unpacked identically on every machine |
| Configs | `analysis/client-perf/proposed-configs/out/<ID>/`, generated by `build.py` at the recorded commit |
| In-game pins | phase0 Step 7/8. The `options.txt` keys that matter are already in every bench variant (`maxFps:260`, `enableVsync:false`, `renderDistance:8`, `simulationDistance:8`). GUI scale, FOV, resolution and fullscreen are recorded per machine and never changed. |
| Resource packs / shaders | none, unless the block says otherwise |
### Applying a config
With the game closed, run
`python3 proposed-configs/apply_variant.py <ID> <instance>/.minecraft`. It copies all 10
config files (every variant has every file, so nothing from a previous variant survives)
and **merges** `options.txt` key by key, so GUI scale, resolution and keybinds are kept.
It also writes the ID to `.minecraft/BENCH_VARIANT.txt`; check it before each run. On
Windows without Python, copy the `config/` tree by hand and edit the listed `options.txt`
keys in game. Default Options seeds only missing files, so it never interferes.
**Relaunch for every config change**, even ones a mod could hot-reload. Run all of that
config's scenes in one session, in the order S1 → S2 → S3 → S4 → S5 → S6.
### JVM sets (Prism → Java arguments; `-Xmx` per block)
All four were checked to parse on OpenJDK 21.0.12.
| ID | Arguments (plus `-Xmx`) |
| --- | --- |
| **J0** (phase0 default) | `-XX:+UseG1GC -XX:+ParallelRefProcEnabled -XX:MaxGCPauseMillis=200 -XX:+UnlockExperimentalVMOptions -XX:+DisableExplicitGC -XX:G1NewSizePercent=30 -XX:G1MaxNewSizePercent=40 -XX:G1HeapRegionSize=8M -XX:G1ReservePercent=20 -XX:G1HeapWastePercent=5 -XX:G1MixedGCCountTarget=4 -XX:InitiatingHeapOccupancyPercent=15 -XX:G1MixedGCLiveThresholdPercent=90 -XX:G1RSetUpdatingPauseTimePercent=5 -XX:SurvivorRatio=32 -XX:+PerfDisableSharedMem -XX:MaxTenuringThreshold=1` |
| **J1** (client G1, brucethemoose) | `-XX:+UseG1GC -XX:MaxGCPauseMillis=37 -XX:G1HeapRegionSize=16M -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=23 -XX:G1ReservePercent=20 -XX:G1MixedGCCountTarget=3 -XX:G1HeapWastePercent=20 -XX:InitiatingHeapOccupancyPercent=10 -XX:G1RSetUpdatingPauseTimePercent=0 -XX:MaxTenuringThreshold=1 -XX:GCTimeRatio=99 -XX:+DisableExplicitGC -XX:+PerfDisableSharedMem` |
| **J2** (Generational ZGC) | `-XX:+UseZGC -XX:+ZGenerational -XX:+DisableExplicitGC -XX:+PerfDisableSharedMem`. Plain `-XX:+UseZGC` on JDK 21 is the old non-generational ZGC. |
| **J3** (Shenandoah) | `-XX:+UseShenandoahGC -XX:+DisableExplicitGC -XX:+PerfDisableSharedMem`. **Not** r6's `-XX:ShenandoahGCMode=iu`: on JDK 21 that aborts VM startup unless `-XX:+UnlockExperimentalVMOptions` is added (tested), and the mode is gone in later JDKs. |
Default heap outside B4 (phase0): P0 `-Xmx5G`, P1 `-Xmx8G`, P2 `-Xmx6G`, all with J0.
---
## 2. Bench world (built once on P2)
1. Copy `bench/onion-bench/` into a new world's `datapacks/` folder. Create the world:
Creative, cheats on, seed `onionbench`, default world type. Run `/function bench:setup`.
2. **S2**: `/function bench:s2`, then `/function bench:s2_setup`. Check that the shafts and
cogwheels **rotate**. If the `/fill`-placed network didn't initialise, break and re-place
one motor per row by hand. Accept when F3 shows Flywheel instances and every row turns.
3. **S3**: `/function bench:s3`, then `/function bench:s3_setup`. Check the counts with
`/execute if entity @e[type=villager,x=1999,y=150,z=-1,dx=25,dy=8,dz=25]` (expect 30).
4. **S4**: `/function bench:s4` (camera at 3000 172 -10, facing south). Build one
Aeronautics test ship (about 5×7×15 blocks, planks + glass + 1 propeller) and assemble it
so it hovers at y≈170. Copy it with a Create schematic to get **4 ships, centred at z =
32, 96, 192 and 384** (2, 6, 12 and 24 chunks away). SSRD 16 then cuts only the 384 one.
Record the sub-level count Sable shows. This is the only hand-built scene. It's baked into
the zip, so runs never rebuild it. To get the 0- and 1-ship states, break ships into
blocks *in a copy of the world*: `bench-world-v1-s4-0.zip` and `-s4-1.zip`.
5. **DH pre-generation**: use the upstream DH file
(`data/observed-default-configs/DistantHorizons.toml`: `SURFACE_THEN_CHUNKS`, radius
256), then stand at S1 until DH's F3 generation queue reads 0.
Run `/function bench:tour_start` with the same settings, waiting at each hop until the
queue drains (re-issue `bench:tour/stepN` by hand). Do the same at S4. Every bench config
then runs with `generatorPlan = "DISABLED"`, so no world generation happens during
measurement.
6. Leave the world at S1, save, quit and zip it.
### Scenes
| ID | Command | What it loads | Capture |
| --- | --- | --- | --- |
| **S1** vista | `/function bench:s1` | 0 200 0, facing south, 20° down. Pure terrain + DH LODs | 15 s warm-up + 30 s, hands off |
| **S2** Create floor | `/function bench:s2` | 2,304 kinetic BEs (Flywheel instancing; vanilla BE path under shaders) | 15 + 30 s |
| **S2s** sound storm | S2 + `/function bench:storm_on` (stop: `storm_off`) | 24 sounds/tick from 3 capped Create IDs (8 per ID per tick vs cap 4) | 15 + 30 s, sound on |
| **S3** mob pen | `/function bench:s3` | 30 villagers, 15 cows, 15 sheep, 10 allays carrying torches (moving LDL sources), 10 dropped torches | 15 + 30 s |
| **S4** airships | `/function bench:s4` | 0 / 1 / 4 Sable sub-levels at 2–24 chunks | 15 + 30 s |
| **S5** tour | `/function bench:s1`, wait 10 s, then `/function bench:tour_start` | 24 teleports of 160 blocks every 5 s along +x: chunk + LOD streaming, GC churn | **all 120 s, no warm-up discard** |
| **S6** GUI | at S1, press E with the JEI overlay open; mouse parked over the JEI list | GUI / JEI / tooltip path | 15 + 30 s |
---
## 3. Config IDs
Generated by `proposed-configs/build.py`. `out/MANIFEST.md` lists every changed key.
**C0** = every file at upstream default; **C1** = the proposed pack default (= mid tier).
All other IDs are C1 with **one** change.
| ID | Change vs C1 |
| --- | --- |
| C0 | everything back to upstream (DH 256 / SSAO on / 4 threads, Flywheel SMOOTH, LDL fancy, SPR 32/4, mip 4, blend 2, ModernFix dynres off, …) |
| C1-deck, C1-high | the tier deltas from `proposed-configs/README.md` §2 |
| dh-r256 / dh-r192 / dh-r64 | DH LOD radius (C1 = 128) |
| dh-off | C1, then DH options → *Enable Rendering* off after each launch. That toggle is GUI-only and never written to the file. |
| dh-ssao / dh-thr4 / dh-qlow | SSAO on / 4 DH threads / DH's LOW quality preset at radius 128 |
| fw-flat / fw-smooth | Flywheel `lightSmoothness` (C1 = TRI_LINEAR) |
| mf-dynres-off | ModernFix `dynamic_resources=false` |
| ssrd-32 / -64 / -128 | SSRD `physicsRenderDistance` (C1 = 16) |
| sable-noshade | Sable `sub_level_dynamic_shading=false` |
| emf-lod20 / emf-lod8 | EMF LOD 20 + Average (= upstream) / LOD 8 + `retainDetailOnLowFps=false` |
| ldl-fancy / ldl-fastest | LambDynamicLights mode (C1 = fast); `fastest` also turns entity light sources off |
| spr-up / spr-strict / spr-nocap | SPR rays 32/4 (upstream) / `strict_occlusion=true` / Create sound caps removed |
| sod-thr3 | Sodium `chunk_builder_threads=3` (C1 = 0 = auto = 2) |
| opt-blend2 / opt-blend0 / opt-mip4 | biome blend 5×5 / off; mipmap 4 |
---
## 4. Blocks, in run order
"Win" means the median p99 frametime improves by more than that machine's **B0 spread**, and
the 1 % low doesn't get worse by more than the spread. Ties keep the upstream value (less
change). FPS floors for tier picks: **P0 1 % low ≥ 30**, **P1/P2 1 % low ≥ 60**.
| Block | Machines | Configs (× JVM) | Scenes | Records | Decision rule |
| --- | --- | --- | --- | --- | --- |
| **B0** noise floor | all | C0 ×3 sessions | S1 | p99 / 1 % spread | Defines each machine's threshold. P2 also checks `MemAvailable` drift (phase0 Step 4). |
| **B1** baseline | all | C0 | S1–S6 | + `Game took N seconds to start` (ModernFix log line), the `Created: …blocks.png-atlas` line, `/sparkc heapsummary` after S1 loads, VRAM peak (P1/P2) | Reference numbers for everything below |
| **B2** composite | all; tiers on their machine | C1 (all), C1-deck (P0), C1-high (P2) | S1–S6 | as B1 | If C1 isn't a win on ≥ 2 machines, stop and bisect with B3–B11 before shipping anything |
| **B3** Distant Horizons | all | dh-r256, dh-r192, C1, dh-r64, dh-off | S1, S5 | + DH memory in F3 | **Radius per tier** = the largest radius meeting the FPS floor on S1 *and* S5: P0 → deck, P1 → default, P2 → high |
| | P0, P1 | dh-ssao, dh-qlow | S1 | | Adopt SSAO-off / LOW-quality for that tier on a win |
| | all | dh-thr4 | S1, S5 | | Keep 2 threads unless 4 is a win on S5 *and* not a loss on S1 |
| **B4** heap & GC | P2, then P0 | C1 (C1-deck on P0) × J0, J1, J2, J3 at `-Xmx6G` (P2) / `-Xmx5G` (P0); then the winner at 4 / 5 / 6 G | S5 (120 s), S2 | + `/sparkc gc` after S5 (pause count / max / total), swap delta (P2) | GC = best S5 1 % low. Heap = the smallest size within the spread of the best. Feeds `PLAYER-TUNING.md` §2. P1 isn't run (32 GB, not a constraint). |
| **B5** Sable / SSRD | P0, P1 | world s4-0 / s4-1 / s4-4 × C1; s4-4 × ssrd-32, ssrd-64, ssrd-128, sable-noshade | S4 | sub-level count | SSRD per tier = the largest value meeting the floor with 4 ships. sable-noshade ships only on a win *and* if it looks acceptable. |
| | P1 | C1, s4-4, J0 | S4, **45 min** (2 runs) | FPS at 0 / 15 / 30 / 45 min, `/sparkc heapsummary` at each | Decay > spread is a Sable #1011-class finding: report it, no config fix |
| **B6** ModernFix | P2, P0 | C1 vs mf-dynres-off, 3 cold launches each | S1, S2, S6 | startup, heap after load, missing-texture check (below) | Ship `dynamic_resources=true` only if: heap −300 MB or more *or* startup faster beyond spread, **and** zero missing textures, **and** no crash in 3 launches |
| **B7** shaders | P1, P2: all rows; P0: MakeUp rows only | C1 with: none / MakeUp `shadowless_medium` / MakeUp `medium` / Complementary `LOW` / Complementary `MEDIUM` (profiles set in Iris' shader settings) | S2, S1, S4 (s4-4) | `Flywheel` backend line in F3 (expect off with shaders); visual check for Iris #3164 on ships | Data for the owner's shader policy, no auto-decision. Report the FPS cost per profile and whether ship corruption appears with shadow profiles |
| **B8** entities | P2, P0 (P1: FA rows only) | C1 / C1 + Fresh Animations / C1 + FA + Extensions / emf-lod20 + FA / emf-lod8 + FA; ldl-fancy, ldl-fastest (no FA) | S3 | | EMF: adopt the smallest LOD that's a win with FA on. LDL: per tier, the cheapest mode that's a win. FA guidance → `PLAYER-TUNING.md` §4 |
| **B9** Flywheel | P0, P1 | fw-flat, C1, fw-smooth (no shaders) | S2 | | Per tier: the smoothest value meeting the floor |
| **B10** Sound Physics | P2, P0 | spr-up, C1, spr-strict, spr-nocap | S2s | | Adopt each change that's a win. Listen for obvious audio breakage. |
| **B11** vanilla / Sodium | P1, P2 | sod-thr3 | S5, S1 | | 3 threads only if S5 wins and S1 doesn't lose |
| | all | opt-blend2, opt-blend0 | S5 | | Lowest blend radius that's a win, per tier |
| | P1 | opt-mip4 | S1, S2 | VRAM peak | Mip 4 for mid/high only if VRAM peak ≤ 5.5 GB and no loss |
| **B12a** added-mod ablation | P2, P0 (P1: Sodium Extra only) | C1 with **one** of BadOptimizations / Particle Core / Sodium Extra removed from `mods/` | S1, S3, S2s | | Keep the mod unless removing it is a win (it costs FPS) or it breaks something visible. Sodium Extra + RSO stay regardless for their per-machine options. |
| **B12b** trials | per mod: Gnetum (all), Better Block Entities (all, with FA on and off), Flerovium (all), Super Resolution (P0), Ixeris (P1), Iris Flywheel Compat (with shaders, B7 scenes), Cull Leaves + MidnightLib (with Better Leaves) | C1 + one mod | the scenes that mod targets | | Owner pre-approved helpful adds. Add with `packwiz modrinth add` only on a win with no breakage. **Not More Culling**: its NeoForge build declares `minecraft [1.21,1.21.1)`. A new mod set means re-running B0 first. |
| **B13** profile | P2 | the worst scene from B2 under C1 | that scene | `/sparkc profiler start --timeout 60`, upload or save the report | Flag any mod over 5 % of render-thread time that isn't Sodium, Iris, DH or Flywheel |
| **B14** spawn tuning | P2 | singleplayer, defaults vs the shipped spawn files | river, jungle, warm ocean (10 min each) | per-species and total entity counts | Procedure and keep/back-off rule: `SPAWN-TUNING.md` §B14 |
**Missing-texture check (B6)**: in creative, open JEI, search `@chipped`, `@rechiseled` and
`@handcrafted`, scroll each list, and place a 4×4 wall of 3 connected-texture Rechiseled
blocks. Any magenta/black texture or broken CTM seam fails the check.
### Rough budget
Assumes ~4 min per launch (B1 measures the real figure) and ~3 min per scene for 3 × 45 s.
| Block | Launches (all machines) | Hours |
| --- | --- | --- |
| B0–B2 | ~12 | ~5 |
| B3 | ~20 | ~4 |
| B4 | ~14 | ~3 |
| B5 | ~12 + 1.5 h decay | ~4 |
| B6 | 12 cold launches | ~2 |
| B7–B11 | ~45 | ~7 |
| **Total** | | **~25 h machine time**, ~10 h per machine |
## 5. Output
One CSV row per run, using the phase0 recording sheet plus `config_id`, `jvm_set`, `xmx`,
`scene`, `world_sha`, `pack_commit`. When the matrix is done, write the winners back into
`proposed-configs/build.py` (DEFAULT/DECK/HIGH), regenerate, and only then present the files
for shipping.
+176
View File
@@ -0,0 +1,176 @@
# Onion MC — client performance levers (Phase 1, unmeasured)
Fleet (from `phase0/`): **P0** Steam Deck (GPU/shared-RAM bound), **P1** 7700K + GTX 1060 6 GB
(VRAM bound), **P2** 6700K + 1080 Ti with ~8 GB free RAM (main-thread + heap bound). Every
machine is 4C/8T. That makes CPU-side render cost, chunk/LOD worker threads and GC the
common denominator.
Impact estimates are informed guesses until Phase 2 measures them. Tags: **V** verified
in source or config, **D** documented upstream, **C** community, **I** inference.
Sources are in `research/` and `data/`.
---
## 1. The shape of the problem
From `data/jarscan-report.md`:
| Surface | Size | Who dominates |
| --- | --- | --- |
| Mixin classes on per-frame paths | 951 (121 `@Overwrite` / `@Redirect`) | Sable 127, Iris 114, Controlify 84 (GUI), Sodium 48, EMF 42, Create 30, ETF 27, Subtle Effects 26 |
| Mods subscribing to per-frame events | 58 | Puzzles Lib, Create, Alex's Caves, Mowzie's, Twilight Forest, Ars Nouveau, Balm, Xaero's |
| Mods on client / player / entity tick events | 79 | — |
| Block + item atlas | ~60k 16×16-sprite equivalents (≥4096²) | **Handcrafted 27 %, Chipped 21 %, Rechiseled 9 %** (58 % together) |
| Baked models / blockstates | 69,442 / 16,361 | Chipped 16.8k, Rechiseled 13.9k, Handcrafted 12.4k models (62 %) |
| Entity types | ~600 | Alex's Mobs 140, Alex's Caves 92, Twilight Forest 80, Ars Nouveau 51 |
| Animated atlas textures | 312 | Frights' Delight 69, TF 44, Chipped 30, Ars 29 |
| Post-processing / shader payloads | — | Lodestone 59 files, Alex's Caves 38 (7 post), Charta 31, Exposure 21 (19 post); vanilla core-shader overrides from Sable, Sodium, Xaero's ×2 |
What a player pays **by default today**, before choosing any options:
- **Shaders and resource packs are not on by default.** packwiz only downloads them; the
last real launch had `resourcePacks:[]` and no shaderpack. So Fresh Animations, Better
Leaves, Complementary and MakeUp cost nothing until a player enables them. **I**
- **Distant Horizons is mandatory and its defaults are heavy:** 256-chunk LOD radius, SSAO
on, AA on, MEDIUM/MEDIUM quality, transparency COMPLETE. **V** (observed `DistantHorizons.toml`)
- **Every mod's own defaults ship unchanged.** The pack ships **no client performance
config**. Its only configs are PetProtect, Akashic Tome and the Paxi datapack.
- The JVM, heap and GC are whatever each player's Prism instance has. The old instance had
`MaxMemAlloc=8192` and stock G1.
That last bullet is the reason for §2.
---
## 2. Meta-levers (enablers; do these first)
| # | Lever | Why |
| --- | --- | --- |
| M1 | **A way to ship tuned defaults without clobbering player changes.** **Resolved (2026-10-14, Phase 1b):** use Default Options (`config/defaultoptions/`, client-only, copy-if-absent), plus an enforced packwiz file for `modernfix-mixins.properties`, which is read at mixin time. `preserve` survives `packwiz refresh` but leaks into the server dir, which matters for DH `[server]`/`[common]` and SSRD COMMON. Evidence: `proposed-configs/README.md` §1. | Without this, every config lever below depends on 10 players hand-editing files. |
| M2 | **Per-tier profiles** (Deck / mid / high). Ship one conservative default, plus a short "if your machine is X, change Y" doc. Optionally make heavy client-only cosmetics packwiz `optional` (today only Controlify is). | Fleet constraints differ in direction. P2 should lower DH *threads*; P1 should lower DH *distance and quality*. One global ordering won't fit (already noted in `phase0/P2`). |
| M3 | **Profile with spark on the client** (`/sparkc profiler`; spark is already in the pack) in Phase 2, not only FPS percentiles. | 951 frame-path mixins means attribution must come from a profiler, not from guessing which mod is slow. |
---
## 3. Ranked levers
### Tier 1 — biggest expected wins, config or policy only
| # | Lever | Mechanism | Helps | Risk | Conf. |
| --- | --- | --- | --- | --- | --- |
| **1** | **Distant Horizons defaults per tier.** `lodChunkRenderDistanceRadius` 256 → ~64–96 (P0), 128–192 (P1), ~128 (P2). Turn SSAO off on P0 and P1. Lower the CPU thread preset on P2. Keep cave culling on. LODs come from the server; do `/dh pregen` server-side, not Chunky. | DH cost scales with LOD distance in VRAM, GPU and CPU. It is the largest always-on renderer the pack adds. | all; P1 VRAM, P0 everything | visual only | V/D |
| **2** | **Shader policy.** Default off, opt-in per machine. If on: MakeUp UF, or Complementary at ≤ MEDIUM profile, shadow distance ≤ 8 chunks, entity shadows off. | With any shaderpack active, **Flywheel marks both GPU backends unsupported** (`!ShadersModHelper.isShaderPackInUse()`, checked in source). Create then renders every kinetic block entity on the CPU, and again in the shadow pass. EMF/GeckoLib entities are also redrawn for shadows, and DH adds a shadow pass over all LODs. | all; P0 hardest | none (policy) | **V** |
| **3** | **Entity count, set on the server.** *Shipped in `d80f85b`, see `SPAWN-TUNING.md`.* Tune Alex's Mobs spawn weights: the 1.21.1 port has an open issue about inflated vanilla spawn rates (#62). Cap Fowlplay: #214 reports ~400 birds even after tuning. Cap Critters & Companions spawns via datapack (it has no config). | Every entity pipeline (vanilla, EMF/FA, GeckoLib, ETF, LambDynamicLights, Perception trails) multiplies by visible entity count. | all clients + server tick | gameplay feel | D/C |
| **4** | **EMF/ETF throttles.** `animationLODDistance` 20 → ~8–12. Consider `retainDetailOnLowFps=false` on P0. `modelUpdateFrequency` Average → Slow. Keep `animationFrameSkipDuringIrisShadowPass=true` (already the default, **V** observed). Treat the FA Extensions pack as opt-in. | FA turns every vanilla mob into an animated CEM model. EMF's frame-skip-by-distance is the throttle. | P0, P2 | animation smoothness at range | V |
| **5** | **JVM heap and GC per machine** (Prism settings; packwiz can't ship them). Heap: P0 5–6 G, P1 6–8 G, P2 ≤ 5–6 G (not the old instance's 8 G). Benchmark three GCs: client-tuned G1 (brucethemoose set), Generational ZGC (`-XX:+UseZGC -XX:+ZGenerational`; plain `UseZGC` on JDK 21 is the *non*-generational one), and Shenandoah. | DH warns about G1 itself. GC pauses show up as 1 % lows. P2's 8 GB headroom makes heap size a hard constraint. | P2, P0 | low | D/V |
| **6** | **ModernFix `mixin.perf.dynamic_resources=true`.** Off by default (**V** in the observed `modernfix-mixins.properties`). Also consider `dynamic_entity_renderers`. | 69k baked models and 16k blockstates sit in heap. The author documents ~−55 % memory even with FerriteCore. ModernFix has a CTM sub-option (`dynamic_resources.ctm`); test against Fusion and Athena. | P2, P0 (RAM) | med: missing textures or crashes with CTM/model mods | D/V |
| **7** | **Flywheel `lightSmoothness` SMOOTH → FLAT or TRI_LINEAR** (`flywheel-client.toml`). | The config comment itself says "may have a large performance impact". It only matters when shaders are off, i.e. when Flywheel is actually used. | all, Create-heavy bases | visual | V |
| **7b** | **Sable / SSRD sub-level budget.** Sable has no renderer of its own. Its `SODIUM_REACHAROUND` path runs Sodium's chunk renderer once per visible sub-level, so cost is roughly sub-levels × meshed sections, on top of terrain. Default the client SSRD distance low (8–16 chunks), not the 128-chunk server cap. Keep `sub_level_skylight_shadows=false` (the default, **V** observed). | Each airship is a second terrain pass. Under shaders, shadows also trigger open Iris #3164 sub-level corruption. | all; P0, P1 first | visual range of airships | V (config) / I (magnitude) |
| **8** | **LambDynamicLights**: mode → fast or fastest. On P0/P2 also set `light_sources.entities=false` (keep self). | Each moving light source triggers Sodium chunk-section rebuilds. On 4-core CPUs those compete with chunk builders, which default to 2 threads. | P2, P0 | less responsive light | V |
### Tier 2 — solid, smaller or more situational
| # | Lever | Helps | Conf. |
| --- | --- | --- | --- |
| 9 | **Sound Physics Remastered**: ray count 32 → 16, bounces 4 → 2, `strict_occlusion=true` (1 occlusion path instead of 9). Cap noisy Create and mob sounds in `sound_rates.properties`. Cost scales with concurrent sounds, so a Create floor is the worst case. | P2, P0 | V |
| 10 | **Vanilla and Sodium options**: render distance 8 to match the server (the old client had 12, which loads nothing extra in multiplayer). Biome blend 2 → 1 or 0. Mipmap 4 → 2 on P1/P0 (the atlas is ≥4096²). Entity distance 75–80 %. Sodium chunk threads auto-resolve to **2** on every fleet machine; try 3 on P1/P2. | all | V/I |
| 11 | **Better Leaves needs leaf culling** if anyone enables it. Use **Cull Leaves** (same author, made for it) or More Culling. **Do not use Sodium Leaf Culling**: it crashes on Sodium ≥ 0.8.11. | all, forests | D |
| 12 | **Twilight Forest / Alex's Caves client effects.** TF `cloudBlockPrecipitationDistance` → 0 and aurora toggles. AC `biome_ambient_light_coloring=false` for shader users. DH flags AC as partially incompatible (**V**, log). | in those dimensions | C/D |
| 13 | **Jade.** Pre-tune `hide-blocks.json` (player heads) and container-content display. Sophisticated Backpacks' "20–30 FPS when looking at a backpack" report was traced to Jade's content display. | all | C |
| 14 | **Bump Puzzles Lib 21.1.62 → 21.1.64**, as a *bugfix*, not a perf lever. The 21.1.64 cache is in `FabricEventFactory`, which isn't in the NeoForge jar. The NeoForge 62 → 64 diff is access-transformer restorations (21.1.63) plus one item-properties class. Applied in `a01bc3b`. | — | **V** (jar diff) |
| 15 | **Xaero's**: cap world-map loaded regions, keep the minimap modest. Radar as dots. | P2 heap | D |
| 16 | **WATUT**: raise `tickReceiveAndRenderRateOfGUIUpdates`, or `dontSendDetailedGUIInfo=true`. Watch the open TF conflict (#106). **Perception**: remove XP-orb trails. **Subtle Effects**: dust clouds off on P0. **FWA**: chain/lantern animations off on P0. | P0, P2 | V/C |
| 17 | **Platform**: `mesa_glthread=true` + gamemode on the Deck. NVCP "Prefer maximum performance" on P1. Leave threaded optimisation alone; Sodium manages it. | P0, P1 | D/C |
### Tier 3 — content weight (structural; decide after measuring)
- **Handcrafted + Chipped + Rechiseled** = 58 % of the atlas and 62 % of all models. They
cost startup time, heap (baked models) and some VRAM. Lever 6 mitigates the heap part.
Removing any of them is a content decision, but they're the only lever that moves startup
and model RAM materially. Chipped requires Athena, and Rechiseled requires Fusion.
- **Fresh Animations (+ Extensions)**: the largest documented entity-render multiplier,
especially with shaders (EMF #443, Oculus era: 165 → 40 FPS with 30+ mobs). It's already
opt-in because it's a resource pack. Keep it that way and say so in the player doc.
---
## 4. Mods to add (all confirmed with NeoForge 1.21.1 builds via the Modrinth API)
**Owner decisions, 2026-10-14:**
- Adding any helpful mod is allowed. Default Options, Sodium Extra, Reese's Sodium Options,
BadOptimizations and Particle Core were **added in `a01bc3b`**.
- The trials are bench block B12b.
- More Culling is out: its NeoForge build excludes 1.21.1.
- Shaders stay **opt-in**.
| Mod | Why | Verdict |
| --- | --- | --- |
| **Default Options** (`default-options`) | Lever M1 delivery mechanism; Balm already present | **Add** |
| **Sodium Extra** + **Reese's Sodium Options** | Expose particle, animation and fog toggles per machine. RSO works with Controlify, which matters on the Deck. | **Add** |
| **Particle Core** (`particle-core` 0.3.3) | Particle frustum culling, async ticking, per-type limits. Big particle sources here: Subtle Effects, Perception, Ars, Alex's Caves, Sooty Chimneys. | **Add, then verify** |
| **BadOptimizations** (2.4.1) | Lightmap and sky caching; self-disables on conflicts | **Add** |
| **Gnetum** (3.3.6) | Spreads HUD rendering over frames. This pack is HUD-heavy (Xaero's, Jade, AppleSkin, titles, plaques). The author says it's compatible with ImmediatelyFast. Replaces Exordium, which has no NF 1.21.1 build. | **Trial** |
| **Cull Leaves** or **More Culling** | Only if Better Leaves stays (lever 11) | **Add one** |
| **Better Block Entities** (1.3.4, built for Sodium 0.8.12–0.8.13) | Meshes static chests, signs and beds into terrain. Its EMF compat is only for 1.21.11+, so test it with FA. | **Trial** |
| **Flerovium** | Item, particle and entity render culling. Higher visual-glitch risk with layered models. | **Trial** |
| **Super Resolution** (alpha) | FSR upscaling. Potentially the biggest P0 lever, but alpha, and Complementary has no SR interface. | **Trial on P0 only** |
| **Ixeris** | Moves event polling off the render thread. Big win only on Windows with high-poll mice. Has open crash reports on older NVIDIA cards. | **Trial on P1** |
| **Iris Flywheel Compat** | Restores Flywheel instancing under shaders, which would neutralise most of lever 2's Create penalty. Unofficial and breaks on Create/Iris updates. | **Trial only if shaders are wanted** |
**Skip**: Sodium Leaf Culling (crashes), ScalableLux (breaks DH), Moonrise and C2ME on the
client (no client gain in multiplayer), Exordium / Krypton / Nvidium / VulkanMod / FastChest /
YOSBR (no NeoForge 1.21.1 build), Memory Leak Fix (obsolete), Sodium Options API (superseded
by Sodium 0.8), Sodium Dynamic Lights (duplicates LambDynamicLights).
## 5. Mods worth considering for removal
**Owner decision, 2026-10-14: remove no mods.** Kept for reference only. Mitigate with
config instead (spawn tuning: `analysis/client-perf/SPAWN-TUNING.md`).
Ordered by cost to value. None is urgent; measure first.
| Mod | Cost evidence | Note |
| --- | --- | --- |
| **Miner's Delight** | It's the *only* consumer of **Lodestone** (10 frame mixins incl. 3 overwrite/redirect, 59 shader files, post effects). **V** (dependency scan) | Removing one food addon drops a whole rendering library |
| **Fowlplay** | Open 1.21.1 issue: hundreds of birds; per-tick flight pathfinding (server) | Remove if spawn caps don't hold |
| **Charta** | 31 shader files registered at load; niche use | Only if nobody plays cards (both sides) |
| **WATUT** | Streams other players' GUI state each tick; open TF conflict | Flavour only |
| **Emojiful** | Font-render hooks; known chat freezes upstream | Low impact; social call |
| **Fresh Animations Extensions** | Extra CEM models on top of FA | Keep opt-in, recommend against on P0 |
| **AmbientSounds** | Largest jar (85 MB of ogg); RAM residency unmeasured | Measure heap first |
**Not removable, contrary to r4's suggestion**: one of Fusion/Athena. Chipped *requires*
Athena and Rechiseled *requires* Fusion (**V**, `neoforge.mods.toml` dependencies).
---
## 6. Phase 2 — test order
**Superseded by [`BENCH-MATRIX.md`](BENCH-MATRIX.md)**: world, scenes, config IDs, blocks
B0–B13 with decision rules.
## 7. Corrections to subagent research (verified by the orchestrator)
Added in Phase 1b (2026-10-14):
- **DH default threads is 4 on the fleet, not 2.** The default is `ceil(nproc × 0.5)`
(`ThreadPresetConfigEventHandler` @ 3.3.2). The observed `numberOfThreads = 2` came from
the owner's 4-thread machine (`nproc` = 4). Every other observed DH value matches the
source defaults.
- **Puzzles Lib 21.1.64 has no perf change on NeoForge** (see lever 14). r9's lead and this
file's earlier "the fix *is* in 21.1.64 for 1.21.1" were wrong for our loader.
- **r6's Shenandoah flags crash JDK 21.** `-XX:ShenandoahGCMode=iu` needs
`-XX:+UnlockExperimentalVMOptions` (tested on OpenJDK 21.0.12). Use plain
`-XX:+UseShenandoahGC`.
- **SSRD's distance is a COMMON config** (`config/ssrd-common.toml`,
`physicsRenderDistance`, default 128, slider floor 16), and the server reads it too. It
is not stored in Sodium's options.
- r4 "remove one CTM engine": wrong. Both are hard dependencies (see §5).
- r9 "Puzzles Lib ~8 % render-thread overhead": the measurement was on MC 26.2/Fabric. The
fix *is* in 21.1.64 for 1.21.1; the size of the gain there is unknown.
- r3/r8 cite EMF #443 for magnitude. That report is from the Oculus/Forge era and is closed.
Treat the 4× figure as directional only.
- Static scan's "Sable overrides vanilla core shaders" (r7 checked it): real but small, just `worldborder.*` from the nested Veil. The substantive part is Sable's runtime patching of Flywheel's internal shaders.
- r1's Flywheel-under-shaders claim was checked in `Backends.java` on the 1.21.1 branch:
confirmed.
+134
View File
@@ -0,0 +1,134 @@
# Onion MC: performance settings for players
These are things the pack can't set for you, plus the settings to change for your machine.
Values marked *(provisional)* are waiting on Phase 2 benchmarks and may change.
## 1. Which tier are you?
| Tier | Typical machine | Examples |
| --- | --- | --- |
| **Deck** | handheld or integrated graphics, shared RAM | Steam Deck, laptop iGPU |
| **Mid** (pack default) | 4–6 core CPU, ~6 GB VRAM graphics card | GTX 1060 6 GB, RX 580 |
| **High** | 8 GB+ VRAM card | GTX 1080 Ti, RTX 3060+ |
The pack's defaults are the **mid** tier. They're applied only when the config file doesn't
exist yet. **If you played before the defaults shipped**, close the game and delete these
files from the instance folder to pick them up on the next launch. This resets those mods'
settings.
```
config/DistantHorizons.toml
config/sodium-options.json
config/entity_model_features.json
config/flywheel-client.toml
config/lambdynlights.toml
config/ssrd-common.toml
config/sound_physics_remastered/soundphysics.properties
```
Don't delete `options.txt`: that resets all your video, audio and control settings,
keybinds included. Set the video values in the table below by hand instead.
Then change these for your tier *(provisional)*:
| Setting | Where | Deck | Mid | High |
| --- | --- | --- | --- | --- |
| LOD render distance | Options → Distant Horizons button | 64 | 128 | 128 (192–256 if you have ≥16 GB free RAM and 6+ cores) |
| DH ambient occlusion (SSAO) | DH → Advanced → Graphics | off | off | on |
| DH quality preset | DH quick options | Low | Medium | Medium |
| Biome blend | Video Settings | off | 3×3 | 5×5 |
| Mipmap levels | Video Settings | 2 | 2 | 4 |
| Particles / entity shadows | Video Settings | Decreased / off | All / on | All / on |
| Leaves & weather quality | Sodium → Quality | Fast | Default | Default |
| Sub-level (airship) render distance | Sodium video settings slider | 16 | 16 | 32 |
| Dynamic lights | LambDynamicLights settings | Fastest, entities off | Fast | Fast, entities off |
Leave **render distance at 8**. The server sends 8 chunks, so anything higher loads nothing
extra in multiplayer. Distant Horizons draws everything beyond that.
## 2. Java memory and garbage collector (Prism → Edit Instance → Settings → Java)
Use **Java 21** (Temurin 21 recommended). More memory is *not* faster: a bigger heap makes
each GC pause longer.
| Your machine | Max memory (`-Xmx`) | Min memory |
| --- | --- | --- |
| Steam Deck (16 GB shared with the GPU) | **5 GB**, never above 6 | leave low (512 MB) |
| 16 GB PC | **6 GB** | leave low |
| 32 GB PC | **6–8 GB** | may equal max |
| PC with little free RAM (other apps/containers running) | min(6 GB, free RAM − 2 GB) | leave low |
**JVM arguments** *(provisional; Phase 2 block B4 picks the winner)*. Paste one line into
*Java arguments* (Prism adds `-Xmx` itself from the memory box):
- **Default (all machines):** client-tuned G1
```
-XX:+UseG1GC -XX:MaxGCPauseMillis=37 -XX:G1HeapRegionSize=16M -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=23 -XX:G1ReservePercent=20 -XX:G1MixedGCCountTarget=3 -XX:G1HeapWastePercent=20 -XX:InitiatingHeapOccupancyPercent=10 -XX:G1RSetUpdatingPauseTimePercent=0 -XX:MaxTenuringThreshold=1 -XX:GCTimeRatio=99 -XX:+DisableExplicitGC -XX:+PerfDisableSharedMem
```
- **32 GB machines, if you still get stutter:** Generational ZGC. Distant Horizons
recommends it in its log warning about G1.
```
-XX:+UseZGC -XX:+ZGenerational -XX:+DisableExplicitGC -XX:+PerfDisableSharedMem
```
`-XX:+ZGenerational` is required: on Java 21, `-XX:+UseZGC` alone selects the older
non-generational ZGC. Avoid ZGC on the Deck or on low-RAM PCs. It needs spare memory and
CPU those machines don't have.
Don't add `-XX:+AlwaysPreTouch` on the Deck or on low-RAM PCs. Don't copy
`-XX:ShenandoahGCMode=iu` from older guides: Java 21 refuses to start with it.
## 3. Shaders
*Pending the owner's shader policy. Interim advice:* **shaders off** is the pack default.
They cost more in this pack than usual:
- With any shaderpack on, **Create's GPU renderer (Flywheel) switches off**, so every
rotating shaft and machine is drawn the slow way, and drawn again for shadows.
- Shader **shadows corrupt airships** (Sable sub-levels; Iris issue #3164).
- Distant Horizons adds a shadow pass over all its terrain.
If you want shaders anyway:
| Tier | Pack | Profile (shader settings screen) |
| --- | --- | --- |
| Deck | MakeUp – Ultra Fast | `shadowless_low` or `shadowless_medium`. These have no shadows, so no airship corruption. |
| Mid | MakeUp – Ultra Fast | `shadowless_medium`, or `low` if you accept shadow artefacts on airships |
| High | Complementary Reimagined | `LOW` or `MEDIUM` (MEDIUM = 8-chunk shadows). Avoid `HIGH` and above near Create builds. |
## 4. Resource packs
The pack downloads these but doesn't enable them:
- **Fresh Animations** (+ **FA: Extensions**): re-models and animates every vanilla mob. It's
the most expensive optional visual in the pack, especially with shaders and near villages
or farms. **Deck: don't use it.** Mid: Fresh Animations alone is OK, but skip Extensions.
High: fine.
- **Better Leaves**: much denser leaves. The pack has no leaf-culling mod for it yet, so
**avoid it on Deck and mid** until one is added.
## 5. Steam Deck
- Run Prism in **Desktop Mode** (flatpak from prismlauncher.org).
- Prism → Edit Instance → Settings → **Environment variables**: `mesa_glthread=true`.
Minecraft uses Mesa's OpenGL driver (radeonsi), and glthread helps the Deck's CPU-bound
draw path.
- Prism → Custom Commands → **Wrapper command**: `gamemoderun` (the flatpak reaches GameMode
through the desktop portal).
- Native 1280×800. Cap FPS at the panel rate (60 LCD / 90 OLED) **after** tuning.
Uncapped only matters for benchmarks.
## 6. Other platforms
- **Windows + NVIDIA**: NVIDIA Control Panel → Manage 3D settings → Program settings → your
Java `javaw.exe` → *Power management mode: Prefer maximum performance*. Leave *Threaded
optimization* alone: the driver ignores it for Minecraft, and Sodium handles it.
- **Linux + NVIDIA**: use the proprietary driver, not nouveau. Sodium already sets
`__GL_THREADED_OPTIMIZATIONS=0`, so you don't need to.
## 7. Still slow? Change these first
1. Turn shaders off.
2. Lower the Distant Horizons LOD distance (biggest always-on cost).
3. Disable Fresh Animations.
4. Lower the airship render distance (Sodium video settings).
5. Lower biome blend (helps stutter while flying, not steady FPS).
+53
View File
@@ -0,0 +1,53 @@
# Client performance analysis — Phase 1 (static baseline)
Goal: map the **client-side optimisation surface** of Onion MC (212 mods, MC 1.21.1 /
NeoForge 21.1.251) and rank the levers *before* benchmarking. Nothing here has been
measured on a client yet; Phase 2 benchmarks it (see `../../phase0/` for the fleet harness).
**Start with [`LEVERS.md`](LEVERS.md)**: the prioritised lever list, plus add and remove
candidates.
## Layout
| Path | What |
| --- | --- |
| `LEVERS.md` | Synthesis: ranked levers, per-machine expectations, add/remove candidates, corrections |
| `proposed-configs/` | **Phase 1b**: staged tuned configs (tiers + bench variants, generated by `build.py`) and the delivery-mechanism decision (README §1) |
| `BENCH-MATRIX.md` | **Phase 1b**: the Phase 2 run sheet (world, scenes S1–S6, config IDs, blocks B0–B13, decision rules) |
| `bench/onion-bench/` | Datapack for the bench world: scene teleports, `/fill` setups, sound storm, 120 s tour |
| `SPAWN-TUNING.md` | Shipped server spawn tuning (Alex's Mobs, Fowl Play, Critters): evidence and the B14 measurement plan |
| `PLAYER-TUNING.md` | **Phase 1b**: player guide (tiers, JVM/heap, shaders, resource packs, Deck) |
| `data/jarscan-report.md` | Static scan of every pinned jar: per-frame mixins, per-frame event hooks, atlas/model/shader/sound payloads, entity counts |
| `data/jarscan.json` | Raw scan output (re-generate, don't hand-edit) |
| `data/observed-default-configs/` | Generated defaults from the last real client launch (2026-09-24, older 110-mod pack). Use these to see actual default values |
| `research/r1-render-core.md` | Sodium / Iris + shaderpacks / Flywheel / ModernFix / ImmediatelyFast / EntityCulling / mipmaps |
| `research/r2-dh-xaero.md` | Distant Horizons 3.3.2 client + Xaero's minimap / world map |
| `research/r3-entity-animation.md` | EMF/ETF + Fresh Animations, GeckoLib, player animation mods, LambDynamicLights |
| `research/r4-effects-audio-hud.md` | Sound Physics, AmbientSounds, Subtle Effects, Perception, WATUT, TF / Alex's Caves visuals, HUD mods |
| `research/r5-candidate-mods.md` | Perf mods *not* in the pack (availability on NeoForge 1.21.1, compat, verdict) |
| `research/r6-jvm-platform.md` | GC / heap / JVM, Mesa / NVIDIA driver, Steam Deck platform levers |
| `research/r7-sable-create-client.md` | Sable / Aeronautics / SSRD / Create + Flywheel client cost |
| `research/r8-sweep-content-mobs.md` | Known-issue sweep: mob and content mods |
| `research/r9-sweep-libs-ui-misc.md` | Known-issue sweep: libraries, UI, misc client hooks |
| `scripts/jarscan.py`, `scripts/report.py` | The scanner |
| `scripts/jx.py` | Jar inspection without unzip/java: `ls`, `cat`, `str` (class-file string constants); nested jars as `outer.jar!inner.jar` |
Re-run the scan after the mod set changes:
```sh
# jars: download every mods/*.pw.toml url into a dir (analysis/audit/fetch.py does this)
python3 scripts/jarscan.py /tmp/onion/jars ../.. data/jarscan.json
python3 scripts/report.py data/jarscan.json data/jarscan-report.md
```
## Method and confidence
- **Static scan.** The scanner parses class-file annotations to get real `@Mixin` targets and
injector kinds. It reads constant pools for event-type references and PNG headers for
texture sizes, and it skips the Fabric-only payloads of multi-loader jars. The numbers are
*surface*, not cost: a mixin on `LevelRenderer` may be a one-line early-return.
- **Research.** Nine subagent briefs (deepseek-v4.1-flash / glm-5.3-flash) are tagged
VERIFIED / DOCUMENTED / COMMUNITY / INFERENCE with URLs. Load-bearing claims were
spot-checked by the orchestrator. Corrections are listed in `LEVERS.md` §7.
- **Observed defaults.** These come from the old Prism instance's generated configs. They
are the authoritative "what a player gets today" values for the mods that existed then.
+63
View File
@@ -0,0 +1,63 @@
# Spawn tuning (server-side lever 3)
**Owner brief (2026-10-14):** tune spawns, but not in a way that hurts gameplay much. All
three files ship **enforced** from `config/` (this repo is the server directory, and clients
get them too, which only matters in singleplayer). Each file is **partial**: the mod fills
every other key with its default. Research came from three subagent briefs (2026-10-14);
every load-bearing fact below was re-checked against the pinned jar or the source at the
matching version. **Unmeasured:** bench block B14 (below) checks it.
## What shipped
### Alex's Mobs 1.22.17: `config/alexsmobs-common.toml`
- Format: NeoForge `ModConfigSpec` **COMMON** (`AlexsMobs.class`: `registerConfig(COMMON, …)`;
no custom filename). Keys are flat under `[spawning]` (`CommonConfig`: `push("spawning")`;
`buildInt` ignores its category argument). A partial file gets corrected and re-saved by
NeoForge.
- Changed (weight, 0–1000; group sizes are hard-coded in `AMWorldRegistry`): gazelle 40→20
(herds of 7), capuchinMonkey 28→14 (groups of 9–16), elephant 30→15, straddler 70→35,
rockyRoller 60→30, underminer 50→25, blobfish 30→15, mudskipper 28→14, caiman 29→15.
Everything rare is untouched.
- Issue #62 on Raguto/AlexsMobs-1.21.1 ("tons of monsters" / inflated *vanilla* spawns) is
open, unexplained, and no config addresses it. If it shows up, A/B test a world without
Alex's Mobs.
### Fowl Play 1.2.3: `config/fowlplay.json5`
- Format: YACL v3 JSON5 (`YACLIntegration`: `fowlplay.json5`). YACL 3.8.2
(`GsonConfigSerializer.loadSafely`) keeps defaults for missing fields and re-saves; a bad
value is logged and left at its default, not a crash.
- Changed (default → new): duck weight 4→2, max group 6→4 · goose 4→2, 4→3 · gull 5→3, 8→5 ·
sparrow 20→12, 6→4. Songbirds and raptors are untouched.
- Context: #214 (~400 ducks on rivers) is open. 1.2.1 added a 200-tick spawn gate. The
category caps (`fowlplay_birds` 20, `fowlplay_ambient_birds` 15) scale with loaded chunks
like vanilla, and only became configurable *after* 1.2.3. If counts are still high, the
next lever is a Paxi datapack that narrows `#fowlplay:spawns_ducks` (currently includes
forest tags), added through `analysis/audit/gen_fixes.py`.
### Critters and Companions 2.7.0: `config/crittersandcompanions-common.json5`
- It *does* have a spawn config (contrary to LEVERS' "no config"): YACL JSON5, nested
`spawning` object, one `List<SpawnEntry>` per mob. `SpawnEntry` is a record
`{biomeSpec, weight, min, max}` with no custom type adapter, so it serialises as plain Gson
record JSON. The jar has no biome-modifier JSON, so a datapack *cannot* reduce these spawns.
- A listed mob's list **replaces** its defaults, so each changed mob lists all its default
biomes. `"configVersion": 2` is required, otherwise the v1→v2 migration runs.
- Changed: sea bunny (the worst: warm ocean 32 × groups ≤4 → 20 × ≤3; other oceans 16 → 10,
max 4 → 3), leaf insect jungle 14→8 / forest 6→4, dragonfly lush 10→6, and the
ladybug / stag beetle / roly poly / snail / stick bug / weevil rules about −40 %. Unchanged:
jumping spider, red panda, ferret, dumbo octopus, otter, koi, shima enaga.
## Verify on first boot (part of BENCH-MATRIX §0)
- `latest.log` has no YACL "Failed to deserialize" lines for `fowlplay` or `crittersandcompanions`.
- After the first launch, each file has been re-saved in full with our values intact.
(In the repo working tree that shows up as a diff: **don't commit the expanded files**
unless you mean to.)
## B14: measure it (P2, singleplayer, Creative, `doMobSpawning true`)
Fresh world `onionspawn`, at a river/forest edge (ducks), a jungle (capuchins, leaf
insects) and a warm ocean (sea bunnies). Stand still 10 minutes at each, then count with
`/execute if entity @e[type=<id>,distance=..128]` for `fowlplay:duck`, `fowlplay:gull`,
`alexsmobs:capuchin_monkey`, `crittersandcompanions:sea_bunny`, and in total
(`@e[type=!player,distance=..128]`). Compare against the same world with these three
config files removed (defaults). **Keep the tuning** if totals drop and every species still
appears; **back it off** if a species effectively disappears. Spot-check that vanilla
passives (cows, sheep) still spawn normally.
@@ -0,0 +1 @@
tp @a 0 200 0 0 20
@@ -0,0 +1 @@
tp @a 1023 165 -10 0 40
@@ -0,0 +1,98 @@
# Create floor: 2304 kinetic block entities. Verify they rotate (see BENCH-MATRIX.md).
fill 998 150 -1 1048 150 48 minecraft:smooth_stone
fill 1000 151 0 1047 151 0 create:shaft[axis=x]
setblock 999 151 0 create:creative_motor[facing=east]
fill 1000 151 1 1047 151 1 create:cogwheel[axis=x]
setblock 999 151 1 create:creative_motor[facing=east]
fill 1000 151 2 1047 151 2 create:shaft[axis=x]
setblock 999 151 2 create:creative_motor[facing=east]
fill 1000 151 3 1047 151 3 create:cogwheel[axis=x]
setblock 999 151 3 create:creative_motor[facing=east]
fill 1000 151 4 1047 151 4 create:shaft[axis=x]
setblock 999 151 4 create:creative_motor[facing=east]
fill 1000 151 5 1047 151 5 create:cogwheel[axis=x]
setblock 999 151 5 create:creative_motor[facing=east]
fill 1000 151 6 1047 151 6 create:shaft[axis=x]
setblock 999 151 6 create:creative_motor[facing=east]
fill 1000 151 7 1047 151 7 create:cogwheel[axis=x]
setblock 999 151 7 create:creative_motor[facing=east]
fill 1000 151 8 1047 151 8 create:shaft[axis=x]
setblock 999 151 8 create:creative_motor[facing=east]
fill 1000 151 9 1047 151 9 create:cogwheel[axis=x]
setblock 999 151 9 create:creative_motor[facing=east]
fill 1000 151 10 1047 151 10 create:shaft[axis=x]
setblock 999 151 10 create:creative_motor[facing=east]
fill 1000 151 11 1047 151 11 create:cogwheel[axis=x]
setblock 999 151 11 create:creative_motor[facing=east]
fill 1000 151 12 1047 151 12 create:shaft[axis=x]
setblock 999 151 12 create:creative_motor[facing=east]
fill 1000 151 13 1047 151 13 create:cogwheel[axis=x]
setblock 999 151 13 create:creative_motor[facing=east]
fill 1000 151 14 1047 151 14 create:shaft[axis=x]
setblock 999 151 14 create:creative_motor[facing=east]
fill 1000 151 15 1047 151 15 create:cogwheel[axis=x]
setblock 999 151 15 create:creative_motor[facing=east]
fill 1000 151 16 1047 151 16 create:shaft[axis=x]
setblock 999 151 16 create:creative_motor[facing=east]
fill 1000 151 17 1047 151 17 create:cogwheel[axis=x]
setblock 999 151 17 create:creative_motor[facing=east]
fill 1000 151 18 1047 151 18 create:shaft[axis=x]
setblock 999 151 18 create:creative_motor[facing=east]
fill 1000 151 19 1047 151 19 create:cogwheel[axis=x]
setblock 999 151 19 create:creative_motor[facing=east]
fill 1000 151 20 1047 151 20 create:shaft[axis=x]
setblock 999 151 20 create:creative_motor[facing=east]
fill 1000 151 21 1047 151 21 create:cogwheel[axis=x]
setblock 999 151 21 create:creative_motor[facing=east]
fill 1000 151 22 1047 151 22 create:shaft[axis=x]
setblock 999 151 22 create:creative_motor[facing=east]
fill 1000 151 23 1047 151 23 create:cogwheel[axis=x]
setblock 999 151 23 create:creative_motor[facing=east]
fill 1000 151 24 1047 151 24 create:shaft[axis=x]
setblock 999 151 24 create:creative_motor[facing=east]
fill 1000 151 25 1047 151 25 create:cogwheel[axis=x]
setblock 999 151 25 create:creative_motor[facing=east]
fill 1000 151 26 1047 151 26 create:shaft[axis=x]
setblock 999 151 26 create:creative_motor[facing=east]
fill 1000 151 27 1047 151 27 create:cogwheel[axis=x]
setblock 999 151 27 create:creative_motor[facing=east]
fill 1000 151 28 1047 151 28 create:shaft[axis=x]
setblock 999 151 28 create:creative_motor[facing=east]
fill 1000 151 29 1047 151 29 create:cogwheel[axis=x]
setblock 999 151 29 create:creative_motor[facing=east]
fill 1000 151 30 1047 151 30 create:shaft[axis=x]
setblock 999 151 30 create:creative_motor[facing=east]
fill 1000 151 31 1047 151 31 create:cogwheel[axis=x]
setblock 999 151 31 create:creative_motor[facing=east]
fill 1000 151 32 1047 151 32 create:shaft[axis=x]
setblock 999 151 32 create:creative_motor[facing=east]
fill 1000 151 33 1047 151 33 create:cogwheel[axis=x]
setblock 999 151 33 create:creative_motor[facing=east]
fill 1000 151 34 1047 151 34 create:shaft[axis=x]
setblock 999 151 34 create:creative_motor[facing=east]
fill 1000 151 35 1047 151 35 create:cogwheel[axis=x]
setblock 999 151 35 create:creative_motor[facing=east]
fill 1000 151 36 1047 151 36 create:shaft[axis=x]
setblock 999 151 36 create:creative_motor[facing=east]
fill 1000 151 37 1047 151 37 create:cogwheel[axis=x]
setblock 999 151 37 create:creative_motor[facing=east]
fill 1000 151 38 1047 151 38 create:shaft[axis=x]
setblock 999 151 38 create:creative_motor[facing=east]
fill 1000 151 39 1047 151 39 create:cogwheel[axis=x]
setblock 999 151 39 create:creative_motor[facing=east]
fill 1000 151 40 1047 151 40 create:shaft[axis=x]
setblock 999 151 40 create:creative_motor[facing=east]
fill 1000 151 41 1047 151 41 create:cogwheel[axis=x]
setblock 999 151 41 create:creative_motor[facing=east]
fill 1000 151 42 1047 151 42 create:shaft[axis=x]
setblock 999 151 42 create:creative_motor[facing=east]
fill 1000 151 43 1047 151 43 create:cogwheel[axis=x]
setblock 999 151 43 create:creative_motor[facing=east]
fill 1000 151 44 1047 151 44 create:shaft[axis=x]
setblock 999 151 44 create:creative_motor[facing=east]
fill 1000 151 45 1047 151 45 create:cogwheel[axis=x]
setblock 999 151 45 create:creative_motor[facing=east]
fill 1000 151 46 1047 151 46 create:shaft[axis=x]
setblock 999 151 46 create:creative_motor[facing=east]
fill 1000 151 47 1047 151 47 create:cogwheel[axis=x]
setblock 999 151 47 create:creative_motor[facing=east]
@@ -0,0 +1 @@
tp @a 2011 158 -6 0 35
@@ -0,0 +1,84 @@
# Mob pen: 30 villagers, 15 cows, 15 sheep, 10 torch-carrying allays, 10 dropped torches.
fill 1999 150 -1 2024 157 24 minecraft:glass hollow
fill 2000 150 0 2023 150 23 minecraft:grass_block
kill @e[type=!player,x=1990,y=140,z=-10,dx=45,dy=30,dz=45]
summon minecraft:villager 2002 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2004 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2006 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2008 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2010 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2012 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2014 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2016 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2018 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2020 151 2 {PersistenceRequired:1b}
summon minecraft:villager 2002 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2004 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2006 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2008 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2010 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2012 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2014 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2016 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2018 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2020 151 5 {PersistenceRequired:1b}
summon minecraft:villager 2002 151 8 {PersistenceRequired:1b}
summon minecraft:villager 2004 151 8 {PersistenceRequired:1b}
summon minecraft:villager 2006 151 8 {PersistenceRequired:1b}
summon minecraft:villager 2008 151 8 {PersistenceRequired:1b}
summon minecraft:villager 2010 151 8 {PersistenceRequired:1b}
summon minecraft:villager 2012 151 8 {PersistenceRequired:1b}
summon minecraft:villager 2014 151 8 {PersistenceRequired:1b}
summon minecraft:villager 2016 151 8 {PersistenceRequired:1b}
summon minecraft:villager 2018 151 8 {PersistenceRequired:1b}
summon minecraft:villager 2020 151 8 {PersistenceRequired:1b}
summon minecraft:cow 2002 151 12 {PersistenceRequired:1b}
summon minecraft:cow 2006 151 12 {PersistenceRequired:1b}
summon minecraft:cow 2010 151 12 {PersistenceRequired:1b}
summon minecraft:cow 2014 151 12 {PersistenceRequired:1b}
summon minecraft:cow 2018 151 12 {PersistenceRequired:1b}
summon minecraft:cow 2002 151 15 {PersistenceRequired:1b}
summon minecraft:cow 2006 151 15 {PersistenceRequired:1b}
summon minecraft:cow 2010 151 15 {PersistenceRequired:1b}
summon minecraft:cow 2014 151 15 {PersistenceRequired:1b}
summon minecraft:cow 2018 151 15 {PersistenceRequired:1b}
summon minecraft:cow 2002 151 18 {PersistenceRequired:1b}
summon minecraft:cow 2006 151 18 {PersistenceRequired:1b}
summon minecraft:cow 2010 151 18 {PersistenceRequired:1b}
summon minecraft:cow 2014 151 18 {PersistenceRequired:1b}
summon minecraft:cow 2018 151 18 {PersistenceRequired:1b}
summon minecraft:sheep 2003 151 13 {PersistenceRequired:1b}
summon minecraft:sheep 2007 151 13 {PersistenceRequired:1b}
summon minecraft:sheep 2011 151 13 {PersistenceRequired:1b}
summon minecraft:sheep 2015 151 13 {PersistenceRequired:1b}
summon minecraft:sheep 2019 151 13 {PersistenceRequired:1b}
summon minecraft:sheep 2003 151 16 {PersistenceRequired:1b}
summon minecraft:sheep 2007 151 16 {PersistenceRequired:1b}
summon minecraft:sheep 2011 151 16 {PersistenceRequired:1b}
summon minecraft:sheep 2015 151 16 {PersistenceRequired:1b}
summon minecraft:sheep 2019 151 16 {PersistenceRequired:1b}
summon minecraft:sheep 2003 151 19 {PersistenceRequired:1b}
summon minecraft:sheep 2007 151 19 {PersistenceRequired:1b}
summon minecraft:sheep 2011 151 19 {PersistenceRequired:1b}
summon minecraft:sheep 2015 151 19 {PersistenceRequired:1b}
summon minecraft:sheep 2019 151 19 {PersistenceRequired:1b}
summon minecraft:allay 2002 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:allay 2004 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:allay 2006 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:allay 2008 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:allay 2010 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:allay 2012 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:allay 2014 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:allay 2016 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:allay 2018 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:allay 2020 154 20 {PersistenceRequired:1b,HandItems:[{id:"minecraft:torch",count:1},{}]}
summon minecraft:item 2002 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
summon minecraft:item 2004 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
summon minecraft:item 2006 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
summon minecraft:item 2008 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
summon minecraft:item 2010 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
summon minecraft:item 2012 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
summon minecraft:item 2014 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
summon minecraft:item 2016 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
summon minecraft:item 2018 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
summon minecraft:item 2020 151 22 {Age:-32768s,PickupDelay:32767s,Item:{id:"minecraft:torch",count:1}}
@@ -0,0 +1 @@
tp @a 3000 172 -10 0 5
@@ -0,0 +1,12 @@
# Run once after creating the bench world (creative, cheats on).
gamerule doDaylightCycle false
gamerule doWeatherCycle false
gamerule doMobSpawning false
gamerule doPatrolSpawning false
gamerule doTraderSpawning false
gamerule doInsomnia false
gamerule doFireTick false
gamerule announceAdvancements false
time set 6000
weather clear
difficulty normal
@@ -0,0 +1 @@
schedule clear bench:storm_tick
@@ -0,0 +1 @@
function bench:storm_tick
@@ -0,0 +1,26 @@
# Called every tick while the storm runs. Stop with bench:storm_off.
playsound create:mechanical_press_activation block @a 1004 151 4 1 1
playsound create:mechanical_press_activation block @a 1020 151 4 1 1
playsound create:mechanical_press_activation block @a 1036 151 4 1 1
playsound create:mechanical_press_activation block @a 1044 151 20 1 1
playsound create:mechanical_press_activation block @a 1004 151 28 1 1
playsound create:mechanical_press_activation block @a 1020 151 44 1 1
playsound create:mechanical_press_activation block @a 1036 151 36 1 1
playsound create:mechanical_press_activation block @a 1044 151 44 1 1
playsound create:cogs block @a 1004 151 4 1 1
playsound create:cogs block @a 1020 151 4 1 1
playsound create:cogs block @a 1036 151 4 1 1
playsound create:cogs block @a 1044 151 20 1 1
playsound create:cogs block @a 1004 151 28 1 1
playsound create:cogs block @a 1020 151 44 1 1
playsound create:cogs block @a 1036 151 36 1 1
playsound create:cogs block @a 1044 151 44 1 1
playsound create:mixing block @a 1004 151 4 1 1
playsound create:mixing block @a 1020 151 4 1 1
playsound create:mixing block @a 1036 151 4 1 1
playsound create:mixing block @a 1044 151 20 1 1
playsound create:mixing block @a 1004 151 28 1 1
playsound create:mixing block @a 1020 151 44 1 1
playsound create:mixing block @a 1036 151 36 1 1
playsound create:mixing block @a 1044 151 44 1 1
schedule function bench:storm_tick 1t
@@ -0,0 +1,2 @@
tp @a 0 180 0 -90 15
schedule function bench:tour/step1 100t
@@ -0,0 +1,2 @@
tp @a 160 180 0 -90 15
schedule function bench:tour/step2 100t
@@ -0,0 +1,2 @@
tp @a 1600 180 0 -90 15
schedule function bench:tour/step11 100t
@@ -0,0 +1,2 @@
tp @a 1760 180 0 -90 15
schedule function bench:tour/step12 100t
@@ -0,0 +1,2 @@
tp @a 1920 180 0 -90 15
schedule function bench:tour/step13 100t
@@ -0,0 +1,2 @@
tp @a 2080 180 0 -90 15
schedule function bench:tour/step14 100t
@@ -0,0 +1,2 @@
tp @a 2240 180 0 -90 15
schedule function bench:tour/step15 100t
@@ -0,0 +1,2 @@
tp @a 2400 180 0 -90 15
schedule function bench:tour/step16 100t
@@ -0,0 +1,2 @@
tp @a 2560 180 0 -90 15
schedule function bench:tour/step17 100t
@@ -0,0 +1,2 @@
tp @a 2720 180 0 -90 15
schedule function bench:tour/step18 100t
@@ -0,0 +1,2 @@
tp @a 2880 180 0 -90 15
schedule function bench:tour/step19 100t
@@ -0,0 +1,2 @@
tp @a 3040 180 0 -90 15
schedule function bench:tour/step20 100t
@@ -0,0 +1,2 @@
tp @a 320 180 0 -90 15
schedule function bench:tour/step3 100t
@@ -0,0 +1,2 @@
tp @a 3200 180 0 -90 15
schedule function bench:tour/step21 100t
@@ -0,0 +1,2 @@
tp @a 3360 180 0 -90 15
schedule function bench:tour/step22 100t
@@ -0,0 +1,2 @@
tp @a 3520 180 0 -90 15
schedule function bench:tour/step23 100t
@@ -0,0 +1,2 @@
tp @a 3680 180 0 -90 15
tellraw @a {"text":"bench tour done"}
@@ -0,0 +1,2 @@
tp @a 480 180 0 -90 15
schedule function bench:tour/step4 100t
@@ -0,0 +1,2 @@
tp @a 640 180 0 -90 15
schedule function bench:tour/step5 100t
@@ -0,0 +1,2 @@
tp @a 800 180 0 -90 15
schedule function bench:tour/step6 100t
@@ -0,0 +1,2 @@
tp @a 960 180 0 -90 15
schedule function bench:tour/step7 100t
@@ -0,0 +1,2 @@
tp @a 1120 180 0 -90 15
schedule function bench:tour/step8 100t
@@ -0,0 +1,2 @@
tp @a 1280 180 0 -90 15
schedule function bench:tour/step9 100t
@@ -0,0 +1,2 @@
tp @a 1440 180 0 -90 15
schedule function bench:tour/step10 100t
@@ -0,0 +1 @@
function bench:tour/step0
@@ -0,0 +1,23 @@
schedule clear bench:tour/step1
schedule clear bench:tour/step2
schedule clear bench:tour/step3
schedule clear bench:tour/step4
schedule clear bench:tour/step5
schedule clear bench:tour/step6
schedule clear bench:tour/step7
schedule clear bench:tour/step8
schedule clear bench:tour/step9
schedule clear bench:tour/step10
schedule clear bench:tour/step11
schedule clear bench:tour/step12
schedule clear bench:tour/step13
schedule clear bench:tour/step14
schedule clear bench:tour/step15
schedule clear bench:tour/step16
schedule clear bench:tour/step17
schedule clear bench:tour/step18
schedule clear bench:tour/step19
schedule clear bench:tour/step20
schedule clear bench:tour/step21
schedule clear bench:tour/step22
schedule clear bench:tour/step23
@@ -0,0 +1 @@
{"pack": {"pack_format": 48, "description": "Onion MC client-perf bench scenes (Phase 2)"}}
+312
View File
@@ -0,0 +1,312 @@
# Static client-perf surface scan
Generated by `scripts/jarscan.py` + `scripts/report.py` from the exact jars pinned in `mods/*.pw.toml`.
All numbers are static (what the jar *contains*), not runtime cost. They tell us where cost *can* come from.
- **frame mixins** = mixin classes whose `@Mixin` target is on a per-frame path (LevelRenderer, GameRenderer, entity/item/block-entity renderers, Gui, ParticleEngine, blaze3d, Sodium, Iris, Camera).
- **risky** = `@Overwrite`/`@Redirect` injectors inside those frame mixins (replace vanilla logic; most likely to conflict with Sodium/Iris/ModernFix).
- **frame events** = NeoForge/Architectury/Fabric per-frame event types referenced by the mod’s classes.
- **atlas sprites** = block+item textures in 16×16-sprite equivalents (what lands in `blocks.png-atlas`, mipmapped, in VRAM).
## Pack totals (client-loaded mods)
| metric | value |
| --- | --- |
| client-loaded mods | 209 (server-only: 3) |
| mixin classes (client-loaded) | 3883 |
| frame-path mixin classes | 951 |
| frame-path @Overwrite/@Redirect | 121 |
| mods hooking ≥1 per-frame event | 58 |
| mods hooking client/player/entity tick events | 79 |
| block+item textures | 25277 files, 15.4 Mpx ≈ 60138 16×16 sprites |
| implied blocks atlas (lower bound, + vanilla) | ≥ 4096×4096 ; ×4 B ×1.33 mip ≈ 85 MiB VRAM at the square size |
| animated block/item textures | 312 |
| entity textures | 37.7 Mpx |
| models / blockstates | 69442 / 16361 |
| entity types (lang proxy) | 603 |
| blocks / items (lang proxy) | 15422 / 5178 |
| geckolib geo+animation files | 264 |
| vanilla core-shader overrides | sable, sodium, xaeros-minimap, xaeros-world-map |
| post-effect files | alexs-caves-(unofficial-port)(7), charta(1), citadel-(1.21.1-port)(1), exposure(19), lodestonelib(2), playerrevive(1), shatterbyte-lib(1) |
## Per-frame mixin surface
| mod | side | frame mixins | risky | all mixins | hottest targets |
| --- | --- | ---: | ---: | ---: | --- |
| sable | both | 127 | 29 | 496 | LevelRenderer×23, GameRenderer×12, Camera×5, RenderTarget×4, EntityRenderDispatcher×3, EntityRenderer×3 |
| iris | client | 114 | 28 | 171 | LevelRenderer×11, GlStateManager×7, GameRenderer×4, RenderType×4, BufferBuilder×3, DebugScreenOverlay×3 |
| controlify | client | 84 | 0 | 143 | AbstractSelectionList×4, AbstractContainerScreen×3, AbstractWidget×3, CreativeModeInventoryScreen×3, Gui×3, Screen×3 |
| sodium | client | 48 | 28 | 111 | LevelRenderer×5, ItemRenderer×3, BufferBuilder×2, DebugScreenOverlay×2, RenderChunkRegion×2, RenderSystem×2 |
| entity-model-features | client | 42 | 0 | 64 | CustomHeadLayer×2, EntityModelSet×2, GameRenderer×2, ModelPart$Cube×2, ParrotOnShoulderLayer×2, ArrowRenderer×1 |
| create | both | 30 | 0 | 101 | LevelRenderer×6, GameRenderer×2, HumanoidArmorLayer×2, PoseStack×2, RenderSystem×2, Screen×2 |
| entitytexturefeatures | client | 27 | 0 | 60 | BlockEntityRenderDispatcher×1, BufferBuilder×1, ElytraLayer×1, EndCrystalRenderer×1, EnderDragonRenderer×1, EntityRenderDispatcher×1 |
| subtle-effects | both | 26 | 0 | 118 | ParticleEngine×3, GameRenderer×2, BubbleColumnUpParticle×1, BubbleColumnUpParticle$Provider×1, BubbleParticle×1, BubbleParticle$Provider×1 |
| immediatelyfast | client | 25 | 11 | 39 | GameRenderer×3, DebugScreenOverlay×2, GuiGraphics×2, AbstractContainerScreen×1, BufferUploader×1, ChatScreen×1 |
| modernfix | both | 21 | 4 | 156 | CreateWorldScreen×2, ItemRenderer×2, LivingEntityRenderer×2, ConnectScreen×1, CubeDefinition×1, EnderDragonRenderer×1 |
| create-aeronautics | both | 20 | 0 | 134 | LevelRenderer×5, CreativeModeInventoryScreen×2, AbstractContainerScreen×1, CompassItemPropertyFunction×1, CreateWorldScreen×1, CreateWorldScreen$WorldTab×1 |
| emotecraft | both | 18 | 2 | 29 | LivingEntityRenderer×2, ModelPart×2, PlayerModel×2, Camera×1, CapeLayer×1, ElytraLayer×1 |
| playeranimator | both | 16 | 2 | 17 | LivingEntityRenderer×2, PlayerModel×2, Camera×1, CapeLayer×1, ElytraLayer×1, EntityRenderDispatcher×1 |
| adorable-hamster-pets | both | 12 | 0 | 38 | Gui×2, LivingEntityRenderer×2, AbstractContainerScreen×1, BlockEntityRenderDispatcher×1, EntityRenderDispatcher×1, ItemInHandLayer×1 |
| exposure | both | 12 | 1 | 41 | DebugScreenOverlay×2, AnvilScreen×1, Camera×1, GameRenderer×1, Gui×1, HumanoidModel×1 |
| icys-better-horses | both | 12 | 0 | 56 | AbstractContainerScreen×2, HorseModel×2, LivingEntityRenderer×2, AbstractHorseRenderer×1, Camera×1, GameRenderer×1 |
| moonlight | both | 12 | 0 | 82 | AgeableListModel×1, CartographyTableScreen×1, GameRenderer×1, HumanoidModel×1, ItemInHandRenderer×1, Lighting×1 |
| 3dskinlayers | client | 11 | 0 | 23 | CustomHeadLayer×1, Deadmau5EarsLayer×1, GuiGraphics×1, ModelPart×1, NativeImage×1, PlayerModel×1 |
| alexs-caves-(unofficial-port) | both | 11 | 0 | 61 | HumanoidModel×3, Camera×1, GameRenderer×1, HumanoidArmorLayer×1, ItemFrameRenderer×1, LevelRenderer×1 |
| doggy-talents-next | both | 11 | 0 | 17 | Camera×2, CubeDefinition×1, CubeDeformation×1, Gui×1, LayerDefinition×1, LivingEntityRenderer×1 |
| lambdynamiclights | client | 11 | 0 | 42 | LevelRenderer×3, DebugScreenOverlay×1, EntityRenderer×1, GameRenderer×1, Particle×1, ParticleEngine×1 |
| lodestonelib | both | 10 | 3 | 15 | AbstractContainerScreen×1, CreativeModeInventoryScreen×1, EffectProgram×1, GameRenderer×1, Gui×1, GuiGraphics×1 |
| iceberg | both | 9 | 0 | 22 | GuiGraphics×2, HumanoidArmorLayer×2, TooltipRenderUtil×2, ClientTextTooltip×1, Gui×1, Screen×1 |
| shatterbyte-lib | both | 9 | 1 | 11 | GameRenderer×3, AbstractWidget×2, AbstractContainerScreen×1, Gui×1, ParticleEngine×1, Screen×1 |
| ssrd | both | 9 | 1 | 24 | BlockEntityRenderer×1, EntityRenderDispatcher×1, Frustum×1, GameRenderer×1, LevelRenderer×1, RenderSectionManager×1 |
| what-are-they-up-to | both | 9 | 1 | 11 | Screen×2, GameRenderer×1, Gui×1, NativeImage×1, ParticleEngine×1, PlayerModel×1 |
| xaeros-minimap | both | 9 | 0 | 30 | AbstractButton×1, AgeableListModel×1, EnderDragonRenderer$DragonModel×1, HierarchicalModel×1, ListModel×1, LlamaModel×1 |
| entityculling | client | 8 | 0 | 19 | BlockEntityRenderDispatcher×1, BlockEntityRenderer×1, DebugScreenOverlay×1, EntityRenderer×1, GuiGraphics×1, LevelRenderer×1 |
| fusion-connected-textures | client | 8 | 0 | 33 | EntityModelSet×1, EntityRenderDispatcher×1, EntityRenderer×1, EntityRenderers×1, ItemRenderer×1, RenderChunkRegion×1 |
| sound | client | 8 | 0 | 33 | AbstractContainerScreen×1, ChatComponent×1, ChatScreen×1, CreativeModeInventoryScreen×1, CreativeModeInventoryScreen$ItemPickerMenu×1, EditBox×1 |
| ars-nouveau | both | 7 | 1 | 46 | LevelRenderer×2, AbstractSliderButton×1, ChatComponent×1, EntityRenderer×1, GameRenderer×1, Screen×1 |
| chalk-mod | both | 7 | 0 | 16 | ClientTooltipComponent×2, DebugScreenOverlay×2, AbstractContainerScreen×1, EntityRenderer×1, LevelRenderer×1 |
| distanthorizons | both | 7 | 2 | 43 | GlFramebuffer×2, DebugScreenOverlay×1, FogRenderer×1, LevelRenderer×1, LightTexture×1, OptionsScreen×1 |
| fwa | client | 7 | 1 | 12 | BlockRenderer×2, BlockEntityRenderDispatcher×1, LevelRenderer×1, RenderChunkRegion×1, ShadowRenderer×1, ShulkerBoxRenderer×1 |
| slice-and-dice | both | 7 | 0 | 20 | BufferBuilder×1, GameRenderer×1, ItemRenderer×1, ParticleEngine×1, RenderSystem×1, RenderType×1 |
| artifacts | both | 6 | 0 | 56 | PlayerRenderer×3, GameRenderer×1, HumanoidModel×1, LivingEntityRenderer×1 |
| blueprint | both | 6 | 0 | 36 | Camera×1, ModelPart×1, PlayerRenderer×1, RabbitRenderer×1, SkinCustomizationScreen×1, WorldOpenFlows×1 |
| clientsort | both | 6 | 0 | 15 | AbstractContainerScreen×2, Screen×2, CreativeModeInventoryScreen×1, CreativeModeInventoryScreen$SlotWrapper×1 |
| dungeons_delight | both | 6 | 1 | 29 | Gui×2, AbstractContainerScreen×1, EffectRenderingInventoryScreen×1, HumanoidModel×1, LevelRenderer×1 |
| dynamic-fps | client | 6 | 0 | 10 | DebugScreenOverlay×1, GameRenderer×1, Gui×1, LoadingOverlay×1, ToastComponent×1, Window×1 |
## Per-frame event subscribers
| mod | side | frame events | tick events |
| --- | --- | --- | --- |
| puzzles-lib | both | ComputeFovModifierEvent, CustomizeGuiOverlayEvent, RenderBlockScreenEffectEvent, RenderFrameEvent, RenderGuiEvent, RenderGuiLayerEvent, RenderHandEvent, RenderHighlightEvent, RenderLevelStageEvent, RenderLivingEvent, RenderNameTagEvent, RenderPlayerEvent, RenderTooltipEvent, ViewportEvent | ClientTickEvent, EntityTickEvent, LevelTickEvent, PlayerTickEvent |
| create | both | CustomizeGuiOverlayEvent, RenderArmEvent, RenderFrameEvent, RenderGuiLayerEvent, RenderHandEvent, RenderHighlightEvent, RenderLevelStageEvent, RenderPlayerEvent, RenderTooltipEvent, ViewportEvent | ClientTickEvent, EntityTickEvent, LevelTickEvent, PlayerTickEvent |
| alexs-caves-(unofficial-port) | both | ComputeFovModifierEvent, CustomizeGuiOverlayEvent, RenderBlockScreenEffectEvent, RenderGuiLayerEvent, RenderHandEvent, RenderLevelStageEvent, RenderLivingEvent, RenderNameTagEvent, ViewportEvent | ClientTickEvent, EntityTickEvent, PlayerTickEvent |
| mowzies-mobs | both | ComputeFovModifierEvent, CustomizeGuiOverlayEvent, RenderFrameEvent, RenderGuiLayerEvent, RenderHandEvent, RenderLevelStageEvent, RenderLivingEvent, RenderNameTagEvent, ViewportEvent | EntityTickEvent, LevelTickEvent, PlayerTickEvent |
| the-twilight-forest | both | ComputeFovModifierEvent, CustomizeGuiOverlayEvent, RenderArmEvent, RenderFrameEvent, RenderGuiLayerEvent, RenderHighlightEvent, RenderLevelStageEvent, RenderLivingEvent, ViewportEvent | ClientTickEvent, EntityTickEvent, PlayerTickEvent |
| ars-nouveau | both | RenderFrameEvent, RenderGuiLayerEvent, RenderHandEvent, RenderHighlightEvent, RenderLevelStageEvent, RenderTooltipEvent | ClientTickEvent, LevelTickEvent, PlayerTickEvent |
| balm | both | ComputeFovModifierEvent, GuiDrawEvent, RenderGuiEvent, RenderGuiLayerEvent, RenderHandEvent, RenderHighlightEvent | ClientTickEvent, ClientTickHandler, EntityTickEvent, LevelTickEvent, PlayerTickEvent |
| alexs-mobs(1.21.1) | both | RenderGuiLayerEvent, RenderHandEvent, RenderLevelStageEvent, RenderLivingEvent, ViewportEvent | ClientTickEvent, EntityTickEvent |
| xaeros-minimap | both | CustomizeGuiOverlayEvent, RenderFrameEvent, RenderGuiEvent, RenderGuiLayerEvent, RenderLevelStageEvent | ClientTickEvent, PlayerTickEvent |
| architectury-api | both | ClientGuiEvent, CustomizeGuiOverlayEvent, RenderGuiEvent, RenderTooltipEvent | ClientTickEvent, LevelTickEvent, PlayerTickEvent |
| doggy-talents-next | both | RenderArmEvent, RenderLevelStageEvent, RenderPlayerEvent, ViewportEvent | ClientTickEvent |
| modernfix | both | CustomizeGuiOverlayEvent, RenderFrameEvent, RenderLivingEvent, RenderPlayerEvent | ClientTickEvent |
| adorable-hamster-pets | both | ClientGuiEvent, RenderLevelStageEvent, WorldRenderEvents | ClientTickEvent |
| apotheosis | both | RenderHighlightEvent, RenderLevelStageEvent, RenderTooltipEvent | ClientTickEvent, EntityTickEvent |
| citadel-(1.21.1-port) | both | RenderLevelStageEvent, RenderPlayerEvent, RenderTooltipEvent | ClientTickEvent, EntityTickEvent |
| lodestonelib | both | RenderFrameEvent, RenderLevelStageEvent, ViewportEvent | ClientTickEvent, LevelTickEvent |
| slice-and-dice | both | RenderGuiLayerEvent, RenderLevelStageEvent, RenderTooltipEvent | ClientTickEvent, LevelTickEvent |
| alltheleaks | both | CustomizeGuiOverlayEvent, RenderLivingEvent | ClientTickEvent, EntityTickEvent, LevelTickEvent |
| appleskin | both | CustomizeGuiOverlayEvent, RenderTooltipEvent | ClientTickEvent, EntityTickEvent |
| arsdelight | both | RenderLevelStageEvent, RenderLivingEvent | ClientTickEvent, PlayerTickEvent |
| artifacts | both | RenderArmEvent, RenderLivingEvent | ClientTickEvent, EntityTickEvent |
| barbeques-delight-forge | both | RenderLevelStageEvent, RenderLivingEvent | ClientTickEvent, PlayerTickEvent |
| create-aeronautics | both | RenderGuiEvent, RenderLevelStageEvent | ClientTickEvent, LevelTickEvent |
| creativecore | both | RenderFrameEvent, RenderGuiEvent | ClientTickEvent, LevelTickEvent |
| distanthorizons | both | RenderLevelStageEvent, WorldRenderEvents | |
| exposure | both | RenderGuiEvent, RenderLevelStageEvent | |
| extradelight | both | ComputeFovModifierEvent, ViewportEvent | |
| fruits-delight | both | RenderLevelStageEvent, RenderLivingEvent | ClientTickEvent, PlayerTickEvent |
| jade | both | CustomizeGuiOverlayEvent, RenderGuiEvent | ClientTickEvent |
| modonomicon | both | RenderFrameEvent, RenderLevelStageEvent | ClientTickEvent |
| patchouli | both | RenderFrameEvent, RenderTooltipEvent | ClientTickEvent |
| playerrevive | both | RenderFrameEvent, RenderGuiLayerEvent | ClientTickEvent, PlayerTickEvent |
| sable | both | RenderLevelStageEvent, ViewportEvent | ClientTickEvent |
| sophisticated-core | both | RenderLevelStageEvent, RenderTooltipEvent | ClientTickEvent, LevelTickEvent |
| twilight-delight | both | RenderLevelStageEvent, RenderLivingEvent | ClientTickEvent, PlayerTickEvent |
| akashic-tome | both | RenderGuiLayerEvent | |
| comforts | both | RenderPlayerEvent | ClientTickEvent |
| dynamic-fps | client | RenderGuiEvent | ClientTickEvent |
| ferrite-core | both | RenderLevelStageEvent | |
| ftb-library-forge | both | ClientGuiEvent | ClientTickEvent |
| fwa | client | RenderLevelStageEvent | |
| iceberg | both | RenderTooltipEvent | |
| iris | client | RenderLevelStageEvent | |
| jei | both | RenderTooltipEvent | ClientTickEvent |
| keybind-atlas | client | RenderGuiEvent | |
| legendary-tooltips | client | RenderTooltipEvent | |
| minopp | both | ComputeFovModifierEvent | ClientTickEvent |
| mru | both | HudRenderCallback | |
| music-disc-maker | both | RenderLevelStageEvent | ClientTickEvent |
| quick-skin | both | ClientGuiEvent | ClientTickEvent |
| rechiseled | both | RenderLevelStageEvent | |
| resourceful-lib | both | RenderHighlightEvent | |
| shatterbyte-lib | both | RenderLevelStageEvent | ClientTickEvent |
| sophisticated-backpacks | both | RenderLevelStageEvent | ClientTickEvent, EntityTickEvent, LevelTickEvent |
| sophisticated-storage | both | RenderHighlightEvent | ClientTickEvent, LevelTickEvent |
| subtle-effects | both | RenderLevelStageEvent | ClientTickEvent |
| xaeros-world-map | both | RenderFrameEvent | ClientTickEvent, PlayerTickEvent |
| zume | client | ViewportEvent | |
## Block/item atlas pressure
| mod | side | sprites (16² eq.) | files | animated | % of pack | models | blockstates |
| --- | --- | ---: | ---: | ---: | ---: | ---: | ---: |
| handcrafted | both | 16,359 | 976 | 0 | 27.2 | 12394 | 267 |
| chipped | both | 12,754 | 12299 | 30 | 21.2 | 16832 | 6981 |
| rechiseled | both | 5,680 | 657 | 0 | 9.4 | 13855 | 3627 |
| create | both | 4,012 | 1083 | 4 | 6.7 | 2684 | 643 |
| ars-nouveau | both | 3,778 | 547 | 29 | 6.3 | 870 | 200 |
| too-many-bows | both | 3,322 | 166 | 0 | 5.5 | 150 | 0 |
| extradelight | both | 1,847 | 1847 | 0 | 3.1 | 3759 | 822 |
| adorable-hamster-pets | both | 1,051 | 121 | 0 | 1.7 | 82 | 10 |
| doggy-talents-next | both | 981 | 192 | 0 | 1.6 | 164 | 6 |
| the-twilight-forest | both | 889 | 827 | 44 | 1.5 | 3107 | 523 |
| create-aeronautics | both | 740 | 261 | 1 | 1.2 | 605 | 141 |
| alexs-caves-(unofficial-port) | both | 717 | 711 | 27 | 1.2 | 1284 | 354 |
| macaws-doors | both | 702 | 702 | 0 | 1.2 | 1394 | 246 |
| dungeons_delight | both | 450 | 327 | 17 | 0.7 | 416 | 65 |
| wings-of-fire | both | 417 | 57 | 2 | 0.7 | 53 | 7 |
| alexs-mobs(1.21.1) | both | 410 | 254 | 13 | 0.7 | 438 | 37 |
| tiny-dragons | both | 378 | 9 | 1 | 0.6 | 25 | 3 |
| rustic-delight | both | 363 | 348 | 0 | 0.6 | 423 | 55 |
| sophisticated-storage | both | 349 | 271 | 0 | 0.6 | 299 | 59 |
| farmers-delight | both | 348 | 348 | 2 | 0.6 | 369 | 132 |
| immersive-paintings | both | 341 | 89 | 0 | 0.6 | 4 | 0 |
| fruits-delight | both | 254 | 254 | 0 | 0.4 | 649 | 200 |
| items-displayed-forge | both | 243 | 129 | 0 | 0.4 | 315 | 109 |
| twilight-delight | both | 233 | 221 | 11 | 0.4 | 356 | 95 |
| frights-delight | both | 217 | 172 | 69 | 0.4 | 271 | 43 |
| mowzies-mobs | both | 174 | 70 | 1 | 0.3 | 96 | 9 |
| veggies-delight | both | 170 | 170 | 0 | 0.3 | 178 | 29 |
| exposure | both | 166 | 52 | 1 | 0.3 | 54 | 8 |
| macaws-windows | both | 164 | 164 | 0 | 0.3 | 1887 | 328 |
| arsdelight | both | 159 | 142 | 0 | 0.3 | 165 | 26 |
## Animated atlas textures (uploaded every tick unless culled by Sodium)
| mod | side | animated |
| --- | --- | ---: |
| frights-delight | both | 69 |
| the-twilight-forest | both | 44 |
| chipped | both | 30 |
| ars-nouveau | both | 29 |
| alexs-caves-(unofficial-port) | both | 27 |
| macaws-lights-and-lamps | both | 18 |
| dungeons_delight | both | 17 |
| alexs-mobs(1.21.1) | both | 13 |
| apotheosis | both | 12 |
| twilight-delight | both | 11 |
| moonlight | both | 10 |
| create-enchantment-industry | both | 7 |
| create | both | 4 |
| apothic-enchanting | both | 3 |
| ends-delight | both | 2 |
| farmers-delight | both | 2 |
| macaws-roofs | both | 2 |
| slice-and-dice | both | 2 |
| sophisticated-core | both | 2 |
| wings-of-fire | both | 2 |
## Entity content (renderer + animation load)
| mod | side | entity types | entity tex Mpx | geckolib files |
| --- | --- | ---: | ---: | ---: |
| alexs-mobs(1.21.1) | both | 140 | 7.17 | 0 |
| alexs-caves-(unofficial-port) | both | 92 | 11.45 | 0 |
| the-twilight-forest | both | 80 | 0.95 | 0 |
| ars-nouveau | both | 51 | 0.37 | 132 |
| aquaculture | both | 40 | 0.05 | 0 |
| mowzies-mobs | both | 30 | 0.38 | 38 |
| critters-and-companions | both | 17 | 0.47 | 60 |
| items-displayed-forge | both | 17 | 0.07 | 0 |
| icys-better-horses | both | 16 | 5.37 | 14 |
| fowlplay | both | 14 | 0.09 | 0 |
| friends-and-foes-forge | both | 14 | 0.16 | 0 |
| fishermans-haven | both | 11 | 0.00 | 0 |
| tiny-dragons | both | 10 | 0.00 | 9 |
| create | both | 9 | 0.02 | 0 |
| adorable-hamster-pets | both | 7 | 0.26 | 4 |
| dungeons_delight | both | 7 | 0.05 | 0 |
| create-aeronautics | both | 6 | 0.01 | 0 |
| pet-cemetery | both | 6 | 0.01 | 0 |
| wings-of-fire | both | 6 | 0.00 | 2 |
| exposure | both | 5 | 0.00 | 0 |
| immersive-paintings | both | 4 | 0.00 | 0 |
| blueprint | both | 3 | 0.00 | 0 |
| doggy-talents-next | both | 3 | 10.09 | 0 |
| charta | both | 2 | 0.03 | 0 |
| handcrafted | both | 2 | 0.00 | 0 |
| jade | both | 2 | 0.00 | 0 |
| lootr | both | 2 | 0.00 | 0 |
| too-many-bows | both | 2 | 0.02 | 0 |
| artifacts | both | 1 | 0.10 | 0 |
| farmers-delight | both | 1 | 0.07 | 0 |
## Shader assets
| mod | side | shader files | post effects | core overrides |
| --- | --- | ---: | ---: | ---: |
| lodestonelib | both | 59 | 2 | 0 |
| alexs-caves-(unofficial-port) | both | 38 | 7 | 0 |
| charta | both | 31 | 1 | 0 |
| xaeros-minimap | both | 31 | 0 | 31 |
| xaeros-world-map | both | 31 | 0 | 31 |
| distanthorizons | both | 23 | 0 | 0 |
| exposure | both | 21 | 19 | 0 |
| what-are-they-up-to | both | 16 | 0 | 0 |
| ars-nouveau | both | 9 | 0 | 0 |
| sodium | client | 9 | 0 | 3 |
| blueprint | both | 6 | 0 | 0 |
| moonlight | both | 4 | 0 | 0 |
| playerrevive | both | 4 | 1 | 0 |
| the-twilight-forest | both | 4 | 0 | 0 |
| apotheosis | both | 3 | 0 | 0 |
| citadel-(1.21.1-port) | both | 3 | 1 | 0 |
| create | both | 3 | 0 | 0 |
| sable | both | 3 | 0 | 3 |
| shatterbyte-lib | both | 3 | 1 | 0 |
| ssrd | both | 1 | 0 | 0 |
## Sound payload
| mod | side | ogg MB |
| --- | --- | ---: |
| ambientsounds | client | 85.5 |
| alexs-caves-(unofficial-port) | both | 68.8 |
| mowzies-mobs | both | 33.2 |
| create-aeronautics | both | 26.2 |
| alexs-mobs(1.21.1) | both | 20.3 |
| the-twilight-forest | both | 17.3 |
| adorable-hamster-pets | both | 15.2 |
| sound | client | 7.9 |
| playerrevive | both | 5.1 |
| dungeons_delight | both | 5.1 |
| apothic-enchanting | both | 4.8 |
| doggy-talents-next | both | 4.3 |
| ars-nouveau | both | 4.3 |
| friends-and-foes-forge | both | 3.9 |
| apotheosis | both | 3.9 |
## Jar size
| mod | side | MB |
| --- | --- | ---: |
| ambientsounds | client | 84.8 |
| alexs-caves-(unofficial-port) | both | 74.9 |
| mowzies-mobs | both | 36.0 |
| music-disc-maker | both | 35.0 |
| create-aeronautics | both | 33.1 |
| distanthorizons | both | 28.2 |
| the-twilight-forest | both | 27.2 |
| alexs-mobs(1.21.1) | both | 26.6 |
| adorable-hamster-pets | both | 20.3 |
| ars-nouveau | both | 20.1 |
| create | both | 19.1 |
| chipped | both | 15.0 |
| sable | both | 13.0 |
| when-dungeons-arise | both | 11.8 |
| rechiseled | both | 11.5 |
| doggy-talents-next | both | 11.3 |
| extradelight | both | 11.0 |
| sound | client | 8.7 |
| controlify | client | 8.0 |
| fragmentum | both | 7.8 |
## Resource packs / shader packs
- **better-leaves** (both): atlas sprites 2,469, entity tex 0.00 Mpx, models 3223, blockstates 871, CEM/EMF files 0, shader files 0
- **complementary-reimagined** (both): atlas sprites 0, entity tex 0.00 Mpx, models 0, blockstates 0, CEM/EMF files 0, shader files 0
- **fresh-animations** (both): atlas sprites 0, entity tex 0.65 Mpx, models 0, blockstates 0, CEM/EMF files 240, shader files 0
- **fresh-animations-extensions** (both): atlas sprites 0, entity tex 0.48 Mpx, models 0, blockstates 0, CEM/EMF files 218, shader files 0
- **makeup-ultra-fast-shaders** (both): atlas sprites 0, entity tex 0.00 Mpx, models 0, blockstates 0, CEM/EMF files 0, shader files 0
File diff suppressed because it is too large. Load diff
@@ -0,0 +1,981 @@
_version = 4
[server]
#
# Defines the distance the player will receive updates around.
realTimeUpdateDistanceRadiusInChunks = 256
#
# Prefix of the level keys sent to the clients.
# If the mod is running behind a proxy, each backend should use a unique value.
# If this value is empty, level key will be based on the server's seed hash.
levelKeyPrefix = ""
#
# Defines the distance allowed to be synchronized around the player.
# Should be the same or larger than maxGenerationRequestDistance in most cases.
maxSyncOnLoadRequestDistance = 4096
#
# If true, clients will receive updated LODs when joining or loading new LODs.
synchronizeOnLoad = true
#
# Custom server key used which can be used to always reuse the same LOD data folder,
# for cases when the server doesn't have a static IP for some reason.
# If this value is empty, the client itself decides which folder name to use.
# Requires rejoining the server to apply after changing.
serverKey = ""
#
# Defines the distance allowed to generate around the player.
maxGenerationRequestDistance = 4096
#
# Makes the server send level keys for each world.
# Disable this if you use alternative ways to send level keys.
sendLevelKeys = true
#
# DO NOT CHANGE UNLESS YOU KNOW WHAT YOU'RE DOING.
# Autogenerated ID used to prevent multiple independent servers from accidentally
# writing over each other's LODs when the same serverKey is set on both.
serverId = 1518119460
#
# How many LOD generation requests per second should a client send?
# Also limits the number of client requests allowed to stay in the server's queue.
generationRequestRateLimit = 20
#
# How many LOD sync requests per second should a client send?
# Also limits the amount of player's requests allowed to stay in the server's queue.
syncOnLoadRateLimit = 50
#
# If true, clients will receive real-time LOD updates for chunks outside the client's render distance.
enableRealTimeUpdates = true
#
# Maximum global speed for uploading LODs to the clients, in KB/s.
# Value of 0 disables the limit.
globalBandwidthLimit = 0
#
# Maximum per-player speed for uploading LODs to the clients, in KB/s.
# Value of 0 disables the limit.
playerBandwidthLimit = 500
#
# Enables adaptive transfer speed based on client performance.
# If true, DH will automatically adjust transfer rate to minimize connection lag.
# If false, transfer speed will remain fixed.
enableAdaptiveTransferSpeed = false
[common.lodBuilding]
#
# How should block data be compressed when creating LOD data?
# This setting will only affect new or updated LOD data,
# any data already generated when this setting is changed will be
# unaffected until it is modified or re-loaded.
#
# MERGE_SAME_BLOCKS
# Every block/biome change is recorded in the database.
# This is what DH 2.0 and 2.0.1 all used by default and will store a lot of data.
# Expected Compression Ratio: 1.0
#
# VISUALLY_EQUAL
# Only visible block/biome changes are recorded in the database.
# Hidden blocks (IE ores) are ignored.
# Expected Compression Ratio: 0.7
worldCompression = "VISUALLY_EQUAL"
#
# Requires a level restart to apply.
#
# Setting this to a less strict mode increases DB read/write
# speed at the cost of potential data loss/corruption if
# the computer looses power
# (unexpected program shutdown should be safe for all options).
#
# FULL
# ACID - data will never be lost or corrupted
# Slow
# At max throughput: ~2k saves per sec, ~70% disk usage
#
# NORMAL
# May not be durable - some data may be lost on power loss, but DB should be safe from corruption
# Fast
# At max throughput: ~14k saves per sec, ~40% disk usage
#
# OFF
# Not consistent - database may be corrupted during power loss
# Very Fast
# At max throughput: ~16k saves per sec, ~6% disk usage
databaseSyncMode = "NORMAL"
dataCompression = "Z_STD_BLOCK"
#
# Enabling this will drastically speed up chunk processing time
# if you are CPU limited.
# Disabling it will drastically speed up chunk processing time
# if you are disk speed/IO limited.
#
# Normally DH will attempt to skip creating LODs for chunks it's already seen
# and that haven't changed.
#
# Disabling this option can also fix a rare bug where
# modified chunks are skipped due to being too similar to
# their saved hash.
disableUnchangedChunkCheck = false
[common.multiThreading]
#
# How many threads should be used by Distant Horizons?
numberOfThreads = 2
#
# A value between 1.0 and 0.0 that represents the percentage
# of time each thread can run before going idle.
#
# This can be used to reduce CPU usage if the thread count
# is already set to 1 for the given option, or more finely
# tune CPU performance.
threadRunTimeRatio = "1.0"
#
# What Java thread priority should DH's primary thread pools run with?
#
# You probably don't need to change this unless you are also
# running C2ME and are seeing thread starvation in either C2ME or DH.
threadPriority = 5
[common.logging]
#
# If enabled, the mod will log information about the renderer setup, cleanup, and any issues it may encounter.
# This can be useful for debugging.
logRendererEventToFile = "INFO"
#
# If enabled, the mod will log information about the world generation process.
# This can be useful for debugging.
logWorldGenEventToFile = "INFO"
#
# If enabled, the mod will log information about the renderer OpenGL process.
# This can be useful for debugging.
logRendererGLEventToChat = "ERROR"
#
#
globalChatMaxLevel = "ERROR"
#
# If enabled, the mod will log information about the world generation process.
# This can be useful for debugging.
logWorldGenChunkLoadEventToFile = "INFO"
#
# If enabled, the mod will log information about the renderer OpenGL process.
# This can be useful for debugging.
logRendererGLEventToFile = "INFO"
#
# If enabled, the mod will log information about network operations.
# This can be useful for debugging.
logNetworkEventToFile = "INFO"
#
# If enabled, config changes sent by the server will be logged.
logConnectionConfigChangesToFile = "WARN"
#
#
globalFileMaxLevel = "INFO"
[common.logging.warning]
#
# If enabled, a message will be displayed in chat if explicit garbage collection
# is disabled.
# This is known to cause out-of-memory issues
# and is better solved with a concurrent garbage collector.
showExplicitGcDisabledWarning = false
#
# If enabled, a chat message will be displayed when DH has too many chunks
# queued for updating.
showSlowWorldGenSettingWarnings = true
#
# If enabled, a chat message will be displayed when DH has too many chunks
# queued for updating.
showUpdateQueueOverloadedChatWarning = false
#
# If enabled, a message will be logged if explicit garbage collection
# is disabled.
# This is known to cause out-of-memory issues
# and is better solved with a concurrent garbage collector.
logExplicitGcDisabledWarning = false
#
# If enabled, a chat message will be displayed if Java doesn't have enough
# memory allocated to run DH well.
showLowMemoryWarningOnStartup = true
#
# If enabled, a chat message will be displayed when a replay is started
# giving some basic information about how DH will function.
showReplayWarningOnStartup = true
#
# If enabled, a chat message will be displayed when a potentially problematic
# mod is installed alongside DH.
showModCompatibilityWarningsOnStartup = true
#
# If enabled, a chat message will be displayed if vanilla MC's
# render distance is higher than the recommended amount.
showHighVanillaRenderDistanceWarning = true
#
# If enabled, a chat message will be displayed if DH detects
# that any pooled objects have been garbage collected.
showPoolInsufficientMemoryWarning = true
#
# If enabled, a message will be logged if the garbage
# collector Java is currently using is known
# to cause frame stuttering and/or other issues.
logGarbageCollectorWarning = true
#
# If enabled, a chat message will be displayed in chat if the garbage
# collector Java is currently using is known
# to cause frame stuttering and/or other issues.
showGarbageCollectorWarning = true
[common.worldGenerator]
#
# How should distant generator progress be displayed?
#
# OVERLAY: may be the same as CHAT for some Minecraft versions
# CHAT
# LOG
# DISABLED
showGenerationProgress = "DISABLED"
#
# If the SURFACE_THEN_CHUNKS generator plan is
# in use, this percentage can be defined to reduce how far the
# second high-quality generation pass will go
# as a percentage of your total render distance:
# -1.0 = Infinity
# 0.0 = 0%
# 0.5 = 50%
# 1.0 = 100%
# 2.0 = 200%
#
# Does nothing on a dedicated server.
surfaceRegenMaxDistancePercent = "-1.0"
#
# The max radius in chunks around the central point where world generation is allowed.
# If this value is set to 0, generation bounds are disabled and the render distance will be used.
#
# This should only be set if you have a pre-generated world that has a very limited size.
# Setting this on a normal MC world will prevent the world generator from filling
# out your render distance.
generationMaxChunkRadius = 0
#
# If the Minecraft server thread is taking too long
# Distant Horizons will pause world gen to reduce server stuttering/lag.
limitIfServerUnhealthy = true
#
# How often should the distant generator progress be displayed?
generationProgressDisplayIntervalInSeconds = 2
#
# When logging generation progress also include the rate at which chunks
# are being generated.
# This can be useful for troubleshooting performance.
generationProgressIncludeChunksPerSecond = true
#
# How detailed should LODs be generated outside the vanilla render distance?
#
# PRE_EXISTING_ONLY
# Only create LOD data for already generated chunks.
#
# FEATURES
# Generate everything except structures.
# Note: This may cause world generator bugs or instability when paired with certain world generator mods.
#
# INTERNAL_SERVER
# Ask the local server to generate/load each chunk.
# This is the most compatible and will generate structures correctly,
# but may cause server/simulation lag.
# Note: unlike other modes this option DOES save generated chunks to
# Minecraft's region files.
chunkGeneratorMode = "FEATURES"
#
# Defines how LODs will be generated
# outside the vanilla render distance.
# In multiplayer, this may be overridden by the server.
#
# SURFACE_THEN_CHUNKS
# The rough surface will be generated first
# then chunks will be generated to fill in
# missing features (ie trees and villages).
#
# Recommended for modded or vanilla worlds.
#
# SURFACE_ONLY
# Only the rough surface will be generated.
# Chunk features like trees and villages
# won't be generated.
#
# Recommended for computers that don't have
# enough CPU power or RAM space to handle
# the chunk generator.
#
# CHUNKS_ONLY
# Slower than either surface options,
# but provides more accurate terrain.
#
# Recommended for custom worlds
# where the surface generator would
# generate incorrect terrain.
#
# DISABLED
# No distant terrain will be generated.
generatorPlan = "SURFACE_THEN_CHUNKS"
#
# If true and the player/camera is moving quickly
# Distant Horizons will pause world gen to improve loading speed
# and reduce CPU load.
pauseIfMovingQuickly = true
#
# For how many seconds should instructions for disabling the distant generator progress be displayed?
# Setting this to 0 hides the instructional message so the world gen progress is shown immediately when it starts.
generationProgressDisableMessageDisplayTimeInSeconds = 20
#
# The center Z chunk position that the world gen max radius is centered around.
generationCenterChunkZ = 0
#
# The center X chunk position that the world gen max radius is centered around.
generationCenterChunkX = 0
[client]
#
# Should Distant Horizon's config button appear in Minecraft's options screen next to the fov slider?
showDhOptionsButtonInMinecraftUi = true
[client.advanced.autoUpdater]
#
# If DH should use the nightly (provided by Gitlab), or stable (provided by Modrinth) build.
# If [AUTO] is selected DH will update to new stable releases if the current jar is a stable jar
# and will update to new nightly builds if the current jar is a nightly jar (IE the version number ends in '-dev').
updateBranch = "AUTO"
#
# Automatically check for updates on game launch?
enableAutoUpdater = true
#
# Should Distant Horizons silently, automatically download and install new versions?
# This setting is force disabled on dedicated servers for stability reasons.
enableSilentUpdates = false
[client.advanced.debugging]
#
# If enabled this will disable (most) vanilla Minecraft rendering.
#
# NOTE: Do not report any issues when this mode is on!
# This setting is only for fun and debugging.
# Mod compatibility is not guaranteed.
lodOnlyMode = false
#
# What renderer is active?
#
# DEFAULT: Default lod renderer
# DEBUG_TRIANGLE: Debug testing renderer
# DISABLED: Disable rendering
rendererMode = "DEFAULT"
#
# If true overlapping quads will be rendered as bright red for easy identification.
# If false the quads will be rendered normally.
showOverlappingQuadErrors = false
#
# If true OpenGL Buffer garbage collection will be logged
# this also includes the number of live buffers.
logBufferGarbageCollection = false
#
# Should specialized colors/rendering modes be used?
#
# OFF: LODs will be drawn with their normal colors.
# SHOW_DETAIL: LODs' color will be based on their detail level.
# SHOW_BLOCK_MATERIAL: LODs' color will be based on their material.
# SHOW_OVERLAPPING_QUADS: LODs will be drawn with total white, but overlapping quads will be drawn with red.
debugRenderingColors = "OFF"
#
# Stops vertex colors from being passed.
# Useful for debugging shaders
enableWhiteWorld = false
#
# If enabled the LODs will render as wireframe.
renderWireframe = false
#
# If true several keys can be used to toggle debug states.
# F6 - enable/disable LOD rendering
# F7 - enable/disable LOD only rendering
# F8 - cycle through the different debug rendering modes
enableDebugKeybindings = false
[client.advanced.debugging.debugWireframe]
#
# Render LOD section status?
showRenderSectionStatus = false
#
# Render queued network sync on load tasks?
showNetworkSyncOnLoadQueue = false
#
# Render full data update/lock status?
showFullDataUpdateStatus = false
#
# Render queued world gen tasks?
showWorldGenQueue = false
#
# Render Quad Tree Rendering status?
showQuadTreeRenderStatus = false
#
# If enabled, various wireframes for debugging internal functions will be drawn.
#
# NOTE: There WILL be performance hit!
# Additionally, only stuff that's loaded after you enable this
# will render their debug wireframes.
enableRendering = false
[client.advanced.debugging.openGl]
#
# Defines how OpenGL errors are handled.
# Requires rebooting Minecraft to change.
# Will catch OpenGL errors thrown by other mods.
overrideVanillaGLLogger = true
#
# Defines how OpenGL errors are handled.
# May incorrectly catch OpenGL errors thrown by other mods.
#
# IGNORE: Do nothing.
# LOG: write an error to the log.
# LOG_THROW: write to the log and throw an exception.
# Warning: this should only be enabled when debugging the LOD renderer
# as it may break Minecraft's renderer when an exception is thrown.
glErrorHandlingMode = "IGNORE"
#
# If true each Open GL error will only be logged once.
# Enabling this may cause some error logs to be missed.
# Does nothing if overrideVanillaGLLogger is set to false.
#
# Generally this can be kept as 'true' to prevent log spam.
# However, Please set this to 'false' if a developer needs your log to debug a GL issue.
onlyLogGlErrorsOnce = true
[client.advanced.debugging.exampleConfigScreen]
shortTest = "69"
mapTest = "{}"
byteTest = "8"
longTest = "42069"
listTest = ["option 1", "option 2", "option 3"]
boolTest = false
doubleTest = "420.69"
floatTest = "0.42069"
linkableTest = 420
intTest = 69420
stringTest = "Test input box"
[client.advanced.debugging.f3Screen]
#
# Shows info about the render thread tasks.
showRenderThreadTasks = false
#
# Shows how many chunks are queued for processing and the max count that can be queued.
showQueuedChunkUpdateCount = true
#
# Shows the memory use and array counts for each DH object pool.
showSeparatedObjectPools = false
#
# Shows the player's LOD position.
showPlayerPos = true
#
# Shows the combined memory use and array counts for all DH pooled objects.
showCombinedObjectPools = false
#
# Defines what internal detail level the player position will be shown as.
# Internal detail level means: 6 = 1x1 block, 7 = 2x2 blocks, etc.
playerPosSectionDetailLevel = 6
#
# Only show levels that DH is actively rendering.
onlyShowRenderingLevels = true
#
# Shows info about each thread pool.
showThreadPools = true
#
# Shows what levels are loaded and world gen/rendering info about those levels.
showLevelStatus = true
[client.advanced.debugging.positionFinderDebugging]
positionFinderEnable = false
positionFinderMinBlockY = -64
positionFinderZPos = 0
positionFinderXPos = 0
positionFinderMaxBlockY = 125
positionFinderDetailLevel = 6
positionFinderMarginPercent = "0.0"
[client.advanced.graphics]
#
# Enabling Anti-Aliasing smooths edges and reduces flickering when moving.
enableAntiAliasing = true
#
# Enable Screen Space Ambient Occlusion
enableSsao = true
#
# If true some vanilla graphics settings will be automatically changed
# during DH setup to provide a better experience.
#
# IE disabling vanilla clouds (which render on top of DH LODs),
# and chunk fading (DH already fades MC chunks)
overrideVanillaGraphicsSettings = true
[client.advanced.graphics.culling]
#
# Determines how far from the camera Distant Horizons will start rendering.
# Measured as a percentage of the vanilla render distance.
#
# -1 = auto, overdraw will change based on the vanilla render distance.
#
# Higher values will prevent LODs from rendering behind vanilla blocks at a higher distance,
# but may cause holes in the world.
# Holes are most likely to appear when flying through unloaded terrain.
#
# Increasing the vanilla render distance increases the effectiveness of this setting.
overdrawPrevention = "-1.0"
#
# Identical to the other frustum culling option
# only used when a shader mod is present using the DH API
# and the shadow pass is being rendered.
#
# Disable this if shadows render incorrectly.
disableShadowPassFrustumCulling = false
#
# A comma separated list of block resource locations that will be replaced by water
# if they're visible on the water's surface.
waterSubSurfaceBlockReplacementCsv = "minecraft:kelp,minecraft:tall_seagrass,minecraft:seagrass"
#
# A comma separated list of block resource locations that won't be rendered by DH.
# Air is always included in this list.
#
# Note:
# If you see gaps, or holes you may have to change
# worldCompression to [MERGE_SAME_BLOCKS] and re-generate the LODs.
ignoredRenderBlockCsv = "minecraft:barrier,minecraft:structure_void,minecraft:light,minecraft:tripwire,minecraft:brown_mushroom"
#
# A comma separated list of block resource locations that will be removed
# when on top of water.
waterSurfaceBlockReplacementCsv = "minecraft:lily_pad"
#
# Defines what blocks should be rendered as LODs.
#
# NONE: Include all blocks in the LODs
# NON_COLLIDING: Only render solid blocks in the LODs (tall grass, torches, etc. will be ignored)
blocksToIgnore = "NON_COLLIDING"
#
# If true LODs outside the player's camera
# aren't drawn, increasing GPU performance.
#
# If false all LODs are drawn, even those behind
# the player's camera, decreasing GPU performance.
#
# Disable this if you see LODs disappearing at the corners of your vision.
disableFrustumCulling = false
#
# If false all beacons near the camera won't be drawn to prevent vanilla overdraw.
# If true all beacons will be rendered.
#
# Generally this should be left as true. It's main purpose is for debugging
# beacon updating/rendering.
disableBeaconDistanceCulling = true
#
# Should the blocks underneath avoided blocks gain the color of the avoided block?
#
# True: a red flower will tint the grass below it red.
# False: skipped blocks will not change color of surface below them.
tintWithAvoidedBlocks = true
#
# If enabled caves won't be rendered.
#
# Note: for some world types this can cause
# overhangs or walls for floating objects.
# Tweaking the caveCullingHeight, can resolve some
# of those issues.
enableCaveCulling = true
#
# At what Y value should cave culling start?
# Lower this value if you get walls for areas with 0 light.
caveCullingHeight = 60
#
# A comma separated list of block resource locations that shouldn't be rendered
# if they are in a 0 sky light underground area.
# Air is always included in this list.
#
# Defaults to an empty list since most cave blocks will be automatically ignored due to being:
# transparent, non-solid, or liquids, but new blocks can be added here if needed.
ignoredRenderCaveBlockCsv = ""
#
# If set to true the overdraw prevention radius will get closer
# to the camera when flying/moving quickly.
#
# This helps reduce issues where Minecraft can't load or
# generate chunks fast enough to keep up with DH.
reduceOverdrawWithFastMovement = true
[client.advanced.graphics.texture]
#
# A comma separated list of block resource locations
# that DH will render their sides using the bottom texture.
# Partial matches/incomplete resource locations will also match.
#
# Example: "minecraft:grass_block,nylium"
#
# Changes require a restart.
blocksDontUseSideTextureCsv = "grass_block,mycelium,nylium,dirt_path,grass"
#
# The highest detail level number that can render with block textures.
# At higher detail levels each LOD covers multiple blocks,
# which can essentially make textures smaller than a pixel and therefore invisible.
#
# Larger numbers texture more distant LODs
# but increase memory usage.
maxTexturedLodDetailLevel = 2
#
# If true nearby and zoomed-in LODs will render with their block's
# actual texture instead of a single flat color.
#
# Only applies to high detail LODs where the texture is actually visible,
# distant LODs always use flat colors.
# Some shader packs nay not have an affect.
enableTexturedLods = true
#
# A comma separated list of block resource locations
# that DH won't render textures on.
# Partial matches/incomplete resource locations will also match.
#
# Example: "minecraft:grass_block,nylium"
#
# Changes require a restart.
blocksDontRenderTextureCsv = "minecraft:bamboo"
#
# A comma separated list of tag names
# that DH will render their sides using the bottom texture.
#
# Example: "grass_blocks,nylium"
#
# Changes require a restart.
blockTagsDontUseSideTextureCsv = "grass_blocks,nylium"
#
# A comma separated list of block resource locations
# that DH will use rasterization to determine
# the face textures.
#
# Can be used to fix issues with mods/blocks where
# a side uses just part of a modeled block's texture.
#
# Example: "minecraft:beacon"
#
# Changes require a restart.
blocksAlwaysRasterizeTextureCsv = "minecraft:beacon"
[client.advanced.graphics.noiseTexture]
#
# Should a noise texture be applied to LODs?
#
# This is done to simulate textures and make the LODs appear more detailed.
enableNoiseTexture = true
#
# Defines how far should the noise texture render before it fades away. (in blocks)
# Set to 0 to disable noise from fading away
noiseDropoff = 1024
#
# How many steps of noise should be applied to LODs?
noiseSteps = 4
#
# How intense should the noise should be?
noiseIntensity = "0.05"
[client.advanced.graphics.experimental]
#
# A comma separated list of dimension resource locations where DH won't render.
#
# Example: "minecraft:the_nether,minecraft:the_end"
# For Minecraft 1.12.2 and older:
# Open the F3 screen and copy the dimension_name:ID shown in yellow. Example: "overworld:0"
#
# Note:
# Some DH settings will be disabled and/or changed to improve
# visuals when DH rendering is disabled.
ignoredDimensionCsv = ""
#
# Requires a restart to change.
#
# Options:
# AUTO - changes based on the most likely API for that MC version
# OPEN_GL - The Default for MC 1.21.11 and older (supports Iris shaders)
# BLAZE_3D - The Default for MC 26.1.2 and newer (supports Vulkan)
renderingEngine = "AUTO"
#
# This is the earth size ratio when applying the curvature shader effect.
# Note: Enabling this feature may cause rendering bugs.
#
# 0 = flat/disabled
# 1 = 1 to 1 (6,371,000 blocks)
# 100 = 1 to 100 (63,710 blocks)
# 10000 = 1 to 10000 (637.1 blocks)
#
# Note: Due to current limitations, the min value is [50]
# and the max value is 5000. Any values outside this range
# will be set to 0 (disabled).
earthCurveRatio = 0
[client.advanced.graphics.genericRendering]
#
# A comma separated separated list of dimension resource locations where DH clouds will render.
#
# Example: "minecraft:overworld,minecraft:the_end"
#
# Changes require a world re-load.
dimensionEnabledCloudRenderingCsv = "minecraft:overworld"
#
# If true LOD clouds will be rendered.
enableCloudRendering = true
#
# If true LOD beacon beams will be rendered wider at extreme distances,
# making them easier to see.
# If false all LOD beacon beams will only ever be 1 block wide.
expandDistantBeacons = true
#
# Sets the maximum height beacons will render up to.
#
# Requires a world re-load to take affect.
beaconRenderHeight = 6000
#
# If true LOD beacon beams will be rendered.
enableBeaconRendering = true
#
# If true non terrain objects will be rendered by DH.
# i.e. beacon beams and clouds.
enableGenericRendering = true
#
# False = DH will render a single layer of clouds, like vanilla Minecraft.
# True = DH will render 3 layers of clouds at different heights.
enableMultiLayerClouds = true
[client.advanced.graphics.quality]
#
# What is the maximum detail LODs can render at?
# Higher settings will increase memory and GPU usage.
#
# CHUNK: render 1 LOD for each Chunk.
# HALF_CHUNK: render 4 LODs for each Chunk.
# FOUR_BLOCKS: render 16 LODs for each Chunk.
# TWO_BLOCKS: render 64 LODs for each Chunk.
# BLOCK: render 256 LODs for each Chunk (width of one block).
#
# Fastest: CHUNK
# Fanciest: BLOCK
maxHorizontalResolution = "BLOCK"
#
# If true LODs will fade away as you get closer to them.
# If false LODs will cut off abruptly at a set distance from the camera.
# This setting is affected by the vanilla overdraw prevention config.
ditherDhFade = true
#
# If true DH will try to use the camera position when
# determining LOD quality drop-off.
# If false DH will use the player's position.
#
# Enabling helps free-cam mods render correctly.
# Disabling helps multi-camera mods render correctly (ie Immersive Portals or camera mods).
useCameraPositionForQualityDropOff = true
#
# How bright LOD colors are.
#
# 0 = black
# 1 = normal
# 2 = near white
brightnessMultiplier = "1.0"
#
# How many detail levels zooming in can increase LOD quality by.
# Higher numbers allow stronger zooms to render crisper terrain,
# but will increase memory and GPU usage while zoomed in.
#
# A vanilla spyglass needs 4 detail levels to reach its full quality.
maxZoomQualityIncrease = 4
#
# How should LODs be shaded?
#
# AUTO: Uses the same side shading as vanilla Minecraft blocks.
# ENABLED: Simulates Minecraft's block shading for LODs.
# Can be used to force LOD shading when using some shaders.
# DISABLED: All LOD sides will be rendered with the same brightness.
lodShading = "AUTO"
#
# How saturated LOD colors are.
#
# 0 = black and white
# 1 = normal
# 2 = very saturated
saturationMultiplier = "1.0"
#
# This indicates how well LODs will represent
# overhangs, caves, floating islands, etc.
# Higher options will make the world more accurate, butwill increase memory and GPU usage.
#
# Lowest Quality: HEIGHT_MAP
# Highest Quality: PIXEL_ART
verticalQuality = "MEDIUM"
#
# The radius of the mod's render distance. (measured in chunks)
#
# Note: this is a best effort number.
# The actual render distance may be above or below this number
# depending on your other graphic settings.
lodChunkRenderDistanceRadius = 256
#
# How should the sides and bottom of grass block LODs render?
#
# AS_GRASS: all sides of dirt LOD's render using the top (green) color.
# FADE_TO_DIRT: sides fade from grass to dirt.
# AS_DIRT: sides render entirely as dirt.
grassSideRendering = "FADE_TO_DIRT"
#
# This indicates how far apart drops in LOD quality are.
#
# Higher settings will increase the distance between drops
# but will increase memory and GPU usage.
horizontalQuality = "MEDIUM"
#
# How should LOD transparency be handled.
#
# COMPLETE: LODs will render transparent.
# DISABLED: LODs will be opaque.
transparency = "COMPLETE"
#
# This is the same as vanilla Biome Blending settings for Lod area.
# Note: anything above '0' will slow down LOD loading time.
#
# '0' equals to Vanilla Biome Blending of '1x1' or 'OFF',
# '1' equals to Vanilla Biome Blending of '3x3',
# '2' equals to Vanilla Biome Blending of '5x5'...
lodBiomeBlending = 3
#
# How should vanilla Minecraft fade into Distant Horizons LODs?
#
# NONE: Fastest, there will be a pronounced border between DH and MC rendering.
# SINGLE_PASS: Fades after MC's transparent pass, opaque blocks underwater won't be faded.
# DOUBLE_PASS: Slowest, fades after both MC's opaque and transparent passes, provides the smoothest transition.
vanillaFadeMode = "DOUBLE_PASS"
#
# If true LOD quality will increase when the camera is zoomed in,
# IE when using a spyglass or zoom mod.
#
# Only LODs visible through the camera view are affected.
#
# When zoomed in LODs will load to the same detail level
# they would have if you were close to them.
increaseQualityWhenZoomedIn = true
[client.advanced.graphics.fog]
#
# Should Minecraft's fog render?
# Note: Other mods may conflict with this setting.
enableVanillaFog = false
#
# What is the maximum fog thickness?
#
# 0.0: No fog.
# 1.0: Fully opaque fog.
farFogMax = "1.0"
#
# Determines if fog is drawn on DH LODs.
enableDhFog = true
#
# At what distance should the far fog start?
#
# 0.0: Fog starts at the player's position.
# 1.0: Fog starts at the closest edge of the vanilla render distance.
# 1.414: Fog starts at the corner of the vanilla render distance.
farFogStart = "0.4"
#
# What is the minimum fog thickness?
#
# 0.0: No fog.
# 1.0: Fully opaque fog.
farFogMin = "0.0"
#
# What color should fog use?
#
# USE_WORLD_FOG_COLOR: Use the world's fog color.
# USE_SKY_COLOR: Use the sky's color.
colorMode = "USE_WORLD_FOG_COLOR"
#
# How should the fog thickness should be calculated?
#
# LINEAR: Linear based on distance (will ignore 'density')
# EXPONENTIAL: 1/(e^(distance*density))
# EXPONENTIAL_SQUARED: 1/(e^((distance*density)^2)
farFogFalloff = "EXPONENTIAL_SQUARED"
#
# Used in conjunction with the Fog Falloff.
farFogDensity = "2.5"
#
# Where should the far fog end?
#
# 0.0: Fog ends at player's position.
# 1.0: Fog ends at the closest edge of the vanilla render distance.
# 1.414: Fog ends at the corner of the vanilla render distance.
farFogEnd = "1.0"
[client.advanced.graphics.fog.heightFog]
#
# Where should the height fog start?
#
# ABOVE_CAMERA: Height fog starts at the camera and goes towards the sky
# BELOW_CAMERA: Height fog starts at the camera and goes towards the void
# ABOVE_AND_BELOW_CAMERA: Height fog starts from the camera to goes towards both the sky and void
# ABOVE_SET_HEIGHT: Height fog starts from a set height and goes towards the sky
# BELOW_SET_HEIGHT: Height fog starts from a set height and goes towards the void
# ABOVE_AND_BELOW_SET_HEIGHT: Height fog starts from a set height and goes towards both the sky and void
heightFogDirection = "BELOW_SET_HEIGHT"
#
# What is the minimum fog thickness?
#
# 0.0: No fog.
# 1.0: Fully opaque fog.
heightFogMin = "0.0"
#
# If the height fog is calculated around a set height, what is that height position?
heightFogBaseHeight = "80.0"
#
# What is the maximum fog thickness?
#
# 0.0: No fog.
# 1.0: Fully opaque fog.
heightFogMax = "1.0"
#
# How should the height fog thickness should be calculated?
#
# LINEAR: Linear based on height (will ignore 'density')
# EXPONENTIAL: 1/(e^(height*density))
# EXPONENTIAL_SQUARED: 1/(e^((height*density)^2)
heightFogFalloff = "EXPONENTIAL_SQUARED"
#
# What is the height fog's density?
heightFogDensity = "20.0"
#
# How should height effect the fog thickness?
# Note: height fog is combined with the other fog settings.
#
# SPHERICAL: Fog is calculated based on camera distance.
# CYLINDRICAL: Ignore height, fog is calculated based on horizontal distance.
#
# MAX: max(heightFog, farFog)
# ADDITION: heightFog + farFog
# MULTIPLY: heightFog * farFog
# INVERSE_MULTIPLY: 1 - (1-heightFog) * (1-farFog)
# LIMITED_ADDITION: farFog + max(farFog, heightFog)
# MULTIPLY_ADDITION: farFog + farFog * heightFog
# INVERSE_MULTIPLY_ADDITION: farFog + 1 - (1-heightFog) * (1-farFog)
# AVERAGE: farFog*0.5 + heightFog*0.5
heightFogMixMode = "SPHERICAL"
#
# Should the start of the height fog be offset?
#
# 0.0: Fog start with no offset.
# 1.0: Fog start with offset of the entire world's height. (Includes depth)
heightFogStart = "0.0"
#
# Should the end of the height fog be offset?
#
# 0.0: Fog end with no offset.
# 1.0: Fog end with offset of the entire world's height. (Include depth)
heightFogEnd = "0.6"
[client.advanced.multiplayer]
#
# How should multiplayer save folders should be named?
#
# NAME_ONLY: Example: "Minecraft Server"
# IP_ONLY: Example: "192.168.1.40"
# NAME_IP: Example: "Minecraft Server IP 192.168.1.40"
# NAME_IP_PORT: Example: "Minecraft Server IP 192.168.1.40:25565"NAME_IP_PORT_MC_VERSION: Example: "Minecraft Server IP 192.168.1.40:25565 GameVersion 1.16.5"
serverFolderNameMode = "NAME_ONLY"
@@ -0,0 +1,35 @@
[visuals]
#whether to cave maps are visible when held by players from the third-person perspective.
cave_maps_visible_in_third_person = true
#whether to shake the screen from tremorsaurus stomping, nuclear explosions, etc.
screen_shaking = true
#true if some block models, like uranium ore or abyssmarine bricks render as fullbright. May increase load time, no gameplay performance impact.
emissive_block_models = true
#whether to make the screen flash white during nuclear explosions.
nuclear_bomb_flash = true
#true if some biomes, such as primordial caves, have ambient light that makes the biome easier to see in.
biome_ambient_light = true
#true if some biomes, such as toxic caves, apply a color to ambient light. May conflict with shaders.
biome_ambient_light_coloring = true
#true if some biomes, such as primordial caves, have an always well-lit sky when in them. May conflict with shaders.
biome_sky_overrides = true
#true if some biomes, such as abyssal chasm, have an thicker water fog to them. May conflict with shaders.
biome_sky_fog_overrides = true
#true if ambersol block renders with rays of light emerging from it.
ambersol_shines = true
#true if irradiated effect makes mobs glow. May conflict with shaders.
radiation_glow_effect = true
#determines how far to the left the subterranodon flight indicator renders on the screen when mounted. Negative numbers will render it on the right.
# Default: 22
# Range: -12000 ~ 12000
subterranodon_indicator_x = 22
#determines how far from bottom the subterranodon flight indicator renders on the screen when mounted.
# Default: 6
# Range: -12000 ~ 12000
subterranodon_indicator_y = 6
#true if sugar rush makes the world more saturated. May conflict with shaders.
sugar_rush_saturation_effect = true
[audio]
#whether nuclear explosions briefly muffle other sounds.
nuclear_bomb_muffles_sounds = true
@@ -0,0 +1,14 @@
{
"ingredientDedupe": false,
"debugItemStackModifications": false,
"version": 1,
"debugNativeImage": false,
"disableSearchTree": false,
"logIntervalInMinutes": 10,
"showSummaryOnDebugScreen": true,
"memoryUsageWarningPercentage": 90,
"debugChunkLoading": false,
"debugThreadsStuck": false,
"disableEternalStarlightProgress": false,
"skipTickingUnloadedFluxNetworks": false
}
@@ -0,0 +1,228 @@
{
"general": {
"engines": 0,
"volume": 1,
"useSoundMasterSource": false,
"scanStepAmount": 100,
"playSoundWithOffset": true
},
"dimensions": {
"abyssalcraft": 1,
"betweenlands": 1,
"cave": 1,
"end": 1,
"galacticraft": 1,
"galacticraft.planets": 1,
"midnight": 1,
"nether": 1,
"surface": 1,
"twilightforest": 1,
"void": 1
},
"regions": {
"abyssalcraft_dark": {
"overall": 1,
"suspense.suspense": 1
},
"end_unknown": {
"overall": 1,
"suspense.suspense": 1
},
"galacticraft_planets_wind": {
"overall": 1,
"wind.light-wind": 1
},
"nether_suspense": {
"overall": 1,
"nether": 1
},
"twilightforest_unknown": {
"overall": 1,
"suspense.suspense": 1
},
"void_dark": {
"overall": 1,
"suspense.suspense": 1
},
"beach": {
"overall": 1,
"beach": 1,
"seagull": 1,
"seagull-long": 1
},
"cave_ambience": {
"overall": 1,
"cave": 1,
"cave-water": 1,
"cave-deep": 1,
"cave-large": 1
},
"cave_deep-dark": {
"overall": 1,
"deep-dark": 1,
"water-droplets": 1
},
"cave": {
"overall": 1
},
"cave_lush": {
"overall": 1,
"cave-lush": 1,
"frog": 1
},
"cold_artic": {
"overall": 1,
"heavy-wind": 1
},
"cold": {
"overall": 1,
"wind.light-wind": 1
},
"desert": {
"overall": 1,
"cicadas-desert": 1,
"wind.light-wind": 1
},
"forest_cold": {
"overall": 1,
"crow": 1
},
"forest": {
"overall": 1,
"bird-ambience": 1,
"owl": 1
},
"forest_roofed": {
"overall": 1,
"bird-ambience-spooky": 1
},
"grass": {
"overall": 1,
"cricket": 1,
"cricket-night": 1,
"cicadas-night": 1
},
"highland": {
"overall": 1,
"heavy-wind": 1,
"wind-in-leaves": 1
},
"jungle": {
"overall": 1,
"cricket-jungle": 1,
"cricket-jungle-night": 1,
"bird-ambience-jungle": 1,
"bird-ambience-jungle-night": 1
},
"mesa": {
"overall": 1,
"wind-mesa": 1
},
"mushroom_fields": {
"overall": 1,
"cicadas-mushroom-fields": 1,
"special-mushroom-fields": 1
},
"ocean": {
"overall": 1,
"ocean": 1,
"wind.light-wind": 1
},
"ocean_deep": {
"overall": 1,
"whale": 1
},
"pale-garden": {
"overall": 1,
"pale-garden-ambience": 1,
"owl": 1
},
"plains": {
"overall": 1,
"cricket": 1,
"cricket-night": 1,
"cicadas-night": 1
},
"rain": {
"overall": 1,
"rain": 1
},
"savanna": {
"overall": 1,
"cricket": 1,
"cicadas": 1,
"cicadas-desert": 1,
"cricket-warm-night": 1,
"wolf": 1,
"long-wolf": 1,
"bird-warm": 1
},
"sky": {
"overall": 1,
"wind.light-wind": 1
},
"space": {
"overall": 1
},
"storm_away": {
"overall": 1,
"storm-away": 1,
"howling-wind": 1
},
"storm_close": {
"overall": 1,
"storm-close": 1,
"wind": 1
},
"surface": {
"overall": 1
},
"swamp": {
"overall": 1,
"cricket-swamp": 1,
"cricket-warm-night": 1,
"frog": 1,
"mouring_dove": 1
},
"taiga": {
"overall": 1,
"bird-ambience-huge": 1
},
"underwater": {
"overall": 1,
"underwater": 1,
"underwater-deep": 1
},
"underworld": {
"overall": 1,
"underworld": 1
},
"warden": {
"overall": 1,
"warden": 1
}
},
"categories": {
"animal": {
"animal": 1,
"bird": {
"bird": 1,
"bird_day": 1,
"bird_night": 1
},
"cicadas": 1,
"cricket": {
"cricket": 1,
"cricket_day": 1,
"cricket_night": 1
}
},
"cave": 1,
"suspense": 1,
"weather": 1,
"wind": 1
},
"fade-volume": 0.005,
"fade-pitch": 0.005,
"silent-dimensions": []
}
@@ -0,0 +1,68 @@
#Lighting
[lights]
#Show the supporter message. This is set to false after the first time.
showSupporterMessage = true
#If dynamic lights are enabled
lightsEnabled = false
#How bright the touch light is
# Default: 8
# Range: 0 ~ 15
touchLightLuminance = 8
#How long the touch light lasts in ticks
# Default: 8
# Range: 0 ~ 40
touchLightDuration = 8
#Light level an entity should emit when dynamic lights are on
#Example entry: minecraft:blaze=15
entity_lights = ["minecraft:blaze=10", "ars_nouveau:orbit=15", "ars_nouveau:linger=15", "ars_nouveau:spell_proj=15", "minecraft:magma_cube=8", "ars_nouveau:flying_item=10", "minecraft:spectral_arrow=8", "ars_nouveau:follow_proj=10"]
#Light level an item should emit when held when dynamic lights are on
#Example entry: minecraft:stick=15
item_lights = ["minecraft:redstone_torch=10", "minecraft:soul_lantern=12", "minecraft:glow_ink_sac=10", "minecraft:verdant_froglight=15", "minecraft:blaze_rod=10", "minecraft:shroomlight=10", "minecraft:lantern=14", "minecraft:soul_torch=10", "minecraft:glow_berries=8", "minecraft:glowstone_dust=8", "minecraft:pearlescent_froglight=15", "minecraft:nether_star=14", "minecraft:glowstone=15", "minecraft:torch=14", "minecraft:ochre_froglight=15", "minecraft:lava_bucket=15"]
#Overlay
[overlays]
#X offset for the tooltip
# Default: 20
# Range: > -2147483648
xTooltip = 20
#Y offset for the tooltip
# Default: 0
# Range: > -2147483648
yTooltip = 0
#X offset for the Mana Bar
# Default: 0
# Range: > -2147483648
xManaBar = 0
#Y offset for the Mana Bar
# Default: 0
# Range: > -2147483648
yManaBar = 0
#X offset for the Spell Name
# Default: 10
# Range: > -2147483648
xSpellName = 10
#Y offset for the Spell Name
# Default: 30
# Range: > -2147483648
ySpellName = 30
#If the Storage Lectern should show the recipe book icon
showRecipeBook = true
#If scrolling in the Storage Lectern should be inverted
invertLecternScrolling = false
#Inform the player of Dynamic lights once.
informLights = false
#Whether the Selection HUD is toggled or held
toggleSelectionHUD = true
#Misc
[misc]
#Use simplified renderer for Warp Portals
no_end_portal_render = false
#Disables the skyweave renderer. Disable if your sky is broken with shaders.
disable_skyweave = false
#Show spell tooltips with glyphs instead of plain text
glyphTooltips = true
#Enables transparent/opaque rendering of elements in the book GUI. Disable if it leads to crash with Sodium derivatives
gui_transparency = true
#Disables translucent particles. Disable if your particles are invisible with shaders.
opaque_particles = false
@@ -0,0 +1,147 @@
#.
#Client-only settings - If you're looking for general settings, look inside your worlds serverconfig folder!
[client]
#.
#Show item descriptions on Shift and controls on Ctrl.
enableTooltips = true
#.
#Display a tooltip when looking at overstressed components.
enableOverstressedTooltip = true
#.
#Log a stack-trace when rendering issues happen within a moving contraption.
explainRenderErrors = false
#.
#Higher density means more spawned particles.
# Default: 0.5
# Range: 0.0 ~ 1.0
fanParticleDensity = 0.5
#.
#[in Blocks]
#Maximum Distance to the player at which items in Blocks' filter slots will be displayed
# Default: 10.0
# Range: 1.0 ~ 3.4028234663852886E38
filterItemRenderDistance = 10.0
#.
#Choose the menu row that the Create config button appears on in the main menu
#Set to 0 to disable the button altogether
# Default: 2
# Range: 0 ~ 4
mainMenuConfigButtonRow = 2
#.
#Offset the Create config button in the main menu by this many pixels on the X axis
#The sign (-/+) of this value determines what side of the row the button appears on (left/right)
# Default: -4
# Range: > -2147483648
mainMenuConfigButtonOffsetX = -4
#.
#Choose the menu row that the Create config button appears on in the in-game menu
#Set to 0 to disable the button altogether
# Default: 3
# Range: 0 ~ 5
ingameMenuConfigButtonRow = 3
#.
#Offset the Create config button in the in-game menu by this many pixels on the X axis
#The sign (-/+) of this value determines what side of the row the button appears on (left/right)
# Default: -4
# Range: > -2147483648
ingameMenuConfigButtonOffsetX = -4
#.
#Setting this to true will prevent Create from sending you a warning when playing with Fabulous graphics enabled
ignoreFabulousWarning = false
#.
#Disable to prevent being rotated while seated on a Moving Contraption
rotateWhenSeated = true
#.
#Configure your vision range when submerged in Create's custom fluids
[client.fluidFogSettings]
#.
#The vision range through honey will be multiplied by this factor
# Default: 1.0
# Range: 0.125 ~ 256.0
honey = 1.0
#.
#The vision range though chocolate will be multiplied by this factor
# Default: 1.0
# Range: 0.125 ~ 256.0
chocolate = 1.0
#.
#Settings for the Goggle Overlay
[client.goggleOverlay]
#.
#Offset the overlay from goggle- and hover- information by this many pixels on the respective axis; Use /create overlay
# Default: 20
# Range: > -2147483648
overlayOffsetX = 20
#.
#Offset the overlay from goggle- and hover- information by this many pixels on the respective axis; Use /create overlay
# Default: 0
# Range: > -2147483648
overlayOffsetY = 0
#.
#Enable this to use your custom colors for the Goggle- and Hover- Overlay
customColorsOverlay = false
#.
#The custom background color to use for the Goggle- and Hover- Overlays, if enabled
#[in Hex: #AaRrGgBb]
#[@cui:IntDisplay:#]
# Default: -267386864
# Range: > -2147483648
customBackgroundOverlay = -267386864
#.
#The custom top color of the border gradient to use for the Goggle- and Hover- Overlays, if enabled
#[in Hex: #AaRrGgBb]
#[@cui:IntDisplay:#]
# Default: 1347420415
# Range: > -2147483648
customBorderTopOverlay = 1347420415
#.
#The custom bot color of the border gradient to use for the Goggle- and Hover- Overlays, if enabled
#[in Hex: #AaRrGgBb]
#[@cui:IntDisplay:#]
# Default: 1344798847
# Range: > -2147483648
customBorderBotOverlay = 1344798847
#.
#Sound settings
[client.sound]
#.
#Make cogs rumble and machines clatter.
enableAmbientSounds = true
#.
#Maximum volume modifier of Ambient noise
# Default: 0.10000000149011612
# Range: 0.0 ~ 1.0
ambientVolumeCap = 0.10000000149011612
#.
#Mod Integration and Recipe Viewer
[client.recipeViewerIntegration]
#.
#How Recipe Viewer search should interact with Stock Keepers
#Allowed Values: SYNC_BOTH, SYNC_FROM_JEI, SYNC_FROM_STOCK_KEEPER, NONE
syncRecipeViewerSearch = "SYNC_BOTH"
#.
#Railway related settings
[client.trains]
#.
#How far away the Camera should zoom when seated on a train
# Default: 3.0
# Range: 0.0 ~ 3.4028234663852886E38
mountedZoomMultiplier = 3.0
#.
#Display nodes and edges of a Railway Network while f3 debug mode is active
showTrackGraphOnF3 = false
#.
#Additionally display materials of a Rail Network while f3 debug mode is active
showExtendedTrackGraphOnF3 = false
#.
#Display Track Networks and Trains on supported map mods
showTrainMapOverlay = true
#.
#Track Network Color on maps
#Allowed Values: RED, GREY, WHITE
trainMapColorTheme = "RED"
@@ -0,0 +1,36 @@
{
"allowedCEM": "ALL",
"logModelCreationData": false,
"debugOnRightClick": false,
"renderModeChoice": "NORMAL",
"vanillaModelHologramRenderMode_2": "OFF",
"modelExportMode": "NONE",
"automaticModelExporting": false,
"attemptPhysicsModPatch_2": "CUSTOM",
"modelUpdateFrequency": "Average",
"entityRenderModeOverrides": {},
"entityPhysicsModPatchOverrides": {},
"entityVanillaHologramOverrides": {},
"modelsNamesDisabled": [],
"allowEBEModConfigModify": true,
"animationLODDistance": 20,
"retainDetailOnLowFps": true,
"retainDetailOnLargerMobs": true,
"animationFrameSkipDuringIrisShadowPass": true,
"preventFirstPersonHandAnimating": false,
"onlyClientPlayerModel": false,
"doubleChestAnimFix": true,
"enforceOptifineVariationRequiresDefaultModel": false,
"enforceOptifineVariationRequiresDefaultModel_v2": false,
"resetPlayerModelEachRender": true,
"resetPlayerModelEachRender_v2": true,
"onlyDebugRenderOnHover": false,
"enforceOptifineSubFoldersVariantOnly": false,
"enforceOptiFineAnimSyntaxLimits": true,
"allowOptifineFallbackProperties": true,
"showReloadErrorToast": true,
"exportRotations": false,
"asmMaths": true,
"logASM": false,
"parrotShoulderPositionAnimatesByDefault": true
}
@@ -0,0 +1,41 @@
{
"optifine_limitRandomVariantGapsBy10": false,
"optifine_allowWeirdSkipsInTrueRandom": true,
"optifine_preventBaseTextureInOptifineDirectory": true,
"illegalPathSupportMode": "None",
"enableCustomTextures": true,
"enableCustomBlockEntities": true,
"textureUpdateFrequency_V2": "Fast",
"enableEmissiveTextures": true,
"enableEnchantedTextures": true,
"enableEmissiveBlockEntities": true,
"emissiveRenderMode": "DULL",
"alwaysCheckVanillaEmissiveSuffix": true,
"enableArmorAndTrims": true,
"skinFeaturesEnabled": true,
"skinTransparencyMode": "ETF_SKINS_ONLY",
"skinTransparencyInExtraPixels": true,
"skinFeaturesEnableTransparency": true,
"skinFeaturesEnableFullTransparency": false,
"tryETFTransparencyForAllSkins": false,
"enableEnemyTeamPlayersSkinFeatures": true,
"enableBlinking": true,
"blinkFrequency": 150,
"blinkLength": 1,
"advanced_IncreaseCacheSizeModifier": 1.0,
"debugLoggingMode": "None",
"logTextureDataInitialization": false,
"hideConfigButton": false,
"stackDebugPrinting": false,
"configButtonLoc": "BOTTOM_RIGHT",
"disableVanillaDirectoryVariantTextures": false,
"use3DSkinLayerPatch": true,
"enableFullBodyWardenTextures": true,
"entityEmissiveOverrides": {},
"propertiesDisabled": [],
"propertyInvertUpdatingOverrides": [],
"entityRandomOverrides": {},
"entityEmissiveBrightOverrides": {},
"entityRenderLayerOverrides": {},
"entityLightOverrides": {}
}
@@ -0,0 +1,149 @@
[ui]
#Tooltips for Developing Film Rolls and Copying Photographs will be shown on Film Rolls and Photographs respectively, describing the crafting recipe.
#Only when JEI is not installed. (Only JEI shows these recipes, not REI or EMI)
recipe_tooltips_without_jei = true
#Details about Camera configuring will be shown in Camera item tooltip.
camera_details_tooltip = true
#Film Roll Frames will be shown in the camera tooltip.
#Default: true
camera_film_frames_tooltip = true
#Film Roll fullness bar will be shown on the Camera item.
#Default: false
camera_shows_film_bar = false
#Photographer name will be shown in Photograph's tooltip.
photograph_photographer_name_tooltip = false
#Crosshair will not get in the way when holding a photograph.
photograph_in_hand_hide_crosshair = true
#When looking at the Camera Stand, in-world tooltip will show information about the camera on it. Default: true
camera_stand_tooltip = true
#Album will show how many photographs it contains in a tooltip.
album_show_photos_count = true
[ui.album]
#Color in hex format. AARRGGBB.
font_main_color = "FFB59774"
#Color in hex format. AARRGGBB.
font_secondary_color = "FFEFE4CA"
#Color in hex format. AARRGGBB.
selection_color = "FF8888FF"
#Color in hex format. AARRGGBB.
selection_unfocused_color = "FFBBBBFF"
[viewfinder]
#Clicking middle mouse button will open Viewfinder Controls. This is independent of Open Camera Controls keybind.
#Allows opening camera controls without dismounting from a vehicle - and keeping controls on sneak or other button as well.
#Default: true
middle_click_controls = true
#How much zooming influences mouse sensitivity.
#0 - no change to sensitivity. 1 - full effect.
#Default: 0.75
# Default: 0.75
# Range: 0.0 ~ 1.0
zoom_sensitivity_influence = 0.75
#Color in hex format. AARRGGBB.
background_color = "FA1F1D1B"
#Color in hex format. AARRGGBB.
font_main_color = "FF2B2622"
#Color in hex format. AARRGGBB.
font_secondary_color = "FF7A736C"
#HUD will be hidden while looking through viewfinder. Default: true
hide_hud_while_in_viewfinder = true
#X offset of a viewfinder status icon. Default: 0
# Default: 0
# Range: -999 ~ 999
status_icon_offset_x = 0
#Y offset of a viewfinder status icon. Default: 0
# Default: 0
# Range: -999 ~ 999
status_icon_offset_y = 0
[capture]
#Keep Post Effect (vanilla shader) when capturing an image.
#It is sometimes used by mods to change how player sees the world. (Cold Sweat's overheating blur, Supplementaries mob heads, for example).
#In vanilla, it's only used when spectating a creeper/enderman/etc.
#Default: false
keep_post_effect = false
#Delay in ticks before capturing an image when shooting with flash.
#If you experience flash synchronization issues (Flash having no effect on the image) - try increasing the value.
# Default: 4
# Range: 1 ~ 8
flash_capture_delay_ticks = 4
#Force legacy (pre 1.21) capturing method for taking images. Enable if you experiencing issues with resulting images.
#Direct method will be used regardless of this setting if mods defined in 'force_direct_capture_default_mods' is installed.
#Default: false
force_direct_capture = false
#Direct capture will be used if any of these mods is installed.
#Format: '["mod_id", "mod_id"]'. Default: [veil, pmweather]
force_direct_capture_default_mods = ["veil", "pmweather"]
#Delay in frames before capturing an image if 'direct_capture' method is in use.
#Set to higher value when leftovers of GUI elements (such as nameplates) are visible on the images
#(some shaders have temporal effects that take several frames to disappear fully)
# Default: 0
# Range: 0 ~ 100
direct_capture_delay_frames = 0
#Sets the game to 'panoramic mode' when capturing the image with background capture method (default).
#Enabling this might fix some graphical issues, such as water being invisible.
#If captured images are still not looking properly - enable 'force_direct_capture'.
#Default: false
background_capture_use_panoramic_mode = false
[capture.loading]
#Loading from file will only accept a path relative to game directory, when on the dedicated server (multiplayer).
#This option is for protection against malicious actions using Projector or load commands.
#Default: false
multiplayer_file_loading_only_from_game_dir = false
#How loading from URL should behave when on the dedicated server (multiplayer).
#This option is for protection against malicious actions using Projector or load commands.
#Default: ONLY_ALLOWED_DOMAINS
#Allowed Values: ALL, ONLY_ALLOWED_DOMAINS, NONE
multiplayer_url_loading = "ONLY_ALLOWED_DOMAINS"
#List of allowed domains for loading from URl, if 'multiplayer_url_loading' is set to ONLY_ALLOWED_DOMAINS.
multiplayer_url_loading_allowed_domains = ["i.imgur.com", "cdn.discordapp.com", "media.discordapp.net", "raw.githubusercontent.com"]
#List of allowed domains for loading from URl, if 'multiplayer_url_loading' is set to ONLY_ALLOWED_DOMAINS.
multiplayer_url_loading_allowed_subdomains = [".imgur.com", ".discordapp.com"]
[render]
#Makes photos in Photograph Frame render with alignment to 16 pixel grid (like paintings). Just for fun. Default: false
pixel_perfect_photograph_frame = false
#Photographs in Item Frame will be rendered as image instead of an item icon. Default: false
photograph_renders_in_item_frame = false
#Projected photographs (using Interplanar Projector) made by other players will be censored (pixelated). Default: false
censor_projected_photographs_made_by_others = false
#All photographs made by other players will will be censored (pixelated). Default: false
censor_all_photographs_made_by_others = false
#Distance from the player beyond which Photograph Frame would not be rendered. Default: 64
#Note: this number may not relate to distance in blocks exactly. It's influenced by render distance and entity distance settings.
# Default: 64
# Range: 8 ~ 128
photograph_frame_culling_distance = 64
#Depth offset to Photograph in Photograph Frame. Can be used to fix issues with some 3D resourcepacks. Value of 0.015 is good for 'Classic 3D' resourcepack. Default: 0.0
# Default: 0.0
# Range: -1.0 ~ 1.0
photograph_frame_image_offset = 0.0
[integration]
#Useful information about some items will be shown in JEI description category. Default: true
jei_information = true
#[Real Camera] Disable player model rendering when looking through viewfinder. Default: true
real_camera_disable_in_viewfinder = true
[export]
#When the Photograph you took is viewed in UI (by using a Photograph), image will be exported to '<instance>/exposures' folder as a png.
export_viewed_photographs = true
#When exporting, exposures will be organized to subfolders with world name.
export_organize_by_world = true
#Exported exposures will be scaled by this multiplier.
#Given the default exposure size of 320 pixels - this will produce:
#320/640/960/1280/etc image. Be careful with larger frame sizes.
#Default: 2
# Default: 2
# Range: 1 ~ 10
export_size_multiplier = 2
[tutorial]
#Toast that teaches hovering mouse over camera parts will be shown when attachments menu is first opened. Default: true.
#*This setting will be automatically set to false on first show.*
attachments_show_info_toast = true
#Toast that teaches wiki opening will be shown when attachments menu is first opened, after info toast. Default: true.
#*This setting will be automatically set to false on first show.*
attachments_show_wiki_toast = true
@@ -0,0 +1,24 @@
#Use a slightly more compact, but also slightly slower representation for block states
compactFastMap = false
#Replace objects used to detect multi-threaded access to chunks by a much smaller field. This option is disabled by default due to very rare and very hard-to-reproduce crashes, use at your own risk!
useSmallThreadingDetector = false
#Cache the predicate instances used in multipart models
cacheMultipartPredicates = true
#Do not create a new MultipartBakedModel instance for each block state using the same multipartmodel. Requires cacheMultipartPredicates to be enabled
multipartDeduplication = true
#Deduplicate cached data for blockstates, most importantly collision and render shapes
blockstateCacheDeduplication = true
#Save memory overhead from empty data component maps/patched
dataComponentPatch = true
#Avoid creation of new strings when creating ModelResourceLocations
modelResourceLocations = true
#Use smaller data structures for "simple" models, especially models with few side-specific faces
modelSides = true
#Replace the blockstate neighbor table
replaceNeighborLookup = true
#Populate the neighbor table used by vanilla. Enabling this slightly increases memory usage, but can help with issues in the rare case where mods access it directly.
populateNeighborTable = false
#Do not store the properties of a state explicitly and read themfrom the replace neighbor table instead. Requires replaceNeighborLookup to be enabled
replacePropertyMap = true
#Deduplicate vertex data of baked quads in the basic model implementations
bakedQuadDeduplication = true
@@ -0,0 +1,14 @@
#Select the backend to use. Set to "DEFAULT" to let Flywheel decide.
backend = "DEFAULT"
#Enable or disable instance update limiting with distance.
limitUpdates = true
#The number of worker threads to use. Set to -1 to let Flywheel decide. Set to 0 to disable parallelism. Requires a game restart to take effect.
# Default: -1
# Range: -1 ~ 4
workerThreads = -1
#Config options for Flywheel's built-in backends.
[flw_backends]
#How smooth Flywheel's shader-based lighting should be. May have a large performance impact.
#Allowed Values: FLAT, TRI_LINEAR, SMOOTH, SMOOTH_INNER_FACE_CORRECTED
lightSmoothness = "SMOOTH"
@@ -0,0 +1,22 @@
{
"REGULAR_INFO": "----- Regular config values below -----",
"font_atlas_resizing": true,
"map_atlas_generation": true,
"hud_batching": true,
"fast_text_lookup": true,
"fast_buffer_upload": true,
"COSMETIC_INFO": "----- Cosmetic only config values below (Does not optimize anything) -----",
"dont_add_info_into_debug_hud": false,
"EXPERIMENTAL_INFO": "----- Experimental config values below (Rendering glitches may occur) -----",
"experimental_disable_error_checking": false,
"experimental_disable_resource_pack_conflict_handling": false,
"experimental_sign_text_buffering": false,
"experimental_screen_batching": false,
"DEBUG_INFO": "----- Debug only config values below (Do not touch) -----",
"debug_only_and_not_recommended_disable_universal_batching": false,
"debug_only_and_not_recommended_disable_mod_conflict_handling": false,
"debug_only_and_not_recommended_disable_hardware_conflict_handling": false,
"debug_only_print_additional_error_information": false,
"debug_only_use_last_usage_for_batch_ordering": false,
"debug_only_detailed_memory_leak_detection": false
}
@@ -0,0 +1,6 @@
# This is the configuration file for Lithium.
#
# You can find information on editing this file and all the available options here:
# https://github.com/CaffeineMC/lithium-fabric/wiki/Configuration-File
#
# By default, this file will be empty except for this notice.
@@ -0,0 +1,2 @@
#These JEI plugins will be loaded on the main thread
blacklist_async_jei_plugins = ["jepb:jei_plugin"]
@@ -0,0 +1,105 @@
# This is the configuration file for ModernFix.
# In general, prefer using the config screen to editing this file. It can be accessed
# via the standard mod menu on your respective mod loader. Changes will, however,
# require restarting the game to take effect.
#
# The following options can be enabled or disabled if there is a compatibility issue.
# Add a line with your option name and =true or =false at the bottom of the file to enable
# or disable a rule. For example:
# mixin.perf.dynamic_resources=true
# Do not include the #. You may reset to defaults by deleting this file.
#
# To enable features that are still in testing, add a line at the bottom setting the stability level:
# stability_level=BETA
#
# Available options:
# mixin.bugfix.chunk_deadlock=true # (default)
# mixin.bugfix.cofh_core_crash=true # (default)
# mixin.bugfix.concurrency=true # (default)
# mixin.bugfix.ctm_resourceutil_cme=true # (default)
# mixin.bugfix.ender_dragon_leak=true # (default)
# mixin.bugfix.entity_pose_stack=true # (default)
# mixin.bugfix.extra_experimental_screen=true # (default)
# mixin.bugfix.fix_config_crashes=true # (default)
# mixin.bugfix.missing_block_entities=false # (default)
# mixin.bugfix.packet_leak=false # (default)
# mixin.bugfix.paper_chunk_patches=true # (default)
# mixin.bugfix.recipe_book_type_desync=true # (default)
# mixin.bugfix.restore_old_dragon_movement=false # (default)
# mixin.bugfix.skip_redundant_saves=false # (default)
# mixin.bugfix.sprite_borders=true # (default)
# mixin.bugfix.unsafe_modded_shape_caches=true # (default)
# mixin.bugfix.world_leaks=true # (default)
# mixin.bugfix.world_screen_skipped=true # (default)
# mixin.devenv=false # (default)
# mixin.feature.blockentity_incorrect_thread=false # (default)
# mixin.feature.branding=true # (default)
# mixin.feature.cause_lag_by_disabling_threads=false # (default)
# mixin.feature.direct_stack_trace=false # (default)
# mixin.feature.integrated_server_watchdog=true # (default)
# mixin.feature.log_stdout_in_log_files=true # (default)
# mixin.feature.mcfunction_profiling=true # (default)
# mixin.feature.measure_time=true # (default)
# mixin.feature.registry_event_progress=true # (default)
# mixin.feature.remove_chat_signing=false # (default)
# mixin.feature.remove_telemetry=true # (default)
# mixin.feature.snapshot_easter_egg=true # (default)
# mixin.feature.spam_thread_dump=false # (default)
# mixin.feature.spark_profile_launch=false # (default)
# mixin.feature.spark_profile_world_join=false # (default)
# mixin.feature.stalled_chunk_load_detection=false # (default)
# mixin.feature.suppress_narrator_stacktrace=true # (default)
# mixin.feature.warn_missing_perf_mods=true # (default)
# mixin.launch.class_search_cache=true # (default)
# mixin.perf.attribute_supplier_dedup=true # (default)
# mixin.perf.cache_blockstate_cache_arrays=true # (default)
# mixin.perf.cache_profile_texture_url=true # (default)
# mixin.perf.cache_strongholds=true # (default)
# mixin.perf.capability_list_compaction=true # (default)
# mixin.perf.chunk_meshing=true # (default)
# mixin.perf.clear_mixin_classinfo=false # (default)
# mixin.perf.compact_bit_storage=true # (default)
# mixin.perf.compact_entity_models=true # (default)
# mixin.perf.compact_imposterprotochunks=true # (default)
# mixin.perf.compact_mojang_registries=true # (default)
# mixin.perf.compress_unihex_font=true # (default)
# mixin.perf.datapack_reload_exceptions=true # (default)
# mixin.perf.dedicated_reload_executor=true # (default)
# mixin.perf.deduplicate_climate_parameters=false # (default)
# mixin.perf.deduplicate_location=false # (default)
# mixin.perf.deduplicate_wall_shapes=true # (default)
# mixin.perf.dynamic_dfu=true # (default)
# mixin.perf.dynamic_entity_renderers=false # (default)
# mixin.perf.dynamic_languages=true # (default)
# mixin.perf.dynamic_resources=false # (default)
# mixin.perf.dynamic_resources.ctm=true # (default)
# mixin.perf.dynamic_resources.ldlib=true # (default)
# mixin.perf.dynamic_structure_manager=true # (default)
# mixin.perf.encoder_cache_leak=true # (default)
# mixin.perf.faster_ingredients=true # (default)
# mixin.perf.faster_item_rendering=false # (default)
# mixin.perf.faster_texture_stitching=true # (default)
# mixin.perf.fix_loop_spin_waiting=true # (default)
# mixin.perf.forge_registry_alloc=true # (default)
# mixin.perf.ingredient_item_deduplication=true # (default)
# mixin.perf.lazy_search_tree_registry=true # (default)
# mixin.perf.memoize_creative_tab_build=true # (default)
# mixin.perf.model_optimizations=true # (default)
# mixin.perf.mojang_registry_size=true # (default)
# mixin.perf.optimize_surface_rules=true # (default)
# mixin.perf.patchouli_deduplicate_books=true # (default)
# mixin.perf.reduce_blockstate_cache_rebuilds=true # (default)
# mixin.perf.release_protochunks=true # (default)
# mixin.perf.remove_biome_temperature_cache=true # (default)
# mixin.perf.resourcepacks=true # (default)
# mixin.perf.smart_ingredient_sync=true # (default)
# mixin.perf.state_definition_construct=true # (default)
# mixin.perf.suspend_integrated_server_during_load=true # (default)
# mixin.perf.tag_id_caching=true # (default)
# mixin.perf.thread_priorities=true # (default)
# mixin.perf.ticking_chunk_alloc=true # (default)
# mixin.perf.worldgen_allocation=true # (default)
# mixin.safety=true # (default)
# stability_level=GA # (default)
#
# User overrides go here.
@@ -0,0 +1,17 @@
[client]
#Toggles the lantern glow effect, which may look bad with certain shaders.
glow_effect = true
#Toggles the Umvuthana footprint effects, which may decrease performance.
umvuthana_footprints = true
#Enable camera shaking during certain mob attacks and abilities.
do_camera_shake = true
#Play boss battle themes during boss encounters.
play_boss_music = true
#Use custom boss health bar textures, if the boss has them.
custom_boss_bar = true
#Use custom player animations.
custom_player_anims = true
#Set to true to hide your own 3rd-person player animations while you are in 1st-person view mode. This is useful with mods that render the 3rd-person model in 1st-person, as some of the Mowzie's Mobs 3rd-person animations can block the camera.
hide_player_anims_in_first_person = false
#Play Umvuthana Crane heal sounds. Turn this off if you are experiencing crashes when Cranes appear during Umvuthi's boss battle.
crane_heal_sounds = true
@@ -0,0 +1,8 @@
#EXPERIMENTAL: Enable the NeoForge block rendering pipeline - fixes the lighting of custom models.
experimentalForgeLightPipelineEnabled = false
#When enabled, NeoForge will show any warnings that occurred during loading.
showLoadWarnings = true
#Set to true to use a combined DEPTH_STENCIL attachment instead of two separate ones.
useCombinedDepthStencilAttachment = false
#A config option mainly for developers. Logs out configuration values that do not have translations when running a client in a development environment.
logUntranslatedConfigurationWarnings = true
@@ -0,0 +1,21 @@
#Whether sub-levels should apply block shading dynamically
sub_level_dynamic_shading = true
#Whether sub-levels can occlude the water surface
sub_level_water_occlusion = true
#Whether sub-levels should cast a shadow on the world
sub_level_skylight_shadows = false
#Whether to draw loaded chunks on the client in the chunk debug renderer
debug_draw_loaded_chunks = false
#The distance back in game-ticks that the snapshot interpolation should operate
# Default: 1.5
# Range: 0.0 ~ 100.0
sub_level_snapshot_interpolation_delay_ticks = 1.5
#The renderer to use for sub-levels
#Allowed Values: SODIUM_REACHAROUND
sub_level_renderer = "SODIUM_REACHAROUND"
#The zoom sensitivity for sub-level camera types
# Default: 0.2
# Range: 0.0 ~ 100.0
sub_level_zoom_sensitivity = 0.2
#If Sable should attempt to establish a UDP connection with the server, to receive sub-level movement data over a UDP channel
attempt_udp_networking = true
@@ -0,0 +1,36 @@
#.
#Settings of Simulated Items
[items]
#.
#.
#When to display physics properties in block tooltips
#Allowed Values: ALWAYS, SHIFT, GOGGLES, SHIFT_GOGGLES, NEVER
displayProperties = "GOGGLES"
#.
#The sensitivity of scrolling when holding a sub-level with the Creative Physics Staff
# Default: 0.6000000238418579
# Range: 0.0 ~ 3.4028234663852886E38
physics_staff_scroll_sensitivity = 0.6000000238418579
#.
#The sensitivity of rotation when holding a sub-level with the Creative Physics Staff
# Default: 0.3499999940395355
# Range: 0.0 ~ 3.4028234663852886E38
physics_staff_rotate_sensitivity = 0.3499999940395355
#.
#If ponders that have new additions should display the "(New!)" text
show_new_ponders = true
#.
#Settings of Simulated Blocks
[block]
#.
#.
#Offsets the Steering Wheel GUI on the X axis.
# Default: 0
# Range: -1000 ~ 1000
steering_wheel_x_offset = 0
#.
#Offsets the Steering Wheel GUI on the Y axis.
# Default: 0
# Range: -1000 ~ 1000
steering_wheel_y_offset = 0
@@ -0,0 +1,20 @@
{
"enableHat": true,
"enableJacket": true,
"enableLeftSleeve": true,
"enableRightSleeve": true,
"enableLeftPants": true,
"enableRightPants": true,
"baseVoxelSize": 1.15,
"bodyVoxelWidthSize": 1.05,
"headVoxelSize": 1.18,
"renderDistanceLOD": 14,
"enableSkulls": true,
"enableSkullsItems": true,
"skullVoxelSize": 1.1,
"fastRender": true,
"compatibilityMode": true,
"irisCompatibilityMode": false,
"applySodiumWorkaround": false,
"firstPersonPixelScaling": 1.1
}
@@ -0,0 +1,6 @@
# This is the configuration file for Sodium.
#
# You can find information on editing this file and all the available options here:
# https://github.com/CaffeineMC/sodium/wiki/Configuration-File
#
# By default, this file will be empty except for this notice.
@@ -0,0 +1,30 @@
{
"quality": {
"weather_quality": "DEFAULT",
"leaves_quality": "DEFAULT",
"enable_vignette": true,
"use_closest_point_entity_sort": false
},
"advanced": {
"enable_memory_tracing": false,
"use_advanced_staging_buffers": true,
"cpu_render_ahead_limit": 3
},
"performance": {
"chunk_builder_threads": 0,
"chunk_build_defer_mode": "ALWAYS",
"animate_only_visible_textures": true,
"use_entity_culling": true,
"use_fog_occlusion": true,
"use_block_face_culling": true,
"use_no_error_g_l_context": true,
"quad_splitting_mode": "SAFE"
},
"notifications": {
"has_cleared_donation_button": false,
"has_seen_donation_prompt": false
},
"debug": {
"terrain_sorting_enabled": true
}
}
@@ -0,0 +1,219 @@
# Values for blocks can be defined as follows:
#
# By sound type:
# WOOD=1.0
#
# By block tag:
# \#minecraft\:logs=1.0
#
# By block ID:
# minecraft\:oak_log=1.0
# Amethyst (Sound Type)
AMETHYST=1.0
# Amethyst Cluster (Sound Type)
AMETHYST_CLUSTER=1.0
# Ancient Debris (Sound Type)
ANCIENT_DEBRIS=1.0
# Anvil (Sound Type)
ANVIL=1.0
# Azalea (Sound Type)
AZALEA=1.0
# Azalea Leaves (Sound Type)
AZALEA_LEAVES=1.0
# Bamboo (Sound Type)
BAMBOO=0.1
# Bamboo Sapling (Sound Type)
BAMBOO_SAPLING=0.1
# Bamboo Wood (Sound Type)
BAMBOO_WOOD=1.0
# Bamboo Wood Hanging Sign (Sound Type)
BAMBOO_WOOD_HANGING_SIGN=1.0
# Basalt (Sound Type)
BASALT=1.0
# Big Dripleaf (Sound Type)
BIG_DRIPLEAF=1.0
# Bone Block (Sound Type)
BONE_BLOCK=1.0
# Calcite (Sound Type)
CALCITE=1.0
# Candle (Sound Type)
CANDLE=1.0
# Cave Vines (Sound Type)
CAVE_VINES=1.0
# Chain (Sound Type)
CHAIN=0.0
# Cherry Leaves (Sound Type)
CHERRY_LEAVES=1.0
# Cherry Sapling (Sound Type)
CHERRY_SAPLING=1.0
# Cherry Wood (Sound Type)
CHERRY_WOOD=1.0
# Cherry Wood Hanging Sign (Sound Type)
CHERRY_WOOD_HANGING_SIGN=1.0
# Chiseled Bookshelf (Sound Type)
CHISELED_BOOKSHELF=1.0
# Copper (Sound Type)
COPPER=1.0
# Coral Block (Sound Type)
CORAL_BLOCK=1.0
# Crop (Sound Type)
CROP=0.0
# Decorated Pot (Sound Type)
DECORATED_POT=1.0
# Decorated Pot Cracked (Sound Type)
DECORATED_POT_CRACKED=1.0
# Deepslate (Sound Type)
DEEPSLATE=1.0
# Deepslate Bricks (Sound Type)
DEEPSLATE_BRICKS=1.0
# Deepslate Tiles (Sound Type)
DEEPSLATE_TILES=1.0
# Dripstone Block (Sound Type)
DRIPSTONE_BLOCK=1.0
# Flowering Azalea (Sound Type)
FLOWERING_AZALEA=1.0
# Froglight (Sound Type)
FROGLIGHT=1.0
# Frogspawn (Sound Type)
FROGSPAWN=1.0
# Fungus (Sound Type)
FUNGUS=0.0
# Gilded Blackstone (Sound Type)
GILDED_BLACKSTONE=1.0
# Glass (Sound Type)
GLASS=0.1
# Glow Lichen (Sound Type)
GLOW_LICHEN=0.0
# Grass (Sound Type)
GRASS=1.0
# Gravel (Sound Type)
GRAVEL=1.0
# Hanging Roots (Sound Type)
HANGING_ROOTS=1.0
# Hanging Sign (Sound Type)
HANGING_SIGN=1.0
# Hard Crop (Sound Type)
HARD_CROP=1.0
# Honey Block (Sound Type)
HONEY_BLOCK=0.5
# Ladder (Sound Type)
LADDER=0.0
# Lantern (Sound Type)
LANTERN=1.0
# Large Amethyst Bud (Sound Type)
LARGE_AMETHYST_BUD=0.0
# Lily Pad (Sound Type)
LILY_PAD=0.0
# Lodestone (Sound Type)
LODESTONE=1.0
# Mangrove Roots (Sound Type)
MANGROVE_ROOTS=1.0
# Medium Amethyst Bud (Sound Type)
MEDIUM_AMETHYST_BUD=0.0
# Metal (Sound Type)
METAL=1.0
# Moss (Sound Type)
MOSS=0.75
# Moss Carpet (Sound Type)
MOSS_CARPET=0.1
# Mud (Sound Type)
MUD=1.0
# Muddy Mangrove Roots (Sound Type)
MUDDY_MANGROVE_ROOTS=1.0
# Mud Bricks (Sound Type)
MUD_BRICKS=1.0
# Netherite Block (Sound Type)
NETHERITE_BLOCK=1.0
# Netherrack (Sound Type)
NETHERRACK=1.0
# Nether Bricks (Sound Type)
NETHER_BRICKS=1.0
# Nether Gold Ore (Sound Type)
NETHER_GOLD_ORE=1.0
# Nether Ore (Sound Type)
NETHER_ORE=1.0
# Nether Sprouts (Sound Type)
NETHER_SPROUTS=1.0
# Nether Wart (Sound Type)
NETHER_WART=1.0
# Nether Wood (Sound Type)
NETHER_WOOD=1.0
# Nether Wood Hanging Sign (Sound Type)
NETHER_WOOD_HANGING_SIGN=1.0
# Nylium (Sound Type)
NYLIUM=1.0
# Packed Mud (Sound Type)
PACKED_MUD=1.0
# Pointed Dripstone (Sound Type)
POINTED_DRIPSTONE=0.0
# Polished Deepslate (Sound Type)
POLISHED_DEEPSLATE=1.0
# Powder Snow (Sound Type)
POWDER_SNOW=0.1
# Rooted Dirt (Sound Type)
ROOTED_DIRT=1.0
# Roots (Sound Type)
ROOTS=0.0
# Sand (Sound Type)
SAND=1.0
# Scaffolding (Sound Type)
SCAFFOLDING=0.0
# Sculk (Sound Type)
SCULK=1.0
# Sculk Catalyst (Sound Type)
SCULK_CATALYST=1.0
# Sculk Sensor (Sound Type)
SCULK_SENSOR=1.0
# Sculk Shrieker (Sound Type)
SCULK_SHRIEKER=1.0
# Sculk Vein (Sound Type)
SCULK_VEIN=1.0
# Shroomlight (Sound Type)
SHROOMLIGHT=1.0
# Slime Block (Sound Type)
SLIME_BLOCK=1.0
# Small Amethyst Bud (Sound Type)
SMALL_AMETHYST_BUD=0.0
# Small Dripleaf (Sound Type)
SMALL_DRIPLEAF=0.0
# Snow (Sound Type)
SNOW=0.1
# Soul Sand (Sound Type)
SOUL_SAND=1.0
# Soul Soil (Sound Type)
SOUL_SOIL=1.0
# Spore Blossom (Sound Type)
SPORE_BLOSSOM=0.0
# Stem (Sound Type)
STEM=1.0
# Stone (Sound Type)
STONE=1.0
# Suspicious Gravel (Sound Type)
SUSPICIOUS_GRAVEL=1.0
# Suspicious Sand (Sound Type)
SUSPICIOUS_SAND=1.0
# Sweet Berry Bush (Sound Type)
SWEET_BERRY_BUSH=0.0
# Tuff (Sound Type)
TUFF=1.0
# Twisting Vines (Sound Type)
TWISTING_VINES=0.0
# Vine (Sound Type)
VINE=0.0
# Wart Block (Sound Type)
WART_BLOCK=1.0
# Weeping Vines (Sound Type)
WEEPING_VINES=0.0
# Wet Grass (Sound Type)
WET_GRASS=0.1
# Wood (Sound Type)
WOOD=1.0
# Wool (Sound Type)
WOOL=1.5
# Jukebox (Block)
minecraft\:jukebox=0.0
# Lava (Block)
minecraft\:lava=0.75
# Water (Block)
minecraft\:water=0.25
@@ -0,0 +1,213 @@
# Values for blocks can be defined as follows:
#
# By sound type:
# WOOD=1.0
#
# By block tag:
# \#minecraft\:logs=1.0
#
# By block ID:
# minecraft\:oak_log=1.0
# Amethyst (Sound Type)
AMETHYST=1.5
# Amethyst Cluster (Sound Type)
AMETHYST_CLUSTER=0.5
# Ancient Debris (Sound Type)
ANCIENT_DEBRIS=0.5
# Anvil (Sound Type)
ANVIL=0.5
# Azalea (Sound Type)
AZALEA=0.5
# Azalea Leaves (Sound Type)
AZALEA_LEAVES=0.5
# Bamboo (Sound Type)
BAMBOO=0.5
# Bamboo Sapling (Sound Type)
BAMBOO_SAPLING=0.5
# Bamboo Wood (Sound Type)
BAMBOO_WOOD=0.5
# Bamboo Wood Hanging Sign (Sound Type)
BAMBOO_WOOD_HANGING_SIGN=0.5
# Basalt (Sound Type)
BASALT=1.5
# Big Dripleaf (Sound Type)
BIG_DRIPLEAF=0.5
# Bone Block (Sound Type)
BONE_BLOCK=1.5
# Calcite (Sound Type)
CALCITE=1.5
# Candle (Sound Type)
CANDLE=0.5
# Cave Vines (Sound Type)
CAVE_VINES=0.5
# Chain (Sound Type)
CHAIN=0.5
# Cherry Leaves (Sound Type)
CHERRY_LEAVES=0.5
# Cherry Sapling (Sound Type)
CHERRY_SAPLING=0.5
# Cherry Wood (Sound Type)
CHERRY_WOOD=0.5
# Cherry Wood Hanging Sign (Sound Type)
CHERRY_WOOD_HANGING_SIGN=0.5
# Chiseled Bookshelf (Sound Type)
CHISELED_BOOKSHELF=0.5
# Copper (Sound Type)
COPPER=1.25
# Coral Block (Sound Type)
CORAL_BLOCK=0.2
# Crop (Sound Type)
CROP=0.5
# Decorated Pot (Sound Type)
DECORATED_POT=0.5
# Decorated Pot Cracked (Sound Type)
DECORATED_POT_CRACKED=0.5
# Deepslate (Sound Type)
DEEPSLATE=1.5
# Deepslate Bricks (Sound Type)
DEEPSLATE_BRICKS=1.5
# Deepslate Tiles (Sound Type)
DEEPSLATE_TILES=1.5
# Dripstone Block (Sound Type)
DRIPSTONE_BLOCK=0.5
# Flowering Azalea (Sound Type)
FLOWERING_AZALEA=0.5
# Froglight (Sound Type)
FROGLIGHT=0.5
# Frogspawn (Sound Type)
FROGSPAWN=0.5
# Fungus (Sound Type)
FUNGUS=0.5
# Gilded Blackstone (Sound Type)
GILDED_BLACKSTONE=0.5
# Glass (Sound Type)
GLASS=0.75
# Glow Lichen (Sound Type)
GLOW_LICHEN=0.5
# Grass (Sound Type)
GRASS=0.3
# Gravel (Sound Type)
GRAVEL=0.3
# Hanging Roots (Sound Type)
HANGING_ROOTS=0.5
# Hanging Sign (Sound Type)
HANGING_SIGN=0.5
# Hard Crop (Sound Type)
HARD_CROP=0.5
# Honey Block (Sound Type)
HONEY_BLOCK=0.1
# Ladder (Sound Type)
LADDER=0.5
# Lantern (Sound Type)
LANTERN=0.5
# Large Amethyst Bud (Sound Type)
LARGE_AMETHYST_BUD=0.5
# Lily Pad (Sound Type)
LILY_PAD=0.5
# Lodestone (Sound Type)
LODESTONE=0.5
# Mangrove Roots (Sound Type)
MANGROVE_ROOTS=0.5
# Medium Amethyst Bud (Sound Type)
MEDIUM_AMETHYST_BUD=0.5
# Metal (Sound Type)
METAL=1.25
# Moss (Sound Type)
MOSS=0.1
# Moss Carpet (Sound Type)
MOSS_CARPET=0.5
# Mud (Sound Type)
MUD=0.5
# Muddy Mangrove Roots (Sound Type)
MUDDY_MANGROVE_ROOTS=0.5
# Mud Bricks (Sound Type)
MUD_BRICKS=0.5
# Netherite Block (Sound Type)
NETHERITE_BLOCK=1.5
# Netherrack (Sound Type)
NETHERRACK=1.1
# Nether Bricks (Sound Type)
NETHER_BRICKS=1.5
# Nether Gold Ore (Sound Type)
NETHER_GOLD_ORE=1.1
# Nether Ore (Sound Type)
NETHER_ORE=1.1
# Nether Sprouts (Sound Type)
NETHER_SPROUTS=0.5
# Nether Wart (Sound Type)
NETHER_WART=0.5
# Nether Wood (Sound Type)
NETHER_WOOD=0.5
# Nether Wood Hanging Sign (Sound Type)
NETHER_WOOD_HANGING_SIGN=0.5
# Nylium (Sound Type)
NYLIUM=0.5
# Packed Mud (Sound Type)
PACKED_MUD=0.5
# Pointed Dripstone (Sound Type)
POINTED_DRIPSTONE=0.5
# Polished Deepslate (Sound Type)
POLISHED_DEEPSLATE=1.5
# Powder Snow (Sound Type)
POWDER_SNOW=0.5
# Rooted Dirt (Sound Type)
ROOTED_DIRT=0.5
# Roots (Sound Type)
ROOTS=0.5
# Sand (Sound Type)
SAND=0.2
# Scaffolding (Sound Type)
SCAFFOLDING=0.5
# Sculk (Sound Type)
SCULK=0.5
# Sculk Catalyst (Sound Type)
SCULK_CATALYST=0.5
# Sculk Sensor (Sound Type)
SCULK_SENSOR=0.5
# Sculk Shrieker (Sound Type)
SCULK_SHRIEKER=0.5
# Sculk Vein (Sound Type)
SCULK_VEIN=0.5
# Shroomlight (Sound Type)
SHROOMLIGHT=0.5
# Slime Block (Sound Type)
SLIME_BLOCK=0.5
# Small Amethyst Bud (Sound Type)
SMALL_AMETHYST_BUD=0.5
# Small Dripleaf (Sound Type)
SMALL_DRIPLEAF=0.5
# Snow (Sound Type)
SNOW=0.15
# Soul Sand (Sound Type)
SOUL_SAND=0.2
# Soul Soil (Sound Type)
SOUL_SOIL=0.2
# Spore Blossom (Sound Type)
SPORE_BLOSSOM=0.5
# Stem (Sound Type)
STEM=0.4
# Stone (Sound Type)
STONE=1.5
# Suspicious Gravel (Sound Type)
SUSPICIOUS_GRAVEL=0.5
# Suspicious Sand (Sound Type)
SUSPICIOUS_SAND=0.5
# Sweet Berry Bush (Sound Type)
SWEET_BERRY_BUSH=0.5
# Tuff (Sound Type)
TUFF=1.5
# Twisting Vines (Sound Type)
TWISTING_VINES=0.5
# Vine (Sound Type)
VINE=0.5
# Wart Block (Sound Type)
WART_BLOCK=0.5
# Weeping Vines (Sound Type)
WEEPING_VINES=0.5
# Wet Grass (Sound Type)
WET_GRASS=0.5
# Wood (Sound Type)
WOOD=0.4
# Wool (Sound Type)
WOOL=0.1
@@ -0,0 +1,99 @@
# Enables/Disables all sound effects
enabled=true
# Affects how quiet a sound gets based on distance
# Lower values mean distant sounds are louder
# This setting requires you to be in singleplayer or having the mod installed on the server
# 1.0 is the physically correct value
attenuation_factor=1.0
# The ray distance at which reverb starts
# 0.0 disables reverb attenuation
reverb_attenuation_distance=0.0
# The volume of simulated reverberations
reverb_gain=1.0
# The brightness of reverberation
# Higher values result in more high frequencies in reverberation
# Lower values give a more muffled sound to the reverb
reverb_brightness=1.0
# The distance of reverb relative to the sound distance
reverb_distance=1.5
# The amount of sound that will be absorbed when traveling through blocks
block_absorption=1.0
# Higher values mean smaller objects won't be considered as occluding
occlusion_variation=0.35
# The default amount of sound reflectance energy for all blocks
# Lower values result in more conservative reverb simulation with shorter reverb tails
# Higher values result in more generous reverb simulation with higher reverb tails
default_block_reflectivity=0.5
# The default amount of occlusion for all blocks
# Lower values will result in sounds being less muffled through walls
# Higher values mean sounds will be not audible though thicker walls
default_block_occlusion_factor=1.0
# Minecraft won't allow sounds to play past a certain distance
# This parameter is a multiplier for how far away a sound source is allowed to be in order for it to actually play
# This setting only takes affect in singleplayer worlds and when installed on the server
sound_distance_allowance=4.0
# A value controlling the amount that air absorbs high frequencies with distance
# A value of 1.0 is physically correct for air with normal humidity and temperature
# Higher values mean air will absorb more high frequencies with distance
# 0 disables this effect
air_absorption=1.0
# How much sound is filtered when the player is underwater
# 0.0 means no filter
# 1.0 means fully filtered
underwater_filter=0.9
# Whether sounds like cave, nether or underwater ambient sounds should have sound physics
evaluate_ambient_sounds=false
# The number of rays to trace to determine reverberation for each sound source
# More rays provides more consistent tracing results but takes more time to calculate
# Decrease this value if you experience lag spikes when sounds play
environment_evaluation_ray_count=32
# The number of rays bounces to trace to determine reverberation for each sound source
# More bounces provides more echo and sound ducting but takes more time to calculate
# Decrease this value if you experience lag spikes when sounds play
environment_evaluation_ray_bounces=4
# If sound hits a non-full-square side, block occlusion is multiplied by this
non_full_block_occlusion_factor=0.25
# The maximum amount of rays to determine occlusion
# Directly correlates to the amount of blocks between walls that are considered
max_occlusion_rays=16
# The amount at which occlusion is capped
max_occlusion=64.0
# If enabled, the occlusion calculation only uses one path between the sound source and the listener instead of 9
strict_occlusion=false
# Whether to try calculating where the sound should come from based on reflections
sound_direction_evaluation=true
# Skip redirecting non-occluded sounds (the ones you can see directly)
redirect_non_occluded_sounds=true
# If music discs or other longer sounds should be frequently reevaluated
update_moving_sounds=false
# The interval in ticks that moving sounds are reevaluated
# Lower values mean more frequent reevaluation but also more lag
# This option only takes effect if update_moving_sounds is enabled
sound_update_interval=5
# The maximum distance a sound can be processed
max_sound_processing_distance=512.0
# Disable level clone and cache. This will fall back to original main thread access.
# WARNING! Enabling this will cause instability and issues with other mods.
unsafe_level_access=false
# The radius of chunks to clone for level access
level_clone_range=4
# The maximum number of ticks to retain the cloned level in the cache
level_clone_max_retain_ticks=20
# The maximum distance a player can move from the cloned origin before invalidation
level_clone_max_retain_block_distance=16
# Enables debug logging
debug_logging=false
# Provides more information about occlusion in the logs
occlusion_logging=false
# Provides more information about the environment calculation in the logs
environment_logging=false
# Provides more information about how long computations take
performance_logging=false
# If enabled, the path of the sound will be rendered in game
render_sound_bounces=false
# If enabled, occlusion will be visualized in game
render_occlusion=false
# Enables/Disables sound effects for Simple Voice Chat audio
simple_voice_chat_integration=true
# Enables/Disables hearing your own echo with Simple Voice Chat
simple_voice_chat_hear_self=false
@@ -0,0 +1,182 @@
# Client-perf configs: generator, tiers, bench variants
**Status (`a01bc3b`):** the owner approved the mechanism below. Default Options is in the
pack, and the `T-default` files are shipped under `config/defaultoptions/` via
`build.py --ship`. **Every value is still unmeasured.** `../BENCH-MATRIX.md` decides them.
ModernFix `dynamic_resources` is held back until B6 passes.
```sh
python3 build.py # regenerates out/ (stdlib only, ~1 s)
python3 build.py --ship # + copies T-default into config/defaultoptions/
~/go/bin/packwiz refresh # from the repo root, after --ship
python3 apply_variant.py C1 <instance>/.minecraft # bench: apply a variant (merges options.txt)
```
**Iteration loop:** edit `DEFAULT` / `DECK` / `HIGH` in `build.py`, then `build.py --ship`,
then `packwiz refresh`, then commit. The shipped defaults are seed-once: they reach fresh
installs only. Players who already have the files follow `../PLAYER-TUNING.md` §1.
| Path | What |
| --- | --- |
| `build.py` | Single source of truth: tiers, bench variants, base files. **Fails if an override names a key that isn't already in the base file.** That enforces the "confirmed keys only" rule mechanically. |
| `templates/` | Hand-written bases for files without a same-version observed default (keys taken from the pinned jar or its source, see §3) |
| `out/T-default`, `T-deck`, `T-mid`, `T-high` | Player tiers. `T-mid` = `T-default` |
| `out/C0`, `C1`, `C1-*`, `dh-*`, `fw-*`, … | Phase 2 bench variants (see `../BENCH-MATRIX.md`) |
| `out/MANIFEST.md` | Generated list of every changed key per variant |
| `apply_variant.py` | Bench: apply `out/<ID>/` to an instance, merging `options.txt` |
---
## 1. Delivery mechanism (LEVERS M1): resolved
**Recommendation: add Default Options, and stage the tuned files under
`config/defaultoptions/`. The one exception is `modernfix-mixins.properties`, which ships as
a normal (enforced) packwiz file.** Evidence follows. All of it was read from the exact
versions in use: packwiz `ef87d96` (the commit `~/go/bin/packwiz` was built from, per
`go version -m`), packwiz-installer `v0.5.14` (the jar in the Prism instance reports
`Implementation-Version: v0.5.14`), and Default Options `21.1.8` (source tag
`1.21.1@94e2f17` plus the Modrinth jar).
### packwiz `preserve = true`
| Question | Answer | Evidence |
| --- | --- | --- |
| How is it set? | Only by hand-editing `index.toml`; no CLI flag | `Preserve` exists only in `core/indexfiles.go:29`; no `cmd/` reference |
| Does `packwiz refresh` keep it? | **Yes**, as long as the file stays on disk and not ignored. `updateFileEntry` mutates the loaded entry in place. | `core/indexfiles.go` `updateFileEntry`. **Tested**: kept across refresh, a content change + refresh, and an unrelated `packwiz update` |
| When is it lost? | Any refresh while the file is absent or ignored deletes the entry (`Refresh()` drops entries that are not `markedFound`). Re-adding it comes back **without** `preserve`. | `core/index.go` `Refresh()`. **Tested**: delete → refresh → restore → refresh = `preserve` gone |
| What does the installer do? | Writes the file only if the destination **does not exist**. It never updates it afterwards. | `DownloadTask.kt:222-227` |
| Side effects | (a) When the installer skips the file, the manifest entry gets no `cachedLocation`, so every launch logs "invalidated, marked for redownloading" and the installer can't take its "pack unchanged" fast path (it re-reads the index each launch). (b) If the installer *did* write the file, a later removal from the index **deletes the player's copy** (`UpdateManager.kt:250-262`). | source |
| Timing | Pre-launch (Prism `PreLaunchCommand`), so it beats everything, including mixin-time configs | `instance.cfg` |
| Sided? | **No.** Plain index files have no `side`. This repo *is* the server directory, so a file in `config/` also configures the server. | `indexFile` struct |
### Default Options 21.1.8 (BlayTheNinth)
| Question | Answer | Evidence |
| --- | --- | --- |
| Compatible? | NeoForge `[21-beta,)`, MC `[1.21,)`, Balm `[21.0.39,)`. The pack has Balm 21.0.66. | jar `neoforge.mods.toml` |
| `options.txt` | `config/defaultoptions/options.txt` is copied **only if** `options.txt` is absent. `key_*` lines are stripped (keybinds have their own handler). | `DefaultOptionsDefaultHandlers`, `SimpleDefaultOptionsFileHandler.shouldLoadDefaults` |
| Any config file | `config/defaultoptions/extra/<path>` is copied to `<gamedir>/<path>` **only if** the target is absent | `ExtraDefaultOptionsHandler.loadDefaults` |
| Timing | `EARLY_LOAD` runs at `GameConfig.<init>` RETURN, which is in `Main`, *before* `new Minecraft()`. NeoForge 1.21.1 constructs mods inside `Minecraft.<init>` (`ClientModLoader.begin`, Minecraft.java.patch), so the files land before any mod constructor creates its config. They land **after** mixin bootstrap. | `GameConfigMixin`; NeoForge `1.21.1` patch |
| Sided? | Client-only mod (`dist = CLIENT`), and the files sit in `config/defaultoptions/`, which no server-side code reads | — |
| Updating defaults later | Editing the shipped defaults never clobbers a player's live file. Removing them never deletes anything. | copy-if-absent |
### Why this split
1. **Server bleed rules out `preserve` for most files.** `DistantHorizons.toml` carries
`[server]` and `[common.multiThreading]` sections that the server-side DH also reads.
`ssrd-common.toml` is a NeoForge **COMMON** config: SSRD 1.8.7 registers it with
`ModConfig.Type.COMMON` and reads `physicsRenderDistance` server-side in
`ChunkMapTrackedEntityMixin` and `SubLevelTrackingSystemMixin`. Shipping a client value of
16 into the repo's `config/` would also change the server's tracking.
`config/defaultoptions/extra/` keeps them client-only.
2. **Both mechanisms are seed-once.** Neither reaches an instance that already has the file.
Existing players need a one-time reset (see `../PLAYER-TUNING.md` §1). That's a wash.
3. **ModernFix is the exception.** It reads `config/modernfix-mixins.properties` from its
mixin plugin (`ModernFixMixinPlugin`), which runs before `GameConfig`, so Default Options
is too late on first launch. Ship it **enforced** (a plain packwiz file, no `preserve`).
It's a pack-correctness flag, not a preference, and enforcing it keeps it revertible for
everyone if `dynamic_resources` misbehaves. The server reads it too, but
`dynamic_resources` only patches client resource loading.
4. Default Options also gives default keybinds and default resource packs (its journal is
used only for resource packs), with no index hand-editing and nothing to silently lose on
a refresh.
### Proposed repo layout (not applied)
```
config/defaultoptions/options.txt <- out/T-default/options.txt
config/defaultoptions/extra/config/<file> <- out/T-default/config/<file> (all except ModernFix)
config/modernfix-mixins.properties <- out/T-default/config/modernfix-mixins.properties
```
`.packwizignore`, appended at the bottom (tested with `packwiz refresh` in a scratch copy:
it indexes exactly these 11 files and still ignores runtime `config/*.json`):
```gitignore
# Client perf defaults: seeded by Default Options (copy-if-absent, client only)
!config/defaultoptions
!config/defaultoptions/**
# Read at mixin bootstrap, before Default Options runs: enforced by packwiz
!config/modernfix-mixins.properties
```
Applied in `a01bc3b`, minus the ModernFix lines (held for B6). packwiz wrote
`side = "client"` for Default Options by itself.
---
## 2. Tiers
`T-default` is the pack-wide default and equals `T-mid`. `T-deck` and `T-high` are deltas on
top of it. Every fleet machine is 4C/8T, so the CPU-side levers stay on in every tier.
"High" means a strong GPU, not a strong CPU.
| File | Key | Upstream | **Default / mid** | Deck | High |
| --- | --- | --- | --- | --- | --- |
| options.txt | renderDistance / simulationDistance | 12 / 12 | **8 / 8** | | |
| | biomeBlendRadius | 2 | **1** | 0 | 2 |
| | mipmapLevels | 4 | **2** | | 4 |
| | entityDistanceScaling | 1.0 | **0.75** | | 1.0 |
| | particles / entityShadows | 0 / true | | 1 / false | |
| DistantHorizons.toml | lodChunkRenderDistanceRadius | 256 | **128** | 64 | |
| | enableSsao | true | **false** | | true |
| | numberOfThreads | ceil(nproc/2) = **4** | **2** | | |
| | horizontal / vertical quality, transparency, vanillaFadeMode, lodBiomeBlending | MEDIUM / MEDIUM, COMPLETE, DOUBLE_PASS, 3 | | LOW / LOW, DISABLED, SINGLE_PASS, 1 (= DH's own LOW preset) | |
| sodium-options.json | quality.weather_quality / leaves_quality | DEFAULT | | FAST / FAST | |
| entity_model_features.json | animationLODDistance | 20 | **12** | 8 | |
| | modelUpdateFrequency | Average | **Slow** | | |
| | retainDetailOnLowFps | true | | false | |
| flywheel-client.toml | flw_backends.lightSmoothness | SMOOTH | **TRI_LINEAR** | FLAT | SMOOTH |
| lambdynlights.toml | mode | fancy | **fast** | fastest | |
| | light_sources.entities | true | | false | false |
| soundphysics.properties | environment_evaluation_ray_count / ray_bounces | 32 / 4 | **16 / 2** | | |
| | strict_occlusion | false | | true | true |
| sound_rates.properties | 19 noisy Create sounds | -1 (unlimited) | **4 per tick** | | |
| ssrd-common.toml | physicsRenderDistance | 128 | **16** | | 32 |
| modernfix-mixins.properties | mixin.perf.dynamic_resources | false | **true (gated on B6)** | | |
| sable-client.toml | — | — | unchanged | | |
Notes:
- **Sable**: the defaults are already right (`sub_level_skylight_shadows=false`). The file is
staged only so the bench variant `sable-noshade` (`sub_level_dynamic_shading=false`) has a
base. Don't ship it unless B4 shows a win.
- **SSRD**: 16 is the floor of SSRD's own slider (`minPhysicsRenderDistance = 16`). Players
can still raise it in Sodium's video settings.
- **High-tier DH radius stays 128** because P2 (the fleet's "high" GPU) has only ~8 GB of
free RAM. A player with ≥16 GB free and a 6+ core CPU can go to 192–256
(`PLAYER-TUNING.md`).
- **DH presets are GUI-only** (`qualityPresetSetting` and `threadPresetSetting` are
`ONLY_IN_GUI`), so the files set the raw keys. The values are taken from DH's own preset
tables (`RenderQualityPresetConfigEventHandler`, `ThreadPresetConfigEventHandler` @ 3.3.2).
- **Stripped**: DH `[server] serverId` is a per-install `new Random().nextInt()` ("DO NOT
CHANGE"). It's removed so each install generates its own. DH re-adds missing keys with
their defaults (`ConfigFileHandler.loadEntry` → `saveEntry`).
---
## 3. Key provenance
"Observed" means the file was generated on 2026-09-24 by the **same jar version that's pinned
now**. Versions were checked against that launch's `latest.log` and the instance's `mods/`:
DH 3.3.2, Sodium 0.8.13, EMF 3.3.9, Create 6.0.10 / Flywheel 1.0.6, Sable 2.0.5, SPR 1.5.1.
For DH, all 172 observed values were also diffed against `Config.java` @ 3.3.2. The only
differences are the two machine-computed ones (`numberOfThreads`, `serverId`), so the file
holds no owner edits.
| File | Base | Keys confirmed in |
| --- | --- | --- |
| DistantHorizons.toml | observed (3.3.2) | enum values from `EDhApi*` classes in the jar; defaults and presets from DH core `3.3.2` source |
| sodium-options.json | observed (0.8.13) | `SodiumOptions$LeavesQuality` / `$WeatherQuality` = DEFAULT/FANCY/FAST/FABULOUS (nested mod jar); Gson `LOWER_CASE_WITH_UNDERSCORES` |
| entity_model_features.json | observed (3.3.9) | `ETFConfig$UpdateFrequency` = Never/Slow/Average/Fast/Instant (ETF 7.2.4 jar) |
| flywheel-client.toml | observed (1.0.6) | allowed values are listed in the file's own comment |
| sable-client.toml | observed (2.0.5) | — |
| soundphysics.properties | observed (1.5.1) | — |
| sound_rates.properties | template, partial | `SoundRateConfig.load()` starts from all registered sounds at -1 and overlays file entries (SPR `1.21.1-1.5.1` source). Over-cap sounds play without physics (`SoundPhysics.java`). Create IDs come from the observed list. |
| lambdynlights.toml | template | `DynamicLightsConfig` @ `v4.8.11+1.21.1`. Strings match the nested NeoForge jar. Modes are lowercase `off/fastest/fast/fancy`; dotted keys become TOML tables; missing keys fall back via `getOrElse`. |
| ssrd-common.toml | template | `Config.java` @ SSRD HEAD = 1.8.7 (comments and translation keys match the jar). `ModConfig.Type.COMMON` from `ssrd.class`. |
| modernfix-mixins.properties | template | option name and default from the observed file's own option list (5.27.24) |
| options.txt | template, partial | key names from the instance's real 1.21.1 `options.txt` (`version:3955`). `version` is included so vanilla doesn't run the options DataFixer from 0. |
Not drafted (keys unverified this session, Tier 2): Twilight Forest
`cloudBlockPrecipitationDistance`, Alex's Caves `biome_ambient_light_coloring`, Jade,
Xaero's, WATUT, Perception, Subtle Effects, FWA.
@@ -0,0 +1,60 @@
#!/usr/bin/env python3
"""Apply a generated variant to a Minecraft instance (game closed!).
python3 apply_variant.py <ID> <path/to/.minecraft> # e.g. C1, dh-r64, T-deck
Copies every config file of out/<ID>/ over the instance. options.txt is
*merged* key by key, so GUI scale, resolution, keybinds etc. survive variant
switches. Prints what changed. Stdlib only; works on Windows too.
"""
import shutil
import sys
from pathlib import Path
HERE = Path(__file__).resolve().parent
def merge_options(src, dst):
new = dict(l.split(":", 1) for l in src.read_text().splitlines() if ":" in l)
lines = dst.read_text().splitlines() if dst.exists() else []
seen, out, changed = set(), [], []
for l in lines:
k = l.split(":", 1)[0]
if k in new:
seen.add(k)
if l != f"{k}:{new[k]}":
changed.append(f"{k}:{new[k]}")
l = f"{k}:{new[k]}"
out.append(l)
for k, v in new.items():
if k not in seen:
out.append(f"{k}:{v}")
changed.append(f"{k}:{v} (added)")
dst.write_text("\n".join(out) + "\n")
return changed
def main():
if len(sys.argv) != 3:
sys.exit(__doc__)
vid, game = sys.argv[1], Path(sys.argv[2])
src = HERE / "out" / vid
if not src.is_dir():
sys.exit(f"{src} missing - run build.py first")
if not (game / "mods").is_dir():
sys.exit(f"{game} doesn't look like a .minecraft dir (no mods/)")
for f in sorted(p for p in src.rglob("*") if p.is_file()):
rel = f.relative_to(src)
dst = game / rel
if rel.as_posix() == "options.txt":
for c in merge_options(f, dst):
print(f"options.txt {c}")
continue
dst.parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(f, dst)
print(f"copied {rel.as_posix()}")
(game / "BENCH_VARIANT.txt").write_text(vid + "\n")
print(f"applied {vid}; recorded in BENCH_VARIANT.txt")
main()
@@ -0,0 +1,355 @@
#!/usr/bin/env python3
"""Generate the staged client-perf configs (tiers + Phase 2 bench variants).
Every override is applied to a *base* file and must hit a key that already
exists in that base, otherwise the build fails. Bases are either the observed
defaults generated by the exact pinned jar (DH 3.3.2, Sodium 0.8.13, EMF 3.3.9,
Flywheel 1.0.6, Sable 2.0.5, SPR 1.5.1 - versions verified against the
2026-09-24 launch log) or hand-authored templates whose keys were read from the
pinned jar's source (see README.md, "Key provenance").
Output: out/<variant>/<path relative to the game dir>, plus out/MANIFEST.md.
python3 build.py # from this directory; stdlib only
python3 build.py --ship # also copy T-default into the repo (see SHIP), then
# run `packwiz refresh` from the repo root
"""
import json
import re
import shutil
import sys
from pathlib import Path
HERE = Path(__file__).resolve().parent
OBSERVED = HERE.parent / "data" / "observed-default-configs"
TEMPLATES = HERE / "templates"
OUT = HERE / "out"
REPO = HERE.parents[2]
# What `--ship` copies from out/T-default into the repo, and where.
# Default Options seeds these client-side only, and only if the file is absent
# (see README §1). Not shipped: sable-client.toml and sodium-options.json (no change
# from upstream). modernfix-mixins.properties is held back until bench block B6
# passes; when it does, add it here with destination "config/modernfix-mixins.properties"
# (enforced packwiz file, because ModernFix reads it before Default Options runs) and
# re-include it in .packwizignore.
DO = "config/defaultoptions"
SHIP = {
"options.txt": f"{DO}/options.txt",
"config/DistantHorizons.toml": f"{DO}/extra/config/DistantHorizons.toml",
"config/entity_model_features.json": f"{DO}/extra/config/entity_model_features.json",
"config/flywheel-client.toml": f"{DO}/extra/config/flywheel-client.toml",
"config/lambdynlights.toml": f"{DO}/extra/config/lambdynlights.toml",
"config/ssrd-common.toml": f"{DO}/extra/config/ssrd-common.toml",
"config/sound_physics_remastered/soundphysics.properties":
f"{DO}/extra/config/sound_physics_remastered/soundphysics.properties",
"config/sound_physics_remastered/sound_rates.properties":
f"{DO}/extra/config/sound_physics_remastered/sound_rates.properties",
}
# game-dir path -> (base file, format, may_append_new_keys)
FILES = {
"options.txt": (TEMPLATES / "options.txt", "options", False),
"config/DistantHorizons.toml": (OBSERVED / "DistantHorizons.toml", "toml", False),
"config/sodium-options.json": (OBSERVED / "sodium-options.json", "json", False),
"config/entity_model_features.json": (OBSERVED / "entity_model_features.json", "json", False),
"config/flywheel-client.toml": (OBSERVED / "flywheel-client.toml", "toml", False),
"config/sable-client.toml": (OBSERVED / "sable-client.toml", "toml", False),
"config/ssrd-common.toml": (TEMPLATES / "config/ssrd-common.toml", "toml", False),
"config/lambdynlights.toml": (TEMPLATES / "config/lambdynlights.toml", "toml", False),
"config/modernfix-mixins.properties": (TEMPLATES / "config/modernfix-mixins.properties", "properties", False),
"config/sound_physics_remastered/soundphysics.properties": (
OBSERVED / "sound_physics_remastered/soundphysics.properties", "properties", False),
# SPR merges partial files over its generated defaults (SoundRateConfig.load)
"config/sound_physics_remastered/sound_rates.properties": (
TEMPLATES / "config/sound_physics_remastered/sound_rates.properties", "properties", True),
}
DH_Q = "client.advanced.graphics.quality"
DH_G = "client.advanced.graphics"
DH_T = "common.multiThreading"
DH_W = "common.worldGenerator"
# Create 6.0.10 sound IDs (from the observed sound_rates.properties, same Create version).
# Over the cap, SPR plays the sound dry (SoundPhysics.java: setDefaultEnvironment), it is not dropped.
CREATE_NOISY = [
"create:cogs", "create:mixing", "create:mixing_compounded_1",
"create:mechanical_press_activation", "create:mechanical_press_activation_compounded_1",
"create:mechanical_press_activation_belt", "create:mechanical_press_activation_belt_compounded_1",
"create:crushing_1", "create:crushing_2", "create:crushing_3",
"create:saw_activate_stone", "create:saw_activate_wood",
"create:funnel_flap", "create:funnel_flap_compounded_1",
"create:depot_slide", "create:depot_plop", "create:steam",
"create:sanding_short", "create:sanding_long",
]
def sound_caps(n):
return {s.replace(":", "\\:"): n for s in CREATE_NOISY}
# Observed DH values were computed on a 4-thread box; DH's real default is
# ceil(nproc * 0.5) (ThreadPresetConfigEventHandler) = 4 on every 8-thread fleet
# machine. Applied first to every variant so C0 is the fleet's true default.
UPSTREAM = {"config/DistantHorizons.toml": {(DH_T, "numberOfThreads"): 4}}
# Per-install values that must not ship: DH regenerates missing keys with their
# default (ConfigFileHandler.loadEntry -> saveEntry); serverId is new Random().nextInt().
STRIP = {"config/DistantHorizons.toml": [("server", "serverId")]}
# --------------------------------------------------------------------------
# Tiers. "default" is the pack-wide conservative default; deck/high are deltas
# on top of it; mid == default.
# --------------------------------------------------------------------------
DEFAULT = {
"options.txt": {
"renderDistance": 8, # server view-distance is 8; more loads nothing in MP
"simulationDistance": 8, # singleplayer only
"biomeBlendRadius": 1, # 3x3; chunk-build cost (Sodium tooltip)
"mipmapLevels": 2, # block atlas is >=4096^2
"entityDistanceScaling": 0.75, # slider steps are 0.25
},
"config/DistantHorizons.toml": {
(DH_Q, "lodChunkRenderDistanceRadius"): 128, # default 256
(DH_G, "enableSsao"): False, # default true
(DH_T, "numberOfThreads"): 2, # default ceil(nproc*0.5) = 4 on the fleet
},
"config/entity_model_features.json": {
"animationLODDistance": 12, # default 20; lower = more frame skipping
"modelUpdateFrequency": "Slow", # default Average; model refresh, not animation
},
"config/flywheel-client.toml": {
("flw_backends", "lightSmoothness"): "TRI_LINEAR", # default SMOOTH
},
"config/ssrd-common.toml": {
("", "physicsRenderDistance"): 16, # default 128; slider floor is minPhysicsRenderDistance=16
},
"config/lambdynlights.toml": {
("", "mode"): "fast", # default fancy; fast = TickMode.SLOW
},
"config/modernfix-mixins.properties": {
"mixin.perf.dynamic_resources": "true", # GATED on bench block B6
},
"config/sound_physics_remastered/soundphysics.properties": {
"environment_evaluation_ray_count": 16, # default 32
"environment_evaluation_ray_bounces": 2, # default 4
},
"config/sound_physics_remastered/sound_rates.properties": sound_caps(4),
}
DECK = {
"options.txt": {"biomeBlendRadius": 0, "particles": 1, "entityShadows": "false"},
# = DH's own LOW quality preset (RenderQualityPresetConfigEventHandler) + radius 64
"config/DistantHorizons.toml": {
(DH_Q, "lodChunkRenderDistanceRadius"): 64,
(DH_Q, "horizontalQuality"): "LOW",
(DH_Q, "verticalQuality"): "LOW",
(DH_Q, "transparency"): "DISABLED",
(DH_Q, "vanillaFadeMode"): "SINGLE_PASS",
(DH_Q, "lodBiomeBlending"): 1,
},
"config/sodium-options.json": {
"quality.weather_quality": "FAST",
"quality.leaves_quality": "FAST",
},
"config/entity_model_features.json": {
"animationLODDistance": 8,
"retainDetailOnLowFps": False,
},
"config/flywheel-client.toml": {("flw_backends", "lightSmoothness"): "FLAT"},
"config/lambdynlights.toml": {
("", "mode"): "fastest",
("light_sources", "entities"): False,
},
"config/sound_physics_remastered/soundphysics.properties": {"strict_occlusion": "true"},
}
HIGH = { # strong GPU, but still a 4C/8T CPU (true of every fleet machine)
"options.txt": {"mipmapLevels": 4, "biomeBlendRadius": 2, "entityDistanceScaling": 1.0},
"config/DistantHorizons.toml": {(DH_G, "enableSsao"): True},
"config/flywheel-client.toml": {("flw_backends", "lightSmoothness"): "SMOOTH"},
"config/ssrd-common.toml": {("", "physicsRenderDistance"): 32},
"config/lambdynlights.toml": {("light_sources", "entities"): False},
"config/sound_physics_remastered/soundphysics.properties": {"strict_occlusion": "true"},
}
# --------------------------------------------------------------------------
# Phase 2 bench variants. C0 = every file at upstream default (explicit, so stale
# instance edits can't leak in). Everything else is C1 (= T-mid) plus ONE change.
# BENCH is layered on every bench variant: uncapped, vsync off, phase0 pins,
# no DH world generation during runs (world is pre-generated).
# --------------------------------------------------------------------------
BENCH = {
"options.txt": {"maxFps": 260, "enableVsync": "false", "renderDistance": 8,
"simulationDistance": 8},
"config/DistantHorizons.toml": {(DH_W, "generatorPlan"): "DISABLED"},
}
def c1(extra):
return [DEFAULT, extra]
VARIANTS = {
# player tiers (no BENCH layer)
"T-default": ([DEFAULT], False),
"T-deck": ([DEFAULT, DECK], False),
"T-mid": ([DEFAULT], False),
"T-high": ([DEFAULT, HIGH], False),
# bench: composites
"C0": ([], True),
"C1": ([DEFAULT], True),
"C1-deck": ([DEFAULT, DECK], True),
"C1-high": ([DEFAULT, HIGH], True),
# bench: Distant Horizons
"dh-r256": (c1({"config/DistantHorizons.toml": {(DH_Q, "lodChunkRenderDistanceRadius"): 256}}), True),
"dh-r192": (c1({"config/DistantHorizons.toml": {(DH_Q, "lodChunkRenderDistanceRadius"): 192}}), True),
"dh-r64": (c1({"config/DistantHorizons.toml": {(DH_Q, "lodChunkRenderDistanceRadius"): 64}}), True),
"dh-ssao": (c1({"config/DistantHorizons.toml": {(DH_G, "enableSsao"): True}}), True),
"dh-thr4": (c1({"config/DistantHorizons.toml": {(DH_T, "numberOfThreads"): 4}}), True),
"dh-qlow": (c1({"config/DistantHorizons.toml": DECK["config/DistantHorizons.toml"]
| {(DH_Q, "lodChunkRenderDistanceRadius"): 128}}), True),
# bench: Flywheel / ModernFix / Sable / SSRD
"fw-flat": (c1({"config/flywheel-client.toml": {("flw_backends", "lightSmoothness"): "FLAT"}}), True),
"fw-smooth": (c1({"config/flywheel-client.toml": {("flw_backends", "lightSmoothness"): "SMOOTH"}}), True),
"mf-dynres-off": (c1({"config/modernfix-mixins.properties": {"mixin.perf.dynamic_resources": "false"}}), True),
"ssrd-32": (c1({"config/ssrd-common.toml": {("", "physicsRenderDistance"): 32}}), True),
"ssrd-64": (c1({"config/ssrd-common.toml": {("", "physicsRenderDistance"): 64}}), True),
"ssrd-128": (c1({"config/ssrd-common.toml": {("", "physicsRenderDistance"): 128}}), True),
"sable-noshade": (c1({"config/sable-client.toml": {("", "sub_level_dynamic_shading"): False}}), True),
# bench: entities / lights / sound
"emf-lod20": (c1({"config/entity_model_features.json": {"animationLODDistance": 20,
"modelUpdateFrequency": "Average"}}), True),
"emf-lod8": (c1({"config/entity_model_features.json": {"animationLODDistance": 8,
"retainDetailOnLowFps": False}}), True),
"ldl-fancy": (c1({"config/lambdynlights.toml": {("", "mode"): "fancy"}}), True),
"ldl-fastest": (c1({"config/lambdynlights.toml": {("", "mode"): "fastest",
("light_sources", "entities"): False}}), True),
"spr-up": (c1({"config/sound_physics_remastered/soundphysics.properties": {
"environment_evaluation_ray_count": 32, "environment_evaluation_ray_bounces": 4}}), True),
"spr-strict": (c1({"config/sound_physics_remastered/soundphysics.properties": {"strict_occlusion": "true"}}), True),
"spr-nocap": (c1({"config/sound_physics_remastered/sound_rates.properties": sound_caps(-1)}), True),
# bench: vanilla / Sodium
"sod-thr3": (c1({"config/sodium-options.json": {"performance.chunk_builder_threads": 3}}), True),
"opt-blend2": (c1({"options.txt": {"biomeBlendRadius": 2}}), True),
"opt-blend0": (c1({"options.txt": {"biomeBlendRadius": 0}}), True),
"opt-mip4": (c1({"options.txt": {"mipmapLevels": 4}}), True),
}
# --------------------------------------------------------------------------
def toml_val(v):
if isinstance(v, bool):
return "true" if v else "false"
if isinstance(v, (int, float)):
return str(v)
return json.dumps(v)
def apply_toml(text, ov, name):
lines = text.split("\n")
hdr = re.compile(r"^\s*\[([^\]]+)\]\s*$")
for (section, key), val in ov.items():
cur, hits = "", []
for i, ln in enumerate(lines):
m = hdr.match(ln)
if m:
cur = m.group(1).strip()
continue
if cur == section and re.match(rf"^\s*{re.escape(key)}\s*=", ln):
hits.append(i)
if len(hits) != 1:
raise SystemExit(f"{name}: [{section}] {key}: {len(hits)} matches in base")
i = hits[0]
indent = re.match(r"^(\s*)", lines[i]).group(1)
lines[i] = f"{indent}{key} = {toml_val(val)}"
return "\n".join(lines)
def apply_json(text, ov, name):
data = json.loads(text)
for path, val in ov.items():
node, parts = data, path.split(".")
for p in parts[:-1]:
node = node[p]
if parts[-1] not in node:
raise SystemExit(f"{name}: {path} not in base")
if type(node[parts[-1]]) is not type(val):
raise SystemExit(f"{name}: {path} type {type(node[parts[-1]]).__name__} != {type(val).__name__}")
node[parts[-1]] = val
return json.dumps(data, indent=2) + "\n"
def apply_kv(text, ov, name, sep, append):
lines = text.rstrip("\n").split("\n")
for key, val in ov.items():
sval = toml_val(val) if isinstance(val, bool) else str(val)
rx = re.compile(rf"^{re.escape(key)}{re.escape(sep)}")
hits = [i for i, ln in enumerate(lines) if rx.match(ln)]
if len(hits) > 1 or (not hits and not append):
raise SystemExit(f"{name}: {key}: {len(hits)} matches in base")
if hits:
lines[hits[0]] = f"{key}{sep}{sval}"
else:
lines.append(f"{key}{sep}{sval}")
return "\n".join(lines) + "\n"
def strip(text, keys, name):
lines = text.split("\n")
hdr = re.compile(r"^\s*\[([^\]]+)\]\s*$")
for section, key in keys:
cur, hits = "", []
for i, ln in enumerate(lines):
m = hdr.match(ln)
if m:
cur = m.group(1).strip()
elif cur == section and re.match(rf"^\s*{re.escape(key)}\s*=", ln):
hits.append(i)
if len(hits) != 1:
raise SystemExit(f"{name}: strip [{section}] {key}: {len(hits)} matches")
del lines[hits[0]]
return "\n".join(lines)
def render(layers, name):
base, fmt, append = FILES[name]
text = strip(base.read_text(), STRIP.get(name, []), name)
merged = {}
for layer in [UPSTREAM] + layers:
merged.update(layer.get(name, {}))
if fmt == "toml":
return apply_toml(text, merged, name), merged
if fmt == "json":
return apply_json(text, merged, name), merged
sep = ":" if fmt == "options" else "="
return apply_kv(text, merged, name, sep, append), merged
def main():
if OUT.exists():
shutil.rmtree(OUT)
manifest = ["# Generated by build.py - do not edit\n",
"Changed keys per variant, relative to the upstream default of each file.\n"]
for vid, (layers, bench) in VARIANTS.items():
layers = list(layers) + ([BENCH] if bench else [])
manifest.append(f"\n## {vid}\n")
for name in FILES:
text, merged = render(layers, name)
dest = OUT / vid / name
dest.parent.mkdir(parents=True, exist_ok=True)
dest.write_text(text)
for k, v in merged.items():
k = f"[{k[0]}] {k[1]}" if isinstance(k, tuple) else k
manifest.append(f"- `{name}`: `{k}` = `{v}`\n")
(OUT / "MANIFEST.md").write_text("".join(manifest))
print(f"wrote {len(VARIANTS)} variants x {len(FILES)} files to {OUT}")
if "--ship" in sys.argv:
shutil.rmtree(REPO / DO, ignore_errors=True)
for src, dst in SHIP.items():
(REPO / dst).parent.mkdir(parents=True, exist_ok=True)
shutil.copyfile(OUT / "T-default" / src, REPO / dst)
print(f"shipped {len(SHIP)} files to {REPO / DO}; now run `packwiz refresh`")
main()
@@ -0,0 +1,16 @@
mode = "fancy"
chunk_rebuild_scheduler = "culling"
[adaptive_ticking]
slow = 5
slower = 8
background_sleep = true
[light_sources]
entities = true
self = true
water_sensitive_check = true
beam = true
guardian_laser = true
sonic_boom = true
glowing_effect = true
@@ -0,0 +1 @@
mixin.perf.dynamic_resources=false
@@ -0,0 +1 @@
# Partial file: SPR merges these over its generated per-sound defaults (-1 = unlimited).
@@ -0,0 +1,12 @@
#The render distance for physics objects (SubLevels) in chunks.
# Default: 128
# Range: 1 ~ 1000000
physicsRenderDistance = 128
#The minimum render distance for physics objects (SubLevels) in chunks.
# Default: 16
# Range: 1 ~ 1000000
minPhysicsRenderDistance = 16
#The maximum render distance for physics objects (SubLevels) in chunks.
# Default: 4096
# Range: 1 ~ 1000000
maxPhysicsRenderDistance = 4096
@@ -0,0 +1,11 @@
version:3955
renderDistance:12
simulationDistance:12
biomeBlendRadius:2
mipmapLevels:4
entityDistanceScaling:1.0
particles:0
entityShadows:true
graphicsMode:1
maxFps:120
enableVsync:true
@@ -0,0 +1,278 @@
# Research: Core render stack levers
Scope: client-side render stack for **Onion MC** — Minecraft 1.21.1 / NeoForge 21.1.251, ~212 mods, ~10 players, server view-distance 8.
Fleet: **P0** Steam Deck (Zen2 8CU RDNA2 iGPU, 16 GB shared, 1280×800, Mesa/RADV) · **P1** i7-7700K + GTX 1060 **6 GB** (VRAM-bound) · **P2** i7-6700K + GTX 1080 Ti 11 GB with only ~8 GB free RAM (CPU/heap-bound).
Confidence tags used throughout:
- **VERIFIED** — read in the pinned mod's source/config code or its own shipped defaults.
- **DOCUMENTED** — official README / wiki / changelog / mod-author description.
- **COMMUNITY** — forum/Reddit/third-party guide.
- **INFERENCE** — my reasoning, no direct source.
Every non-inference claim has a URL. Config keys are only named where I actually saw them in source or a shipped properties file.
---
## Summary
The single biggest client-side render lever in this pack is **Iris/shaders, not Sodium**: with any shaderpack active, Flywheel 1.0.x marks *both* of its GPU backends unsupported, so Create 6 falls back to per-block-entity rendering and shader packs re-draw that content in the shadow pass; on top of that, DH's shadow pass is auto-enabled and renders *all* DH chunks. Sodium itself is already near-optimal on 0.8.13 (most impactful options — animate-only-visible-textures, fog occlusion, entity culling, block face culling, no-error GL context — are **on by default** and built into Sodium, no add-on needed). The remaining cheap wins are shader-quality knobs (shadow distance/quality, SSAO, entity shadows, volumetric clouds), ModernFix `mixin.perf.dynamic_resources=true` for the RAM-starved P2, mipmap-level reduction for the VRAM-bound P1, and Fresh-Animations/EMF animation throttles.
---
## Findings
### 1. Sodium 0.8.13 (`mc1.21.1-0.8.13`) — options that matter, and their real defaults
Sodium 0.8.13 is the 1.21.1 backport of Sodium 0.8; its changelog (0.8.12, the base of this line) claims **"up to +115%"** world-render improvement, reduced chunk-update micro-stutter, and slightly faster entity/particle rendering, and states compatibility "Create Aeronautics works as of 1.3.0, Sable as of 2.0.0, Veil works as of 4.1.2, Iris works as of 1.8.13". [Modrinth version page](https://modrinth.com/mod/sodium/version/mc1.21.1-0.8.12-neoforge) — **DOCUMENTED**. (Confirms the pack's version matrix is a supported one; it also warns Sodium is *not* compatible with "Sodium Options API".)
**Option exposure: everything in the task list is in Sodium's own Video Settings — no add-on required.** The 0.8.13 1.21.1 config builder registers pages *General / Quality / Performance / Advanced* and puts chunk-update threads, chunk-updates (defer), block face culling, fog occlusion, entity culling, animate-only-visible-textures, block-transparency-limits and **Use No Error Context on the Performance page**, and persistent-mapping + CPU render-ahead limit on Advanced. [SodiumConfigBuilder @ mc1.21.1-0.8.13](https://github.com/CaffeineMC/sodium/blob/mc1.21.1-0.8.13/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumConfigBuilder.java) — **VERIFIED**.
Defaults are hard-coded in `PerformanceSettings` / `QualitySettings` / `AdvancedSettings` in [SodiumOptions.java @ mc1.21.1-0.8.13](https://github.com/CaffeineMC/sodium/blob/mc1.21.1-0.8.13/common/src/main/java/net/caffeinemc/mods/sodium/client/gui/SodiumOptions.java) — **VERIFIED**:
| Video option (label) | Config field | Default | Impact as labelled | Notes |
|---|---|---|---|---|
| Chunk Update Threads | `performance.chunkBuilderThreads` | `0` = auto | High | `0` resolves to `clamp(max(cores/3, cores−6), 1, 10)` → **2 threads on every 4C/8T fleet machine** ([ChunkBuilder.java](https://github.com/CaffeineMC/sodium/blob/mc1.21.1-0.8.13/common/src/main/java/net/caffeinemc/mods/sodium/client/render/chunk/compile/executor/ChunkBuilder.java)). Range is 0..`availableProcessors`. Requires renderer reload. |
| Chunk Updates | `performance.chunkBuildDeferMode` | `DeferMode.ALWAYS` ("Deferred") | High | Other values `ONE_FRAME` ("Soon"), `ZERO_FRAMES` ("Immediate"). Already at the frame-rate-friendliest setting. |
| Animate Only Visible Textures | `performance.animateOnlyVisibleTextures` | **`true`** | High | Already on. Tooltip: "significant performance improvement on some hardware, especially with heavier resource packs". |
| Use Fog Occlusion | `performance.useFogOcclusion` | **`true`** | Medium | Already on. |
| Use Entity Culling | `performance.useEntityCulling` | **`true`** | Medium | Already on. |
| Use Block Face Culling | `performance.useBlockFaceCulling` | **`true`** | Medium | Already on. |
| Block Transparency Limits (quad splitting) | `performance.quadSplittingMode` | `SAFE` | Medium | `BASIC`/`SAFE`/`UNLIMITED`. Controller: translucency sorting. |
| Use No Error Context | `performance.useNoErrorGLContext` | **`true`** | Low | Only enable-able on GL 4.6 / `GL_KHR_no_error`; needs game restart. Effect is "slight". |
| CPU Render-Ahead Limit | `advanced.cpuRenderAheadLimit` | `3` | (debug) | Docs say don't touch. |
| Use Persistent Mapping | `advanced.useAdvancedStagingBuffers` | `true` | (debug) | — |
| Entity Sorting | `quality.useClosestPointEntitySort` | `false` | Medium | "Enhanced" costs a little CPU. |
| Leaves | `quality.leavesQuality` (vanilla `cutoutLeaves`) | default/fancy | Medium | Fast = opaque, cullable leaves. |
| Mipmap Levels / Biome Blend / Entity Distance / Entity Shadows | vanilla-backed (`mipmapLevels`, `biomeBlendRadius`, `entityDistanceScaling`, `entityShadows`) | vanilla defaults | Med / Low / High / Medium | See §6. |
Two options people commonly cite (**"Hidden Fluid Culling"**, **"Improved Fluid Shaping"**, **"Texel Interpolation / pixel filtering mode"**) are **not present in the 0.8.13 / 1.21.1 build** — their lang keys exist only on Sodium `dev` (26.x). Do not look for them in-game on this version. [compare dev lang](https://github.com/CaffeineMC/sodium/blob/dev/common/src/main/resources/assets/sodium/lang/en_us.json) vs [0.8.13 lang](https://github.com/CaffeineMC/sodium/blob/mc1.21.1-0.8.13/common/src/main/resources/assets/sodium/lang/en_us.json) — **VERIFIED**.
**Add-on boundary (what is *not* in Sodium):** fog-type toggles, cloud height, particle-culling detail, and "turn off all fog" are Sodium-Extra/Extras features. [Sodium Extras description](https://modrinth.com/mod/sodium-extras) — **DOCUMENTED**. None of the options in this task's list requires an add-on; Sodium Extra is optional polish. (Neither Sodium Extra nor Sodium Extras is in the current pack.)
### 2. Iris 1.8.14-beta.1 + the two shaderpacks
**Complementary Reimagined r5.9.3** exposes a *Profile* selector plus per-setting overrides. The profile table and default shadow distances are shipped in the pack's `shaders.properties` (read from the author's repo, `main` branch — treat the exact numbers as "current author defaults, verify in-game for r5.9.3"): [ComplementaryReimagined/shaders/shaders.properties](https://github.com/ComplementaryDevelopment/ComplementaryReimagined/blob/main/shaders/shaders.properties) — **DOCUMENTED**.
| Profile | `SHADOW_QUALITY` | `shadowDistance` | `ENTITY_SHADOW` | `CLOUD_QUALITY` | `RAIN_PUDDLES` |
|---|---|---|---|---|---|
| POTATO | −1 (OFF) | 64 (4 ch) | −1 (off) | 1 | 0 |
| VERYLOW / LOW | 0 (Very Low) | 64 / 96 | off | 1 / 2 | 0 |
| MEDIUM | 2 (Medium) | 128 (8 ch) | off | 2 | 0 |
| HIGH | 2 (Medium) | **192 (12 ch)** | 1 | 2 | 0 |
| VERYHIGH | 2 | 192 | 1 | 2 | 2 |
| ULTRA | 2 | 224 (14 ch) | 1 | 3 | 2 |
| COMPLEMENTARY | 3 (High) | 256 (16 ch) | 1 | 3 | 2 |
Author-supplied cost notes in the pack's own lang file (same source) — **DOCUMENTED**:
- **Entity Shadows** — "impact performance way more than expected, costing **more than 50% of your fps in some cases**". This is the single biggest per-setting cost in the pack, and it is **off in every profile except HIGH and above**.
- **Colored Lighting** (ACT/voxel floodfill) — "each increment can cost more than twice the performance of the previous tier".
- **Shadow Distance** — "lower values may cause excessive Light Shaft leaking" (visual, not perf).
- Informational panel tells users to keep render distance "2–4 chunks higher than the shadow distance of the Profile", e.g. 16 chunks RD for the HIGH profile — i.e. **at server view-distance 8, no profile above MEDIUM's 8-chunk shadow distance is even productive**.
- Rain Puddles and volumetric clouds are called out as expensive.
**MakeUp Ultra Fast 9.5f** — its settings screen and defaults are in the pack's `shaders.properties` (open source): [MakeUpUltraFast/shaders/shaders.properties](https://github.com/javiergcim/MakeUpUltraFast/blob/master/shaders/shaders.properties) — **VERIFIED**. Relevant keys and shipped profile values:
| Key | Meaning | Values seen in shipped profiles |
|---|---|---|
| `SHADOW_CASTING` | shadows on/off | `no_effects` / `shadowless_*` profiles have `!SHADOW_CASTING` (off); `low`…`extremeplus` have it on |
| `SHADOW_DISTANCE_SLIDER` | slider | 0 (low), 1 (medium), 2 (high/extremeplus) |
| `SHADOW_QTY_SLIDER` | slider | 1 / 2 / 3 |
| `REFLECTION_SLIDER` | water/block reflections | 0–2 |
| `AO` / `AOSTEPS` / `AO_STRENGTH` | AO on/off and steps | `AOSTEPS=5` |
| `V_CLOUDS` / `CLOUD_STEPS_AVG` / `CLOUD_VOL_STYLE` | volumetric clouds | `CLOUD_STEPS_AVG=10` |
| `BLOOM` / `BLOOM_SAMPLES`, `VOL_LIGHT`, `CHROMA_ABER`, `AA_TYPE`, `DOF` | post | author notes Bloom/DoF/Shadows are the heaviest effects |
| `dhShadow.enabled` | DH shadow pass | **`false`** in MakeUp |
MakeUp also sets `shadow.culling = true`. Its README positions it as "Intended for low-spec computers … FAST!", with optional shadows/volumetric clouds/DoF/bloom. [MakeUp README](https://github.com/javiergcim/MakeUpUltraFast) — **DOCUMENTED**.
**Comparative cost:** I could not find any *primary/measured* head-to-head between these exact two packs; every comparison I found is COMMUNITY (e.g. "MakeUp Ultra Fast … gives better fps tho", [r/minecraftshaders](https://www.reddit.com/r/minecraftshaders/comments/1m9c569/any_nice_looking_shaders_that_run_well/)). The defensible statement is structural and comes from the profiles themselves: MakeUp's *default* profile ships with lower shadow distance/quality and `dhShadow` off, whereas Complementary's HIGH-and-above profiles enable entity shadows and 12–16-chunk shadows. That gap — especially **Entity Shadows** — is where the FPS difference will come from, not from the shader's core lighting. **INFERENCE**, with **DOCUMENTED** inputs.
**Iris-level knobs:** Iris exposes each pack's own options, and the shader-lab community wiki describes the shader-selection-menu sliders ("Render Quality", "Shadow Quality", "Antialiasing") as OptiFine-only and says baseline render distance with shaders should stay under 16 chunks. [shaderLABS Performance Tips](https://shaderlabs.org/wiki/Performance_Tips) — **COMMUNITY/DOCUMENTED** (page is old; treat as directional only).
### 3. Iris + Distant Horizons (mandatory in this pack)
- DH + Iris requires **Iris 1.7+** and a shaderpack *built for DH*; DH itself says most shaderpacks will not work. [DH Modrinth description](https://modrinth.com/mod/distanthorizons) — **DOCUMENTED**.
- Iris adds `dh_terrain`, `dh_water`, `dh_shadow` programs, and **"The DH shadow pass is automatically enabled … Distant Horizons has no set shadow distance; all chunks will be rendered."** [Iris docs — Distant Horizons](https://shaders.properties/current/reference/mod-support/distant_horizons/) — **DOCUMENTED**. This is the key interaction cost: *your shadow pass covers DH's full LOD distance*, not the vanilla 8 chunks.
- DH's own config (read from the current core repo) — **VERIFIED** keys/defaults: `Client.Advanced.Graphics.Quality.lodChunkRenderDistanceRadius` (min/default/max **32/256/4096** chunks), `maxHorizontalResolution` default **BLOCK** (256 LODs per chunk — the "Fanciest"), `horizontalQuality` default **MEDIUM**, `verticalQuality` default **MEDIUM**, `Client.Advanced.Culling.overdrawPrevention` default **−1 (auto)**, `reduceOverdrawWithFastMovement` default **true**, `enableCaveCulling` default **true**, `Client.Advanced.Graphics.Quality.transparency` default **COMPLETE**, `vanillaFadeMode` default **DOUBLE_PASS** ("Slowest … provides the smoothest transition"), `lodBiomeBlending` default **3** ("anything above 0 will slow down LOD loading time"), `enableNoiseTexture` default **true**, far-fog `farFogStart` 0.4 / `farFogEnd` 1.0. Quality preset default `MEDIUM`, thread preset default `BALANCED`. [distant-horizons-core Config.java](https://gitlab.com/distant-horizons-team/distant-horizons-core/-/blob/main/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java) — **VERIFIED**.
- DH's official stutter advice, in order: use a concurrent GC (ZGC/Shenandoah), allocate 6–8 GB for 4–8 core CPUs, **lower DH's CPU load**, disable **Distant Generation**, lower the **Graphics Preset**. [DH Modrinth description](https://modrinth.com/mod/distanthorizons) — **DOCUMENTED**. Note "6–8 GB allocated" directly conflicts with P2's ~8 GB free RAM — that machine will be the DH-stutter canary.
### 4. Create 6.0.10 / Flywheel 1.0.6 with Iris shaders — **it falls back**
This is the most important verified finding. In Flywheel's 1.21.1 branch, both GPU backends declare themselves unsupported whenever a shaderpack is in use:
```java
INSTANCING: .supported(() -> GlCompat.SUPPORTS_INSTANCING && InstancingPrograms.allLoaded()
&& !ShadersModHelper.isShaderPackInUse())
INDIRECT : .supported(() -> GlCompat.SUPPORTS_INDIRECT && IndirectPrograms.allLoaded()
&& !ShadersModHelper.isShaderPackInUse())
```
[Flywheel Backends.java @ 1.21.1/dev](https://github.com/Engine-Room/Flywheel/blob/1.21.1/dev/common/src/backend/java/dev/engine_room/flywheel/backend/Backends.java) — **VERIFIED**; the same guard is present at the 1.21.1 `mc1.21.1/v1.0.5` tag, the nearest tagged release below the pack's 1.0.6 — **VERIFIED**. `ShadersModHelper` is Iris-backed (`IrisApi.isShaderPackInUse()`), and this is exactly what `IrisCompat` exists for. [IrisCompat.java](https://github.com/Engine-Room/Flywheel/blob/1.21.1/dev/common/src/main/java/dev/engine_room/flywheel/impl/compat/IrisCompat.java) — **VERIFIED**.
When neither backend is supported, `BackendManagerImpl.chooseBackend()` falls through to `OFF_BACKEND` (`flywheel:off`) and logs `"Flywheel backend fell back from '…' to 'flywheel:off'"`. [BackendManagerImpl.java](https://github.com/Engine-Room/Flywheel/blob/1.21.1/dev/common/src/main/java/dev/engine_room/flywheel/impl/BackendManagerImpl.java) — **VERIFIED**.
What that costs, confirmed in Create's own code: Create 6's kinetic/contraption renderers are *guarded* by Flywheel visualization availability —
```java
protected void renderSafe(T be, …) {
if (VisualizationManager.supportsVisualization(be.getLevel())) return;
…
}
```
[Create KineticBlockEntityRenderer @ mc1.21.1/dev](https://github.com/Creators-of-Create/Create/blob/mc1.21.1/dev/src/main/java/com/simibubi/create/content/kinetics/base/KineticBlockEntityRenderer.java) — **VERIFIED** (same pattern in `ShaftRenderer`). So with shaders on, every shaft/cog/gear/belt is drawn as an ordinary per-block-entity draw instead of one instanced/indirect batch. Iris's own tracking issue states this in plain terms: *"Create through Flywheel uses a highly-optimized rendering engine normally, but when Iris is enabled it has to use a slower fallback … Iris also has to render the Create content **twice** using this slower fallback path with most shader packs to implement dynamic shadows."* [Iris issue #1414](https://github.com/IrisShaders/Iris/issues/1414) — **DOCUMENTED** (coderbot16, Iris maintainer), corroborated by the Ocuwheel description: *"When Iris/Oculus shaderpacks are active, Flywheel can disable its GPU-instancing backend and fall back to CPU rendering."* [Ocuwheel](https://www.curseforge.com/minecraft/mc-mods/ocuwheel-oculus-flywheel-compat) — **DOCUMENTED**.
Mitigations exist but are third-party and not listed in the pack: **Iris Flywheel Compat** (`irisflw` / backend id seen in the wild as `irisflw:iris_instancing`) and the newer **Colorwheel**, which claims better compatibility. Iris maintainers explicitly warn the former "isn't supported by either team, and almost always breaks on a Create or Iris update. It's a brute force method". [Iris issue #1414 comments](https://github.com/IrisShaders/Iris/issues/1414) — **DOCUMENTED**. Also note Sodium's own 0.8.12 changelog lists **"Create Aeronautics works as of 1.3.0"** and **"Sable works as of 2.0.0"** — so the aeronautics half of Create *is* version-aligned, it is specifically the Flywheel backend gate that costs you. **INFERENCE** from DOCUMENTED inputs.
**Flywheel config levers (NeoForge client config, `flw_backends` section)** — [NeoForgeFlwConfig.java](https://github.com/Engine-Room/Flywheel/blob/1.21.1/dev/neoforge/src/main/java/dev/engine_room/flywheel/impl/NeoForgeFlwConfig.java) — **VERIFIED**:
- `backend` (default `"DEFAULT"`) — you can force `flywheel:instancing` / `flywheel:indirect` / `flywheel:off`, but the `supported()` test still gates it.
- `limitUpdates` (default `true`) — instance-update limiting by distance.
- `workerThreads` (default `-1` = auto, `0` = no parallelism, needs restart).
- `flw_backends.lightSmoothness` (default `SMOOTH`) — "May have a large performance impact"; **irrelevant while a shaderpack is active**, because the Flywheel engine is off.
There is also a `/flywheel backend` client command. **VERIFIED** (BackendArgument exists in the repo). [BackendArgument.java](https://github.com/Engine-Room/Flywheel/blob/1.21.1/dev/common/src/main/java/dev/engine_room/flywheel/impl/BackendArgument.java)
### 5. Veil + irisveil (Iris Veil Compat 0.3.0)
- Veil is a rendering SDK; **Create: Aeronautics and Sable are the prominent consumers** (Aeronautics "uses Veil for its airplane wings, glass panels, contrails, and other visual effects"). [iris-veil-compat README](https://github.com/leon-o/iris-veil-compat) — **DOCUMENTED**.
- Without a bridge, "Veil-rendered visuals bypass the shaderpack's pipeline entirely, causing them to appear broken or missing" — i.e. irisveil is a *correctness* mod first.
- Mechanism/overhead: it mixin-intercepts Veil shader compilation, **caches the processed shader source**, and at render time does **AST-level patching (glsl-transformer)** to inject Veil logic into the shaderpack's gbuffer vertex/fragment programs, then **creates an extra Iris `ShaderInstance`** to replace the original Veil shader. Cache invalidates on shaderpack switch/reload. [README](https://github.com/leon-o/iris-veil-compat) — **DOCUMENTED**.
- Cost profile (**INFERENCE** from that mechanism): a one-time compile/patch cost per shaderpack load, plus one extra ShaderInstance and its draw path per Veil object; not a per-frame CPU cost of the same order as the Flywheel fallback. It requires Iris 1.8.1+, Sodium, Veil 4.0.0+, and was tested against **Sable 2.0.6**.
- Note its pinned dev baseline is *exactly* this pack's stack: Iris 1.8.14-beta.1+1.21.1, Sodium 0.8.13+mc1.21.1, Veil 4.5.1, Flywheel 1.0.6, Create Aeronautics 1.3.2, Sable 2.0.6, NeoForge 21.1.255 (min 21.1.228). The README mentions "the existing **Iris Flywheel Compat** missing-access-transformer warning remains in the log" — i.e. the tested configuration *did* include Iris Flywheel Compat, which the pack does not list. [iris-veil-compat README](https://github.com/leon-o/iris-veil-compat) — **DOCUMENTED**. Worth confirming against the pack manifest.
### 6. ImmediatelyFast · EntityCulling · ModernFix · FerriteCore
**ImmediatelyFast 1.6.14** — batches immediate-mode draws (entities, block entities, particles, text, GUI/HUD, other mods' immediate rendering) and replaces vanilla map/HUD/text paths. Author's own benchmark table (Ryzen 5 1600 + GTX 1060 — close to P1) claims ~2× FPS for entity-heavy scenes, ~1.4× HUD, ~2× text, ~5× maps; notably the *same* test with **Iris+Sodium** only improved 60 → 76 FPS (1.27×) on 1000 cows, because the GPU bound. [ImmediatelyFast README](https://github.com/RaphiMC/ImmediatelyFast/blob/1.21/README.md) — **DOCUMENTED**. Shipped defaults (all "regular" options on): `font_atlas_resizing`, `map_atlas_generation`, `hud_batching`, `fast_text_lookup`, `fast_buffer_upload` = **true**; experimental (`experimental_disable_error_checking`, `experimental_disable_resource_pack_conflict_handling`, `experimental_sign_text_buffering`, `experimental_screen_batching`) = **false**. [ImmediatelyFastConfig.java @ 1.21](https://github.com/RaphiMC/ImmediatelyFast/blob/1.21/common/src/main/java/net/raphimc/immediatelyfast/feature/core/ImmediatelyFastConfig.java) — **VERIFIED**. Practical read: with shaders on, ImmediatelyFast mostly buys back CPU headroom, not GPU frames.
**EntityCulling 1.11.2** — asynchronous path-traced occlusion culling on spare CPU threads, plus entity tick culling; "Fully configurable … Whitelist entities and block entities that should not be culled or tick-culled", and there is a "treat leaves as solid blocks for Entity Culling" option to help in forests. [EntityCulling README](https://github.com/tr7zw/EntityCulling/blob/main/README.md) — **DOCUMENTED**. Shipped defaults (`config/entityculling.json`, configVersion 9) — [Config.java](https://github.com/tr7zw/EntityCulling/blob/main/EntityCulling-Versionless/src/main/java/dev/tr7zw/entityculling/versionless/Config.java) — **VERIFIED**:
| Key | Default | Comment |
|---|---|---|
| `safeMode` | `true` | — |
| `tracingDistance` | `128` | blocks of ray-tracing range |
| `tickCulling` | `true` | entity tick culling on |
| `captureRate` | `5` | how often visibility is recomputed |
| `hitboxLimit` | `50` | don't cull when too many hitboxes on screen |
| `sleepDelay` | `10` | thread sleep |
| `blockEntityFrustumCulling` | `true` | — |
| `solidLeaves` | `false` | "treat leaves as solid" — relevant with fast/cullable leaves |
| `skipEntityCulling` / `skipBlockEntityCulling` | `false` | global off-switches |
| `forceDisplayCulling` | `false` | — |
| `renderNametagsThroughWalls` | `true` | cosmetic |
| `blockEntityWhitelist` / `entityWhitelist` / `tickCullingWhitelist` | populated | **`tickCullingWhitelist` already contains `create:contraption`, `create:carriage_contraption`, `create:gantry_contraption`, `create:stationary_contraption` and `alexscaves:gum_worm`/`gum_worm_segment`** — i.e. this pack's Create + Alex's Caves content is already protected from tick-culling. **VERIFIED** |
**ModernFix 5.27.24 — defaults on NeoForge 1.21.1.** Options default to **enabled unless overridden**; the explicit override map is in source. [ModernFixEarlyConfig.java @ 1.21.1](https://github.com/embeddedt/ModernFix/blob/1.21.1/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java) — **VERIFIED**:
| Option (`mixin.*` in `config/modernfix-mixins.properties`) | Default | Why it matters here |
|---|---|---|
| `perf.dynamic_resources` | **false** | The big one: dynamic/on-demand model loading. Author's wiki: **1.7 GB → 945 MB (−55%)** on a modpack that *already had FerriteCore*. Off by default only for compat risk (startup crash / missing textures). |
| `perf.dynamic_entity_renderers` | **false** | (Option retained in the 1.21.1 defaults map; no matching mixin exists on this branch.) |
| `perf.faster_texture_stitching` | **true** (not overridden) | Speeds atlas stitching at load — valuable with Chipped/Rechiseled/Macaw's texture counts. Auto-disabled if OptiFine present. |
| `perf.faster_item_rendering` | **false** | Off by default. |
| `perf.deduplicate_location`, `perf.deduplicate_climate_parameters`, `perf.clear_mixin_classinfo` | **false** | Off by default. |
| `bugfix.packet_leak`, `bugfix.skip_redundant_saves`, `bugfix.missing_block_entities`, `feature.direct_stack_trace`, `feature.stalled_chunk_load_detection`, `feature.blockentity_incorrect_thread`, `feature.spam_thread_dump`, `feature.remove_chat_signing`, `bugfix.restore_old_dragon_movement` | **false** | Off by default. |
| `feature.integrated_server_watchdog`, `feature.snapshot_easter_egg`, `feature.warn_missing_perf_mods`, `feature.log_stdout_in_log_files` | **true** | — |
| `bugfix.fix_config_crashes`, `feature.registry_event_progress` | **true** on non-Fabric | NeoForge-only. |
| (implicit) `perf.thread_priorities` / `perf.boost_worker_count` | **true** | Sets the system property **`max.bg.threads = availableProcessors − 3`** (reserving server thread + client thread + GC). On the fleet's 4C/8T that's **5**. Can be overridden by `-Dmax.bg.threads`, and is auto-disabled when Smooth Boot / ThreadTweak are present. **VERIFIED** |
The dynamic_resources win is documented by the author as "disabled by default **to maximize compatibility**", with the failure modes being a startup crash or missing textures, and the recommendation that packs which test it should turn it on. [Dynamic Resources FAQ](https://github.com/embeddedt/ModernFix/wiki/Dynamic-Resources-FAQ) — **DOCUMENTED**.
**FerriteCore 7.0.3** — a memory mod (RAM savings, mostly client-side blockstate/model objects). Config file is **`config/ferritecore-mixin.toml`** (built from `Constants.MODID + "-mixin.toml"`). [ConfigFileHandler.java @ 1.21.1](https://github.com/malte0811/FerriteCore/blob/1.21.1/NeoForge/src/main/java/malte0811/ferritecore/mixin/platform/ConfigFileHandler.java) — **VERIFIED**. Options and defaults — [FerriteConfig.java @ 1.21.1](https://github.com/malte0811/FerriteCore/blob/1.21.1/Common/src/main/java/malte0811/ferritecore/mixin/config/FerriteConfig.java) — **VERIFIED**:
| Key | Default |
|---|---|
| `replaceNeighborLookup` | true |
| `replacePropertyMap` (requires the above) | true |
| `cacheMultipartPredicates` | true |
| `modelResourceLocations` | true |
| `multipartDeduplication` (requires predicates) | true |
| `blockstateCacheDeduplication` | true |
| `bakedQuadDeduplication` | true |
| `modelSides` | true |
| `dataComponentPatch` | true |
| `useSmallThreadingDetector` | **false** — "very rare and very hard-to-reproduce crashes, use at your own risk" |
| `compactFastMap` | **false** — "slightly more compact, but also slightly slower representation" |
| `populateNeighborTable` | **false** — "slightly increases memory usage" |
Its own `summary.md` quantifies the mechanism (e.g. ~600 MB of `Table` neighbor structures → ~7 MB of `FastMap`s in a 2020-era pack), i.e. FerriteCore is a bet that pays in **heap**, which is exactly P2's binding constraint. [FerriteCore summary.md](https://github.com/malte0811/FerriteCore/blob/1.21.1/summary.md) — **DOCUMENTED**. Turning on `compactFastMap` trades CPU for a little more RAM — the wrong direction on a 4C/8T main-thread-bound machine; **INFERENCE**.
### 7. Mipmaps, atlas/VRAM, biome blend, Better Leaves, Fresh Animations
**Mipmaps.** Vanilla caps usable mipmap levels at **4**, which is the "full pyramid" level for a 16×16 texture; "Anything higher than that will have incomplete mipmaps", and the optimal level scales with pack resolution (16 → 4, 32 → 5, 64 → 6 …). Because Minecraft stitches every block texture into one atlas, "the maximum mipmap level of this atlas is the smallest maximum mipmap level of any individual texture … a single left-over 16x16 texture will limit the atlas to 4 mipmap levels". [Better Mipmaps](https://modrinth.com/mod/better-mipmaps) — **DOCUMENTED**. Consequences, and the raw VRAM maths, are **INFERENCE**: a mipmap pyramid adds ≈ 1 + ¼ + 1/16 + … ≈ **+33 %** over the base atlas, and that multiplier applies to a *large* base once Chipped / Rechiseled / Macaw's / handcrafted are in play (these add thousands of models, and animated textures occupy atlas space for *every* frame of the animation). Sodium's own tooltip already warns that raising mipmaps "could adversely affect performance with resource packs that use many animated textures", and that the option requires an asset reload. [Sodium 0.8.13 lang](https://github.com/CaffeineMC/sodium/blob/mc1.21.1-0.8.13/common/src/main/resources/assets/sodium/lang/en_us.json) — **VERIFIED**. I could not find a *primary* measured figure for atlas size/VRAM of a 212-mod pack; treat "lower mipmap levels = less VRAM + less asset reload time, biggest for 6 GB P1" as a hypothesis to measure.
**Biome blend.** Sodium's tooltip: default **5×5**; "Higher values will **greatly increase the amount of time it takes to load or update chunks**, for diminishing improvements in quality." [Sodium 0.8.13 lang](https://github.com/CaffeineMC/sodium/blob/mc1.21.1-0.8.13/common/src/main/resources/assets/sodium/lang/en_us.json) — **VERIFIED**. This is a **chunk-build/micro-stutter** cost, not a steady-state FPS cost — relevant on all three machines (all 4C/8T), and it composes with Sodium's 2 chunk-builder threads and DH's `lodBiomeBlending` (default 3). The shaderLABS wiki notes vanilla's implementation is naive and that the fastest reliable reduction is simply lowering it. [shaderLABS](https://shaderlabs.org/wiki/Performance_Tips) — **COMMUNITY**.
**Better Leaves (Motschen's) 9.6.** "Better Leaves adds additional layers to leaf blocks, making them appear more bushy, dense and natural." Version 9.0 pre-generates textures per leaf type for performance; the pack explicitly says: *"I strongly recommend installing the **Cull Leaves** mod alongside Sodium/Embeddium to get more FPS."* [Motschen's Better Leaves](https://modrinth.com/project/uvpymuxq) — **DOCUMENTED**. Read: it *increases* per-leaf-block geometry (more quads → more mesh work + more overdraw) and relies on face culling to pay for it. Sodium's own `Leaves` setting ("Fast = transparent vs opaque") is the vanilla-side lever; Sodium 0.8.12's changelog warns **"sodiumleafculling does not work"** on this line, so don't plan on a Sodium leaf-culling add-on. [Sodium 0.8.12 changelog](https://modrinth.com/mod/sodium/version/mc1.21.1-0.8.12-neoforge) — **DOCUMENTED**. EntityCulling's `solidLeaves` option exists for exactly this scenario. **Cull Leaves is not in the pack.** [Community reports](https://www.reddit.com/r/Minecraft/comments/42glrg/leaves_causing_fps_issues_fixed_with_a_resource/) of leaves dominating FPS in forested/jungle areas are **COMMUNITY** but consistent with the pack's own geometry change.
**Fresh Animations 1.10.4 + EMF 3.3.9 + ETF 7.2.4.** Fresh Animations requires EMF/ETF on 1.19+. [Fresh Animations](https://modrinth.com/resourcepack/fresh-animations) — **DOCUMENTED**. Reported cost ~5–10 FPS in mob-dense areas [mcmodhub](https://mcmodhub.com/resource-packs/fresh-animations) — **COMMUNITY**; there is also a mod-side bug report of "Huge FPS drops with Fresh Animations and the mods needed for it (EMF/ETF)" [easy-villagers #243](https://github.com/henkelmax/easy-villagers/issues/243) — **DOCUMENTED (bug report)**. EMF exposes throttles (**VERIFIED** from [EMFConfig.java](https://github.com/Traben-0/Entity_Model_Features/blob/master/src/main/java/traben/entity_model_features/config/EMFConfig.java)): `animationLODDistance` (**default 20**), `modelUpdateFrequency` (**default `UpdateFrequency.Average`**), `animationFrameSkipDuringIrisShadowPass` (**default `true`** — a real shader-specific saving), `retainDetailOnLowFps` (true), `retainDetailOnLargerMobs` (true), `renderModeChoice` (`NORMAL`), `allowedCEM` (`ALL`). The shadow-pass frame-skip being on by default is worth noting given §3: it is one of the few places Iris+EMF already cooperate.
**Fusion/Athena CTM (1.3.15b / 4.0.6)** and **Chipped/Rechiseled/Macaw's** appear in this stack as texture/model-count amplifiers (atlas + model bake + D4). Fusion CTM is the 1.21.1 successor to the old "CTM" path that ModernFix's `dynamic_resources` explicitly carries compat mixins for (`dynamic_resources/ctm/…`, `…/ldlib/…`). [ModernFix tree @ 1.21.1](https://github.com/embeddedt/ModernFix/tree/1.21.1/src/main/java/org/embeddedt/modernfix/common/mixin/perf/dynamic_resources) — **VERIFIED** presence of those compat patches; whether Fusion specifically is covered is **INFERENCE / to verify**.
---
## Top levers (ranked)
| # | Lever | Expected impact | Machine it helps | Risk | Confidence |
|---|---|---|---|---|---|
| 1 | **Decide whether shaders are mandatory per machine.** With shaders on, Flywheel's instancing/indirect backends are unavailable → Create kinetics render per-BE *and* twice for shadows. Running Complementary only on P1/P2 (or all-off) is the largest single swing. | **High** | all, especially P0 | none (policy) | **VERIFIED** (source) |
| 2 | **Add a Flywheel↔Iris bridge** (Iris Flywheel Compat / Colorwheel) if Create throughput matters with shaders. | **High** | P1/P2 (CPU), P0 | **High** (both are unofficial, "almost always breaks on a Create or Iris update") | **DOCUMENTED** |
| 3 | **Complementary profile ≤ MEDIUM + Shadow Distance ≤ 8, Entity Shadows OFF.** Entity shadows are author-flagged as >50 % FPS in some cases; profiles above MEDIUM push shadow distance past the server's 8-chunk view distance. | **High** | all, esp. P0 | none (visual) | **DOCUMENTED** |
| 4 | **DH settings + shaders:** lower DH `lodChunkRenderDistanceRadius` (default 256), consider `maxHorizontalResolution` below `BLOCK`, `horizontalQuality`/`verticalQuality` below MEDIUM, `vanillaFadeMode` off `DOUBLE_PASS`, `lodBiomeBlending` 3→0, and the DH *CPU/thread preset* down from BALANCED. Remember the DH shadow pass renders **all** DH chunks. | **High** | all; P2 (RAM/CPU) most | low–med (visual bands, DH border) | **VERIFIED** (defaults) + **DOCUMENTED** (behaviour) |
| 5 | **ModernFix `mixin.perf.dynamic_resources=true`** — the biggest documented memory/launch win (−55 % in the author's test *with* FerriteCore), default-off only for compat. | **High** (RAM/load) | **P2** (8 GB free) | Med (startup crash / missing textures) | **DOCUMENTED** + **VERIFIED** (default) |
| 6 | **Lower `mipmapLevels` 4 → 2/3** and/or trim high-res overlays: cuts the ~+33 % mipmap VRAM multiplier on an atlas inflated by Chipped/Rechiseled/Macaw's plus animated-texture frames. | **Med** | **P1** (6 GB VRAM), P0 | low (slight shimmer) | **INFERENCE** on the numbers; **DOCUMENTED** on the mechanism |
| 7 | **Verify Sodium's high-impact options are actually on**: `animateOnlyVisibleTextures`, `useFogOcclusion`, `useEntityCulling`, `useBlockFaceCulling`, `useNoErrorGLContext` — all default `true`, and all are the pack's most animated-texture/RP-heavy-mod sensitive ones. | **Med** | all, P0 (iGPU) most | none | **VERIFIED** (defaults) |
| 8 | **Sodium `chunkBuilderThreads` and `chunkBuildDeferMode`:** default auto = **2 threads** on all three 4C/8T machines with "Deferred" already selected. Try 3–4 threads on P1/P2; expect faster chunk fill, riskier frame times. | **Med** | P1/P2 (chunk-bound) | low–med (frame-time variance) | **VERIFIED** (formula) |
| 9 | **Biome blend 2 → 0/1** (and DH `lodBiomeBlending` 3 → 0) — pure chunk-load/micro-stutter lever, cheap to test. | **Med** | all (4C/8T) | none (visual) | **VERIFIED** (tooltip) |
| 10 | **EMF throttles:** raise `modelUpdateFrequency` toward slower, raise/lower `animationLODDistance`, keep `animationFrameSkipDuringIrisShadowPass=true`. | **Med** | P0/P1 | low (animation quality) | **VERIFIED** (keys/defaults) |
| 11 | **Better Leaves 9.6 + no Cull Leaves = paid geometry.** Add a leaf-culling mod (Cull Leaves) or drop the RP; set EntityCulling `solidLeaves=true` if leaves are opaque. Note `sodiumleafculling does not work` on this Sodium line. | **Med** | all, P0 | low–med | **DOCUMENTED** + **VERIFIED** (Sodium changelog/EntityCulling key) |
| 12 | **ModernFix `max.bg.threads` = cores−3** is already being set; if `-Dmax.bg.threads` is being passed in JVM args, confirm it isn't fighting this. | **Low–Med** | P1/P2 | low | **VERIFIED** |
| 13 | **FerriteCore: leave defaults.** Don't enable `compactFastMap` (CPU for RAM) on a main-thread-bound fleet. | **Low** | P2 only | low | **VERIFIED** (source) |
| 14 | **ImmediatelyFast:** leave defaults; the author's own bench shows only 1.27× under Iris+Sodium. | **Low** | P1/P2 (CPU) | none | **DOCUMENTED** |
---
## Open questions to verify by benchmark
1. **Does the pack actually ship an Iris↔Flywheel bridge?** The provided mod list has `irisveil` but no Iris Flywheel Compat / Colorwheel — yet irisveil's own validated baseline includes Iris Flywheel Compat. Check `mods/` and the log for `Flywheel backend fell back from 'flywheel:indirect' to 'flywheel:off'` and for `irisflw:iris_instancing`. **This single log line decides levers #1/#2.**
2. **What is the actual block-atlas size and VRAM on P1?** (Atlas texture allocation, plus mipmap multiplier.) Only answerable by measurement (e.g. a VRAM/F3 or driver-level capture) — needed before trusting lever #6.
3. **Complementary Reimagined r5.9.3's shipped default profile** — the repo table is authoritative for the settings, but the *default* profile on a fresh install should be read in-game (the repo has a `COMPLEMENTARY` profile the older docs predate).
4. **Whether MakeUp Ultra Fast 9.5f actually beats Complementary at equivalent visual settings** on P0/P1 — no primary comparison exists; measure.
5. **DH's real cost with the chosen shaderpack**: measure with DH rendering on/off, and with DH's shadow pass (`dhShadow.enabled`) forced off, to separate the DH-shadow cost from DH-terrain cost.
6. **ModernFix `dynamic_resources=true` compatibility with Fusion CTM / Athena / Chipped / Rechiseled / Macaw's** on this exact pack — author lists CTM-style compat patches but not these mods by name; test with a resource reload and a look for missing textures.
7. **Does `Animate Only Visible Textures` actually hold up with Fresh Animations + FA All Extensions + Better Leaves' generated textures** (author warns of "issues with some textures not being animated")?
8. **EntityCulling block-entity whitelist adequacy for this pack** — Create contraptions are tick-cull-whitelisted, but check whether specific Create/Alex's Caves block entities pop or vanish (the config is a plain JSON list and is safe to extend).
9. **Whether Sodium's `QuadSplittingMode = SAFE` is limiting translucency correctness/instability** in a Chipped/Rechiseled/glass-heavy base — the tooltip says `UNLIMITED` imposes no geometry cap but risks instability; only worth testing if sorting artifacts are visible.
10. **P2 memory headroom specifically**: with ~8 GB free, does DH's "6–8 GB allocated" recommendation plus ModernFix `dynamic_resources` fit, and does a concurrent GC (ZGC) change the micro-stutter picture?
---
## Sources
**Kept**
- Sodium, `mc1.21.1-0.8.13` source — `SodiumConfigBuilder.java`, `SodiumOptions.java`, `ChunkBuilder.java`, `lang/en_us.json`. https://github.com/CaffeineMC/sodium/tree/mc1.21.1-0.8.13 — the authoritative option set **and defaults** for the pinned version.
- Sodium version page / changelog, `mc1.21.1-0.8.12-neoforge` (the base of the 0.8.13 line). https://modrinth.com/mod/sodium/version/mc1.21.1-0.8.12-neoforge — perf claims + official mod-compat matrix.
- Flywheel 1.21.1 branch: `Backends.java`, `BackendManagerImpl.java`, `IrisCompat.java`, `ShadersModHelper.java`, `NeoForgeFlwConfig.java`. https://github.com/Engine-Room/Flywheel/tree/1.21.1/dev — proves the Iris→backend fallback and gives the real NeoForge config keys.
- Flywheel tag `mc1.21.1/v1.0.5`. https://github.com/Engine-Room/Flywheel/blob/mc1.21.1/v1.0.5/common/src/backend/java/dev/engine_room/flywheel/backend/Backends.java — confirms the shader gate predates 1.0.6.
- Iris issue #1414 ("Flywheel is not supported"), includes maintainer statement. https://github.com/IrisShaders/Iris/issues/1414
- Create `mc1.21.1/dev`: `KineticBlockEntityRenderer.java` (+ `ShaftRenderer.java`). https://github.com/Creators-of-Create/Create/blob/mc1.21.1/dev/src/main/java/com/simibubi/create/content/kinetics/base/KineticBlockEntityRenderer.java — proves the non-Flywheel fallback path exists and is used when visualization is unsupported.
- Iris docs — Distant Horizons integration (`dh_terrain`/`dh_water`/`dh_shadow`, auto-enabled shadow pass, no shadow distance). https://shaders.properties/current/reference/mod-support/distant_horizons/
- Distant Horizons core `Config.java` (current main). https://gitlab.com/distant-horizons-team/distant-horizons-core/-/blob/main/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java — verified config keys + defaults.
- Distant Horizons Modrinth description (shader requirements, stutter checklist). https://modrinth.com/mod/distanthorizons
- Complementary Reimagined `shaders.properties` + `lang/en_US.lang` (author repo). https://github.com/ComplementaryDevelopment/ComplementaryReimagined — profile table, shadow distances, and the author's own perf warnings.
- MakeUp Ultra Fast `shaders.properties` + README (author repo). https://github.com/javiergcim/MakeUpUltraFast — verified option keys, shipped profile values, `dhShadow.enabled=false`.
- Iris Veil Compat README (mechanism, overhead, tested baseline). https://github.com/leon-o/iris-veil-compat
- ModernFix `ModernFixEarlyConfig.java` @ 1.21.1 (default table). https://github.com/embeddedt/ModernFix/blob/1.21.1/src/main/java/org/embeddedt/modernfix/core/config/ModernFixEarlyConfig.java
- ModernFix Dynamic Resources FAQ. https://github.com/embeddedt/ModernFix/wiki/Dynamic-Resources-FAQ — 1.7 GB → 945 MB with FerriteCore already installed; why it's off by default.
- FerriteCore `FerriteConfig.java`, `ConfigFileHandler.java`, `summary.md` @ 1.21.1. https://github.com/malte0811/FerriteCore/tree/1.21.1
- EntityCulling `Config.java` (configVersion 9 defaults + whitelists). https://github.com/tr7zw/EntityCulling/blob/main/EntityCulling-Versionless/src/main/java/dev/tr7zw/entityculling/versionless/Config.java
- ImmediatelyFast `ImmediatelyFastConfig.java` + README bench table. https://github.com/RaphiMC/ImmediatelyFast/blob/1.21/common/src/main/java/net/raphimc/immediatelyfast/feature/core/ImmediatelyFastConfig.java
- EMF `EMFConfig.java` (animation throttles incl. `animationFrameSkipDuringIrisShadowPass`). https://github.com/Traben-0/Entity_Model_Features/blob/master/src/main/java/traben/entity_model_features/config/EMFConfig.java
- Better Mipmaps description (vanilla 4-level cap, atlas-wide minimum, resolution↔level table). https://modrinth.com/mod/better-mipmaps
- Motschen's Better Leaves description (geometry change, Cull Leaves recommendation, v9 perf rework). https://modrinth.com/project/uvpymuxq
- shaderLABS Performance Tips wiki (biome blend, shader menu sliders, RAM guidance). https://shaderlabs.org/wiki/Performance_Tips
- Ocuwheel description (explicit "Flywheel disables GPU instancing under shaders, falls back to CPU rendering"). https://www.curseforge.com/minecraft/mc-mods/ocuwheel-oculus-flywheel-compat
- Sodium Extras description (which options are *not* in Sodium — fog toggles etc.). https://modrinth.com/mod/sodium-extras
**Dropped**
- shadersmods.com / mc-mods.com / mcmodhub "Complementary Reimagined review" pages — SEO content, and their profile tables describe r2.1 (2023). Used only as a secondary lead; superseded by the author's own `shaders.properties`.
- irisshaders.org / minecrafthub.io / mctoolbox.net guides — unverifiable marketing-style guides, no version-specific claims worth keeping.
- r/feedthebeast, r/minecraftshaders, r/Minecraft threads on MakeUp-vs-Complementary FPS — anecdotal, no controlled comparison.
- Sodium `dev`-branch lang file as a *description of 0.8.13* — kept only to demonstrate which options (hidden fluid culling etc.) are **absent** on 1.21.1.
- minecraft.wiki/w/Options.txt — returned HTTP 403, so the vanilla `mipmapLevels`/`biomeBlendRadius` defaults are stated from Sodium's own language file ("Default is 5x5" for biome blend) rather than the wiki.
@@ -0,0 +1,185 @@
# Research: Distant Horizons 3.3.x (client) + Xaero's Minimap 26.5.0 / World Map 1.46.0 — client-side performance
Pack context: Onion MC, MC 1.21.1 / NeoForge 21.1.251, pinned `DistantHorizons-3.3.2-1.21.1-fabric-neoforge.jar`, `xaerominimap-neoforge-1.21.1-26.5.0.jar`, `xaeroworldmap-neoforge-1.21.1-1.46.0.jar` (verified against `mods/*.pw.toml` in this repo). Dedicated server with DH; Iris 1.8.14-beta.1; shaderpacks Complementary Reimagined r5.9.3 + MakeUp Ultra Fast 9.5f. All 3 fleet machines are 4C/8T.
## Summary
DH 3.3.2's client cost splits into (a) CPU: LOD building/generation threads (thread preset; on 8 logical CPUs BALANCED = 4 threads, Minimal = 1), and (b) GPU/VRAM: LOD render distance × quality preset (distance is the dominant term; DH docs say >512 chunks gets "difficult due to high VRAM/GPU usage"; a 1.x-era dev-tracker data point put 1024 chunks at ~4 GB VRAM). In multiplayer the client cannot generate LODs at all — the server sends them (default 500 KB/s per player) — so client-side "distant generation" settings are singleplayer-only; server pregen via `/dh pregen` is the officially recommended path, and running Chunky alongside DH generation is explicitly warned against (holes). Xaero's pair is cheap: the minimap reuses world-map textures by default, world-map disk data grows with exploration but in-RAM region cache is bounded (cappable via a "max loaded regions" setting added in 1.41.2), and the map screen skips world rendering by default.
## Findings — Distant Horizons 3.3.2
### 1. What each client setting actually costs (keys verified from the pinned jar's `assets/distanthorizons/lang/en_us.json` + DH core source)
GUI path and TOML key names below were read from the 3.3.2 jar and DH core `Config.java`; every listed key exists in 3.3.2. [Config.java (DH core, main/3.3.x line)](https://gitlab.com/distant-horizons-team/distant-horizons-core/-/raw/main/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java), [lang file in jar 3.3.2](https://modrinth.com/mod/distanthorizons/version/3.3.2-1.21.1)
| Concern | Key (GUI path) | Verified facts |
|---|---|---|
| LOD render distance | `client.advanced.graphics.quality.lodChunkRenderDistanceRadius` | min 32 / **default 256** / max 4096 chunks; "best effort" number [Config.java](https://gitlab.com/distant-horizons-team/distant-horizons-core/-/raw/main/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java); official gallery: "By default DH renders 256 chunks wide… anything above 512 may become difficult due to high VRAM/GPU usage" [Modrinth gallery](https://modrinth.com/mod/distanthorizons/gallery) |
| Quality preset | `client.qualityPresetSetting` (MINIMUM/LOW/MEDIUM/HIGH/EXTREME) | Preset just sets the sub-options below; **generation is independent** — "DH will always generate LODs at the maximum possible quality so you can use any Quality preset you want later" (no regen needed) [DH FAQ General](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/1-general/General) |
| Horizontal quality / resolution | `…quality.horizontalQuality`, `…quality.maxHorizontalResolution` | "Higher settings will … increase memory and GPU usage"; resolution BLOCK = 256 LODs/chunk (fanciest) vs CHUNK = 1 LOD/chunk (fastest) [Config.java](https://gitlab.com/distant-horizons-team/distant-horizons-core/-/raw/main/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java) |
| Vertical quality | `…quality.verticalQuality` | HEIGHT_MAP (cheapest) → PIXEL_ART; "higher options … increase memory and GPU usage"; too-low vertical quality causes flat/discolored LODs [Config.java + Problems & Solutions](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions) |
| Transparency | `…quality.transparency` | Only `DISABLED` or `COMPLETE` in 3.3.2 (fake transparency removed in 3.1.0-b); DISABLED = opaque LODs = cheaper; **3.1.1-b+ forces transparency ON when Iris is present** [changelog 3.1.0-b/3.1.1-b](https://modrinth.com/mod/distanthorizons/version/3.1.1-b-1.21.1) |
| Cave culling | `…culling.enableCaveCulling`, `…culling.caveCullingHeight` (default 60) | "culls all faces with skylight value of 0 under the cave culling height" — big face-count saver in mountains/overhangs [lang tooltip, jar 3.3.2] |
| Overdraw | `…culling.overdrawPrevention` (default −1 = auto), `…culling.reduceOverdrawWithFastMovement` | % of vanilla RD where DH starts rendering behind vanilla terrain; −1 auto-scales; holes-at-edge tradeoff documented; auto reduce while flying [Config.java + P&S quick guide](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions) |
| Frustum culling | `…culling.disableFrustumCulling` (default false = culling ON), `…culling.disableShadowPassFrustumCulling` | Culling "increasing GPU performance"; leave enabled (disabled only if LODs pop at screen corners) [lang tooltip] |
| Vanilla fade mode | `…quality.vanillaFadeMode` (NONE/SINGLE_PASS/DOUBLE_PASS) | NONE "Fastest… pronounced border"; DOUBLE_PASS "Slowest… smoothest" (MEDIUM+ default) [Config.java] |
| DH SSAO / AA | `client.advanced.graphics.enableSsao`, `…enableAntiAliasing` | 3.3.0 added TAA; SSAO/AA off in MINIMUM/LOW presets [changelog 3.3.0](https://modrinth.com/mod/distanthorizons/version/3.3.0-1.21.1) + preset handler source |
| LOD textures | `…texture.enableTexturedLods`, `maxTexturedLodDetailLevel` | 3.2.0 feature; "Only available for base DH rendering, **Iris shaders will render LODs as untextured**" → no shader cost under Iris either way [changelog 3.2.0-b](https://modrinth.com/mod/distanthorizons/version/3.2.0-b-1.21.1) |
| DH clouds/beacons | `…genericRendering.enableCloudRendering`, `enableMultiLayerClouds`, `enableBeaconRendering` | DH renders its own 3-layer clouds; GPU filler; Complementary sets `dhClouds = off` (see §4) |
| Zoom quality | `…quality.increaseQualityWhenZoomedIn`, `maxZoomQualityIncrease` (default 4) | Loading crisper LODs while zoomed costs CPU/memory while zoomed [Config.java; 3.3.0 fixed "massive lag when zoomed in and spinning the camera"] |
| CPU threads | `client.threadPresetSetting` → `common.multiThreading.numberOfThreads`, `threadRunTimeRatio`, `threadPriority`, `useC2meThreadCount` | Preset = % of **logical** CPUs (source has table: 1.0 ⇒ 8 threads on 8 logical) + runtime ratio [ThreadPresetConfigEventHandler](https://gitlab.com/distant-horizons-team/distant-horizons-core/-/raw/main/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/presets/ThreadPresetConfigEventHandler.java) |
| LOD storage | `common.lodBuilding.dataCompression` (LZ4/ZSTD…), `worldCompression` (MERGE_SAME_BLOCKS/VISUALLY_EQUAL), `databaseSyncMode` (FULL/NORMAL/OFF), `disableUnchangedChunkCheck` | LODs live in SQLite (`.minecraft/Distant_Horizons_server_data/<server>/` in MP); NORMAL sync default since 3.3.0 cut disk work ~50%; OFF risks corruption on power loss [General FAQ](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/1-general/General), [changelog 3.3.0](https://modrinth.com/mod/distanthorizons/version/3.3.0-1.21.1) |
| World gen (SP only) | `common.worldGenerator.enableDistantGeneration`, `generatorPlan` (SURFACE_THEN_CHUNKS/SURFACE_ONLY/CHUNKS_ONLY/DISABLED), `chunkGeneratorMode` (…/SURFACE/FEATURES/INTERNAL_SERVER), `enableFastSurfaceGenerator`, `limitIfServerUnhealthy`, `pauseIfMovingQuickly` | 3.3.0 added fast surface gen + "pause world gen if server thread overloaded or moving quickly — both options can be toggled… if faster world gen is desired over smoothness" [changelog 3.3.0](https://modrinth.com/mod/distanthorizons/version/3.3.0-1.21.1) |
Quality preset → what it sets (from [RenderQualityPresetConfigEventHandler.java](https://gitlab.com/distant-horizons-team/distant-horizons-core/-/raw/main/core/src/main/java/com/seibel/distanthorizons/core/config/eventHandlers/presets/RenderQualityPresetConfigEventHandler.java)) — note the trap that **HIGH/EXTREME turn cave culling OFF**:
| Preset | maxHorizRes | Vertical | Horizontal | Transparency | SSAO | AA | Vanilla fade | Cave culling | Biome blending |
|---|---|---|---|---|---|---|---|---|---|
| Minimum | 2-block | Height map | Lowest | Disabled | off | off | None | on | 0 |
| Low | Block | Low | Low | Disabled | off | on | Single pass | on | 1 |
| Medium | Block | Medium | Medium | Complete | on | on | Double pass | on | 3 |
| High | Block | High | High | Complete | on | on | Double pass | **off** | 3 |
| Extreme | Block | Extreme | Extreme | Complete | on | on | Double pass | **off** | 3 |
Thread presets on the fleet's 4C/8T (source: `ThreadPresetConfigEventHandler` — percentages of `availableProcessors` = 8 logical):
| Preset | Threads | Runtime ratio |
|---|---|---|
| Minimal Impact | 1 | 0.5 |
| Low Impact | 2 | 1.0 |
| Balanced (default) | 4 | 1.0 |
| Aggressive | 6 | 1.0 |
| I Paid For The Whole CPU | 8 | 1.0 |
### 2. GPU upload settings — removed in 3.x
The old 2.x-era `gpuUploadMethod` (Direct / Single draw / Multi draw / Buffer storage) **no longer exists in 3.3.2**: the full option list in the pinned jar contains no upload-method key, and the 3.0.0-b changelog states "Remove instanced rendering config option — instanced rendering will always be used if available". The only related control left is `client.advanced.graphics.experimental.renderingEngine` (Auto / OpenGL / Blaze3D); Blaze3D is only for newer MC — on 1.21.1 it's effectively OpenGL/Auto, and DH ≥3.3 renders with reverse-Z depth. [jar lang file](https://modrinth.com/mod/distanthorizons/version/3.3.2-1.21.1), [changelog 3.0.0-b](https://modrinth.com/mod/distanthorizons/version/3.0.0-b-1.21.1), [changelog 3.1.0-b](https://modrinth.com/mod/distanthorizons/version/3.1.0-b-1.21.1). VERIFIED.
### 3. VRAM / RAM vs distance (no first-party table exists)
- Official qualitative: memory & GPU usage rise with horizontal/vertical quality, max resolution and LOD distance (config comments); >512 chunks "difficult due to high VRAM/GPU usage" [Config.java](https://gitlab.com/distant-horizons-team/distant-horizons-core/-/raw/main/core/src/main/java/com/seibel/distanthorizons/core/config/Config.java), [Modrinth gallery](https://modrinth.com/mod/distanthorizons/gallery). DOCUMENTED.
- Only quantitative tracker data point is old (DH 1.x, 2022): "1024 with default settings uses ~4 GB VRAM and more than 8 GB RAM should be allocated to JRE or else there will be intense stuttering" [GitLab issue #157](https://gitlab.com/distant-horizons-team/distant-horizons/-/issues/157). COMMUNITY/dev-tracker, dated — treat as order-of-magnitude only.
- Heap guidance is first-party: 4–8 core CPUs → allocate 6–8 GB; 10+ cores → 12–16 GB; prefer ZGC (`-XX:+UseZGC`) over G1GC on Java 21 "known to cause stuttering"; DH even warns in-chat if G1GC is used [DH FAQ General](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/1-general/General), [P&S](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions). VERIFIED.
- Community starting profile for mid hardware: LOD 96–192 chunks at Medium quality [distanthorizonsguide calculator](https://distanthorizonsguide.com/calculator). COMMUNITY.
- Official troubleshooting maps symptom→setting: CPU pegged → lower CPU preset or disable world gen; GPU pegged → lower quality preset or LOD distance; VRAM pegged → same [P&S](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions). VERIFIED.
### 4. Iris shader cost & which packs support DH
- Iris ≥1.7 required; DH terrain renders through dedicated `dh_terrain`, `dh_water` and `dh_shadow` programs defined by the shaderpack — i.e. LODs are drawn with full shader effects, so shader cost scales to the LOD distance too; the DH shadow pass can be toggled per-pack via `dhShadow.enabled` [Iris docs — Distant Horizons](https://shaders.properties/current/reference/mod-support/distant_horizons/). VERIFIED.
- **Complementary Reimagined r5.x supports DH**: its `shaders.properties` has a `#ifdef DISTANT_HORIZONS` block with `blend.dh_water=…` and, importantly, `dhShadow.enabled = false` + `dhClouds = off` — the DH shadow pass and DH clouds are disabled, trimming shader work over distant terrain [Complementary Reimagined source](https://raw.githubusercontent.com/ComplementaryDevelopment/ComplementaryReimagined/main/shaders/shaders.properties). VERIFIED.
- **MakeUp Ultra Fast also has DH support**: `#ifdef DISTANT_HORIZONS: dhShadow.enabled = false; blend.dh_water=…` [MakeUp Ultra Fast source](https://raw.githubusercontent.com/javiergcim/MakeUpUltraFast/master/shaders/shaders.properties). VERIFIED. Both pack shaders therefore avoid the most expensive DH-over-shader path (DH shadows render *all* chunks into the shadow map).
- Shaders that don't support DH prevent LODs from rendering entirely [P&S](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions). VERIFIED.
### 5. Client-generated vs server-provided LODs (this pack: server-provided)
- In multiplayer, clients **cannot** generate LODs: "Can clients generate instead? No, world generation is coupled with server-side logic" — the client requests and receives LODs (normal generation), gets real-time updates near players, and sync-on-load with timestamps [Server Owners wiki](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/5-server-owners/Server-Owners). VERIFIED.
- Server must have the same DH version; `Distant Generator Plan` must not be `DISABLED` on either side. Defaults allow **500 KB/s (4 Mbit/s) per player** of LOD traffic (`server.playerBandwidthLimit`); other keys: `generationRequestRateLimit`, `maxGenerationRequestDistance`, `enableRealTimeUpdates` + `realTimeUpdateDistanceRadiusInChunks`, `synchronizeOnLoad` + `syncOnLoadRateLimit` + `maxSyncOnLoadRequestDistance`, `globalBandwidthLimit`, `enableAdaptiveTransferSpeed` [Server Owners wiki + jar lang](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/5-server-owners/Server-Owners). VERIFIED. Client-side keys: `client.advanced.multiplayer.serverFolderNameMode` (local LOD DB naming).
- "Pre-generating LODs is strongly recommended to avoid performance issues" — command `/dh pregen start <dimension> <origin> <chunkRadius>`; avoid pregen on a live server. Client-side pregen alternative: copy server world, generate AFK, ship the SQLite DB back [Server Owners wiki](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/5-server-owners/Server-Owners). VERIFIED.
- World-gen mode notes: default `FEATURES` mode doesn't save generated chunks, so trees/structures can pop in/out at LOD borders; `INTERNAL_SERVER`/`FULL` prevents it [P&S](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions). VERIFIED.
### 6. Known warnings relevant to this pack
- **DH + Chunky**: "Running Chunky will also generate & update LODs, but it's not recommended to rely on this… by loading a lot of chunks quickly you risk overloading DH and ending up with a lot of holes. Either use DH's pre-generation, or temporarily disable the mod entirely" [Server Owners wiki](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/5-server-owners/Server-Owners). DH 3.3.x also changed thread linking: "Don't link DH thread count to C2ME unless Chunky is also present… Using Chunky and DH isn't recommended due to the possibility of holes" [changelog 3.3.0](https://modrinth.com/mod/distanthorizons/version/3.3.0-1.21.1); 3.3.3 added auto-disable of DH worldgen while Chunky worldgen runs (3.3.2 does **not** have that guard). VERIFIED.
- **DH + Alex's Caves**: LODs fail to render; fix = set `biome_ambient_light_coloring = false` in `config/alexscaves-client.toml` (DH bug tracker issue #566) [DH wiki Mod Support](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/4-mod-support/Mod-Support). VERIFIED.
- **DH 3.3.2 + SSRD**: "Mark SSRD (Separate Sable Render Distance) 1.8.6 and below as incompatible — due to DH's change to rendering with Reverse Z depth". Pack has SSRD 1.8.7 → OK, but don't downgrade it [changelog 3.3.2](https://modrinth.com/mod/distanthorizons/version/3.3.2-1.21.1). VERIFIED.
- **Steam Deck / Mesa**: DH+ Sodium crash on Linux AMD/Intel Mesa GPUs → disable Sodium's "Use No Error context" (and delete DH config once) [P&S](https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/1-user-guide/1-frequently-asked-questions/2-problems-and-solutions/Problems-and-Solutions). DH 3.2.0 raised min OpenGL 3.2→3.3 (AMD fix) [changelog 3.2.0-b](https://modrinth.com/mod/distanthorizons/version/3.2.0-b-1.21.1). VERIFIED. Deck players run 128–256 LOD with Iris shaders at 30–40 FPS at 1200×800 [r/DistantHorizons](https://www.reddit.com/r/DistantHorizons/comments/1by5v4u/how_to_get_distant_horizons_working_on_steam_deck/), [r/SteamDeck](https://www.reddit.com/r/SteamDeck/comments/1lak2s5/how_i_got_minecraft_running_with_distant_horizons/). COMMUNITY.
- Black LODs from light-map mods; "Mod Compatibility Warnings" exist at `Advanced → Logging → Warnings` if a known-bad combo is present [P&S + jar lang]. VERIFIED (key exists).
### 7. Recommended starting settings per fleet machine
All values use verified keys; distances assume server VD 8 (vanilla) and server-side pregen so the client isn't starved of LODs. (INFERENCE from the verified mechanics + community profiles above.)
| Setting | (a) Steam Deck (RDNA2 8CU, 1280×800, shared RAM) | (b) P1 GTX 1060 6GB (VRAM-bound) | (c) P2 4C + ~8GB free RAM (heap-bound) |
|---|---|---|---|
| LOD render distance | 96–128 | 128–192 (step up slowly; shaders over 512-chunk LODs is where VRAM dies) | 96–128 (lower if heap spikes) |
| Quality preset | LOW | LOW–MEDIUM (watch VRAM; MEDIUM re-enables transparency+SSAO) | MEDIUM or LOW (quality is render-only cost; cheap to lower) |
| Cave culling | ON (do **not** use HIGH/EXTREME presets without re-enabling) | ON | ON |
| Thread preset | Minimal/Low Impact (leave headroom for Deck's APU) | Low Impact/Balanced | Balanced (4 threads) while playing; Minimal if stutter |
| SSAO / DH anti-aliasing | off (LOW preset) | off unless headroom | default |
| Transparency | Disabled (if no shader) | forced Complete under Iris | forced Complete under Iris |
| Vanilla fade mode | Single pass | Double pass (visual seam vs GPU) | Double pass |
| DH clouds/beacons | off if GPU-bound (Complementary already disables DH clouds) | off | default |
| JVM heap | 6–8 GB `-Xmx` + `-XX:+UseZGC` (wiki guidance) | 6–8 GB | ≤6 GB; prefer cutting LOD distance over heap |
| Generation | server provides LODs; keep `enableDistantGeneration` irrelevant in MP | same | same; keep client DB sync NORMAL |
## Findings — Xaero's Minimap 26.5.0 / World Map 1.46.0
### 8. Where the cost is, and the verified settings that control it
Field names below were extracted from the pinned jars' settings classes (`xaero/common/settings/ModSettings.class`, `xaero/map/settings/ModSettings.class`) — the mods are closed-source but NeoForge builds ship Mojang-mapped symbols. VERIFIED (jar extraction).
| Cost center | Mechanism | Relevant verified settings/keys |
|---|---|---|
| Minimap terrain | Chunk-to-pixel updates as you move; renders into its own FBO (`MinimapFBORenderer`, `bufferSize`) | `minimapSize` (bigger = more fill rate), `zoom`, `caveZoom` |
| Cave mode | Renders below-ground slices; needs roof search + extra depth scanning | `caveMaps` (on/off), `caveMapsDepth`, `caveMapsDisabled`, `manualCaveModeStart`, `autoCaveMode` (WM), per-dimension `defaultCaveModeType`, `legibleCaveMaps` |
| Shading | Extra per-chunk color math | `terrainDepth`, `terrainSlopes`, `biomeBlending`, `blockColours`, `ambientLightColored` |
| Entity radar | Per-frame entity scan + icon rendering (model-based icons are pre-rendered; heavy entity mods = more types) | `entityRadar`, `mainEntityAs`, `dotsStyle`, `smoothDots`, `radarHideInvisibleEntities`, display-names toggles; categories in `xaero/minimap` config |
| Overlays | Extra scans | `displayRedstone`, `displayStainedGlass`, `slimeChunks`, `lightOverlay*` |
| World Map rendering | Full-screen map; **skips world rendering by default while the map is open** — turning that off "significantly reduces your framerate" (official changelog) | world-map-screen "world render skip" option; `openMapAnimation`, `zoomButtons` |
| World Map writing | Client converts explored chunks into region data; "Optimized map writing… less useless chunk iteration" (26.2.0/1.42.0) | `mapWritingDistance` (limit writing distance; option exists since 1.35.0), **"Force Fast Writing"** — official: "Bad for game performance" |
Official changelog anchors: world map 1.42.0 (fast-writing "bad for game performance", world-render skip, optimized map writing), 1.41.2 ("Added a new option… for setting the **maximum number of loaded regions**"), 1.35.0 (map writing distance option), 1.37.2 ("Slightly optimised region unloading"); minimap 26.2.0 ("Optimized map writing"), 25.3.12 (BatchableBufferSource / ImmediatelyFast interplay) — [chocolateminecraft update pages](https://chocolateminecraft.com/update.php?mod_id=2) and [mod_id=0](https://chocolateminecraft.com/update.php?mod_id=0). DOCUMENTED.
### 9. Does world map memory scale with explored area?
- **On disk: yes, unbounded-ish** — regions are saved as `.zip` files per dimension/map under `xaero/world-map/…` (plus separate cache folders the FAQ says can be deleted) [Modrinth FAQ](https://modrinth.com/mod/xaeros-world-map). VERIFIED.
- **In RAM: bounded** — the mod keeps a *region cache* (region-cache fields exist in 1.46.0 bytecode; "Reload Regions"/"Reload All Regions" options manage the cache), region unloading is automatic, and since world map 1.41.2 there is a user setting for the **maximum number of loaded regions** (present in 1.46.0) — so heap use is a function of that cap + zoom level, not of total exploration [changelog 1.41.2](https://chocolateminecraft.com/update.php?mod_id=2). VERIFIED (mechanism) — a third-party benchmark measured roughly flat ~45–85 MB for the pair even with heavy exploration [Oreate guide](https://create.oreateai.com/create/performance-vs-features-the-real-difference-between-journeymap-and-xaeros). COMMUNITY (small blog, directionally consistent with the bounded-cache design).
- Resource pack changes force a full map regeneration (disk churn) [Modrinth description](https://modrinth.com/mod/xaeros-world-map). DOCUMENTED.
### 10. Minimap↔world map integration (perf-positive, keep defaults)
"By default uses the map textures generated by the world map mod instead of generating its own. This improves performance when using both mods" [Minimap description](https://modrinth.com/mod/xaeros-minimap). Also, config moved to `/config/xaero/minimap`, `/config/xaero/world-map`, shared `/config/xaero/lib` (25.3.2/1.40.2 config rework) — the pack can ship enforced defaults per machine there [changelog 25.3.2](https://chocolateminecraft.com/update.php?mod_id=0). VERIFIED. The world map screen's default world-render skipping + auto framerate limit (~625 fps cap) when skipped is another official perf behavior [changelog 1.42.0](https://chocolateminecraft.com/update.php?mod_id=2). VERIFIED.
### 11. Alternatives, briefly
- Community consensus ranks Xaero's as the lightest full-featured pair; JourneyMap is "slightly heavier on system resources" with more RAM/CPU headroom needed; FTB Chunks is often called the most performant but feature-poor and its map/claim data lives in the server world save (server TPS exposure) [r/feedthebeast comparison](https://www.reddit.com/r/feedthebeast/comments/1pnr3bo/for_modded_minecraft_which_minimap_has_more/), [Enigmatica6 issue #1340](https://github.com/EnigmaticaModpacks/Enigmatica6/issues/1340), [Astroworld guide](https://guide.astroworldmc.com/best-minecraft-minimap-mods). COMMUNITY — no first-party benchmarks either way; keep Xaero's.
## Sources
Kept:
- DH GitLab wiki (Server Owners; Problems & Solutions; Mod Support; General FAQ) — primary, maintained by the mod author. https://gitlab.com/distant-horizons-team/distant-horizons/-/wikis/home
- DH core source (Config.java, preset handlers, enums) — authoritative key/behavior definitions. https://gitlab.com/distant-horizons-team/distant-horizons-core
- Pinned jars' embedded lang/setting symbols (DH 3.3.2, XaeroMinimap 26.5.0, XaeroWorldMap 1.46.0) — exact-version config surface. https://modrinth.com/mod/distanthorizons/version/3.3.2-1.21.1
- Iris docs, DH mod-support reference — how shaderpacks integrate DH passes. https://shaders.properties/current/reference/mod-support/distant_horizons/
- Complementary Reimagined + MakeUp Ultra Fast `shaders.properties` — proof of DH support and of disabled DH shadow pass. (GitHub raw links above)
- Xaero's official descriptions + chocolateminecraft changelogs — feature/perf changes per version. https://chocolateminecraft.com/update.php?mod_id=2
- GitLab issues #157 (RAM/VRAM data point), #566 (Alex's Caves fix via wiki) — tracker history.
Dropped:
- distanthorizonsguide.com — useful but third-party SEO-adjacent; kept only its calculator profile as one COMMUNITY data point.
- Sportskeeda/best-settings listicles — no original data, stale version references.
- Steveplays28 shader-compat gist — 1.19.2-era, superseded by per-pack source verification.
- Older Reddit optimization threads (DH 1.18.2 era) — settings names/values changed in 3.x.
## Gaps
- No first-party per-distance VRAM/RAM table for DH 3.3.x exists; the only numbers are 2022-era (issue #157) and community profiles. Benchmark: F3 overlay + RTSS/`radeontop` at 64/128/256 chunks × LOW/MEDIUM with each shaderpack, per machine.
- Actual FPS/VRAM delta of Complementary's DH programs (`dh_terrain`/`dh_water`) vs base renderer, and whether its disabled `dhShadow` fully avoids DH shadow cost (it should by contract, but verify).
- Xaero's minimap cost with heavy entity mods (Alex's Mobs etc.) and with cave mode on — no measurements found; icon pre-rendering burst at first-encounter may stutter on Deck.
- World map "maximum number of loaded regions" default value on 1.46.0 and its heap effect (setting exists; default not visible without running the game).
- Whether the pack's server actually enables `enableRealTimeUpdates`/sync radius ≤ client LOD distance (affects client bandwidth/CPU when riding Create trains).
## Top levers
| # | Lever | Expected impact | Helps | Risk | Confidence |
|---|---|---|---|---|---|
| 1 | Cut DH LOD render distance to 96–128 (Deck/P2) or 128–192 (P1) — keep ≤512 always | High (GPU+VRAM+CPU all scale with it) | All three; most on P1 VRAM & Deck | Visual only | High |
| 2 | Quality preset LOW/MEDIUM **with cave culling re-checked ON** (never leave HIGH/EXTREME presets' culling-off in mountains) | High on GPU-heavy scenes, Med general | Deck, P1 | Slightly flatter distant terrain | High (preset mapping verified) |
| 3 | Server-side `/dh pregen` + keep per-player LOD bandwidth/rate limits (500 KB/s default) so clients stream prebuilt LODs instead of stressing CPU | High (client smoothness), Med (server) | All three; P2 CPU | Server disk/IO during pregen; don't pregen while playing | High |
| 4 | Thread preset: Minimal/Low while exploring fast, Balanced otherwise; keep `pauseIfMovingQuickly`/`limitIfServerUnhealthy` on | Med (stutter elimination on 4C/8T) | P2, Deck | Slower LOD fill-in | High |
| 5 | Heap: `-Xmx6–8G` + `-XX:+UseZGC` (≤6G on P2), keep DH DB sync NORMAL | Med (stutter/GC) | P2 most, Deck (shared RAM) | Lower heap on P2 may thrash if LOD RD kept high | High (official guidance) |
| 6 | Steam Deck: Sodium "Use No Error context" OFF (Mesa fix) + stay on OpenGL rendering engine | Med (crash/stability, some perf) | Deck | None | High (official wiki) |
| 7 | Xaero's: cap world-map "max loaded regions" + keep `mapWritingDistance` default; never enable Force Fast Writing; keep world-render skip ON | Low–Med (heap spikes on P2 when opening map) | P2, Deck | Slower mapping while flying fast | Med |
| 8 | Xaero's minimap: modest `minimapSize`, radar to dots + hide invisible entities, cave mode off above ground for users who don't need it | Low | Deck, P2 | Feature loss (QoL) | Low–Med (mechanism verified, magnitude not) |
| 9 | Keep both shaderpacks' built-in DH integration (dhShadow off) — do not swap in packs without `DISTANT_HORIZONS` support | Prevents catastrophic regressions | All | None (status quo) | High |
| 10 | Pack fixes: Alex's Caves `biome_ambient_light_coloring = false`; pin SSRD ≥1.8.7 with DH 3.3.2 | Prevents broken LODs/rendering | All | AC loses biome tint ambience | High |
## Open questions to verify by benchmark
1. VRAM at 128 vs 192 vs 256 LOD chunks with Complementary Reimagined r5.9.3 on the GTX 1060 6GB — where does the 6 GB budget break?
2. Steam Deck: 30 fps target — LOW preset @128 LOD vs MEDIUM @96 LOD with MakeUp Ultra Fast (which is cheaper per visual quality?).
3. Client thread occupancy (F3 "Show Thread Pools") with thread preset Minimal vs Balanced during flight — does P2's main thread still stutter at 4 DH threads?
4. Heap profile on P2 (8 GB free): peak JVM RSS with ZGC `-Xmx5G` at 128 LOD + world map opened after 2h exploration vs DH SQLite flush behavior.
5. Xaero's: minimap FPS cost with entity radar ON vs OFF in a mob-dense Alex's Caves area; cave-mode ON cost while caving.
6. Bandwidth/latency: server LOD streaming rate when teleporting (Create train) with `realTimeUpdateDistanceRadiusInChunks` at default vs reduced — any client hitching from sync-on-load bursts?
7. Does `enableFastSurfaceGenerator` on the server reduce time-to-filled-horizon for new areas enough to matter for clients joining fresh regions?
@@ -0,0 +1,485 @@
# Research: Entity & Animation Rendering Cost (client-side)
Scope: Minecraft 1.21.1 / NeoForge 21.1.251, Onion MC pack pins. Purely client-side
render/main-thread and heap cost of entity models, animations and dynamic lights.
Tags: **VERIFIED** = read in source/config code, **DOCUMENTED** = official
README/wiki/changelog, **COMMUNITY** = user reports/forums, **INFERENCE** = my reasoning.
---
## Summary
Entity/animation cost in this pack is dominated by three independent CPU-side pipelines
that **do not share configuration**: (1) EMF/CEM custom models driven by Fresh Animations
(`animationLODDistance`, `modelUpdateFrequency`), (2) GeckoLib 4.x models used by Mowzie's,
Fowlplay, dragons, etc. (no user-facing perf config in GeckoLib itself), and (3)
player-animation mods (Better Combat / playerAnimator / Emotecraft) layered on EMF. Only
pipeline (1) is throttled by the EMF knobs most guides mention; the biggest confirmed
per-mob cost multiplier is **Iris shadow-pass re-animation**, which EMF already skips by
default in this version. Dynamic lights (LambDynamicLights 4.8.x) are a separate risk
because each moving light source forces **chunk mesh rebuilds**, which is far more
expensive than animation math. Entity**Culling** (already in pack) and the vanilla
**Entity Distance** slider are the two levers that reduce the *number* of entities hitting
any of these pipelines, and are therefore the highest-leverage, lowest-risk changes.
---
## Findings
### A. EMF 3.x + ETF 7.x with Fresh Animations (+ All Extensions)
1. **EMF exposes exactly five performance-relevant settings.** From `EMFConfig.java`
(repo master = mod_version **3.3.11**; the pack's 3.3.9 is the same config surface):
`animationLODDistance` (int, default **20**, range 0–65), `retainDetailOnLowFps`
(default true), `retainDetailOnLargerMobs` (default true),
`animationFrameSkipDuringIrisShadowPass` (default true), and `modelUpdateFrequency`
(type `ETFConfig.UpdateFrequency`, default `Average`). `asmMaths` ("Compiled animation
math", default true) is the compiled-maths fast path. [VERIFIED]
https://github.com/Traben-0/Entity_Model_Features/blob/master/src/main/java/traben/entity_model_features/config/EMFConfig.java
2. **`animationLODDistance` is frame-skipping keyed to distance from the client player.**
Official tooltip: "Sets the distance at which animations will begin to skip frames,
lower the Level of Detail (LOD) … None = no frame skipping; 16 = will skip 1 frame for
every 16 blocks distance from player. Lower numbers mean more skipped frames and more
performance gain." Default is 20; 0 = the "None" entry on the slider. [DOCUMENTED —
mod lang file, same repo]
https://github.com/Traben-0/Entity_Model_Features/blob/master/src/main/resources/assets/entity_model_features/lang/en_us.json
The setting was introduced in the 1.3 changelog and the size-aware variant
(`retainDetailOnLargerMobs`) in the 2.0 changelog. [DOCUMENTED — CHANGELOG.MD]
https://github.com/Traben-0/Entity_Model_Features/blob/master/CHANGELOG.MD
3. **`retainDetailOnLowFps` and `retainDetailOnLargerMobs` deliberately soften the LOD
effect** (less skipping below 60 fps; less skipping on big mobs). Tooltips: "reduce the
Level of Detail (LOD) impact of the above setting according to the mobs size" / "…
according to your fps. Only applies when below 60 fps." Turning these **off** makes the
LOD slider do more work (more aggressive skipping). [DOCUMENTED — mod lang file]
https://github.com/Traben-0/Entity_Model_Features/blob/master/src/main/resources/assets/entity_model_features/lang/en_us.json
4. **`animationFrameSkipDuringIrisShadowPass` is the single most important EMF option and
is already ON.** Changelog 2.1.1: "added an optimization option that will skip
recalculating entity model animations during the iris shadow pass, on by default, and
**should always stay on**". With shaders, each animated model would otherwise be
animated a second time for the shadow pass. **Verify this is still `true` on all three
fleet machines** — it is the difference between 1× and 2× animation cost per frame.
[VERIFIED — config + DOCUMENTED — changelog]
https://github.com/Traben-0/Entity_Model_Features/blob/master/CHANGELOG.MD
5. **EMF 3.2+ already contains a large animation-speed fix.** Changelog 3.2: "significant
performance improvement for custom animations (**more than doubling frames** when many
animated entities are present)". The pack's EMF 3.3.9 includes this; do not "fix" FA
cost by downgrading. [DOCUMENTED]
https://github.com/Traben-0/Entity_Model_Features/blob/master/CHANGELOG.MD
6. **`modelUpdateFrequency` only controls *model refresh* (health/age/child-state
changes), not per-frame animation.** Tooltip: "Sets how often a mobs model will update
for changes like health & age. Never = never update, Slow = 3-5 seconds, Average =
about 1 second, Fast = less than a second, Instant = instant (possible lag with
hundred of mobs)". Default `Average`. Lowering it to `Slow`/`Never` is a cheap,
low-visual-impact win on busy farms/villager halls. [VERIFIED — config; DOCUMENTED —
lang file]
7. **Per-model opt-out exists** via `modelsNamesDisabled` (a `Set<String>` of
`<name>.jem`), exposed in the GUI as "Enable model" per .jem file. This lets you kill
the most expensive FA models (e.g. villager layers) without dropping FA globally.
[VERIFIED — config]
https://github.com/Traben-0/Entity_Model_Features/blob/master/src/main/java/traben/entity_model_features/config/EMFConfig.java
8. **`allowedCEM` gates which model namespaces EMF touches** (`All` / `Known only (mostly
vanilla/OptiFine)` / `Unknown only (mostly modded)` / `Off`). Setting it to
`Known only` stops EMF from building CEM models for modded mobs — useful if FA-derived
models on modded entities are the hot path. [VERIFIED — config]
9. **Measured Fresh-Animations cost is large and shader-amplified.** On the EMF issue
tracker, a user reported on 1.21.11 + Sodium/Iris: 50 cows on screen = 400+ fps (no
mods) → 110–130 fps with Fresh Animations → **30–40 fps with shaders + FA**; vanilla
animations on the same scene = 300–350 fps / 180–200 fps with shaders. The EMF author
replied the numbers are "more than I'd expect" but that FA "animations are just so
involved compared to vanilla" and you "aren't going to be easily pushing past 200 fps
with fresh animations on ever". A second reporter on 1.20.1 saw 165→40 fps with 30 cows
+ Beefier Bovine x FA + Complementary. The issue was closed as fixed in a later
release. [COMMUNITY — user reports on mod's own tracker; DOCUMENTED — maintainer reply]
https://github.com/Traben-0/Entity_Model_Features/issues/443
10. **Independent corroboration that FA + EMF/ETF drops FPS on villager-heavy scenes:**
easy-villagers #243 "Huge FPS drops with Fresh Animations and the mods needed for it
(EMF/ETF). Seems to be trying to run the animations even tho there's no animation
seen." [COMMUNITY]
https://github.com/henkelmax/easy-villagers/issues/243
11. **EMF recommends EntityCulling specifically for animation-heavy packs.** EMF README:
"Entity Culling … does wonders for reducing entity rendering lag, doing even more than
Sodium's included entity culling. This is very beneficial when using animation heavy
packs like Fresh Animations." [DOCUMENTED — official README]
https://github.com/Traben-0/Entity_Model_Features
12. **ETF: the cost-bearing knobs are the texture-update frequency and emissive/skin
toggles.** From `ETFConfig.java`: `textureUpdateFrequency_V2` (enum `UpdateFrequency`:
`Never` = -1, `Slow` = 80 t, `Average` = 20 t, `Fast` = 5 t, `Instant` = 1; **default
`Fast`**), `enableCustomTextures`, `enableEmissiveTextures`, `enableEmissiveBlockEntities`,
`emissiveRenderMode` (`DULL`/`BRIGHT`), `enableEnchantedTextures`, `enableArmorAndTrims`,
`enableBlinking`, `blinkFrequency` (150), `blinkLength` (1), `skinFeaturesEnabled`,
`skinTransparencyMode`, `use3DSkinLayerPatch`, `alwaysCheckVanillaEmissiveSuffix`,
`advanced_IncreaseCacheSizeModifier` (1.0), `enableFullBodyWardenTextures`,
per-entity override maps (`entityEmissiveOverrides`, `entityRandomOverrides`,
`entityEmissiveBrightOverrides`, `entityRenderLayerOverrides`, `entityLightOverrides`).
`UpdateFrequency` is a **tick delay** for re-evaluating random/variant properties, so
moving `Fast` (5 t, 4 Hz per entity) → `Average` (20 t, 1 Hz) cuts per-entity texture
bookkeeping 4×. [VERIFIED — source]
https://github.com/Traben-0/Entity_Texture_Features/blob/ETF-Main/src/main/java/traben/entity_texture_features/config/ETFConfig.java
13. **ETF rates misbehaving packs as a lag source.** README FAQ: "If you are experiencing
lag please check your most recent log file to see if any errors are being logged,
sometimes an incorrectly written properties file or missing textures may lag the
system." Relevant because FA All Extensions ships many `.properties` files — a single
mis-pathed texture can multiply cost. [DOCUMENTED]
https://github.com/Traben-0/Entity_Texture_Features/blob/ETF-Main/.github/README.md
14. **ETF emissive conflicts with Complementary shaders.** ETF FAQ: "Complimentary shaders
has its own in-built emissive textures that usually work fine but will conflict with
some resource packs. You can either disable Complimentary's emissives or ETF's
emissives to fix this." Relevant because the pack runs Complementary Reimagined r5.9.3.
[DOCUMENTED]
https://github.com/Traben-0/Entity_Texture_Features/blob/ETF-Main/.github/README.md
15. **Known pack-relevant interaction: ImmediatelyFast 1.6.14 vs FA All Extensions.**
ImmediatelyFast issue #180 (still open, last comment Dec 2025): ImmediatelyFast breaks
the custom models of Fresh Animations Extensions. The reporter's working set was
ETF + EMF + Embeddium(+extra) + FreshAnimations + FA+All_Extensions; adding
ImmediatelyFast broke entity rendering. Maintainer: "I added this as a low priority
issue to my todo list." The pack carries ImmediatelyFast 1.6.14 + FA All Extensions
1.8.1 — worth an A/B on entity visuals/cost. [COMMUNITY/DOCUMENTED — mod tracker]
https://github.com/RaphiMC/ImmediatelyFast/issues/180
16. **FA All Extensions is a bundle of official sub-packs** (details, creeper/spider
edits, emissive add-on, quivers, classic horses), i.e. it *adds* cost on top of base
FA rather than being neutral. [DOCUMENTED — mod description]
https://www.curseforge.com/minecraft/texture-packs/fresh-animations-extensions
### B. GeckoLib 4.x (Mowzie's, Fowlplay, dragons, Doggy Talents, etc.)
17. **GeckoLib is a library, and the pack's GeckoLib 4.9.3 has no end-user performance
config.** The official README documents no client perf options — its `wiki.geckolib.com`
is modder documentation (controllers, molang, render layers). Per-entity animation
cost is therefore set by each *consumer mod*, not by a config the pack can tune.
[VERIFIED — README has no config section]
https://github.com/bernie-g/geckolib
18. **Mowzie's Mobs genuinely requires GeckoLib 4.9.3 on 1.21.1 NeoForge** — reproduced in
a 1.21.1/NeoForge 21.1.248 + Mowzie's 1.8.2 + GeckoLib 4.9.3 report. So the pack's
GeckoLib load is not optional. [COMMUNITY/DOCUMENTED — mod repo issue]
https://github.com/BobMowzie/MowziesMobs-Public/issues/64
19. **Third-party GeckoLib optimizers exist and are directly relevant to 1.21.1 NeoForge.**
"GeckoLib Animation Optimizer" requires GeckoLib 4.9.0+ on 1.21.1 NeoForge; its
description claims configurable distance-based animation optimisation and camera
visibility culling enabled by default, block-occlusion culling and player optimisation
disabled by default, "fully client-side". "GeckolibBetterFPS" claims ~"25% faster
rendering of GeckoLib entities" and "reduces micro stutters when multiple GeckoLib
entities are present", but it is a MoePus mod historically targeted at 1.20.1 — check
1.21.1 build availability before proposing. [COMMUNITY — mod listings; treat the
percentages as vendor claims, not verified]
https://www.curseforge.com/minecraft/mc-mods/geckolib-animation-optimizer ,
https://modrinth.com/project/CZyWdBUo
20. **Important negative finding: EMF's animation LOD does NOT throttle GeckoLib.**
EMF only handles OptiFine CEM `.jem` models; GeckoLib renders through its own pipeline.
**INFERENCE**: the `animationLODDistance` lever benefits vanilla-mob/FA content only;
for GeckoLib-heavy scenes the only EMF-independent levers are EntityCulling, the
Entity Distance slider, and reducing the number of GeckoLib entities (spawn/mob count).
21. **Citadel (Alex's Mobs / Alex's Caves) is a different library from GeckoLib.** The
widely-reported Alex's Mobs perf complaints are about **server/world-gen and chunk
loading**, not client rendering — Citadel issue #156 is titled "Alex's Mobs X Citadel:
Slow Chunk loading", and r/feedthebeast discussion is about worldgen/chunky comparison.
A separate community "Alex's Mobs: Tweaks [Performance Optimization]" (AMT) addon
claims to "fix several expensive Alex's Mobs and Citadel hot paths". Treat client-side
Citadel cost as driven mainly by entity *count* and its own model complexity.
[COMMUNITY]
https://github.com/AlexModGuy/Citadel/issues/156 ,
https://www.curseforge.com/minecraft/mc-mods/amt
### C. 3D Skin Layers (1.11.3)
22. **3D Skin Layers already has a built-in distance LOD.** README: "The mod automatically
switches back to vanilla-style 2D rendering when players are more than **12 blocks
away**". The config option is "Level Of Detail Distance" — "The distance at which the
model will switch to a lower level of detail (vanilla 2d)". [DOCUMENTED — README;
VERIFIED — lang file]
https://github.com/tr7zw/3d-Skin-Layers ,
https://github.com/tr7zw/3d-Skin-Layers/blob/main/src/main/resources/assets/skinlayers3d/lang/en_us.json
23. **Per-limb and per-feature toggles let you buy cost back cheaply.** Lang keys observed:
"3D Hat", "3D Jacket", "3D Left/Right Sleeve", "3D Left/Right Pants", "3D Skulls",
"3D Skull Items", plus cost/quality knobs "Voxel Size", "Head Voxel Size", "Body Voxel
Height", "Torso Voxel Width", "Skull Voxel Size", "First Person Voxel Size", "Fast
Render" ("render the 3D models as fast as possible, this may cause some graphical
glitches with transparency"). [VERIFIED — lang file]
https://github.com/tr7zw/3d-Skin-Layers/blob/main/src/main/resources/assets/skinlayers3d/lang/en_us.json
24. **3D Skin Layers is explicitly integrated with EMF and with playerAnimator.**
Repo contains `EMFModelPartMixin.java`; README lists Player Animator as supported
("This means mods that use it like Better Combat and Emotecraft"). ETF in turn exposes
`use3DSkinLayerPatch` which is only shown when `ETF.SKIN_LAYERS_DETECTED`. So EMF/ETF,
3D Skin Layers and playerAnimator form one chained render path on players.
[VERIFIED — source files; DOCUMENTED — README]
https://github.com/tr7zw/3d-Skin-Layers/blob/main/src/main/java/dev/tr7zw/skinlayers/mixin/EMFModelPartMixin.java
25. **Compat/quality switches that trade correctness for cost:** "Compatibility Mode",
"Iris Compatibility Mode" ("fixes weird shadows/colors when using Iris shaders … Will
break the corner connections"), "Sodium Workaround". Only enable as needed. [VERIFIED —
lang file]
26. **Cost is bounded by player count, not mob count.** 3D Skin Layers only affects player
models/heads. On a 10-player server, worst case is 9 remote players within 12 blocks.
[INFERENCE]
### D. Player-animation stack: Better Combat + playerAnimator + Emotecraft
27. **Better Combat requires playerAnimator, and its animation code runs on *every*
player entity, not just yourself.** Its client package contains
`PlayerAttackAnimatable` and `CustomAnimationPlayer` under
`common/…/client/animation/`, i.e. it is a `Player`-model mixin path, and Better Combat
synchronises attacks so remote players' swings animate too (community reports of
multiplayer animation bugs confirm remote-player animation is rendered).
[VERIFIED — repo file tree; COMMUNITY — multiplayer reports]
https://github.com/ZsoltMolnarrr/BetterCombat/tree/1.21.1/common/src/main/java/net/bettercombat/client/animation
28. **Better Combat client-side cost knobs are few but real.** `ClientConfig.java` fields
include `isShowingWeaponTrails` (**default true** — the slash/trail particle system in
`client/particle/TrailParticles.java` and `SlashParticleUtil.java`),
`isSweepingParticleEnabled` (default false), `isShowingArmsInFirstPerson` (false),
`firstPersonAnimations` (TriStateAuto.AUTO), `legAnimationThreshold` (0). Turning off
weapon trails removes a per-swing particle + geometry cost without touching animation
math. [VERIFIED — source]
https://github.com/ZsoltMolnarrr/BetterCombat/blob/1.21.1/common/src/main/java/net/bettercombat/config/ClientConfig.java
29. **There is a first-class EMF ⇄ playerAnimator conflict, and a purpose-built fix.**
"Entity Player Compat" (MIT, client-side, published for **1.21.1 NeoForge/Fabric**,
requires EMF + PlayerAnimator) exists because EMF's custom player models and
playerAnimator both write player part transforms. It does per-part blending
("Automatically detects which specific body parts … are being animated by PlayerAnimator
and only pauses EMF animations for the specific parts currently in use"), a "virtual
follow" limb re-parenting system, and claims "high-performance tick-based caching …
does its work in a handful of hooks per frame." It explicitly lists Better Combat,
FA: Player Extension and GeckoLib/AzureLib armors as tested. [DOCUMENTED — mod page]
https://modrinth.com/mod/entity-player-compat
**INFERENCE**: without it, EMF will animate the player model *and* playerAnimator will
animate it again each frame — double work on every visible player, the exact class of
waste `animationFrameSkipDuringIrisShadowPass` was built to avoid. This is a strong
candidate lever for the 10-player use case.
30. **Emotecraft is built on playerAnimator and is client-side-required.** Emotecraft needs
the client half; the server half is optional, and features stay inactive without a
sync path. Emote animation is transient (only while an emote plays), so steady-state
cost is low; the risk is many simultaneous emotes near the player. [DOCUMENTED —
Emotecraft/playerAnimator listings]
https://minecrafthub.io/mods/emotecraft , https://minecrafthub.io/mods/playeranimator
31. **EMF has explicit Emotecraft integration** — changelog 3.0.7 added
`registerPauseCondition(Function<EMFEntity,Boolean> shouldPause)` to
`EMFAnimationApi` specifically so mods like EmoteCraft stop mixing in, and 3.3.4
"updated emote craft emote pausing support in EMF". So EMF+Emotecraft is a supported
path; the pack's EMF 3.3.9 is new enough. [DOCUMENTED — CHANGELOG.MD]
https://github.com/Traben-0/Entity_Model_Features/blob/master/CHANGELOG.MD
### E. LambDynamicLights 4.8.x on Sodium
32. **Dynamic lights cost is chunk rebuilds, not per-frame shading.** Official
"How does it work": "To apply the dynamic lighting we have to request the affected
chunks a rebuild to rebuild the lightmap, **which is the most critical part
performance-wise**. Rebuilding a chunk cost performances, that's why there's multiple
mode: FASTEST, FAST and FANCY. The fast modes will limit the update." The mod computes
dynamic light over a radius of 7.75 blocks, "which is still a lot" of touched chunks,
and hooks `WorldRenderer#setupTerrain` (or its Sodium equivalent) to schedule rebuilds.
[DOCUMENTED — official doc]
https://github.com/LambdAurora/LambDynamicLights/blob/1.21/HOW_DOES_IT_WORK.md
33. **Exact 1.21-branch config keys (this branch is `@version 4.8.0`, matching pack 4.8.11),
config file `config/lambdynlights.toml`:** `mode` (enum `off`/`fastest`/`fast`/`fancy`,
**default `fancy`**), `chunk_rebuild_scheduler` (`culling` **default** / `immediate`),
`adaptive_ticking.slow` (**5** chunks), `adaptive_ticking.slower` (**8** chunks),
`adaptive_ticking.background_sleep` (**true**), `light_sources.entities` (true),
`light_sources.self` (true), `light_sources.water_sensitive_check` (true),
`light_sources.beam` (true), `light_sources.guardian_laser` (true),
`light_sources.sonic_boom` (true), `light_sources.glowing_effect` (true),
`light_sources.creeper` (`simple`), `light_sources.tnt` (`off`), plus `debug.*`.
[VERIFIED — source]
https://github.com/LambdAurora/LambDynamicLights/blob/1.21/src/main/java/dev/lambdaurora/lambdynlights/DynamicLightsConfig.java
34. **The quality mode maps to a tick mode, not to radius.** `DynamicLightsMode` in the
1.21 branch: `FANCY → TickMode.REAL_TIME`, `FAST → TickMode.SLOW`,
`FASTEST → TickMode.SLOWER`, `OFF → REAL_TIME` (disabled). So `fastest`/`fast` throttle
**how often light updates are applied** (fewer chunk rebuilds/second), which is the
correct lever for stutter, and `fancy` gives real-time smoothness at full rebuild cost.
[VERIFIED — source]
https://github.com/LambdAurora/LambDynamicLights/blob/1.21/src/main/java/dev/lambdaurora/lambdynlights/DynamicLightsMode.java
35. **The 4.8.x line added two dedicated cost mitigations vs older guides.** `chunk_rebuild_scheduler`
(`culling` default vs `immediate`) and the adaptive-ticking distance pair
(`adaptive_ticking.slow` / `.slower`, in **chunks**) plus `background_sleep` under
`adaptive_ticking`. These are the 1.21-branch additions that the widely-copy-pasted
"Light Range / updateInterval / entitiesGlowing" advice (which cites keys that do not
exist in the 1.21 branch source) does not mention. [VERIFIED — source vs the third-party
guide] https://lambdynamiclights.com/configuring-lambdynamiclights-for-peak-performance/
36. **Per-category light-source toggles map to real feature costs.**
`light_sources.entities=false` removes all burning-mob/glow-squid/entity-carried-light
sources (the biggest moving-light population in a survival world);
`light_sources.self=false` removes the first-person player light;
`light_sources.beam`/`guardian_laser`/`sonic_boom`/`glowing_effect` cover beacon beams,
guardian beams, sonic booms and the Glowing effect. Disabling `entities` while keeping
`self` is the usual "I still want my torch to glow, but not 200 burning zombies"
compromise. [VERIFIED — source]
https://github.com/LambdAurora/LambDynamicLights/blob/1.21/src/main/java/dev/lambdaurora/lambdynlights/DynamicLightsConfig.java
37. **Sodium interop is explicit, not accidental.** `HOW_DOES_IT_WORK.md`: "we inject at
`WorldRenderer#setupTerrain` (`WorldRenderer#render` at `WorldRenderer#setupTerrain`
invoke **if Sodium is present**)". So LDD 4.8.x is Sodium-aware by design; the classic
"dynamic lights cause chunk rebuild stutter on Sodium" claim needs to be re-measured
on this version rather than assumed. [DOCUMENTED]
https://github.com/LambdAurora/LambDynamicLights/blob/1.21/HOW_DOES_IT_WORK.md
### F. EntityCulling (1.11.2) interplay
38. **Independently useful alongside Sodium's own culling.** README: "I have 'Use Entity
Culling' enabled in Sodium — does this still help? Yes! … Sodium performs basic
visibility checks based on loaded chunks, this mod goes further. It analyzes the
actual line-of-sight visibility, skipping entities that are within visible chunks but
not actually visible to the player." [DOCUMENTED — official README]
https://github.com/tr7zw/EntityCulling
39. **It has a client-side entity *tick* culling feature, not just render culling.**
`Config.java` (config version 9): `tickCulling` (**true**), with a separate
`tickCullingWhitelist`. This reduces main-thread entity tick cost — relevant to P2's
main-thread bottleneck. [VERIFIED — source]
https://github.com/tr7zw/EntityCulling/blob/main/EntityCulling-Versionless/src/main/java/dev/tr7zw/entityculling/versionless/Config.java
40. **Exact config keys/defaults** (`config/entityculling.json`): `tracingDistance` **128**
(path-trace range), `sleepDelay` **10**, `hitboxLimit` **50**, `captureRate` **5**,
`tickCulling` **true**, `skipEntityCulling` false, `skipBlockEntityCulling` false,
`blockEntityFrustumCulling` **true**, `forceDisplayCulling` false, `solidLeaves`
**false** ("treat leaves as solid blocks … help to increase the performance in
forested areas" — directly relevant with Better Leaves 9.6 in pack), `safeMode` true,
`renderNametagsThroughWalls` true, plus `entityWhitelist` / `blockEntityWhitelist` /
`tickCullingWhitelist`. [VERIFIED — source; DOCUMENTED — README for `solidLeaves`]
41. **Known interaction: client-side/mod "display" entities and far-bounds block entities
need whitelisting** — "Client-side entities, commonly used by magic mods for
animations, may not behave as expected. Whitelist the relevant entities via the config
screen for tick culling and/or entity culling … You'll also need to whitelist block
entities that render well beyond their normal bounds. Examples include the vanilla
beacon, pulleys from Create…". **INFERENCE**: relevant to this pack's Create/Flywheel
contraptions and Veil-based mods; verify no visual regressions before recommending any
change. [DOCUMENTED — README]
42. **Mild CPU trade-off on very weak CPUs.** README: "Consider [disabling] when playing on
a really old computer … When the CPU is already maxed out, there is no spare CPU time
to run the visibility calculations." None of the fleet's CPUs are in that class, but
the Steam Deck's shared power budget makes this worth watching. [DOCUMENTED — README]
43. **Author-provided test reference:** the README's comparison screenshot was captured
with "Sodium, Iris and ImmediatelyFast … alongside EntityCulling" — i.e. exactly the
pack's stack. [DOCUMENTED — README]
44. **Also provide a F3-adjacent debug toggle.** "In the controls menu, you can bind a
debug key to toggle the mod on and off on the fly" — this is the cleanest in-situ
benchmark control for entity cost. [DOCUMENTED — README]
### G. Entity-count drivers and the Entity Distance slider
45. **Clumps is a server-side aggregation mod, so its client benefit is indirect but real.**
"Clumps groups XP orbs together into a single entity to reduce lag when there are many
in a small area." On 1.17+ it is a **server** mod: "For a multiplayer world on 1.17 or
newer, the jar goes on the server rather than on each player's client." Fewer orb
entities on the server → fewer orb entities synchronised → less client render/tick and
(with LDD) fewer dynamic-light sources. Verify it is installed server-side.
[DOCUMENTED — mod listings]
https://modrinth.com/mod/clumps/versions , https://minecrafthub.io/mods/clumps
46. **The vanilla "Entity Distance" video setting is the bluntest client lever.** The
Minecraft Wiki's simulation-distance article states the client does not render entities
based only on Render Distance but on "both 'Render distance' and 'Entity distance'
video settings"; it is a percentage slider scaling entity render distance.
[DOCUMENTED — Minecraft Wiki]
https://minecraft.wiki/w/Simulation_distance
*(A community write-up explicitly frames it: "This setting directly impacts client-side
performance … Setting the rendering distance to its maximum allows all entities to be
visually displayed at the full extent of their tracking distance.")* [COMMUNITY]
https://www.curseforge.com/minecraft/mc-mods/entity-distance-1-12-2
47. **Item entities are the other unbounded count driver.** No mod in the pack aggregates or
culls dropped items; a farm/hopper overflow or an explosion drops hundreds of
`ItemEntity`s, each costing an `ItemRenderer` submission and (with Better Leaves +
FA) potentially full model evaluation for held-block mobs. [INFERENCE]
48. **EMF/ETF+FA cost scales with *visible* model count, which EntityCulling and Entity
Distance both reduce.** Since `animationLODDistance` skips frames as a function of
distance from the player, `Entity Distance` and the LOD slider are multiplicative:
shrinking entity distance removes far models entirely, and the LOD slider makes the
remaining middle-distance models cheaper. [INFERENCE]
---
## Sources
Kept:
- EMF `EMFConfig.java` (master, v3.3.11) — authoritative list of every EMF config key and
defaults. https://github.com/Traben-0/Entity_Model_Features/blob/master/src/main/java/traben/entity_model_features/config/EMFConfig.java
- EMF `lang/en_us.json` — exact tooltip wording for `lod`, `low_fps_lod`, `large_mob_lod`,
`update`, `asmmaths`. https://github.com/Traben-0/Entity_Model_Features/blob/master/src/main/resources/assets/entity_model_features/lang/en_us.json
- EMF `CHANGELOG.MD` — 3.2 "doubling frames", 2.1.1 Iris shadow skip, 1.3/2.0 LOD
history, EmoteCraft integration. https://github.com/Traben-0/Entity_Model_Features/blob/master/CHANGELOG.MD
- EMF README — FA confirmed supported; EntityCulling recommendation.
https://github.com/Traben-0/Entity_Model_Features
- EMF issue #443 — quantified FA/shader cost, maintainer response.
https://github.com/Traben-0/Entity_Model_Features/issues/443
- ETF `ETFConfig.java` — all ETF keys incl. `textureUpdateFrequency_V2` enum ticks.
https://github.com/Traben-0/Entity_Texture_Features/blob/ETF-Main/src/main/java/traben/entity_texture_features/config/ETFConfig.java
- ETF README — emissive/Complementary conflict, "lagging" FAQ.
https://github.com/Traben-0/Entity_Texture_Features/blob/ETF-Main/.github/README.md
- LambDynamicLights `HOW_DOES_IT_WORK.md`, `DynamicLightsConfig.java`,
`DynamicLightsMode.java` (1.21 branch = v4.8.0, matching pack 4.8.11) — chunk-rebuild
cost model and exact keys/enums.
https://github.com/LambdAurora/LambDynamicLights/blob/1.21/HOW_DOES_IT_WORK.md
- EntityCulling `Config.java` + README — exact keys/defaults, tick culling, `solidLeaves`,
whitelist caveats. https://github.com/tr7zw/EntityCulling/blob/main/EntityCulling-Versionless/src/main/java/dev/tr7zw/entityculling/versionless/Config.java
- 3D Skin Layers README + `lang/en_us.json` + repo tree — 12-block LOD default, per-limb
toggles, EMF/playerAnimator integration.
https://github.com/tr7zw/3d-Skin-Layers/blob/main/src/main/resources/assets/skinlayers3d/lang/en_us.json
- Better Combat `ClientConfig.java` + client package tree — weapon trails default, animation
is per-Player.
https://github.com/ZsoltMolnarrr/BetterCombat/blob/1.21.1/common/src/main/java/net/bettercombat/config/ClientConfig.java
- Entity Player Compat mod page — EMF⇄playerAnimator conflict and its fix, 1.21.1 NeoForge.
https://modrinth.com/mod/entity-player-compat
- GeckoLib README — confirms absence of user perf config.
https://github.com/bernie-g/geckolib
- Minecraft Wiki (simulation distance) — Entity Distance affects client entity rendering.
https://minecraft.wiki/w/Simulation_distance
Dropped:
- `bravith.com`, `mythiq.net`, `skinmc.net`, `9minecraft`, `modbay`, `minecrafthub`,
`modrinth.com/mod/geckolib-animation-optimizer` (404) — SEO/aggregator pages; superseded
by the GitHub source I read directly. Used only where no primary source exists (GeckoLib
optimizer, Clumps, Emotecraft) and flagged as vendor/community claims.
- `lambdynamiclights.com/configuring-…` — cites config keys (`updateInterval`,
`lightSourceRenderRange`, `entitiesGlowing`) that **do not exist** in the 1.21-branch
source; treated as unreliable, kept only as an example of bad advice.
- Reddit threads on FA cost — replaced by the two mod-tracker issues which are primary and
quantified.
- ImmediatelyFast issue #180 — kept as a *caveat* only, not as an entity-cost source.
---
## Top levers (ranked)
| # | Lever | Expected impact | Fleet machine | Risk | Confidence |
|---|---|---|---|---|---|
| 1 | Confirm `animationFrameSkipDuringIrisShadowPass=true` in EMF on all 3 machines | **High** when shaders on (halves animation work) | P0, P2 (also P1) | None (default; wrong value is the bug) | High — VERIFIED default + maintainer "should always stay on" |
| 2 | Install **Entity Player Compat** (EMF+playerAnimator bridge) for the Better Combat / Emotecraft / FA-Player path | **High** on player-dense scenes; removes double animation of every visible player | P0, P2 | Med — third-party mod, unofficial fork; test for arm/armor desync | Med — DOCUMENTED mod page; mechanism plausible but percentage unverified |
| 3 | Lower EMF `animationLODDistance` 20 → 8–12 | **Med–High** in mob/animal areas | P0, P2 (CPU-bound); P1 mild | Low — visible low-framerate animations up close | High — VERIFIED semantics; magnitude needs A/B |
| 4 | Iris shader choice: shaders + FA is the dominant cost (issue #443: 110–130 → 30–40 fps) | **High** | P0 (RDNA2 iGPU) most, P1 (VRAM) too | Med — visual (loss of shaders on Deck) | High — consistent across two independent reports |
| 5 | LambDynamicLights `mode` `fancy` → `fast`/`fastest` on the CPU-bound boxes | **Med–High** where fires/burning mobs/held torches are common | P2 (main-thread bound), P0 | Low — slightly less responsive light | High — VERIFIED tick-mode mapping |
| 6 | LambDynamicLights `light_sources.entities=false` (keep `light_sources.self=true`) | **Med** in busy survival areas | P2, P0 | Low–Med (losing burning-mob glow) | High — VERIFIED key exists |
| 7 | EMF `modelUpdateFrequency` `average` → `slow`/`never` | **Med** in villager halls/farms | P0, P2 | Low | Med–High — VERIFIED key; magnitude unmeasured |
| 8 | Vanilla **Entity Distance** slider 100% → 75–80% | **Med** everywhere, scales all pipelines | All three, esp. P0 | Low | Med — documented mechanism, pack-specific magnitude unknown |
| 9 | ETF `textureUpdateFrequency_V2` `fast`(5t) → `average`(20t) | **Med** with random/variant packs | P0, P2 | Low — slower variant swaps | Med–High — VERIFIED ticks |
| 10 | GeckoLib Animation Optimizer (needs GeckoLib ≥4.9.0) | **Med** if GeckoLib mobs are common | P0, P2 | Med–High — third-party, can break animations | Low — vendor claim only, no independent test |
| 11 | Better Combat `isShowingWeaponTrails=false` | **Low–Med** | P2, P0 | Low (visual) | Med — VERIFIED key/default; magnitude small |
| 12 | Reduce 3D Skin Layers "Level Of Detail Distance" below 12 / disable 3D Skulls | **Low** (≤9 players, tightly bounded) | P1 VRAM-mostly | Low | Low–Med |
| 13 | EntityCulling `solidLeaves=true` in forested bases (Better Leaves present) | **Low–Med** in forests | All | Med — leaves stop occluding incorrectly / leaves may hide entities visually | Med — DOCUMENTED option, no pack-specific measurement |
| 14 | Verify Clumps is deployed **server-side** | **Low–Med** on XP-heavy scenes | All (indirect) | Low | Med — DOCUMENTED placement requirement |
---
## Open questions to verify by benchmark
1. **Is `animationFrameSkipDuringIrisShadowPass` actually `true` in the shipped `emf.json`/config?**
Cheapest possible check; if a pack preset or copy flipped it, every shader scene is
paying 2× animation.
2. **What is the real fps delta from EMF `animationLODDistance` 20 vs 8 vs 0-on vs LOD-off**
on a fixed FA mob cluster (e.g. 30–50 animals) on P0 and P2? Issue #443 gives the
magnitude for the FA/shaders *combination* but not for the LOD slider alone.
3. **Does Entity Player Compat measurably help on the 10-player server**, and does it break
FA: Player Extension or armor alignment? Requires ≥2 players within view, attacking.
4. **LambDynamicLights `fancy` vs `fast` chunk-rebuild count** — use the mod's own
`debug.display_dynamic_lighting_chunk_rebuild` and `debug.active_dynamic_lighting_cells`
options (both exist as keys) to count rebuilds per second, then correlate with 1% lows.
Also test whether `chunk_rebuild_scheduler=culling` is genuinely better than `immediate`
on Sodium 0.8.13.
5. **Do the LambDynamicLights `adaptive_ticking.slow`/`.slower` distances (5 / 8 chunks)
default interact badly with shaders?** Not covered by the mod docs beyond the tick-mode
description.
6. **GeckoLib entity share:** measure with a profiler how much main-thread time GeckoLib
models occupy on P2 (Mowzie's boss fights, Fowlplay birds, dragons). If it is <2 %,
GeckoLib optimizers are not worth the risk.
7. **ImmediatelyFast 1.6.14 vs FA All Extensions 1.8.1 (issue #180)** — does the pack
exhibit it? A/B entity visuals with ImmediatelyFast disabled.
8. **ETF emissive vs Complementary Reimagined built-in emissives** — which to disable, and
does disabling one measurably reduce frame time or just fix z-fighting?
9. **`solidLeaves` under Better Leaves 9.6** — measure in forested areas and inspect for
entities disappearing behind custom leaves.
10. **Entity Distance slider calibration** — find the % where mobs stop being visibly
affected at the pack's server view-distance 8 with Distant Horizons mandatory.
11. **Heap/GC effect on P2 (only ~8 GB free):** quantify the RAM cost of FA + FA All
Extensions + Best Leaves textures and EMF's model cache; test whether ETF
`advanced_IncreaseCacheSizeModifier` changes GC pause frequency (it trades RAM for CPU,
likely the wrong direction on P2).
Loaded 100 of 131 files, more files were not shown because too many files have changed in this diff. Show more