Object LoaderDescriptors
-
- All Implemented Interfaces:
public class LoaderDescriptorsWhich descriptor file a modloader reads, at a given Minecraft version. The single home for that fact.
Loaders have moved their descriptor twice in ways that matter, and the version is part of the answer rather than a detail of it:
Why this exists as its own object. ModScanner.scannerFor already owned the era boundaries, and
serverpackcreator-clientside's pre-boot gate held a second, version-blind copy of the same knowledge — a flat descriptor→loader map. It therefore read everyMETA-INF/mods.tomlas Forge's, and refused 13 genuine NeoForge jars on Minecraft 1.20.2–1.20.4 as "not a NeoForge mod" (measured on the live grinder, 2026-09-10). That is theMetadataScanner/ModListCompilerdrift this codebase has already paid for twice: two copies of one fact, only one of them maintained. Both callers now ask here.The two boundaries are different facts about NeoForge and must not be merged. The package rename (
net.minecraftforge→net.neoforged) landed with Minecraft 1.20.2 and is what ends binary jar parity — that claim lives in the clientside engine'sLoaderCompatibilityand stays one version wide. The descriptor rename landed with 1.20.5 and is what this object is about. Between the two, Forge and NeoForge read the same file, so its presence tells a reader nothing about which of them a jar is for.Griefed
-
-
Field Summary
Fields Modifier and Type Field Description public final static StringFABRICpublic final static StringQUILTpublic final static StringFORGE_TOMLpublic final static StringNEOFORGE_TOMLpublic final static StringFORGE_LEGACYpublic final static StringFORGE_ANNOTATIONSpublic final static LoaderDescriptorsINSTANCE
-
Method Summary
Modifier and Type Method Description final Set<String>descriptorsFor(String modloader, String minecraftVersion)The descriptor paths whose presence evidences that a jar was built for modloader on minecraftVersion — empty when nothing distinguishes that loader, and for a loader this does not know. final BooleanforgeUsesToml(String minecraftVersion)Whether Forge on minecraftVersion carries a mods.tomlrather than the annotation-cache the 1.12-and-older scanner reads.final BooleanneoForgeUsesNeoToml(String minecraftVersion)Whether NeoForge on minecraftVersion uses neoforge.mods.tomlrather than Forge'smods.toml.-
-
Method Detail
-
descriptorsFor
final Set<String> descriptorsFor(String modloader, String minecraftVersion)
The descriptor paths whose presence evidences that a jar was built for modloader on minecraftVersion — empty when nothing distinguishes that loader, and for a loader this does not know.
This is the gate's question, not the scanner's, and the two are not the same. A scanner needs the one file to parse (ModScanner.scannerFor asks forgeUsesToml / neoForgeUsesNeoToml for that). A reader asking "was this jar built for NeoForge?" wants every file that would say so — which is why NeoForge's set carries
neoforge.mods.tomlat every version. That file is NeoForge's whenever it appears, even on a Minecraft where the loader would not have read it, and treating its presence as meaningless there would let a NeoForge-only jar pass as a Forge mod.LegacyFabricis deliberately empty. It reads Fabric'sfabric.mod.json, so a jar carrying one says nothing that separates the two, andLoaderCompatibility.alsoRunsalready accepts a Fabric jar for a LegacyFabric boot. Returning{FABRIC}here would instead make every Fabric jar declare two loaders and make LegacyFabric refusable on evidence it never had.Empty is deliberately not an error, matching ModScanner.scannerFor's
null: the caller decides what an unrecognised loader means, and the pre-boot gate treats it as "no opinion", which accepts.- Parameters:
modloader- Canonical modloader name, as de.griefed.serverpackcreator.api.config.minecraftVersion- The Minecraft version being read for, which decides the descriptor era.
-
forgeUsesToml
final Boolean forgeUsesToml(String minecraftVersion)
Whether Forge on minecraftVersion carries a
mods.tomlrather than the annotation-cache the 1.12-and-older scanner reads. Forge switched with Minecraft 1.13.Compares every version component through SemanticVersionComparator rather than testing the minor on its own: Minecraft has two versioning schemes (
1.x.yand the newerYY.x.y), so26.2's minor of2reads as the 1.2 era and would pick the wrong scanner. An unparseable version falls back to the modern descriptor — the annotation cache exists only in jars a decade old, so it is never the safer guess.
-
neoForgeUsesNeoToml
final Boolean neoForgeUsesNeoToml(String minecraftVersion)
Whether NeoForge on minecraftVersion uses
neoforge.mods.tomlrather than Forge'smods.toml.Falls back to the modern descriptor for an unparseable version, for the same reason and by the same route as forgeUsesToml. It used to throw instead: the comparison was unwrapped while Forge's was wrapped, so
scannerFor("NeoForge", "26")propagated anArrayIndexOutOfBoundsExceptionout ofModScanner— and"26"is a legitimate shape under the newer scheme.
-
-
-
-