


Part of the BreakoutMods Valheim modding suite.
BreakoutNet is a small client/server helper library for Valheim mods. It wraps the repetitive BepInEx and ZRoutedRpc glue that most server-aware mods need: side detection, peer lookup, typed RPC messages, server-authoritative settings sync, proximity broadcasts, logging, and basic abuse protection.
GitHub: BreakoutMods/BreakoutNet
Community: BreakoutMods Discord
Support development: BreakoutMods Patreon
Valheim mods often need the same networking building blocks:
BreakoutNet keeps those patterns boring and reusable so mods can share the same network layer.
Use a scoped context when a mod wants BreakoutNet-owned events, hooks, and future module-friendly APIs:
private BreakoutModApp app;
private void Awake()
{
app = BreakoutNet.ForPlugin(this, "com.breakoutmods.valheim.example")
.AddShared<SharedModule>()
.AddServer<ServerModule>()
.AddClient<ClientModule>()
.Build();
}
For lightweight integrations without module ownership:
BreakoutModuleContext context = BreakoutNet.ForMod("com.breakoutmods.valheim.example");
ZNet and ZRoutedRpc are available.public sealed class JoinCheckRequest : IBreakoutSerializable
{
public string ModListHash;
public void Write(ZPackage package) => package.Write(ModListHash ?? string.Empty);
public void Read(ZPackage package) => ModListHash = package.ReadString();
}
BreakoutRpc.Server.Register<JoinCheckRequest>(
"joinguard.check",
(context, request) =>
{
if (string.IsNullOrWhiteSpace(request.ModListHash))
{
context.Reject("Client did not send a mod list hash.");
return;
}
BreakoutRpc.Server.SendToClient(
context.SenderPeerId,
"joinguard.ok",
new JoinCheckResult(),
"com.breakoutmods.valheim.joinguard");
});
Clients send to the server with:
BreakoutRpc.Client.SendToServer(
"joinguard.check",
new JoinCheckRequest { ModListHash = localHash },
"com.breakoutmods.valheim.joinguard");
BreakoutSettingsSync.RegisterServerSettings(
"joinguard.settings",
() => new JoinGuardSettings { RequireMatchingMods = true });
BreakoutSettingsSync.Client.Register<JoinGuardSettings>(
"joinguard.settings",
settings => ApplyServerSettings(settings));
The server broadcasts registered settings periodically and when a session becomes available. Clients only apply settings packets that arrive from the server peer.
if (BreakoutSide.IsDedicatedServer)
{
// Server relay only.
}
foreach (ZNetPeer peer in BreakoutPeers.ConnectedPeers)
{
// Server-visible peers.
}
Every BreakoutNet package includes:
BreakoutNet rejects unknown protocol versions, unregistered RPC names, client-side messages from non-server peers, mismatched DTO types, and excessive inbound client RPCs.
Server RPCs use a conservative inbound client rate limit by default. High-frequency streams such as voice frames can opt into a larger token bucket:
BreakoutRpc.Server.Register<VoiceFrame>(
"voip.voice.frame",
OnVoiceFrame,
BreakoutRpcRateLimit.ForMessagesPerSecond(60f, 3f));
Mods can publish local typed events for internal module communication:
Context.Events.Subscribe<MyEvent>(OnEvent);
Context.Events.Publish(new MyEvent());
Named events are available for public extension points:
Context.Events.Subscribe<MyEvent>("joinguard.policy.checked", OnPolicyChecked);
Context.Events.Publish("joinguard.policy.checked", new MyEvent());
Read-only core hooks expose BreakoutNet lifecycle and RPC observations:
Context.Hooks.OnNetworkReady(OnReady);
Context.Hooks.OnPeerJoined(OnPeerJoined);
Context.Hooks.OnRpcRejected(OnRpcRejected);
More detail: docs/extensions.md
.\build.ps1 -Configuration Release
Deploy into this Valheim server install only when you explicitly ask for it:
.\build.ps1 -Configuration Release -Deploy