SteonMod
View as Markdown

Making routers: start here

For people who connect a game to Fusion, and for the AI agents they work with. Read this page first; it says which other page you need.

A router connects one game to Fusion. It splits the game into blocks (its world, its characters, its NPCs) that players snap together with blocks of other games, with no code: cards, press Play. One router per game; every fusion with that game reuses it.

Why make a router instead of a two-game mod

Today a fusion is a hand-built mod for one pair of games: copy SkyCraft, rename the host, write the link, the collision, the camera sync, the frame pacing, an installer, and publish a repo. The player then installs a mod loader, a launcher, Java, a modpack, and starts both games in order.

A two-game modA Fusion router
What you writeboth halves: link, collision field, camera sync, compositing, input, pause, installeronly what's particular to your game: which object is the player, which are NPCs, how to get past the menu. Mostly data in router.toml
SizeSkyCraft is about 890 KB of codeVEIN's router is 25 lines of data and 36 lines of Lua; "Minecraft in VEIN" is a 15-line scenario
Which games it fuses withone other gameevery game that has a router, in any number, picked block by block
Minecraft's sideyours to fork and maintaindone: Fusion's Fabric kit is SkyCraft's mod, kept up to date
Players installa loader, a launcher, Java, files in the right folders, both games started in orderFusion, then Play: one-click setup installs the loaders and your router
Game updatesit breaks, and someone rediscovers the gametested_builds disables it cleanly; fusion-cli game diff lists what the update renamed
Testinglook at the screenrouter check and router conform measure it in numbers (picture lag in frames, collision, NPCs, sleep and wake)
The next personstarts again from the sourcestarts from your router (router get), its notes.md and MODLOG.md, and sends you improvements

Your path

Run fusion-cli router recon <the game's folder> first. It reads only file names and says the engine, which path fits, whether there's anti-cheat, and whether the game already has a router.

