模组简介
Supported game versions: 0.107.1 / 0.109.0 / 0.110.1 / 0.111.0 Multiplayer compatibility layer for STS2: patches official sync boundaries and offers short conventions for content mods. Not a full multiplayer framework. On install it patches a few official multiplayer sync boundaries: the combat player sync queue keeps the latest snapshot and applies it immediately, stale combat sync is cleared after remote reward resolution, and Neow non-shared options use authoritative snapshots instead of replaying handlers on peers. This reduces checksum desync and mirror state being rolled back by stale snapshots. Among community mods, MpLib is currently the only layer patching official synchronizer semantics; it does not replace each mod's own messages, UI, or field sync. It also exposes short conventions such as CombatActions and NetBootstrap for content mods. Namespaces: Mp.Core, Mp.Combat, Mp.Neow. Do not Harmony-patch the same vanilla methods, e.g. EventSynchronizer.ChooseOptionForEvent and CombatStateSynchronizer.OnSyncPlayerMessageReceived, or patches will overwrite each other. CombatActions Use this for player input with payload. The game scans mod INetAction types; MpLib registers one NetModCombatAction and distinguishes business by stable key. Enqueue like playing a card. actor must be the local player. The host uses the sender NetId as owner and does not read fields on the action. Put other identity in the payload. Both sides register the same key. using Mp.Combat; CombatActions.Register("YourMod.DoThing", async ctx => { ulong targetId = ctx.Payload.ReadULong(); Player? target = ctx.Actor.RunState?.GetPlayer(targetId); if (target is null) return; await ApplyAsync(target, ctx.Choice); }); CombatActions.RequestEnqueue( actor: LocalContext.GetMe(runState)!, key: "YourMod.DoThing", writePayload: w => w.WriteULong(target.NetId)); HookBarrier Empty GenericHookGameAction sends only an ID over the network. When both sides are already in the same combat hook: await HookBarrier.RunInSharedHookAsync(owner, GameActionType.CombatPlayPhaseOnly, async ctx => { await DoWorkAsync(ctx); }); Use CombatActions when UI input has payload. Use RegisterInput and EnqueueFromInput only when there is no payload. The owner side generates the hook; the peer runs work in ExecuteAction. Callers dedupe themselves. Other Register INetMessage handlers at init via NetBootstrap.Add. Register each NetService once. using Mp.Core; NetBootstrap.Add(new YourNetModule()); sealed class YourNetModule : INetModule { public void RegisterHandlers(RunManager runManager) { runManager.NetService?.RegisterMessageHandler ((msg, senderId) => { /* ... */ }); } } Adding the same module type twice is ignored. Use RunAuthority to mutate shared run fields; do not use LocalContext.IsMe. IsRemoteMirror means this client is not authoritative for that player in multiplayer. PlayerSnapshotHooks.AfterRemotePlayerApplied: write back mod state not present on vanilla SerializablePlayer after remote Neow or combat snapshots apply. NeowChoicePolicy: by default non-authoritative clients skip replaying Neow-style eventOption.Chosen() and receive authoritative snapshots instead. Assigning ShouldSkipHandlerReplay replaces the default entirely; return true for stages that need snapshots. Event page SetEventState and each mod's own choice or UI protocols are out of scope here. Scope Built first for LustTravel2 multiplayer. The hard part is official boundaries, not character data. LustTravel2 still depends on it; character state stays in LustTravel2. This is a temporary patch layer. If vanilla adds non-shared event result sync, combat latest-snapshot retention, or message registration APIs, MpLib will shrink to a thin wrapper before considering removal. It does not replace each mod's own choice flow, UI, or fields. 支持游戏版本: 0.107.1 / 0.109.0 / 0.110.1 / 0.111.0 STS2 联机兼容层:补官方同步边界,并给内容 mod 一套短约定。不是完整联机框架。 装上后会自动修补几处官方联机同步边界:战斗玩家同步队列改为保留最新快照并即时应用、远端奖励结算后清掉过期战斗同步、Neow 非共享选项改为权威快照而非对端重演 handler。用于减少 checksum 分叉与镜像状态被过期快照回滚。 修补官方同步器语义这一层,目前社区里实质只有 MpLib 在做;不替代各 mod 自己的消息、UI 与字段同步。另提供 CombatActions / NetBootstrap 等短约定,供内容 mod 选用。 命名空间:Mp.Core、Mp.Combat、Mp.Neow。 不要再 Harmony 同一批官方方法,例如 EventSynchronizer.ChooseOptionForEvent 和 CombatStateSynchronizer.OnSyncPlayerMessageReceived,否则会互相覆盖。 CombatActions 有载荷的玩家输入走这条。官方会扫 mod 的 INetAction;MpLib 只注册一个 NetModCombatAction,用稳定 key 区分业务。入队与打牌相同。 actor 必须是本端玩家。Host 用发送方 NetId 当 owner,不会读 action 上的字段。其它身份写进 payload。两端登记同一 key。 using Mp.Combat; CombatActions.Register("YourMod.DoThing", async ctx => { ulong targetId = ctx.Payload.ReadULong(); Player? target = ctx.Actor.RunState?.GetPlayer(targetId); if (target is null) return; await ApplyAsync(target, ctx.Choice); }); CombatActions.RequestEnqueue( actor: LocalContext.GetMe(runState)!, key: "YourMod.DoThing", writePayload: w => w.WriteULong(target.NetId)); HookBarrier 空 GenericHookGameAction 网上只传 ID。双端已经在同一战斗 hook 里时: await HookBarrier.RunInSharedHookAsync(owner, GameActionType.CombatPlayPhaseOnly, async ctx => { await DoWorkAsync(ctx); }); UI 输入有载荷就用 CombatActions。没有载荷才用 RegisterInput 和 EnqueueFromInput。由 owner 所在端生成 hook,对端在 ExecuteAction 补 work。调用方自己去重。 其它 INetMessage 在初始化时用 NetBootstrap.Add 登记。每个 NetService 只注册一次。 using Mp.Core; NetBootstrap.Add(new YourNetModule()); sealed class YourNetModule : INetModule { public void RegisterHandlers(RunManager runManager) { runManager.NetService?.RegisterMessageHandler ((msg, senderId) => { /* ... */ }); } } 同一模块类型 Add 两次会被忽略。 RunAuthority 用来改共享跑局字段,不要用 LocalContext.IsMe。IsRemoteMirror 表示多人局里本端不是该玩家权威。 PlayerSnapshotHooks.AfterRemotePlayerApplied:vanilla SerializablePlayer 没有的 mod 状态,在远端应用 Neow 或 combat 快照后写回。 NeowChoicePolicy:默认非权威端跳过 Neow 类 eventOption.Chosen() 重演,改收权威快照。给 ShouldSkipHandlerReplay 赋值会整份替换默认;需要快照的阶段请自己返回 true。事件页 SetEventState 和各 mod 自己的选择、UI 协议不在这里。 范围 最初为欲途联机写。难的是官方边界,不是角色数据。欲途继续依赖它,角色状态仍留在 LustTravel2。 这是临时补丁。官方若补上非共享事件结果同步、combat 留最新快照、消息注册 API,会先收成薄封装再考虑卸掉。不覆盖各 mod 自己的选择流程、UI、字段。
条目信息
- 所属游戏
- 杀戮尖塔 2 (Slay the Spire 2)
- 创意工坊 ID
- 3792205243
- 文件名
- 3792205243.bin
- 文件大小
- 189.0 KB
- 最后更新
- 2026/08/30
- 内容版本
- v1788022429-65c5db8f628ce631
- 作者与来源
- 由原作者发布于 Steam 创意工坊。本站不改变署名,作者信息与原始内容请以 Steam 原始页面 为准。
版权与举报
本条目的著作权归其原作者所有。尖塔补给站仅提供索引与下载中转,不存储、不修改、不二次分发其著作权内容, 也不对其内容作任何担保。详见 版权声明 与 免责声明。
若你是该内容的权利人并希望下架此条目,或发现该条目含有违法违规内容,请通过 侵权删除申请 提交材料,我们会在核实后处理并在本页标注状态。

Steam 社区评论
以下评论来自 Steam 创意工坊原始页面,由 Steam 用户发表,不代表本站立场。