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.
This commit is contained in:
1 parent
d80f85b3f6
commit
611a1a5952
102 files changed
+25853
No files matched your search
@@ -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).
|
||||
Reference in new issue
Block a user