ScarNet
Multiplayer automation and debugger.
Make any actor multiplayer-ready in one click, replicate variables and fire network events without touching an RPC, and find out why your netcode is broken with the in-game ScarNet Debugger. Blueprint-first, C++ compatible, and it works with Dedicated, Listen, LAN, Steam and EOS.
- Engine support
- Unreal Engine 5.2 to 5.8
- Version
- 1.3.1
- Backends
- Dedicated, Listen, LAN, Steam, EOS
What you get
- Make any actor multiplayer-ready with one component
- Replication profiles for Character, Weapon, Projectile, Pickup and more
- Replicate variables and fire network events without writing RPCs
- In-game debugger with an Issues tab that names the problem and the fix
- Blueprint-first, C++ compatible
What ScarNet does
Multiplayer in Unreal is 10% gameplay and 90% "why isn't this replicating." ScarNet does two things about that.
- Automates the boring, error-prone setup. Add one component, pick a profile, and your actor is replicated with sane update rates, priority, dormancy, relevancy and ownership. Replicate variables and fire network events straight from Blueprint.
- Tells you what is broken and how to fix it. Press F9 in game for a live debugger that inspects every networked actor and, most importantly, an Issues tab that names the problem in plain English with a suggested fix.
It does not replace Unreal networking. It sits on top of the engine replication layer, so it works with any Online Subsystem and any server type with no backend-specific code.
The golden rule of this plugin: when something does not sync, do not guess. Press F9, read the top red line on the Issues tab, and do what it says. That loop is the whole point of ScarNet.
Install and enable
- 01Copy the ScarNet folder into your project Plugins/ directory.
- 02Open the project. If prompted to rebuild modules, click Yes.
- 03Confirm it is on under Edit > Plugins > Networking > ScarNet. It is enabled by default.
- 04Tune anything you like under Project Settings > Plugins > ScarNet.
C++ is not required. Everything in this guide is done with Blueprint nodes and the Details panel. The plugin is fully C++ compatible too, but you never have to open a .cpp file.
Quick start in 4 steps
| # | Do this | Result |
|---|---|---|
| 1 | Open your actor Blueprint. Add Component ScarNet Ready. | The actor can now be made multiplayer-ready. |
| 2 | In the component Details, pick a Replication Profile (Character, Weapon, Projectile, Pickup and so on). | On Begin Play the actor is replicated with tuned settings for that kind of actor. |
| 3 | Use the ScarNet nodes: Register / Set Replicated Variable, Broadcast / Send To Server / Send To Owner, MP Spawn / Interact. | Variables sync and events fire on the right machines automatically. |
| 4 | Play with 2 or more players and press F9. | The ScarNet Debugger opens and shows any problems, with fixes. |
Call setup on the server, at runtime. Add the component, apply profiles and register variables from Begin Play (or later) on the server, not in a Construction Script and not on a client. Components added on a client do not replicate. ScarNet warns you in the log if you get this wrong.
Replication profiles
A profile is a curated bundle of networking settings for a kind of actor. Pick the closest one and ScarNet applies proven defaults. Choose Custom to set them by hand. All values are editable per project in Project Settings > ScarNet.
| Profile | Use it for | What it tunes |
|---|---|---|
| Character | Player pawns | High update rate, replicated movement, always awake |
| Projectile | Bullets, rockets, grenades | High rate plus replicated movement while alive |
| Weapon | Equipped weapons | Medium rate, relevant through the owner |
| Interactable | Doors, buttons, levers, switches | Dormant until used, then flushed |
| Pickup | World pickups | Low rate, dormant until grabbed |
| Inventory | Private per-player state | Only relevant to the owning player |
| AI | AI pawns | Medium rate, replicated movement |
| Custom | Anything else | You set every value on the component |
Movement replication is on by default. The ScarNet Ready component forces Replicate Movement on, and fixes a Static root that would silently block it. Moving actors just work. Turn it off per component only for truly static objects.
The Blueprint nodes
All nodes handle authority checks and server routing for you. They work on any machine and any net mode. Call them where it reads naturally and ScarNet does the right thing.
Setup
| Node | What it does |
|---|---|
| Make Multiplayer Ready | Adds a ScarNet Ready component (if missing) and applies a profile. Great for actors you spawn at runtime. |
Replicated variables
| Node | What it does |
|---|---|
| Register Replicated Variable | Creates a synced variable with a default value. Replicates to everyone, including late joiners. |
| Set Replicated Variable | Writes it. Automatically routed to the server when called on a client. Fires the change event. |
| Get Replicated Variable | Reads the local copy anywhere. |
| Unregister Replicated Variable | Removes it everywhere (server only). |
To react to a change, select the ScarNet Ready component and bind On Replicated Variable Changed. It fires on the server and every client. Use the As Bool / As Int / As Float / As Vector nodes to unpack the value.
Network events
| Node | Runs on |
|---|---|
| Send To Server | The server only (a client asks the server to do something). |
| Broadcast Event | The server and every client (explosions, round start, global FX). |
| Send To Owner | The client that owns the target actor (ammo, private messages). |
| Network Event | Any of the above. You choose the scope on a dropdown, including Run Locally. |
Receive events by binding On Network Event on the target ScarNet Ready component, then branch on the event name.
Smart actors and interaction
| Node | What it does |
|---|---|
| MP Spawn Actor | Spawns on the server from anywhere and replicates. On the server it returns the actor; on a client it returns None and the actor arrives via replication a moment later. |
| MP Destroy Actor | Destroys on the server from anywhere (client requests obey the security settings). |
| MP Interact | Interacts with an actor that has a ScarNet Interactable component. Works from any machine and is validated (distance-checked) on the server. |
MP Spawn returns None on clients, and that is correct. The actor is created on the server and replicated down, so it does not exist on the calling client yet. Do not try to use the return value on a client. React to the actor in its own Begin Play instead.
Auto variables and the "my RepNotify never fires" trap
ScarNet only sends a variable when its value actually changes, which saves bandwidth. That also means if you set a variable to the value it already has, nothing replicates and the change event does not fire. This is the single most common multiplayer head-scratcher, so ScarNet makes it visible.
- The Variables tab shows a No-Change Sets counter climbing.
- The Issues tab warns: "Variable X was set N times to the value it already had, so it never replicated and its change event never fired."
- If you genuinely need the callback to fire anyway, tick Force Notify on Set Replicated Variable.
If a client callback "never runs", 99% of the time the value simply is not changing on the server. Check the No-Change Sets column first before suspecting replication itself.
The ScarNet Debugger (F9)
Press F9 in any play session, or run the ScarNet.Debugger console command. It opens straight to a status banner and the Issues tab: the answer, not a wall of data. The panel is draggable (grab the header) and resizable (orange corner).
Read the banner first
| Banner colour | Means | Do |
|---|---|---|
| Amber | You are in Standalone, so no networking is running. | Set Number of Players to 2 or more (or Net Mode: Play As Client) in the Play dropdown. |
| Red | Problems were found. | Open the Issues tab (it is already in front) and read the top line. |
| Green | No replication problems detected. | Carry on. Move and interact; issues appear the moment they happen. |
The five tabs
| Tab | Shows |
|---|---|
| Issues | Auto-detected problems, most severe first, each with a suggested fix. Start here. |
| Actors | Per actor: Replicates, Movement, Activity (really moving?), Last Sent, owner, authority, dormancy, update rate, relevancy. |
| Variables | Every registered variable: value, updates, and No-Change Sets. |
| Events | Server / Client / Multicast RPC history with Sent, Received, Failed and Dropped. |
| Health | Ping, packet loss, bandwidth, connections, active vs dormant actors, saturation. |
Debug from any client. Most problems are only visible on the server. When you open the debugger on a client, ScarNet streams the server findings down to you, so the Issues, Events and Variables tabs match the server. Text is clipped to fit, so hover any cell to read the full line.
Bottom bar: Ownership Overlay draws colour-coded boxes in the world (green = server, blue = client, yellow = shared, red = problem). Save Report writes a full diagnostics text file to Saved/ScarNet/ and the on-screen message shows the exact path. Clear Events wipes the RPC history.
How ScarNet decides
A debugger that cries wolf is worse than none. ScarNet only reports what it can back up, and the severity tells you how serious it is.
| Severity | Means | Examples |
|---|---|---|
| ERROR | Broken right now. Players see it. | An actor frozen on clients. A Server RPC Unreal threw away. |
| WARNING | Works for now, but costs you or breaks under load. | Reliable RPC spam. A hitch while an asset loads mid-game. Clients drifting out of sync. |
| INFO | A tip to save bandwidth, or something ScarNet is still confirming. | Idle actors that could sleep. A moving actor no client has confirmed yet. |
Moving actors: the clients get a vote
When the server moves an actor that is not sending its movement, with Replicate Movement off or while Dormant, that is only a bug if clients do not see it move. Many games move hazards, platforms and saw blades on every machine from a small replicated state, and that is correct. So ScarNet asks the connected clients to compare what they see with the server position, allows for the time the check takes to arrive and for each client ping, and only reports what a client confirms twice in a row.
| Clients see the actor | ScarNet shows |
|---|---|
| Moving, in the same place as the server | Nothing. Your setup is correct. |
| Standing still, or stuck where it was before a teleport | ERROR Frozen on clients, with the reason: Replicate Movement off, or Dormant. |
| Moving, but somewhere else | WARNING Out of sync, with the distance in meters, after allowing for ping. |
| No client has answered yet | INFO Moved on the server, not yet confirmed by a client. Many of one class become a single line. |
Example: a door uses Dormant All and opens without Flush Net Dormancy. The server sees it swing open, both clients report it never moved, and the Issues tab shows ERROR Door_3: Frozen on clients. Add Flush Net Dormancy before moving it and the line disappears.
Variables: the clients compare them too
Every few seconds the server sends a short fingerprint of a few actor variables to each client, and each client compares it with its own copy. The same rule as movement applies: a difference only counts when it holds twice in a row while neither side is changing the value, so a value that is still on its way is never reported.
| What a client has | ScarNet shows |
|---|---|
| A different value in a variable that is not replicated, which the server changed | INFO Changes on the server but never reaches clients. Fine if only the server uses it. |
| A different value in a replicated variable | WARNING A client changed it locally. Only the server should set it. |
| The old value, on an actor that is Dormant | WARNING Changed while Dormant. Call Flush Net Dormancy first. |
| No value, because of a Replication Condition such as Owner Only | INFO Only reaches some players. Expected if you meant it. |
| A different Owner | WARNING Set Owner was called on a client, which the server ignores. |
| A different attach parent | WARNING Attached or detached on one side only. |
Simple variables are compared, meaning booleans, numbers, enums, names, text, vectors, rotators and colours, up to 24 per class and 16 actors per check, so the cost stays tiny. Rotators are compared the way Unreal sends them, at 16 bits per axis, so rounding never looks like a difference.
RPCs that run on the wrong machine
Some RPC mistakes make Unreal run the call on the wrong machine with no warning at all. ScarNet watches C++ RPC calls as they run, in Development and Debug builds, and reports them as errors.
- Multicast called on a client: it runs only on that client, and other players never see it.
- Run on Server that only ran on the client: called on an actor that exists only on that client and has no owner, so the server never hears about it.
- Run on owning Client on an actor nobody owns: it runs on the server instead of on a player.
Blueprint graphs call RPC events inside the Blueprint VM, where this hook cannot see them. The Project Check covers Blueprints by reading the graphs instead.
Check your project without playing
Tools, then ScarNet, then Check Project for Network Mistakes reads every Blueprint in /Game and the C++ bodies of your game RPC functions, and lists mistakes in the ScarNet message log. Click a Blueprint line to jump to the node. Nothing has to run, so it also catches code your test session never reached.
Example: an input event calls the Multicast Multi_Boom directly. On the host it works; on every client only that player sees the explosion. The check reports it and names the fix: call a Run on Server event from the input, and call the Multicast inside it.
It follows each chain of nodes from where it starts, meaning input events, widgets, the HUD, both pins of Switch Has Authority, replicated events, Event Possessed and Event Tick, into your own functions and collapsed graphs.
| The graph or C++ RPC body does | Why it breaks |
|---|---|
| Calls a Multicast on a client | It only runs on that client. |
| Sets a replicated variable on a client, and nothing there tells the server | The change stays on that client. |
| Spawns a replicated actor on a client | Other players never see it. |
| Spawns a replicated actor inside a Multicast | The server copy reaches everyone and each client spawns its own: duplicates. |
| Calls Destroy Actor on a client | A client cannot destroy a replicated actor. Nothing happens. |
| Calls a Reliable RPC from Event Tick | Sent every frame, it can overflow and disconnect the player. |
| Uses Get Game Mode on a client | The GameMode exists only on the server, so this is None. |
| Uses Get Player Controller in server code | Returns the host or first player, not the one who called. |
| Creates a widget in server code | Widgets exist only on clients. |
| Plays a sound or effect only inside a Run on Server event | Only the server sees or hears it. Shown as INFO. |
| Has replicated variables or events in a widget, the HUD or the GameMode | They never cross the network. |
| Has replicated variables on an actor with Replicates off | They never reach clients. |
Client prediction is not reported, because changing something locally and telling the server in the same chain is a normal technique. A base class that leaves Replicates off is not reported when a child class turns it on, and a component is judged where an actor adds it.
Console: ScarNet.CheckProject
Build machine: UnrealEditor-Cmd.exe MyGame.uproject -run=ScarNetCheckProject
(add -Path=/Game/Folder to check one folder of Blueprints)
Report: Saved/ScarNet/NetworkCheck.txt (exit code 1 when errors are found)How much it catches, and what it cannot
We collected 52 replication mistakes that Unreal developers commonly hit and checked each one against ScarNet, separately for C++ and Blueprint.
| Mistakes that apply | Caught | Of those, planted and tested | |
|---|---|---|---|
| C++ | 51 | 41 (80%) | 35 |
| Blueprint | 49 | 41 (84%) | 18 |
What it cannot catch, so you know when to look elsewhere and never trust a green banner too far:
- Intent. An Unreliable RPC used for an event that must arrive, a Multicast used for state that late joiners need, Has Authority where Is Locally Controlled was meant, a C++ OnRep expected to run on the server. The code is valid; only you know what it was meant to do.
- Character movement corrections, meaning rubber-banding when speed or movement mode is changed on one side only. Unreal does not expose a count of them.
- State lost across seamless travel.
- RPC calls made from Blueprint graphs at run time, which are invisible to the runtime hook. The Project Check reads the graphs instead, which covers the common cases.
- Movement checks need a connected client. A listen server host playing alone can only show "not yet confirmed".
- Very fast movers on a laggy connection, where the ping allowance can hide a small drift. The distance shown is always a lower bound.
- Shipping builds, which have no per-function RPC list and no RPC hooks, because the engine hooks they use do not exist there. Test in Development builds.
- Gameplay logic. A wrong damage formula is not a replication bug.
Troubleshooting: symptom to fix
The Issues tab detects all of these automatically. This table is the same knowledge for offline reference.
| Symptom | Likely cause | Fix |
|---|---|---|
| Actor says Replicates: Yes but is frozen on clients | Movement replication is off (Movement: No). | Enable Replicate Movement. ScarNet forces it on by default. |
| Nothing replicates at all; only 1 window | You are in Standalone / 1 player. | Play with 2 or more players, or Net Mode: Play As Client. |
| Client RepNotify / change event never fires | The value was set to what it already was. | Change the value, or tick Force Notify. Check No-Change Sets. |
| Spawned actor only appears in one window | It was spawned on a client (client authority). | Use MP Spawn Actor so it spawns on the server. |
| Send To Owner does nothing or logs a failure | The actor has no owning connection. | Set the actor Owner to a player controller or pawn. |
| Actor exists but its state never updates | Runtime-spawned with dormancy Initial, or moving while Dormant All. | Use an Awake profile, or Flush Net Dormancy on change. |
| Interactable state does not sync to others | Only Relevant To Owner is on. | Turn it off. The Interactable profile already sets relevancy. |
| Values set on a client take no effect | Called Set on a client with client writes disabled. | Server-authoritative by design. Enable client writes in Settings if intended. |
Testing multiplayer on one PC
- Quick (PIE): in the Play dropdown set Number of Players to 2 and Net Mode to Play As Client. You get two windows with a hidden dedicated server underneath.
- Realistic: open Tools > ScarNet > ScarNet Debugger and use Dedicated Server Testing. One click launches a dedicated server (or listen host) plus N client processes of your current map, each with its own log in Saved/Logs.
Put movement behind Switch Has Authority. When you test replication, only the server should drive the change (move the actor, set the variable). If both machines do it locally, both windows look right and you have proven nothing.
Settings worth knowing
Project Settings > Plugins > ScarNet:
- Debugger: hotkey (F9 by default), refresh interval, overlay interval, max rows.
- Security: allow or deny client spawn, destroy and variable-write requests. All validated server-side.
- Profiles: every value each built-in profile applies, editable per project.
- Server Testing: default client count, dedicated vs listen, extra launch parameters.
Quick FAQ
| Question | Answer |
|---|---|
| Does it work with Steam / EOS? | Yes, any Online Subsystem. ScarNet has no backend-specific code. |
| Does it run in packaged / shipping builds? | Yes. The debugger uses runtime Slate, so F9 works in packaged games. Not on dedicated servers, where you use ScarNet.Report instead. |
| Is it heavy? | No. Nothing ticks while idle; the debugger costs nothing when closed and streams to clients only while open. |
| Can I still write my own replication? | Absolutely. ScarNet sits on top of the Unreal system, so mix and match freely. |
Stuck on something?
We answer every serious message ourselves. Discord is the fastest way to get an answer from the person who built the plugin.