Unreal routers (Fusion's Unreal kit)
The Unreal kit is a UE4SS mod (a Rust DLL, a little C++, Lua) that Fusion's one-click setup puts in the game. It works on Unreal 4.12 to 5.x, Direct3D 11 and 12. From Unreal's conventions it already does, with no router code:
- the player is player controller 0's pawn; it opens
bind.mapfrom the main menu and waits for the world (and World Partition) to load; picks Fusion's origin on open ground; - draws the world from Fusion's camera with depth (scene captures), and hides the game's own view;
- traces collision around Fusion's camera (if a block gives
collision); - lists characters near Fusion's camera (if a block gives
entities), spawns, removes, sets health, moves and stops NPCs; teleports the player; - plays as the game's own character (a
characterblock that needsinput): Fusion's keys and mouse go through Unreal's own movement, and Fusion's camera follows its eyes; - keeps the game running when it isn't the window in front.
Don't redo any of that in Lua. A router lists only what's particular to the game.
Data: [block.bind] on the world block¶
[block.bind]
map = "/Game/Maps/Town" # opened from the main menu; the name alone also matches
player = "BP_Hero_C" # the game is in its world once the player is one
player_follows_camera = true # World Partition games load around the player
Data: NPCs, on a block that gives entities¶
One rule per kind; other characters are listed as "character".
[[block.bind.entity]]
class = "BP_Zombie_C" # exact class; or is_a = "/Script/Game.BaseEnemy" for subclasses
kind = "zombie"
name = "Zombie"
health = "Health.Health" # field paths from the actor
max_health = "Health.MaxHealth"
team = 2
spawn = "/Game/Zombies/BP_Zombie" # what Fusion's Spawn makes for this kind
Find names by asking the running game (Fusion closed): fusion-cli game find zombie --game-id <id> gives classes and objects; fusion-cli game inspect <object> --game-id <id> lists its fields. An Object field's value is another object: inspect it to build a path such as Health.Health. Router Studio does the same with clicks (F4 in Fusion).
Playing as the game's character¶
[[block]]
id = "mygame.player"
name = "My Game's Hero"
kind = "character"
needs = ["input"]
gives = ["pose"]
No bind data needed: the kit drives player controller 0's pawn.
Lua: router.lua, only when data isn't enough¶
It runs in a sandbox (Router, Game, Lua 5.4's safe libraries; no files, OS or require):
Router.block "mygame.world" {
enter = function() -- twice a second until in the world
local menu = Game.widget("WBP_TitleScreen_C")
if menu then Game.call(menu, "OnStartClicked") end
end,
}
- World blocks:
enter,ready,anchor,hidden. Entity blocks:describe(object, class, is_character)→{ kind, name, health, max_health, team }/false/nil, andspawn = { kind = function(at, rotation) ... end }. Game.*:find,find_all,object,class,class_name,full_name,is_a,get/set(field paths),call,player,controller,world,map,widget,console,trace,spawn,loaded,time,log.- A wrong field name fails when the script runs, with the line and what's allowed.
router checkchecks everyGame.x/Router.xname before that. fusion-cli router reload routers/<id> [--watch]sends router.toml and router.lua to the running game without restarting it.
Setup (one click for players)¶
router new --kit unreal writes it; the project folder is the one holding Binaries/Win64:
[router.setup]
installed_when = "{game}/MyGame/Binaries/Win64/ue4ss/Mods/FusionKit/dlls/main.dll"
[[router.setup.require]]
name = "UE4SS"
check = "{game}/MyGame/Binaries/Win64/ue4ss/UE4SS.dll"
guide = "Download UE4SS and unzip it into the game's MyGame/Binaries/Win64 folder."
url = "https://github.com/UE4SS-RE/RE-UE4SS/releases"
[[router.setup.step]]
copy = "{tools}/fusion_unreal.dll"
to = "{game}/MyGame/Binaries/Win64/ue4ss/Mods/FusionKit/dlls/main.dll"
[[router.setup.step]]
copy = "{fusion}/kits/unreal/lua"
to = "{game}/MyGame/Binaries/Win64/ue4ss/Mods/FusionKit/Scripts"
(plus copies of {router}/router.toml and {router}/router.lua into Scripts, and add_line = "FusionKit : 1" to mods.txt; see example-unreal.router.toml).
Gotchas¶
- Content in
.pakfiles: read it from the running game. Never unlock encrypted paks. - Unreal before 4.13 can't capture depth: the world is drawn behind Fusion's own objects (conformance says so); everything else works.
- After changing the kit itself, set the router up again (My Games → Set up): an old kit in the game gives confusing failures.
- Example:
example-unreal.router.tomlandexample-unreal.router.lua(a made-up game in the shape of a real router: about 20 lines of data, Lua only for two menus and one NPC rule).