Per mod/docs/optimize-layer-design.md Stage 3 (continued). This batch
implements the Stage 1 mixin-contract interfaces on their target MC classes
so CachedName, StateEntity, TickCached, CachedLight, CachedValidity and
CachedStack actually get used. Seven new mixin'ов; no new helpers (the
helpers were all written in Stage 1 already).
Entity-contract mixins (mixins/optimize/entity/):
- EntityNameMixin: implements CachedName on Entity — adds the per-tick
cached name-tag fields (Component + tick). Vanilla Entity.getDisplayName()
rebuilds the team prefix + name + suffix on every call.
- EntityRenderStateEntityMixin: implements StateEntity on EntityRenderState —
adds the back-reference field to the source Entity. Render-states are
rebuilt every frame so they can't keep their own pointer; this is captured
by EntityRendererStateMixin.
- EntityRendererStateMixin: Inject at RETURN on EntityRenderer.createRenderState
— captures the source Entity on the freshly-built state via the StateEntity
contract. ZakoOpt used @ModifyReturnValue; we use plain @Inject because the
MixinExtras ModifyReturnValue transformer is more fragile across MC versions.
- EntityRendererNameMixin: WrapOperation on EntityRenderer.getNameTag's
Entity.getDisplayName call — caches by game tick so the per-frame cost is
one identity check + read instead of a full Component rebuild.
- SodiumEntityRendererMixin: WrapOperation on Sodium EntityRenderer.renderCuboid's
MemoryStack.stackPush — uses CachedStack (Stage 1) to skip the ThreadLocal
lookup on the render thread. Registered as optional via LoVisualMixinPlugin
(only applied when Sodium is loaded); remap = false because the target is
a Sodium class, not a Mojang one.
BlockEntity-contract mixins (mixins/optimize/block/):
- BlockEntityMixin: implements TickCached + CachedLight + CachedValidity on
BlockEntity — adds the per-tick cache slot, per-tick block-light lookups
(single + pair for double-chests), per-tick should-render distance check,
and per-state validity cache. All four are read by the (Stage 3, future)
ChestRendererMixin / BlockEntityRenderStateMixin / BlockEntityRenderDispatcherMixin.
- BaseSpawnerMixin: implements TickCached on BaseSpawner — adds the per-tick
cache slot that SpawnerCache (Stage 1) reads back.
Folder limit (≤4 .java per folder):
- mixins/optimize/entity/ hit 6 files after this batch — split into
mixins/optimize/entity/renderer/ for EntityRendererStateMixin +
EntityRendererNameMixin (the two that target EntityRenderer rather than
Entity/EntityRenderState directly). The other 4 stay in entity/.
lovisual.mixins.json: seven new entries in the 'client' array, alphabetical:
optimize.block.BaseSpawnerMixin
optimize.block.BlockEntityMixin
optimize.entity.EntityNameMixin
optimize.entity.EntityRenderStateEntityMixin
optimize.entity.SodiumEntityRendererMixin
optimize.entity.renderer.EntityRendererNameMixin
optimize.entity.renderer.EntityRendererStateMixin
LoVisualMixinPlugin: added SodiumEntityRendererMixin to OPTIONAL_SODIUM_MIXINS
so the mixin is only applied when Sodium is loaded (matches the existing
convention for sodium.* mixins).
Tests: no new tests in this batch (the new mixins are pure side-effect
field-bags — they don't have unit-testable logic). Existing suite still green.
Total: 866 tests, 0 failures. checkFolderLimit: OK (0 папок >4).