Skip to main content

Overview

Stage 0 provides the initial entrypoint for Essential Loader on each mod loading platform. It discovers, extracts, and loads Stage 1 from embedded JAR resources. Stage 0 must be loaded by the platform’s native class loader to ensure proper isolation and relocation.

Core Components

EssentialLoader (Common)

The shared implementation for discovering and loading Stage 1 across all platforms. Package: gg.essential.loader.stage0
variant
String
required
Platform variant identifier (e.g., “launchwrapper”, “fabric”, “modlauncher8”)

loadStage1File()

Discovers and extracts the most recent Stage 1 JAR file.
public Path loadStage1File(Path gameDir) throws Exception
gameDir
Path
required
Game directory for extracting Stage 1 files
Path
Path
Path to the extracted Stage 1 JAR file ready for class loading
Behavior:
  • Checks for stage1.update.jar and applies updates if present
  • Scans classpath for all gg/essential/loader/stage0/stage1.jar resources
  • Compares versions using manifest Implementation-Version attribute
  • Extracts the latest version to essential/loader/stage0/{variant}/stage1.jar
  • Returns the extracted file path
Storage Location:
{gameDir}/essential/loader/stage0/{variant}/
  ├── stage1.jar          # Current Stage 1 JAR
  └── stage1.update.jar   # Pending update (if present)

Platform Implementations

LaunchWrapper Platform

EssentialSetupTweaker

Entrypoint tweaker for Minecraft Forge’s LaunchWrapper system. Package: gg.essential.loader.stage0 Implements: net.minecraft.launchwrapper.ITweaker
public class EssentialSetupTweaker implements ITweaker {
    public EssentialSetupTweaker() throws Exception
}
Loading Process:
  1. Extract Stage 1: Calls loadStage1File() using Launch.minecraftHome
  2. Add to ClassLoader: Adds Stage 1 JAR to LaunchClassLoader and its parent
  3. Exclusion: Registers gg.essential.loader.stage1. package exclusion
  4. Instantiate: Loads Stage 1’s EssentialSetupTweaker via reflection
  5. Delegate: Forwards all ITweaker calls to Stage 1 instance
Example:
// Automatic initialization when specified as tweaker
// In launcher configuration:
--tweakClass gg.essential.loader.stage0.EssentialSetupTweaker
Class Loader Hierarchy:
System ClassLoader
└── LaunchWrapper ClassLoader (with stage1 exclusion)
    └── Stage 1 Classes (gg.essential.loader.stage1.*)

Fabric Platform

EssentialSetupPreLaunch

Fabric preLaunch entrypoint for loading Stage 1. Package: gg.essential.loader.stage0 Implements: net.fabricmc.loader.api.entrypoint.PreLaunchEntrypoint
public class EssentialSetupPreLaunch implements PreLaunchEntrypoint {
    @Override
    public void onPreLaunch()
}
Loading Process:
  1. Extract Stage 1: Calls loadStage1File() using Fabric’s game directory
  2. Create ClassLoader: Creates isolated URLClassLoader with Stage 1 JAR
  3. Instantiate: Loads Stage 1’s EssentialSetupPreLaunch class
  4. Delegate: Forwards onPreLaunch() call to Stage 1 instance
Configuration:
// In fabric.mod.json
{
  "entrypoints": {
    "preLaunch": [
      "gg.essential.loader.stage0.EssentialSetupPreLaunch"
    ]
  }
}
Class Loader Hierarchy:
Fabric Loader ClassLoader
└── URLClassLoader (isolated)
    └── Stage 1 Classes (gg.essential.loader.stage1.*)

ModLauncher Platform

EssentialTransformationService

Transformation service for Minecraft Forge’s ModLauncher system (1.13+). Package: gg.essential.loader.stage0 Implements: cpw.mods.modlauncher.api.ITransformationService (via delegation)
public class EssentialTransformationService 
    extends EssentialTransformationServiceBase
Separate implementations exist for ModLauncher 8, 9, 10, and 11 to handle API differences.
Loading Process:
  1. Get Game Directory: Queries ModLauncher environment for GAMEDIR
  2. Extract Stage 1: Calls loadStage1File() with discovered game directory
  3. Create ClassLoader: Creates isolated URLClassLoader with Stage 1 JAR
  4. Instantiate: Loads Stage 1’s EssentialTransformationService class
  5. Delegate: Forwards all ITransformationService calls to Stage 1 instance
Service Discovery:
META-INF/services/cpw.mods.modlauncher.api.ITransformationService
  → gg.essential.loader.stage0.EssentialTransformationService
Platform Variants:
  • modlauncher8: Forge 1.15-1.16 (ModLauncher 8.x)
  • modlauncher9: Forge 1.17-1.20.1 (ModLauncher 9.x/10.x)
  • modlauncher11: NeoForge 1.20.2+ (ModLauncher 11.x)

Relocation Requirements

Stage 0 classes must be relocated to avoid conflicts when multiple mods bundle Essential Loader.

Required Relocations

// In build.gradle with Shadow plugin
shadowJar {
    relocate 'gg.essential.loader.stage0', 'your.mod.loader.stage0'
}
Why Relocation is Required:
  1. Class Uniqueness: Each mod needs its own Stage 0 instance in the platform class loader
  2. Conflict Avoidance: Multiple mods may bundle different Stage 0 versions
  3. Isolation: Stage 0 must bootstrap independently per mod
  4. Version Management: Each mod controls its own Stage 1 discovery

Relocation Verification

# Check that stage0 classes are relocated
jar -tf your-mod.jar | grep stage0

# Should show YOUR relocated package, not gg.essential.loader.stage0
com/example/yourmod/loader/stage0/EssentialSetupTweaker.class

Stage 1 Discovery Algorithm

Version Comparison

private static int getVersion(URL file) {
    try (JarInputStream in = new JarInputStream(file.openStream())) {
        Manifest manifest = in.getManifest();
        Attributes attributes = manifest.getMainAttributes();
        
        // Verify package name
        if (!"gg/essential/loader/stage1/".equals(
            attributes.getValue("Name"))) {
            return -1;
        }
        
        // Parse version number
        return Integer.parseInt(
            attributes.getValue("Implementation-Version"));
    }
}

Discovery Order

  1. Check for existing stage1.jar in data directory
  2. Check for pending stage1.update.jar
  3. Scan classpath for embedded gg/essential/loader/stage0/stage1.jar resources
  4. Compare all versions and select highest
  5. Extract selected version if newer than current

Error Handling

Common Errors

Cause: Corrupted JAR file or missing manifestResolution: Stage 0 will skip the corrupted file and try next available version
Cause: Stage 1 JAR not properly bundled in container JARResolution: Ensure stage1.jar is included at gg/essential/loader/stage0/stage1.jar
Cause: ForgeGradle development environment missing game directory argumentResolution: Stage 0 defaults to current directory (.) for development

Development & Testing

Embedding Stage 1

// In build.gradle
configurations {
    stage1
}

dependencies {
    stage1 'gg.essential:loader-stage1:+'
}

processResources {
    from(configurations.stage1) {
        into 'gg/essential/loader/stage0'
        rename { 'stage1.jar' }
    }
}

Local Testing

# Test Stage 0 discovery in development environment
./gradlew runClient \
    -Pessential.loader.stage0.debug=true

See Also

Build docs developers (and LLMs) love