ModNet
Library for multiplayer mods: modded players exchange messages through the game's own network, with a handshake that lists each player's mods and versions. Other mods use it for shared emotes, models
模組介紹 作者原文
ModNet
Lets mods send messages to the other modded players in a multiplayer game, through the game's own network. Other
mods use it to share what only they know about, such as a player's emote or custom model, and to check that
everyone has the same mod version.
ModNet is a library. On its own it does nothing you can see in play. Every player who wants a mod's shared
features needs ModNet and that mod.
- Hello handshake. Each modded player announces their installed mods and versions when they join.
- Players card. With Mods Menu installed, Options → Mods has a
ModNet card listing who runs which mods, with version differences highlighted.
A game where some players don't have ModNet hasn't been tested yet.
Settings
| Setting | Default | |
|---|---|---|
| Enabled | on | Exchange messages with other modded players. Off: mods behave as if nobody else had them |
| Log Traffic | off | Log every message sent and received (turn on when reporting a multiplayer problem) |
| Test Tools | off | Ping and payload-size test buttons on the ModNet card |
The file is BepInEx\config\com.helvetica.modnet.cfg.
How it works
Each message is a string passed to the game's replicated Root.SetAnimationTrigger(Character, string). The host
relays it to every client. On a modded player, a Harmony prefix catches the string before it reaches the
Animator.
For mod developers
- Add a soft dependency, so your mod still loads without ModNet:
[BepInDependency("com.helvetica.modnet", BepInDependency.DependencyFlags.SoftDependency)]
- Reference ModNet.dll with Private="false", so it isn't copied next to your mod.
- Put every ModNet call in one nested class, and only call into it after checking that ModNet is installed: the
runtime loads ModNet's types only when that class's code runs.
internal static class MySync
{
static bool _available;
internal static void Init() { _available = true; Bridge.Hook(); } // from OnModLoaded, if installed
internal static void Tell(Character c, string what) { if (_available) Bridge.Send(c, what); }
static class Bridge
{
internal static void Send(Character c, string p) => ModNetApi.Send("mymod", p, c);
internal static void Hook()
{
ModNetApi.Register("mymod", m => Handle(m.Character, m.Payload));
ModNetApi.PlayerHello += _ => ResendState(); // late joiners
}
}
}
// OnModLoaded: if (Chainloader.PluginInfos.ContainsKey("com.helvetica.modnet")) MySync.Init();
API (ModNetApi)
| Member | |
|---|---|
| Send(channel, payload, subject) | To every other modded player, not to yourself. subject = one of your characters; null = any. Returns false if not sent (true when queued) |
| Register(channel, handler) | NetMessage: Channel, Payload, Character (the subject), SenderOwnerId, Sender |
| Ready, IsMultiplayer, MyOwnerId | Sending starts about 3 s after your characters appear in the world |
| BecameReady | Raised once per session when sending starts |
| PlayerHello | Raised when a modded player is first heard from in a session. Re-send your state here |
| PlayerLeft | Raised when a player leaves |
| Players, GetPlayer(ownerId) | PlayerInfo: Name, IsMe, HasModNet, SteamId, Mods (GUID → version), Has(guid, version) |
| EveryoneHas(guid, version) | Gate for features that need every player to have the mod |
Rules
- Events only. Send events, never per-frame data.
- Size and rate. Payloads up to 1000 characters. Sending is throttled to 10 per second, with bursts of 20.
- Sending from a handler is fine. A message sent while another one is being received (from a handler, or from
PlayerHello) is queued and goes out on the next frame.
- Separator. Use | inside payloads. Channel names can't contain it.
- Don't trust the sender. A message's Character is the sender's own character. Ignore messages that would
change your own characters.
- Protocol version. ModNetApi.Protocol is part of the wire marker. Players on another protocol version ignore
each other.
安裝與使用 安裝:按包內說明操作
- 解壓本站下載的壓縮包,先讀包內的 readme / 說明檔案。
- 多數模組依賴遊戲的模組載入器:常見做法是用社群模組管理器(如 r2modman)選中本遊戲安裝,由管理器自動處理載入器與依賴。
- 手動安裝時,把模組檔案放進遊戲目錄下對應的 Mod / plugins 資料夾。
- 啟動遊戲確認載入成功;帶「前置依賴」的模組需要把依賴一併安裝。
不同模組的安裝位置差異較大,包內說明是最可靠的依據。
下面這些內容需要先安裝,否則該模組不會生效: