Horizon Mod Translator

Horizon ModTranslator

It takes a NeoForge mod's compiled Java and rebuilds it as native Rust inside Horizon, the Minecraft client written in Rust. Nothing runs on a JVM while you play. Create is the first big mod through it, and its gears already turn in game.

  • Create 6.0.10 translated
  • 1.55M lines of generated Rust
  • 0 JVMs at play time

Builds aren't packaged yet. Follow the roadmap.

Pondering: how a mod becomes native

This is Create, a NeoForge mod: 2,692 Java classes packed in one jar.

1 / 6

A drawing of the pipeline. The footage below is the real game.

Running in Horizon today

The video was recorded on 2 November 2026, the stills on 3 November, in Horizon builds with Create compiled in. What turns, fills the tabs and gets placed here is Create's own code, translated.

A creative motor drives three shafts into a cogwheel. A second cogwheel meshes with it and drives three more shafts. Behind them, Create's casings and metal blocks.
Motor side, read in game
16 RPM
Past the mesh
−16 RPM
Translate Create's jar
33 s
Compile the translated engine
≈ 8 min
Tick 4 kinetic block entities 40 times
7.8 ms
Draw Create's turning parts
≈ 130 µs a frame
Blocks and items from Create's code
572
Items Create's code puts in its two tabs
201 + 308

Speeds are read in game with /data get block. Timings come from the translator's harness and game builds on an M4 Pro Mac (14 cores).

Horizon's creative screen on its second page with the Create tab open: flour, dough, rose quartz, sheets, a propeller, a whisk, goggles and more Create items, each with its icon
Page two of the creative screen holds Create's tabs, Create and Create's Building Blocks. Create's own displayItems code fills them, and every item draws its icon.
A row of Create's framed glass, tiled glass and iron windows in front of a wall of coloured wool, which shows through the clear parts. In front lies a cogwheel placed by hand.
Create's framed glass, tiled glass and iron windows in front of a wool wall: the clear parts show what's behind them. In front, a cogwheel placed from the hotbar, laid flat by Create's own placement code.

How it works

Mods ship as Java bytecode. Horizon has no Java in it, so the translator turns that bytecode into Rust ahead of time, and the Rust compiles into the game like any other part of it.

  • The translator reads every class in the jar, plus the libraries it bundles (Create carries Registrate, Flywheel and Ponder). Each method becomes a Rust function: one match arm per bytecode instruction, with lambdas, exceptions and records handled. Differential tests run the same code on the JVM and in Rust, and all 78 results match.

  • The runtime gives that code what Java gave it: objects, strings, static fields, a garbage collector, and method dispatch by class id.

  • horizon-compat answers the calls a mod makes into Minecraft, NeoForge and Java's libraries, in native Rust wired to Horizon's own hooks: blocks, block entities, rendering, events. A call that isn't mapped yet is logged by the game, and the most-called gaps get mapped first.

One method, three ways

// Create's DirectionalKineticBlock: which way a placed part faces
public BlockState getStateForPlacement(BlockPlaceContext context) {
    Direction preferred = getPreferredFacing(context);
    if (preferred == null
            || (context.getPlayer() != null && context.getPlayer().isShiftKeyDown())) {
        Direction nearestLookingDirection = context.getNearestLookingDirection();
        return defaultBlockState().setValue(FACING,
                context.getPlayer() != null && context.getPlayer().isShiftKeyDown()
                        ? nearestLookingDirection
                        : nearestLookingDirection.getOpposite());
    }
    return defaultBlockState().setValue(FACING, preferred.getOpposite());
}
The rule that picks the way a placed part faces. The translator never sees the Java: it reads the bytecode and writes the Rust, one match arm per instruction. The Rust isn't pretty, but it's native and it compiles with the game.

Why not run Java next to the game?

Horizon exists to be fast. A JVM shipped inside it to run mods would bring back the cost Horizon was written to remove. Translated code compiles into the same native binary as the game and calls it directly.

Why Create first

Create is a hard case: kinetic networks, custom renderers, moving contraptions, trains, and three bundled libraries. Most mods use a smaller part of the same API. Nothing in the translator is written for Create in particular. The same steps take any NeoForge jar, and Macaw's Fences already went through them.

Modpacks

Drop a pack in and every jar in it is translated today. Next, a pack becomes one engine, so mods that call each other do it directly and the game is built once.

Where Create stands

What has been seen working, how it was checked, and what is still open. "In harness" means a test program that runs the translated engine without the game around it.

PartStateHow we know
Bytecode to RustWorking in gameAll 78 differential results match the JVM, and Create's translated code runs in game
Create's registrationWorking in game465 blocks and 107 items from Create's own code, none refused
Kinetic networkWorking in gameMotor and shafts at 16 RPM; the meshed cogwheel at −16 RPM
Turning parts drawnWorking in gameCreate's own block entity renderers turn the shafts and gears
Block entitiesWorking in gameThey tick, save to the world and sync to the client
Block shapesWorking in harnessOutlines for every state, from Create's own getShape
Placing blocks by handWorking in gameCreate's getStateForPlacement decides: a cogwheel placed on the floor lies flat, a shaft follows the clicked face, and nothing placed in air comes out waterlogged
Right-click on blocksWorking in gameChecked with a test mod's switch block
Fluids and waterloggingWorking in harnessWater, lava and Create's honey, chocolate, tea and potion answer from Create's own fluid code; the startup crash on a missing fluid is gone
Creative tabsWorking in gameBoth of Create's tabs, filled by its own displayItems code with Create's own exclusions: 201 and 308 items
Item iconsWorking in gameEvery Create item draws its icon; the translator writes the item definitions newer Minecraft needs, 751 for Create
Cutout glass and windowsWorking in gameGlass and iron windows show what's behind them; Horizon reads cutout from the textures, so Create's render-layer calls aren't needed
Wooden windowsIn progressThey all registered under one name; the fix is in, and lands with the next game build
Fluid pipes and tanksOpenFluid stacks, tanks and pipe connections come after machines
Connected glass texturesOpenCreate joins neighbouring glass with its own texture code, not translated yet
Machines: press, mixer, millstone, fans, beltsOpenNeed Create's recipe types and item handling
Recipes, loot tables, tagsOpenNot loaded yet; Create's recipe types will be read through its own codecs
Saving Create's world dataOpenNot written to the save yet
Menus and Ponder screensOpenNot started
Contraptions and trainsOpenNot started
A whole modpack in one buildOpenEach jar translates today; one combined engine is next

Roadmap

Seven phases from the first parsed class to any modpack, on the same timeline as the scene above. Pick a phase to see what's in it.

3. Building by hand Now

Everything a player needs to build with Create without commands.

  • Placing blocks with Create's own placement rules
  • Fluids and waterlogging (works in harness)
  • Create's creative tabs, filled by its own code
  • Item icons and cutout glass
  • The wrench
  • Outlines and collisions checked by hand in game

Talk to me

Questions, testing, a mod you'd like to see translated, or help with the API mapping: message me on Discord. Try a build opens once builds are packaged.

idunnowts on Discord