Skip to main content

Overview

Stage 1 handles configuration management, automatic updates, and loading Stage 2 (the actual Essential mod or other compatible mods). It provides a stable update mechanism that allows Essential Loader to self-update without requiring mod reinstallation.

Core Components

EssentialLoaderBase

Abstract base class providing update checking and Stage 2 loading logic for all platforms. Package: gg.essential.loader.stage1
public abstract class EssentialLoaderBase {
    protected EssentialLoaderBase(String variant, String gameVersion)
    public void load(Path gameDir) throws Exception
    public void initialize()
    public Object getStage2()
    protected abstract ClassLoader addToClassLoader(URL stage2Url) throws Exception
}
variant
String
required
Platform variant (e.g., “launchwrapper”, “fabric”, “modlauncher”)
gameVersion
String
required
Minecraft version (e.g., “1.8.9”, “1.20.1”)

Key Methods

load()

Main entry point that loads and starts Stage 2.
public void load(Path gameDir) throws Exception
gameDir
Path
required
Game directory containing Essential data and configuration
Process Flow:
  1. Configuration Loading
    • Reads essential-loader-stage2.properties from classpath
    • Loads pinned version metadata if present
    • Reads user configuration from data directory
    • Merges environment variables and system properties
  2. Version Resolution
    • Checks local Stage 2 file and validates checksum
    • Fetches latest online version metadata if needed
    • Applies pinned version constraints
    • Handles update prompts based on auto-update mode
  3. Stage 2 Loading
    • Downloads or updates Stage 2 JAR if required
    • Adds Stage 2 to platform class loader
    • Instantiates gg.essential.loader.stage2.EssentialLoader
    • Calls load() method on Stage 2 instance
Storage Location:
{gameDir}/essential/loader/stage1/{variant}/
  ├── stage2.{version}.jar           # Stage 2 JAR file
  ├── stage2.{version}.meta          # Version metadata
  └── stage2.{version}.properties    # User configuration

initialize()

Calls the initialize() method on the loaded Stage 2 instance.
public void initialize()
Timing: Called after Stage 2’s load() completes, typically at a later stage of the game loading process.

getStage2()

Returns the loaded Stage 2 instance for platform-specific access.
public Object getStage2()
stage2
Object
The Stage 2 loader instance (type varies by platform), or null if not loaded

addToClassLoader()

Platform-specific method to add Stage 2 JAR to the appropriate class loader.
protected abstract ClassLoader addToClassLoader(URL stage2Url) throws Exception
stage2Url
URL
required
URL to the Stage 2 JAR file
ClassLoader
ClassLoader
The class loader that now contains Stage 2 classes
Platform Implementations:
@Override
protected ClassLoader addToClassLoader(URL stage2Url) throws Exception {
    Launch.classLoader.addURL(stage2Url);
    return Launch.classLoader;
}

Configuration System

Configuration Properties

essential-loader-stage2.properties (Embedded)

Embedded in container JARs to specify pinned versions.
# Pinned Stage 2 version (optional)
pinnedFile=/path/to/stage2.jar
pinnedFileMd5=abc123...
pinnedFileVersion=1.2.3

# Default branch (optional)
branch=stable
pinnedFile
String
Path to pinned Stage 2 JAR (resource path starting with / or URL)
pinnedFileMd5
String
MD5 checksum of pinned JAR for validation
pinnedFileVersion
String
Version string of pinned JAR for comparison
branch
String
default:"stable"
Default update branch (e.g., “stable”, “beta”)

stage2..properties (User Config)

User-modifiable configuration in the data directory.
# Auto-update mode
autoUpdate=true

# Update branch override
branch=beta

# Advanced: Manual update control
overidePinnedVersion=1.3.0
pendingUpdateVersion=1.3.0
pendingUpdateResolution=true
autoUpdate
String
default:"true"
Auto-update mode:
  • true: Automatic updates (default)
  • with-prompt: Manual updates with user consent
  • false: No automatic updates
branch
String
User’s preferred update branch
overridePinnedVersion
String
Version override for pinned versions (manual update mode)
pendingUpdateVersion
String
Version awaiting user approval (manual update mode)
pendingUpdateResolution
String
User’s decision on pending update: true, false, or unset

Environment Variables

ESSENTIAL_DOWNLOAD_URL
String
default:"https://api.essential.gg/mods"
Base URL for Essential API endpoints
ESSENTIAL_STAGE2_BRANCH
String
Default update branch (overrides embedded config)

System Properties

