File Details
Retromod 1.2.0-rc.1 (NeoForge 26.1.2)
- R
- Jul 6, 2026
- 3.22 MB
- 7
- 26.1.2
- NeoForge
File Name
retromod-1.2.0-rc.1+26.1.2.jar
Supported Versions
- 26.1.2
Curse Maven Snippet
First release candidate for 1.2.0 ("the general update"). Promotes the accumulated snapshot line (snapshot.1 through the unreleased snapshot.9) to a release candidate. Across the 1.2.0 line this delivers MC 26.1.x + 26.2 as the maintained targets on Fabric, NeoForge, and Forge (Forge 65.x, EventBus 6 -> 7), the Forge -> NeoForge migration spine, the 26.2 render-API stand-ins, worldgen on 26.x, and the transform-level 1.12.2 groundwork plus its load layer. The changes new since snapshot.8 are under Fixed below; this rc also closed a cleanup pass:
- Phantom-target cleanup. (done) Deleted the 10 third-party API shims that were entirely phantom (
AutoRegLibApiShim,JadeWailaApiShim,PatchouliApiShim,BaublesApiShim,ThermalApiShim,NeiApiShim,WailaApiShim,FabricShieldLibApiShim,OwoLibApiShim,LbaApiShim): every redirect they registered pointed at a never-written embedded class, so they were dead weight (removed their.javafiles and theirMETA-INF/services/com.retromod.core.VersionShimentries). That takes the phantom count from 97 to 51. The remaining 51 live inside otherwise-valid core version shims (mixed with real registrations) and are paid down over time. NewPhantomBaselineTestfences the set againstphantom-baseline.txtso any NEW phantom fails the build (and fixing one prompts shrinking the baseline). The snapshot.8 runtime guard already made all of these fail-safe; this removes the underlying debt. method_14452PlacementModifier mapping fix. (done, see Fixed below.)- Multi-mod
mcmod.infotomls. (done, see Fixed below.)
Deferred out of 1.2.0 (tracked, roll to a 1.2.x follow-up, not a blocker for this rc):
- ClientPlayNetworking v1 raw-bytes bridge (#51), the §B3 armor-layer
EquipmentClientInfobridge (#70), and the Sinytra Tier B bundle (#94, covering #9/#11/#12/#13). These were staged at the transform level during the snapshot cycle but still need in-game launch validation on their target hosts, so they follow the rc rather than gate it. - Fully running real 1.12.2 mods (beyond the class-load + registration-event stubs this rc ships) is a per-mod chase through a decade of removed systems and earns its own release: the 1.4.0 line, "The 1.12.2 update", in
ROADMAP.md.
Fixed
new ResourceLocation(namespace, path)no longer corrupts to a VerifyError (#135 Wyrms of Nyrus, #136, #121). The polyfill that rewrites the removedResourceLocationconstructors to the static factories registered them as plain method redirects, which only swapped the target and left the uninitializedNEW/DUPon the stack with anINVOKESPECIALagainst the factory:VerifyError: Bad type on operand stack("Type uninitialized 0 ... is not assignable") at class load in any mod building aResourceLocation(the canonical 1.12.2 idiom). It now usesregisterConstructorRedirect(which strips theNEW/DUPand emitsINVOKESTATIC), gated to hosts >= 1.20.5 where those constructors were actually removed (on 1.20.1-1.20.4 the ctor still exists, and firing it there was itself the corruption). One fix clears the same VerifyError across three reports. Validated in-game on Forge 1.20.1: Wyrms of Nyrus advanced past the VerifyError (zero VerifyErrors in the crash).- 1.12.2 removed registration/model events bridged so the mod loads (#134). A 1.12.2 mod's
@SubscribeEventhandler takingRegistryEvent.Register(the pre-1.13 registration event) orModelRegistryEvent(the pre-1.17 model-registration event) hitNoClassDefFoundError. Retromod now embedsRegistryEvent/$Register/$MissingMappingsandModelRegistryEventas synthetic classes that are a valid subtype of the host's eventbusEvent(a class on EventBus 6 and NeoForge, a marker interface on EventBus 7, resolved by probing the running host so the stubextendsorimplementsaccordingly). The event never fires on a modern host, so the registration-via-event stays inert, but the class loads and event-bus registration completes without throwing. Skipped on the offline CLI where the host eventbus can't be resolved (no worse than before). Validated in-game on Forge 1.20.1: Mob Control Wands advanced pastRegistryEvent$Register. - NeoForge
AddReloadListenerEventbridged to 26.2'sAddServerReloadListenersEvent(#139, Legendary Survival Overhaul). NeoForge renamed the event around 26.x and madeaddListenerrequire aResourceLocation/Identifierid. A 1.21.1 mod referencing the old event hitNoClassDefFoundError. Retromod class-redirects the event (fixing the crash and retargeting the@SubscribeEventparameter, both are game-bus events) and bridges the old one-argaddListener(listener)call to the new two-arg form via a shim that synthesizes a deterministic id, so the reload listener actually registers. - 1.12.2 mods no longer die at class-load on removed Forge API types (#131/#132/#134/#135, load layer). A 1.12.2 Forge mod's class
implements/references a Forge type that later Forge deleted (IWorldGeneratorandIGuiHandlerandIMessage/IMessageHandlerin 1.13,IForgeRegistryEntryin 1.17), so the class can't even load (NoClassDefFoundError) on a modern Forge/NeoForge host.Forge_1_12_2_to_1_13_2now embeds an empty stub interface per removed type and redirects the old name onto it, so those classes load. Scope: this fixes the reported class-load errors; the paired registration idioms (GameRegistry.registerWorldGenerator,NetworkRegistry.registerGuiHandler,SimpleNetworkWrapper) target other removed classes and stay inert until bridged, so a mod may surface a next error there.CreativeModeTab.<init>(String)(#133, a constructor-to-builder bridge) is a separate follow-up. Part of the ongoing 1.12.2 baseline (#79); the load layer is transform-tested, full in-game running still needs iteration against the real jars. - 1.12.2
mcmod.infowith multiple mods now declares every modid (#115). A single 1.12.2 jar can list several mods in onemcmod.info(The Betweenlands shipsthebetweenlands+mclib). The synthesizedmods.tomlpreviously kept only the first entry, so the extra modids were never declared, FML never registered them, and any class or registration keyed on the second modid failed.ForgeModTransformer.generateTomlFromMcmodInfonow JSON-parses themcmod.info(both the array form and the{"modList":[...]}v2 wrapper) and emits a[[mods]]block plus its own dependency tables per entry, with a lenient regex fallback preserving the old single-mod behavior for an unparseable file. Because the JSON path decodes escapes into real quotes/newlines, the emittedversionis validated against a[A-Za-z0-9._-]allowlist (falling back to1.0.0) so a craftedmcmod.infocan't break out of the quoted TOML value to inject keys or spoof another modid, and the parse degrades to the regex fallback on anyThrowable(including aStackOverflowErrorfrom deeply-nested input). - Custom
PlacementModifier.getPositionsno longer mis-renamed tocount(#114). The Fabric intermediary short-namemethod_14452is ambiguous: verified against Fabric Yarn 1.18.2 through 1.21.4 it names BOTHPlacementModifier.getPositions(context, random, BlockPos) -> Stream(MojanggetPositions) AND a separategetCount(random, BlockPos) -> int(Mojangcount). The name-only 1.21.4intermediary-to-mojang.tsvkept justcount, so a mod'sgetPositionsoverride was renamed tocount: it stopped overriding the abstract method and threwAbstractMethodErrorduring chunk generation on 26.x (any mod with a custom placement modifier).IntermediaryToMojangMapper.applyTonow registers all four descriptor variants (two eras: 1.18.xjava/util/Random, 1.19+RandomSource) so the transformer's ambiguous-name fallback resolves each site by descriptor. The systemic follow-up (a descriptor-qualified harvest so the tsv itself carries ambiguity) is noted in code. - Removed Fabric v0
ClientTickCallbackbridged toClientTickEvents(#129 Chat Bubbles).net.fabricmc.fabric.api.event.client.ClientTickCallback(SAMtick(MinecraftClient), staticEVENT) was deleted from Fabric API around 1.16, so a 1.15-era mod referencing it dies withNoClassDefFoundErrorwhile its entrypoint class is even being loaded. Retromod now embeds a syntheticClientTickCallbackinterface (kept undercom/retromod/...so it can't split-package with the loader module) that preserves thetickSAM and theEVENTfield;EVENTis wired in<clinit>to an array-backed event whose invoker fires once per client tick viaClientTickEvents.END_CLIENT_TICK. Gated to 26.1+ (the SAM uses the MojangMinecrafttype). Implemented pending in-game verification. - AOT no longer aborts a whole mod on one un-recomputable class (#125 MineColonies, #127 The Flying Things). The AOT compiler's last-resort per-class path recomputes stack-map frames with
COMPUTE_FRAMES, which can throw deep inside ASM (Frame.merge->ArrayIndexOutOfBoundsException/NegativeArraySizeException) on a class whose frames can't be recomputed after our rewrites. That exception propagated out and failed the entire jar's AOT, dropping the mod back to un-transformed bytes. It now falls back per-class to the robust main (JIT) transformer (which has its own ship-original frame-corruption guard), then to the original bytes, and never lets one class take down the jar. This mirrors the snapshot.8 frame-corruption fallback that already protected the JIT path.