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.
37 KiB
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. EntityCulling (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)
- 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), andmodelUpdateFrequency(typeETFConfig.UpdateFrequency, defaultAverage).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 animationLODDistanceis 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.MDretainDetailOnLowFpsandretainDetailOnLargerMobsdeliberately 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.jsonanimationFrameSkipDuringIrisShadowPassis 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 stilltrueon 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- 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
modelUpdateFrequencyonly 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)". DefaultAverage. Lowering it toSlow/Neveris a cheap, low-visual-impact win on busy farms/villager halls. [VERIFIED — config; DOCUMENTED — lang file]- Per-model opt-out exists via
modelsNamesDisabled(aSet<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 allowedCEMgates which model namespaces EMF touches (All/Known only (mostly vanilla/OptiFine)/Unknown only (mostly modded)/Off). Setting it toKnown onlystops EMF from building CEM models for modded mobs — useful if FA-derived models on modded entities are the hot path. [VERIFIED — config]- 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
- 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
- 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
- ETF: the cost-bearing knobs are the texture-update frequency and emissive/skin
toggles. From
ETFConfig.java:textureUpdateFrequency_V2(enumUpdateFrequency:Never= -1,Slow= 80 t,Average= 20 t,Fast= 5 t,Instant= 1; defaultFast),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).UpdateFrequencyis a tick delay for re-evaluating random/variant properties, so movingFast(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 - 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
.propertiesfiles — a single mis-pathed texture can multiply cost. [DOCUMENTED] https://github.com/Traben-0/Entity_Texture_Features/blob/ETF-Main/.github/README.md - 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
- 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
- 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.)
- 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.comis 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 - 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
- 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
- Important negative finding: EMF's animation LOD does NOT throttle GeckoLib.
EMF only handles OptiFine CEM
.jemmodels; GeckoLib renders through its own pipeline. INFERENCE: theanimationLODDistancelever 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). - 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)
- 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
- 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
- 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 exposesuse3DSkinLayerPatchwhich is only shown whenETF.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 - 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]
- 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
- Better Combat requires playerAnimator, and its animation code runs on every
player entity, not just yourself. Its client package contains
PlayerAttackAnimatableandCustomAnimationPlayerundercommon/…/client/animation/, i.e. it is aPlayer-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 - Better Combat client-side cost knobs are few but real.
ClientConfig.javafields includeisShowingWeaponTrails(default true — the slash/trail particle system inclient/particle/TrailParticles.javaandSlashParticleUtil.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 - 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
animationFrameSkipDuringIrisShadowPasswas built to avoid. This is a strong candidate lever for the 10-player use case. - 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
- EMF has explicit Emotecraft integration — changelog 3.0.7 added
registerPauseCondition(Function<EMFEntity,Boolean> shouldPause)toEMFAnimationApispecifically 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
- 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 - Exact 1.21-branch config keys (this branch is
@version 4.8.0, matching pack 4.8.11), config fileconfig/lambdynlights.toml:mode(enumoff/fastest/fast/fancy, defaultfancy),chunk_rebuild_scheduler(cullingdefault /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), plusdebug.*. [VERIFIED — source] https://github.com/LambdAurora/LambDynamicLights/blob/1.21/src/main/java/dev/lambdaurora/lambdynlights/DynamicLightsConfig.java - The quality mode maps to a tick mode, not to radius.
DynamicLightsModein the 1.21 branch:FANCY → TickMode.REAL_TIME,FAST → TickMode.SLOW,FASTEST → TickMode.SLOWER,OFF → REAL_TIME(disabled). Sofastest/fastthrottle how often light updates are applied (fewer chunk rebuilds/second), which is the correct lever for stutter, andfancygives 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 - The 4.8.x line added two dedicated cost mitigations vs older guides.
chunk_rebuild_scheduler(cullingdefault vsimmediate) and the adaptive-ticking distance pair (adaptive_ticking.slow/.slower, in chunks) plusbackground_sleepunderadaptive_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/ - Per-category light-source toggles map to real feature costs.
light_sources.entities=falseremoves all burning-mob/glow-squid/entity-carried-light sources (the biggest moving-light population in a survival world);light_sources.self=falseremoves the first-person player light;light_sources.beam/guardian_laser/sonic_boom/glowing_effectcover beacon beams, guardian beams, sonic booms and the Glowing effect. Disablingentitieswhile keepingselfis 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 - Sodium interop is explicit, not accidental.
HOW_DOES_IT_WORK.md: "we inject atWorldRenderer#setupTerrain(WorldRenderer#renderatWorldRenderer#setupTerraininvoke 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
- 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
- It has a client-side entity tick culling feature, not just render culling.
Config.java(config version 9):tickCulling(true), with a separatetickCullingWhitelist. 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 - Exact config keys/defaults (
config/entityculling.json):tracingDistance128 (path-trace range),sleepDelay10,hitboxLimit50,captureRate5,tickCullingtrue,skipEntityCullingfalse,skipBlockEntityCullingfalse,blockEntityFrustumCullingtrue,forceDisplayCullingfalse,solidLeavesfalse ("treat leaves as solid blocks … help to increase the performance in forested areas" — directly relevant with Better Leaves 9.6 in pack),safeModetrue,renderNametagsThroughWallstrue, plusentityWhitelist/blockEntityWhitelist/tickCullingWhitelist. [VERIFIED — source; DOCUMENTED — README forsolidLeaves] - 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]
- 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]
- 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]
- 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
- 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
- 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
- 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
ItemEntitys, each costing anItemRenderersubmission and (with Better Leaves + FA) potentially full model evaluation for held-block mobs. [INFERENCE] - EMF/ETF+FA cost scales with visible model count, which EntityCulling and Entity
Distance both reduce. Since
animationLODDistanceskips frames as a function of distance from the player,Entity Distanceand 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 forlod,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_V2enum 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
- Is
animationFrameSkipDuringIrisShadowPassactuallytruein the shippedemf.json/config? Cheapest possible check; if a pack preset or copy flipped it, every shader scene is paying 2× animation. - What is the real fps delta from EMF
animationLODDistance20 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. - 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.
- LambDynamicLights
fancyvsfastchunk-rebuild count — use the mod's owndebug.display_dynamic_lighting_chunk_rebuildanddebug.active_dynamic_lighting_cellsoptions (both exist as keys) to count rebuilds per second, then correlate with 1% lows. Also test whetherchunk_rebuild_scheduler=cullingis genuinely better thanimmediateon Sodium 0.8.13. - Do the LambDynamicLights
adaptive_ticking.slow/.slowerdistances (5 / 8 chunks) default interact badly with shaders? Not covered by the mod docs beyond the tick-mode description. - 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.
- 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.
- ETF emissive vs Complementary Reimagined built-in emissives — which to disable, and does disabling one measurably reduce frame time or just fix z-fighting?
solidLeavesunder Better Leaves 9.6 — measure in forested areas and inspect for entities disappearing behind custom leaves.- Entity Distance slider calibration — find the % where mobs stop being visibly affected at the pack's server view-distance 8 with Distant Horizons mandatory.
- 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_IncreaseCacheSizeModifierchanges GC pause frequency (it trades RAM for CPU, likely the wrong direction on P2).