SDK
Porting Guide from NeoForge to ECHO Native
This guide is for moving a NeoForge-style addon toward the ECHO Native 1.0.0-RC1 workflow. Native-first addons compile against the public SDK, package as .echo-addon, and load in release mod
Porting Guide from NeoForge to ECHO Native
This guide is for moving a NeoForge-style addon toward the ECHO Native 1.0.0-RC1 workflow. Native-first addons compile against the public SDK, package as .echo-addon, and load in release mode without direct NeoForge, Forge, Fabric, or loader-internal imports.
Porting Checklist
1. Project Setup
- Apply the ECHO SDK Gradle plugin from the RC channel.
- Compile against the public SDK artifacts:
echo-native-contracts,echoaddonapi,echoadaptercore, andecho-native-testkit. - Keep NeoForge dependencies in a bridge/compat source set or separate bridge template, not in the Native-first entrypoint.
- Run
./gradlew clean check packageEchoNativeAddonbefore treating the addon as release-mode ready.
2. Descriptor
Create META-INF/echo.mod.json with the Native descriptor schema:
{
"schema": "echo.mod.v1",
"id": "exampleaddon",
"version": "1.0.0-RC1",
"entrypoint": "com.example.ExampleAddon",
"side": "common",
"access": {
"nativeClasspath": ["addon.jar"]
}
}
Release mode requires the packaged access.nativeClasspath entry. Gradle or IDE classpath inference is a development convenience only and is rejected for player-facing releases.
3. Entry Point Migration
Native-first code implements EchoNativeModuleEntrypoint:
import dev.echo.nativeplatform.contracts.EchoNativeModuleEntrypoint;
import dev.echo.nativeplatform.contracts.EchoNativeModuleLoadContext;
import dev.echo.nativeplatform.contracts.EchoNativeRegistryService;
import dev.echo.nativeplatform.contracts.EchoNativeRuntimeSide;
import dev.echo.nativeplatform.contracts.EchoNativeServiceMutation;
public final class ExampleAddon implements EchoNativeModuleEntrypoint {
@Override
public void registerServices(EchoNativeModuleLoadContext context) {
EchoNativeServiceMutation mutation = EchoNativeServiceMutation.of(
"exampleaddon",
"registry",
"declare_content",
"exampleaddon:copper_wrench",
EchoNativeRuntimeSide.COMMON
);
context.serviceRegistry()
.service("echo.native.registry", EchoNativeRegistryService.class)
.map(registry -> registry.register(mutation))
.ifPresent(context::recordMutation);
}
}
Do not implement or document EchoNativeAddon or EchoNativeAddonRuntime; they are not the RC1 public entrypoint model. Keep @Mod classes only in explicit NeoForge bridge projects.
4. Mutation Proof
A module is MUTATED only when a typed host service returns an EchoNativeMutationReceipt with status MUTATED. Descriptor metadata, diagnostic maps, lifecycle history, self-minted receipts, and legacy activateNative(Map) claims are not mutation proof.
5. Events, Registry, Networking, and Config
Use typed ECHO host services or SDK contracts for Native-first functionality:
- Registry/content:
EchoNativeRegistryServiceand typed registry receipts. - Events: Native event service contracts when available.
- Networking: Native packet/channel contracts when available.
- Config: SDK config contracts or datapack-friendly data, with NeoForge config specs kept in the bridge lane.
If a feature still requires NeoForge APIs, keep that work in a NEOFORGE_BRIDGE compatibility project and label it as bridge-only.
6. Testing
Add echo-native-testkit smoke tests and assert typed mutation receipts:
EchoNativeSdkTestkit.loadReleaseMode(addonPath)
.requireLoaded("exampleaddon")
.requireOnlyTypedReceipts("exampleaddon");
The external author workflow is:
./gradlew clean check packageEchoNativeAddon
Then load the produced .echo-addon through ECHO Native release mode.
Common Pitfalls
- Direct
ModList, Forge, Fabric, or NeoForge imports in Native-first code. - Using descriptor claims or lifecycle callbacks as mutation proof.
- Shipping a dev jar/classes directory instead of a
.echo-addon. - Missing
sideor loading client-only code on the server. - Marking bridge/compat templates as Native-first release evidence.
See Native Mod Author Guide, Native API Reference, and Native Example Addon Walkthrough for the canonical RC1 workflow.