What you haveWhat you makeRead
An Unreal 4 or 5 gamedata (and maybe a little Lua) on Fusion's Unreal kitagent/unreal.md, router-api.md
A Unity IL2CPP game (GameAssembly.dll in its folder)data (and maybe Lua) on Fusion's Unity kitagent/unity.md, router-api.md
Your own mod already in the game: a BepInEx or MelonLoader plugin (Unity Mono), an SKSE/F4SE/NVSE plugin, a Source server plugin, an injected DLLkeep your mod; replace its link with Fusion's guest SDK (C# FusionGuest.cs, C/C++ fusion_guest.h)agent/sdk.md, porting.md, guest-sdk.md
An open-source game, a rewrite or a recomplink the guest SDK into its source (Rust, Bevy, C, C#)guest-sdk.md
Minecraftnothing: its router is in Fusion; players pick their own modpack on its card
A game with anti-cheatonly if its own launcher has an official anti-cheat-off mode ([router.anticheat]); otherwise it can't come inblock-manifest.md

Already made a passthrough mod (a SkyCraft port, a ReShade bridge)? porting.md maps each part of it to Fusion: most of it is no longer yours to maintain.

Set up

  1. Install Fusion. Its developer tool is fusion-cli.exe in Fusion's bin folder (%LOCALAPPDATA%\Programs\Fusion\versions\<version>\bin; add it to your PATH). fusion-cli where prints every folder you need (docs, the agent pack, the SDK files, routers).
  2. Make a folder for your work, and in it run fusion-cli agent install. Your AI agent then knows Fusion's commands and rules (a Claude Code skill, and a section of AGENTS.md for Codex, Cursor, Copilot and Gemini CLI). Your own text in AGENTS.md stays.
  3. Your routers live in routers/<id>/ in that folder. Fusion's commands read them first, then the routers installed in Fusion.

The loop

  1. Look first. fusion-cli router recon <game folder>. If the game has a router, improve it instead of making a second one: fusion-cli router get <id> --out work/<id>, change it, router check it, then fusion-cli router propose work/<id> --message "what and why" and send the file to its author.
  2. Start. fusion-cli router new <id> --name "<Name>" --kit unreal|unity|sdk (--steam-app N | --exe <path>) writes routers/<id>/: router.toml (the blocks), router.lua (kits), MODLOG.md (what changed and why), notes.md (gotchas for the next person).
  3. Ask the game, don't guess. With the game running and Fusion closed: fusion-cli game find <text> --game-id <id>, game classes, game objects <Class>, game inspect <object>. Or open Fusion, play the router's blocks and press F4 (Router Studio): click "This is the player", "These are NPCs", and save.
  4. Write the data, then Lua only where data can't say it (a menu to click through).
  5. Check. fusion-cli router check routers/<id>: a few lines, each failure with its fix; exit code 0 = pass. --live has the running game try the router.
  6. Measure. fusion-cli router conform routers/<id> --start: Fusion's side, in numbers. It starts the game, checks every port the router promises, the picture's lag behind Fusion's camera, requests it can't do, and sleep and wake. Publishing needs a pass.
  7. Play it. Make a scenario (below) and play it in Fusion. F7 shows collision, F8 entities, F6 cost, F4 Router Studio.
  8. Write it down. A line in MODLOG.md; anything surprising in notes.md (what you saw → why → the fix), with the game build that worked.

Stop after three identical failures: write what you know in MODLOG.md and change approach.

Blocks, and what your router must do for each

Players combine blocks; ports say what flows between them. Fusion wires matching ports by itself.

Block kindWhat it isIt gives / needsWhat your router does
worldthe place everyone stands ingives layer:color+depth, collisionthe game draws its world from Fusion's camera, and sends its ground and walls
charactersomeone the player playsneeds input (and collision if it walks on another World), gives posemoves its character from Fusion's controls; says where its feet and eyes are
npc_groupenemies, animals, vehiclesgives entities, lists actionslists them a few times a second (id, kind, position, health); does remove, set_health, move_to...
items, systemthings to hold; weather, moneygives state, events(v0: few routers have these yet)

One scenario has one World and at most one played Character; any number of the rest. A block that isn't a World plays in Fusion's own playground, so you can test an NPC group without a world.

Everything crosses in Fusion's space: meters, Y up, right-handed, -Z forward. Kits convert from the units your router declares; with the SDK you convert at your game's edge (agent/sdk.md).

A scenario

A scenario is the fusion players press Play on. It names blocks; Fusion does the wiring:

[scenario]
name = "Minecraft in VEIN's World"
description = "Play as the Minecraft player in VEIN Demo's world."

[[block]]
use = "vein.world"

[[block]]
use = "minecraft.player"

Put it in a scenarios/ folder and check it with fusion-cli check-scenario scenarios/<file>.toml. Players make the same thing with cards in Fusion's main menu (Scenario Builder).

Test without the game

  • router check needs no game at all; router conform needs it running.
  • Fusion's test game (fake-guest) and the SDK's example worlds behave like games: try a draft on them first.
  • Record what your game sends once (start Fusion with -- --record=<folder>), then fusion-cli replay <folder>/<router>.fusionrec plays it back with no game running, for testing addons, Devices and Experiences in seconds.

Publish

  1. fusion-cli router conform routers/<id> --start must pass (it writes conformance.toml).
  2. fusion-cli package router routers/<id> --out <id>.fusion checks and signs it. The publish check refuses game files, extracted game data, decompiled code and memory addresses.
  3. Share the .fusion file (players double-click it, or drop it on Fusion), or send it to a content hub.

Trust: a router of data and Lua can come from anyone. A router that carries program files (the DLL of an SDK plugin) is shared only from verified authors. Credit what you build on: contributors, based_on, and keep the licenses of code you reuse (SkyCraft is MIT).

Rules

  • Single-player and offline only. Never touch anti-cheat, online modes or copy protection; the one exception is a game's own official anti-cheat-off mode.
  • Never ship game files, extracted assets, decompiled code or encryption keys. Reading the player's own installed files at runtime for lists and names is fine ([[block.content]]).
  • Never focus a game window or send it input while someone is using the PC. Stop processes by id, never by name.
  • No Nintendo or Take-Two games (Fusion's blocklist).

Where to read more

Page
porting.mdfrom your passthrough mod to a router, part by part
router-api.mdthe kits' data ([block.bind]) and Lua (Router.block, Game.*)
block-manifest.mdevery router.toml field, ports, placeholders, setup recipes
guest-sdk.mdthe guest SDK: Rust, Bevy, C/C++, C#
protocol.mdthe protocol under the SDK and kits, and the questions tools ask a game
packages.md, trust.mdpackages, signing, trust tiers
lua-api.md, devices.mdaddons, Devices and Experiences built on your blocks
agent/the agent pack: SKILL.md and one page per path (fusion-cli where shows it)