essential.download.url
String
Base URL for Essential API (overrides environment variable)
essential.stage2.branch
String
Update branch (overrides all other sources)
essential.autoUpdate
String
Auto-update mode (overrides file configuration)
essential.loader.relaunched
String
Set to true when game has been relaunched (internal)

Update System

Auto-Update Modes

Full

Default ModeAutomatically checks for and installs updates without user interaction.

Manual

With PromptChecks for updates and prompts user before installation. Used when pinned versions are present.

Off

DisabledNo network communication beyond initial download.

Update Flow

API Endpoints

Stage 1 communicates with Essential’s API for version metadata and downloads.
/v1/essential:loader-stage2/versions/{branch}/platforms/{gameVersion}
Fetch latest Stage 2 version metadataResponse:
{
  "version": "1.2.3",
  "checksum": "abc123def456..."
}
/v1/essential:loader-stage2/versions/{version}/platforms/{gameVersion}/download
Fetch download URL for specific versionResponse:
{
  "url": "https://cdn.essential.gg/..."
}
/v1/essential:loader-stage2/versions/{version}/changelog
Fetch changelog for update promptResponse:
{
  "summary": "New features and bug fixes..."
}

Version Comparison

VersionComparison Utility

Compares semantic versions for update decisions.
public static int compareVersions(String v1, String v2)
v1
String
required
First version string (e.g., “1.2.3”)
v2
String
required
Second version string (e.g., “1.2.4”)
result
int
  • Negative if v1 < v2
  • Zero if v1 = v2
  • Positive if v1 > v2
Example:
compareVersions("1.2.3", "1.2.4"); // Returns -1 (1.2.3 < 1.2.4)
compareVersions("1.3.0", "1.2.9"); // Returns 1 (1.3.0 > 1.2.9)
compareVersions("2.0.0", "2.0.0"); // Returns 0 (equal)

Update Prompt UI

ForkedUpdatePromptUI

Displays update prompt in a separate JVM process to avoid class loading conflicts.
public class ForkedUpdatePromptUI {
    public ForkedUpdatePromptUI(String title, String description)
    public void show()
    public Boolean waitForClose()
}
Features:
  • Runs in isolated JVM to avoid Swing/AWT conflicts
  • Shows changelog and version information
  • Returns true (accept), false (decline), or null (closed)
Example:
ForkedUpdatePromptUI ui = new ForkedUpdatePromptUI(
    "Essential Loader Update!",
    "New version includes..."
);
ui.show();
Boolean result = ui.waitForClose();
if (result == Boolean.TRUE) {
    // User accepted update
}

Pinned Versions

Use Case

Mods can pin specific Stage 2 versions to ensure compatibility.
# In essential-loader-stage2.properties
pinnedFile=/stage2-essential-1.2.3.jar
pinnedFileMd5=abc123...
pinnedFileVersion=1.2.3

Behavior

  1. Pinned version takes precedence over existing local versions
  2. Auto-update mode changes to Manual when pinned version detected
  3. User can override pinned version with overridePinnedVersion config
  4. Downgrade support by shipping older container JAR with lower pinned version

Error Handling

Common Scenarios

Error: “Unable to download Essential, please check your internet connection”Causes:
  • Network connectivity issues
  • API endpoint unavailable
  • Firewall blocking requests
Behavior: Stage 1 continues with existing local version if available
Error: “Downloaded Essential file checksum did not match”Causes:
  • Corrupted download
  • Network proxy interference
  • CDN cache inconsistency
Behavior: Downloaded file is deleted, existing version used
Warning: “Essential does not support the following game version”Causes:
  • Minecraft version too new or too old
  • API returns null for version
Behavior: Stage 1 does not load Stage 2

Platform Implementations

LaunchWrapper

Class: gg.essential.loader.stage1.EssentialSetupTweaker
public class EssentialSetupTweaker extends EssentialLoaderBase 
    implements ITweaker

Fabric

Class: gg.essential.loader.stage1.EssentialSetupPreLaunch
public class EssentialSetupPreLaunch extends EssentialLoaderBase 
    implements PreLaunchEntrypoint

ModLauncher

Class: gg.essential.loader.stage1.EssentialTransformationService
public class EssentialTransformationService 
    extends EssentialTransformationServiceBase 
    implements ITransformationService

Integration Testing

Test Properties

# Disable update prompts in tests
essential.integration_testing=true

# Auto-answer update prompts
essential.stage1.fallback-prompt-auto-answer=true

See Also

Build docs developers (and LLMs) love