File Details
Retromod 1.3.0-Snapshot.1 (Fabric 26.1.2)
- B
- Jul 13, 2026
- 3.25 MB
- 4
- 26.1.2
- Fabric
File Name
retromod-1.3.0-snapshot.1+26.1.2.jar
Supported Versions
- 26.1.2
Curse Maven Snippet
First snapshot of the 1.3.0 line ("mixin translation"). The theme: stop soft-failing mixins and actually translate them. Where 1.2.0 could only STRIP a mixin handler whose target drifted (the feature went inert), 1.3.0 rewrites the handler so the feature keeps working. This snapshot lands the first batch of real translations, retiring four blocklist soft-fails, plus two regression fixes to the re-signature engine caught in review.
Added
- ValueIO save-data adapter (#48). A 1.21.1 mod's
@InjectintoEntity.addAdditionalSaveData/readAdditionalSaveData(or the BlockEntitysaveAdditional/loadAdditional) captures aCompoundTag; the 1.21.5 ValueIO refactor made those methods passValueOutput/ValueInput, so Mixin rejected the handler (InvalidInjectionException) and NeoForge cascaded into "broken mod state".MixinValueIoAdapterkeeps the mod's handler body unchanged (still operating on a realCompoundTag) and wraps it: the synthesized handler converts the ValueIO param to aCompoundTagthrough a reflective, Minecraft-free runtime bridge (ValueIoBridge, per-mod-embedded on NeoForge/Forge for JPMS split-package safety). Repair-or-strip: if frame recomputation fails, the handler is stripped (the old soft-fail), so it can never ship aVerifyError. Retires the Darker DepthsPlayerMixinblocklist entry. @Inject/@Redirect/@WrapOperation/@Overwritesignature-drift re-signaturing (#69). The 1.21.5 "world/level threading" refactor prepended aServerLevelto manyLivingEntity/Entity/Mob/Playermethods (doHurtTarget(Entity)becomesdoHurtTarget(ServerLevel, Entity), and so on).MixinHandlerResignatureinserts the new leading param into the handler descriptor, shifts every local slot, and rewrites the drifted@At(INVOKE)injection-point targets, so the handler matches the modern method again. Gated to 1.21.5+ hosts (a no-op where the signatures are intact), re-emitted underCOMPUTE_FRAMESwith a fall-back to the prior soft-fail. Retires Revamped Phantoms'SweepAttackMixindoHurtTargetentry.- MixinExtras injector dispatch.
@ModifyReturnValue/@ModifyExpressionValue/@WrapOperation/... selectors are now routed through the same intermediary-to-Mojang / drift remap as core injectors, with therequire=0soft-fail net added only when a selector was actually rewritten (so a working MixinExtras mixin stays byte-identical). - Revamped Phantoms
PhantomMixin(#50): a real translation via a deleted-superclass owner-alias.FlyingMobwas deleted in ~1.21.2 and Phantom now extendsMobdirectly, but Phantom STILL declaresgetDefaultDimensions(Pose)(its body callsMob.getDefaultDimensions, the formersuper), so the mod's@ModifyExpressionValue's only break was its@At(INVOKE)target still namingFlyingMob. AFlyingMob.getDefaultDimensionstoMob.getDefaultDimensionsmethod redirect (in the three 1.21.11 to 26.1 shims, intermediary key on Fabric) re-owns the injection point, so the phantom-size feature works instead of being stripped. Retires thePhantomMixinblocklist entry. Known limitation: on the rarely-used intermediate host range 1.21.2 to 1.21.10, whereFlyingMobis already gone but that redirect (and the intermediary to Mojang remap) does not apply, the feature hard-fails rather than soft-failing; the maintained 26.1+ path is fully covered, and pre-26.1 hosts are the #55 bridge's scope. - Mixin selector remapping is now applied on ALL loaders and the offline CLI, not just the Fabric runtime. Previously the
@Mixin/@At/method=selector remap (method + class redirects) ran only inside the Fabric-runtime path; the NeoForge/Forge and CLI-batch paths did the blocklist strip + re-signature but skipped the selector remap, so an API-rename redirect (the #50FlyingMobalias, the #28Paintingclass-move on the NeoForge Deeper and Darker, the GameNarrator/setScreen scan-renames) never reached a NeoForge/Forge or offline-transformed mixin's annotation strings. Those paths now run the same full pipeline. (Without this, #50 and the class-moves would have silently regressed to hard injection failures on their actual loaders.) - Scan-rename redirects (from a 19-jar corpus scan of mixin selectors against the 26.x jars):
GameNarrator.sayNowtosaySystemNow,FriendlyByteBuf.readJsonWithCodectoreadLenientJsonWithCodec(26.1 epoch),Minecraft.setScreentosetScreenAndShow(26.2 epoch). - 1.21.11 to 26.1 vanilla class moves:
entity/decoration/Painting+PaintingVariantintoentity/decoration/painting/,entity/monster/Huskintoentity/monster/zombie/, and theMobSpawnTypetoEntitySpawnReasonrename (all verified against the 26.1 and 26.2 jars).
Fixed
- #28 (Deeper and Darker): a stale blocklist entry that protected nothing. The
#28entry named aPaintingItemMixin/deeperdarker$decrementStackOnServerhandler that does NOT exist in the current jar (a silent no-op that hid the mod's real drift). Replaced with entries for the REAL classes:HangingEntityItemMixin.appendHoverText(its target was re-signaturedList<Component>intoTooltipDisplay+Consumer, a param split, and its body reads the deletedPainting.VARIANT_MAP_CODEC/CustomData.read, so it is genuinely unrepairable and is stripped, the variant tooltip going inert) andPaintingMixin.dropItem(aServerLevelsignature drift on a generic name, stripped). ThePaintingclass-move fixes the@Mixintarget soPaintingMixin.getPickResultnow applies natively. - Re-signature engine: a
@Localcaptured after the CallbackInfo trailer could turn a soft-fail into a hard crash. The parameter-annotation decline guard was bounded at the CallbackInfo index, but MixinExtras@Local/@Sharelocals sit AFTER it, and the re-signature does not shift the parameter-annotation arrays, so an inserted leading param misaligned the@Localonto the wrong parameter, anInvalidInjectionException(whichCOMPUTE_FRAMEScan't catch) on exactly the #69doHurtTarget-family methods. The guard is now full-width, so any parameter-annotated handler declines and keeps its soft-fail. - Re-signature engine: the
@Injectmethod=selector was rewritten decoupled from the handler re-signature.rewriteAnnotationDrifteagerly rewrote an@Inject's top-levelmethod=selector to new-form even wheninsertParamslater declined, shipping a new-form selector against an un-re-signatured handler (a hard descriptor mismatch). The top-level@Inject method=rewrite is now owned solely by the coupledinsertParamspath; the@At target=injection-point rewrites (independent of the handler signature) are unchanged. - Owner-only mixin method redirects were silently dropped. The mixin target-redirect builder only recorded a redirect when the method NAME changed, so an owner-only redirect (the #50
FlyingMob.getDefaultDimensionstoMob.getDefaultDimensionsalias) never reached the@At/method=remap. It now records the owner-qualified form for ANY change (owner, name, or descriptor); the owner-agnostic bare-name form still requires a genuine name change on a globally-unique obfuscated name.
Research (documented, not yet shipped)
- True Darkness (#68) confirmed genuinely un-translatable.
LightTexturewas deleted and redesigned intoLightmap(a GPU texture / UBO produced by a separateLightmapRenderStateExtractor), so the mixin's@Shadowof the old CPUDynamicTexturefield has no equivalent and the flicker/dirty state moved to a different class. A real fix is porting the mod to the 26.x render pipeline, outside a mechanical transformer. The whole-class strip stays. - Yung's API
BeardifierMixin/NoiseChunkMixinconfirmed repairable, held pending verification. Research (javap on 26.1/26.2) confirmed both are mechanically repairable (Beardifier: un-strip the mixin, strip only the deadBeardifierAccessor; NoiseChunk: demote the removed@Shadow @Final noiseSettingsto a@Uniquefield captured from the surviving constructor param). They are HELD in this snapshot because re-enabling interdependent worldgen mixins requires a headless-server worldgen pass first (a mis-repair cascades to all chunk generation). The blocklist reasons carry the full mechanism.