Retromod 1.3.0-snapshot.4 (NeoForge 26.1.2)
Curse Maven Snippet
What's new
Fourth snapshot of the 1.3.0 mixin-translation line. This build collects the compatibility, mapping, loader, and publishing fixes completed after snapshot.3, adds four more real mixin member bridges, and closes several paths where mixin repairs were being skipped entirely. Three reported mods were run on a real client while preparing it, which is where most of the entries below came from.
Added
- Legacy MobEffect mixin shadows now survive the Holder migration (#168, Species). A mixin that shadows
LivingEntity.hasEffect(MobEffect)no longer fails when the host only exposeshasEffect(Holder<MobEffect>). Retromod replaces the stale abstract shadow with a mixin-owned overload that wraps the old effect throughBuiltInRegistries.MOB_EFFECT, and applies the same adaptation to relatedLivingEntity.getEffectandMobEffectInstance.getEffectcalls in that mixin. This preserves mod-owned fields that still store rawMobEffectvalues. Tested withMixinLegacyMemberBridgeTestand two load-time mixins in the Fabric test mod, and checked against the real Species 2.3 Fabric jar, where the shadow and all three of its call sites come out correct. - Legacy custom-Pose constructor mixins now follow the expanded enum constructor (#168, Species). The old
(String, int)@Invoker("<init>")becomes a concrete mixin-owned overload that supplies the modern numeric id and serialized name. Existing handler call sites keep their old descriptor. Tested withMixinLegacyMemberBridgeTestand a load-time Fabric test-mod mixin. - Custom worldgen types register again through their legacy mixins (#168, Species). Tree decorators, trunk placers, foliage placers, root placers, feature sizes, and block state providers all keep a private constructor and a private registrar, so a mod can only reach them through an
@Invokermixin, and that invoker still passes theCodecthe mod was built against. The invoker now becomes a mixin-owned method that converts the codec and calls the currentMapCodecmember, which leaves the mod's own codec fields and call sites alone. A codec built byRecordCodecBuilder, which is what mods normally use, is unwrapped back to the exactMapCodecit came from. Any other codec is read as a whole map instead of being nested under a new field, so existing worldgen JSON still loads as written. This covers the mixin written as a class, where the bridge is merged into the target and can reach its private members. A mixin written as an accessor interface is left alone, because a bridge there would sit outside the target and could not reach them. Tested withMixinLegacyMemberBridgeTestand a load-time mixin in the Fabric test mod. - A mod's config screen opens again when its config library moved its own API (#181, Double Hotbar). Cloth Config's 26.1 build moved
getConfigScreenandgetGuiRegistryoffAutoConfigonto a newAutoConfigClient, keeping their signatures. A mod built against an older Cloth still called the old owner, so opening its settings through Mod Menu threwNoSuchMethodErrorwhile the rest of the mod ran. Both calls now follow the move, andregisterandgetConfigHolder, which did not move, are left alone. Established by comparing cloth-config 20.0.149 against 26.1.154 and 26.2.155, and confirmed on a 26.2 client. Tested withClothConfigAutoConfigClientTest. - A shadow of the removed
Gui.getCameraPlayerno longer blocks a HUD mixin. The HUD rework dropped that method, and a shadow that cannot attach makes Mixin refuse the whole class, so a mod's HUD drawing silently stops with no crash to point at. The shadow becomes a mixin-owned method that reads the camera entity from the client, which is what the removed one did, and returns nothing when the camera is not a player. This clears one blocker; a mixin that also shadows other removedGuiinternals still will not attach. Tested withMixinLegacyMemberBridgeTest. - Method-level mixin discovery reports.
scripts/mixin-method-breaks.pycompares scanned selectors with a host jar, follows class moves and inheritance, and ranks missing target methods for review.
Fixed
- Precompiled mods keep working mixins. Both AOT compilers stopped at the class remap, and a mixin selector is annotation text that the remap does not touch. A prepared mod therefore kept selectors naming the version it was built against, such as
method_55665where the host now hasgetDefaultPassengerAttachmentPoint, and every one of its mixins failed to apply. The AOT paths now run the same mixin repairs astransformandbatch, in the same position after the remap. Checked against a real Fabric mod, whose prepared jar now carries the same 53 mixin selectors the transform path produces, and covered byAotMixinRepairTest. - Precompiling a mod no longer drops its refmap, access widener, and data fixes. The AOT path patched mod metadata but skipped three repairs the other paths run: remapping the mixin refmap, remapping an access widener or classTweaker, and normalising datapack JSON. A 26.x host reads the official namespace, so a prepared Fabric mod could be rejected before any of its code ran, and an intermediary access widener fails so early there is no crash report at all. Verified on a real refmap mod, whose prepared jar now carries a byte-identical refmap to the
transformoutput, and covered byAotMixinRepairTest. - A mixin inside a bundled library is repaired like the mod's own. Mods that ship a library as a nested jar had that library's classes renamed but not its mixins, so a bundled library's mixins could not resolve their targets. All three paths that unpack nested jars now repair them, and the precompiler additionally applies the refmap, access widener, and datapack repairs it was only doing at the top level. Tested with
AotMixinRepairTest, using a mod carrying a library built against an older version. - A mod whose mixin config is named
modid.mixin.jsonis repaired again. The Fabric runtime path learns which classes are mixins by reading the mod's mixin configs, and it recognised fewer config names than the rest of Retromod. A mod using the singular spelling looked like it had no mixins at all, so none of its mixins were repaired. It now uses the same naming rules everywhere. Tested withFabricMixinConfigDiscoveryTest. retromod aot --output <file>writes where you asked. The option was accepted and then ignored, so the prepared jar only ever appeared in the internal cache directory.- Mixin member repairs now reach Fabric mods at runtime. The repairs that match a member by its Mojang descriptor, meaning the legacy member bridges above and the removed worldgen shadow demotion, ran before intermediary names were remapped. On the Fabric runtime path they therefore matched nothing, and the mod still failed on the descriptor it was built against. They now run in the same post-remap position on every loader, which is where the offline transform already applied them. Tested with
MixinLegacyMemberBridgeTestandMixinShadowFieldDemotionTest. - Bare mixin selectors now follow owner-scoped Mojang method renames. A selector such as
method = "setPickedItem"can use a verified rename from the shim table when its mixin declares one target owner. Multi-target mixins remain untouched when the rename would be ambiguous. - The 26.1 pick-block rename is complete. Calls and mixin selectors for
Inventory.setPickedItem(ItemStack)now targetaddAndPickItem(ItemStack). - #180 (AutoClicky): frame rebuilding can resolve mod-owned class hierarchies from the jar. This keeps the real shared superclass instead of widening a merge to
Objectand producing aVerifyError. - #184 (S33R More Food): the NeoForge
newSimpleChannelbridge accepts both the oldResourceLocationand post-remapIdentifierspelling. Confirmed on a 26.2 NeoForge client: the reportedNoSuchMethodErroris gone and the mod is scanned and loaded. It now stops on a different problem, recorded below. - The Forge client tick event points at a class that exists.
TickEvent$ClientTickEventwas mapped into theevent/tickpackage alongside its siblings, but NeoForge keeps the client one with the other client events, so the target never resolved. Verified against neoforge-26.2.0.0-beta. - Completed the 26.1 blaze3d
platformtoopenglmove. Eleven missedGlStateManager,GlConst, andGlDebugnested classes now redirect to their verified 26.x locations. - Added two small 26.2 compatibility repairs. The misspelled
InstantenousMobEffectclass follows Mojang's correctedInstantaneousMobEffectname, and removedFlyingAnimalreferences use an embedded replacement interface. - Expanded SRG-to-Mojang coverage through Forge 1.21.8. The generated union now covers verified client and server mappings across the Forge SRG era, while conflicting IDs are omitted instead of guessed.
Infrastructure
- CurseForge uploads include the now-required Client and Server environment versions. Snapshot uploads can select the conventional beta release type without changing the script.
- Compatibility reports use one YAML file per report. Concurrent report pull requests no longer conflict on one shared data file.
Known limitations
- Species 2.3 is not yet fully translated. Its
MobEffectandPosemixins are repaired, verified against the real 2.3 Fabric jar. Two gaps remain: it reaches the tree decorator registrar through an accessor interface, which the new bridge deliberately skips (below), andAbstractCriterionTriggerInstancestill needs its separate class and API migration. Snapshot.4 does not claim the full mod loads. - A Forge mod that listens for tick events still will not construct on NeoForge (#184). NeoForge split each tick event into
PreandPostand made the parent abstract, and it refuses a listener registered on the parent, which fails the mod at construction and takes the whole mod down. Retromod still maps to the parents. Repointing them atPreorPostis not enough by itself: a Forge mod also reads the removedTickEvent.phasefield and compares it against the removedTickEvent.Phaseenum, so the class split, the field, and the enum have to move together. Reproduced on a 26.2 NeoForge client with S33R More Food. - Double Hotbar's second hotbar still does not draw (#181). Its config screen is fixed and the mod loads cleanly, verified on a 26.2 client. The HUD half is a deeper problem: 26.x moved hotbar drawing out of
Guionto a separateHudclass, so the mod'sGuimixin shadowsrenderSlot, which no longer exists anywhere on that class. Retromod cannot recreate vanilla slot rendering, so this one needs a real port by the mod author. The mixin fails to attach and the rest of the mod keeps working, which is the intended soft failure rather than a crash. - A worldgen registrar reached through an accessor interface is not bridged yet. Two things have to move together and only one is handled today. Mixin widens the private registrar only because of the
@Invokera bridge would remove, and the mod's refmap still names that registrar with its oldCodecdescriptor, so retyping the invoker alone would stop it resolving. Mixins written as a class are unaffected. - The new mixin work is verified by transform, not yet in game. Every repair was checked by transforming real mods and reading back the emitted bytecode and stack maps, including the Species jar from the report, and every mixin class across the test corpus still parses afterwards. A launch on a 26.x host is still the confirming step.
All Relations
- All Relations
- Embedded Library
- Optional Dependency
- Required Dependency
- Tool
- Incompatible
- Include
This mod has no related projects

