瓦尔海姆调音

创作者: Akoozie
已更新:2026-09-10 00:28:13
35KB

关于此 MOD

针对英灵神殿专用服务器的服务端性能补丁。在70万物体的世界中,对象同步每次调用从4.1毫秒降至0.09毫秒。玩家无需安装任何内容,网络格式保持不变。已为英灵神殿1.0做好准备。

瓦尔海姆调音

✅ 英灵神殿 1.0.16 已就绪

0.7.5 运行于游戏 1.0.16(网络版本 40),且仍停留在1.0.15、1.0.14和1.0.12(40)以及1.0.7(39)上。这是一次兼容性重建:插件所修补的每个方法在这五个构建版本中均字节完全相同,但0.7.5有 不 已在1.0.16上启动——阅读 更新日志 在你部署之前。从以下版本升级 0.7.4 无需修改配置。运行游戏0.221.12?请使用 0.6.0 相反——版本门控会拒绝将这些补丁应用到旧版本上。

在Thunderstore上: 阿库齐-英灵神殿调音

让一个拥有大型基地和少量玩家的《英灵神殿》专用服务器,感觉就像一个小型服务器一样。

仅限服务器端——玩家无需安装任何内容。 所有改动都在服务端,通信格式保持不变,原版客户端仍能像以前一样正常连接。

游戏 1.0.16、1.0.15、1.0.14 和 1.0.12(网络版本 40),1.0.7(39),专用服务器只需要 BepInEx 5.4.x,状态 0.7.5 是针对 1.0.16 的兼容性重新构建。此插件补丁的每个方法在 1.0.7 到 1.0.16 之间都是字节完全相同的(反编译差异对比),它针对 1.0.16 程序集编译,单元测试也已通过——但尚未在 1.0.16 上启动验证。0.7.0 已在 1.0.7 上实机验证,2026-09-09:698,000 个对象,一个 12,000 实例的基地,2-6 名玩家。

为什么

在该服务器上实测,而非模拟:

香草 瓦尔海姆调谐
同步扫描,每名玩家每回合 4.1 毫秒 0.07 毫秒
自动保存 单帧381毫秒卡顿 约350帧内每次6毫秒
加入同步消耗 每次调用约 11 毫秒 ~5.5 毫秒
加入直播率 1,261 个/秒 3,617 个物体/秒
服务器帧率 30帧,硬性上限 60帧
已同步更新,基地内有2名玩家 基线 减少约55%

每个旋钮默认保持原版设置,只有已验证生效的才会改动。每个数值的来源详见 工作原理.

需求

  • 英灵神殿 专用服务器 (Steam应用896660)。不是客户端内的主机。
  • BepInEx 5.4.x 适用于英灵神殿 (BepInExPack_Valheim)
  • 游戏版本列于 [兼容] 已知正常版本 (当前 1.0.7, 1.0.12, 1.0.14, 1.0.15, 1.0.16)。在其他任何版本中,该插件以原版加测量模式运行,并会在日志中说明。

安装

开 雷暴商店 — 阿库兹-英灵神殿调音注意,模组管理器安装到客户端配置文件;对于专用服务器,你仍然需要将DLL放在 服务器所以下面的手动步骤是正常流程。

  1. 在服务器上安装BepInEx。使用 lloesche/valheim-server Docker 镜像,该镜像 BEPINEX=true 在 服务器环境变量.
  2. 掉落 ValheimTune.dll 进入 BepInEx/plugins/ (Docker: config/bepinex/plugins/)。
  3. 重启。配置文件位于 BepInEx/config/akoozie.valheimtune.cfg.
  4. 检查日志以获取:
[ValheimTune] 0.7.5 已加载至游戏 1.0.16(网络 40),已修补 11 个方法,替换已启用 [ValheimTune] SendZDOs 窗口 10240/2048,已替换 3 个常量(预期 3 个)

推荐设置

参考服务器上运行的内容。每次只应用一项更改,并在两次更改之间阅读统计信息行。大多数调节参数无需重启即可在5秒内生效。

[服务器] TargetFrameRate = 60 [同步] SendWindowBytes = 32768 MinHeadroomBytes = 4096 AllPeersPerRound = true RelayMinIntervalMs = 200 [Steam] SendRateMaxBytesPerSec = 1048576

脏数据集 和 TopK排序 默认已开启。

从早期版本升级

放入新的 DLL 并重启——无需修改配置。 新插件版本不会重写现有的 阿库兹·英灵神殿调音.cfg (BepInEx仅在键不存在时写入默认值),所以你的文件仍然显示 KnownGoodBuilds = 1.0.7从0.7.1版本起,这不再消耗你任何东西:发行版中附带的列表被视为下限,而你的配置只能 添加 对它。启动时你会看到一次:

[ValheimTune] 游戏 1.0.16 不在你的 KnownGoodBuilds (1.0.7) 中,但此版本包含以下构建 (1.0.7, 1.0.12, 1.0.14, 1.0.15, 1.0.16);将使用随附列表。你的配置来自旧版本。

如果你愿意,可以把这行整理一下;不过这并不影响什么。

如果日志显示 替换关闭

[ValheimTune] 游戏 1.0.17 不在 KnownGoodBuilds (1.0.7, 1.0.12, 1.0.14, 1.0.15, 1.0.16) 中:替换补丁未启用,正在运行原版 + 测量

你的服务器已更新到一个此插件尚未验证过的游戏版本。一切都没有损坏——版本门控发挥了作用,拒绝将旧的补丁逻辑运行在新的代码上。但该插件现在只打印统计信息行;所有优化均未运行。 日志行会告诉你确切的游戏版本,而这就是门用来进行比对的东西。

你有三个选择。

等待支持您版本的版本发布。 安全的那一个。检查 发布页面;每一个都标明了它所验证的游戏版本。与此同时,统计信息行仍然有效,因此你可以保留诊断信息。

2. 强行开启并承担风险。 将你的版本添加到列表中:

[兼容] KnownGoodBuilds = 1.0.7, 1.0.12, 1.0.14, 1.0.15, 1.0.16, 1.0.17

重启。Harmony 会拒绝修补任何签名已发生变化的方法并记录日志,而常量交换转译器除非精确匹配它所期望的三个常量,否则会自动中止——因此一个 形状 变更会大声失败,而不是悄无声息地失败。它无法捕捉的是这样一种方法:其形态未变,但其 语义 已移动。

先备份你的世界。 这里的每个补丁只影响性能,都不会写入你的世界文件,但一次游戏更新可能让它们全部失效,而备份没有任何代价。

3. 针对新服务器组件自行搭建。 查看 从源代码构建如果有效,请提交一个问题,说明是哪个游戏版本——这样它才能被纳入下一个发布版本。

无论哪种方式,都欢迎举报。 未知版本禁用 = false 是选项2的直白版本;它强制启用每一个替换补丁,用于 任何 版本,且带有同样的警告,却完全没有你测试内容的记录。

读取属性行

每 日志间隔秒数,前缀为 英灵神殿调校:

帧平均16.7最大17.0毫秒(60帧/秒)| 同步列表平均0.07最大0.20毫秒 | 发送平均0.10毫秒 | Z最大11418 | 对等发送400 | zdos/秒 发送430 接收1000 | 对等节点2 | 标记15750 满0 脏轮399 延迟8300 排空12 | 网格跳过0 按预制体接收(窗口内7848):鱼1=1833 鱼2=1315 ... 热点对象:木材=69@(-327,-631) ...
每个字段的含义
场地 含义 健康
框架 主线程帧时间 平均在你的目标范围内,除加入期间外,最大约在35毫秒以下
同步列表 每位玩家每回合搜索每个候选对象的时间 ~0.1 毫秒稳定,连接时几毫秒
Z 最大值 全量扫描中见过的最大候选集 随你的基础值提升
同伴发送 在窗口内发送呼叫(轮数 x 玩家数) 每位玩家每10秒约200,附带 每轮所有对等点
每秒发送/接收 最后一秒反击 recv是你的玩家客户端推送的内容;sent是中继
标记 窗口内上钩次数 非零时对玩家生效;0表示钩子已失效,看门狗将回退
满 / 脏弹 完整扫描与脏集轮次 满~0,每项一个 调和秒数 每名玩家
已推迟 被油门压制的继电器 大就是好
枯竭 上一轮脏数据中的候选者
网格跳过 网格重建被跳过,原因: 跳过渲染网格 探索新区域时攀升,其他地方为0
已禁用 若看门狗触发则追加 绝不应出现
从预制件接收 你的玩家正在推动哪些预制体 告诉你该清理什么
热物体 每个对象的计数与世界x、z坐标 找到那根永不停歇滚动的原木
完整配置参考 — 每个旋钮、默认值及其生效时机

运行时 = 重读每一个 配置重载秒数 无需重启。 补丁时间 = 插件加载时仅读取一次;重启以更改。

按键 默认 当 什么
[测量] 日志间隔秒数 10 运行时 属性行刷新频率。0 表示禁用。
[测量] ConfigReloadSeconds 5 运行时 配置文件重新读取的频率。
[度量] 热物体忽略 玩家,鱼1,鱼2,鱼3 运行时 预制体未加入热对象行。
[服务器] 延迟资源卸载 假 运行时 留住香草每小时的 卸载未使用的资源 (实测主线程卡顿443-607毫秒)直到没有玩家连接。已延迟,未跳过。
[服务器] 资源卸载最大延迟分钟数 240 运行时 兜底:一旦延迟持续这么久就无论如何都收集,这样即使服务器永远不清空也仍然会收集。
[Server] 跳过渲染网格 否 运行时 在专用服务器上跳过高度图渲染网格重建;它是为玩家探索的每个区域构建的,且从不绘制。碰撞网格不受影响。
[Server] 目标帧率 0 运行时 覆盖服务器硬编码的30帧上限。0 = 保持默认。同步回合周期为 0.05 秒 + 玩家数 / 帧率.
[同步] 发送窗口字节 10240 补丁时间 每名玩家在服务器停止排队前的飞行字节数。原版为10240。
[同步] 最小预留字节 2048 补丁时间 低于此空闲窗口,玩家本轮跳过。保持低于该窗口。
[同步] 覆盖发送窗口 真 补丁时间 如果其他网络模组更改了发送队列大小,请设为 false; 发送ZDO 则保持不变。在原生窗口值下,两种情况都不会发生任何变化。
[同步] 每轮所有玩家 假 运行时间 每轮为每位玩家提供服务,而不是每帧只服务一位玩家。在4名或更多玩家时效果显著。
[同步] 回合秒数 0.05 运行时 当回合周期 每轮所有对手 已开启。
[同步] 脏数据 真 运行时 每轮只考虑发生变化的对象。如果变更钩子静默失效,看门狗会回退到原版。
[同步] 校准秒数 30 每位玩家连接时 安全网全量扫描间隔。
[同步] 中继最小间隔毫秒 0 运行时 重新向同一玩家发送非优先对象的最大频率。0 = 原版。200 为测试值。
[同步] TopKSort 真 运行时 使用有界堆选择,而不是对所有候选项进行完整排序。
[同步] 前K项 0 运行时 每轮候选者排序。0 = 发送窗口字节数 / 64,永远不低于64。
[Steam] 每秒最大发送速率(字节) 153600 补丁时间 Steam每连接发送上限。原版为150 KB/s。请勿超过你的上传速度除以玩家数量。
[Steam] 每秒最小发送速率(字节) 153600 补丁时间 保持默认值,这样 Steam 的估算器就能在丢包链路上进行退避。
[Steam] 覆盖发送速率 真 补丁时间 如果另一个网络模组管理 Steam 发送速率,则设为 false;此时 ValheimTune 永不写入这些速率。无论哪种情况,保持原版数值的速率都不会被写入。
[接收]每帧每对等方最大数据包数 0 运行时 在一帧内处理这么多数据包后,停止消耗单个玩家的套接字。0 = 原版。如果某个玩家的突发数据导致其他玩家卡顿,可以试试 64。
[清理] FloatingDropsRun 假 一次性的 设置为true以扫描掉落物品和漂浮在水中的倒木。会自动重置。除非下一个键为true,否则仅试运行。在698k-ZDO世界中会造成约50毫秒的主线程卡顿。
[清理] 浮空掉落物删除 假 运行时 与 奔跑扫描到的东西一律删除。先做每小时备份。
[兼容] 已知良好版本 1.0.7, 1.0.12, 1.0.14, 1.0.15, 1.0.16 补丁时间 此插件构建已验证兼容的游戏版本。用逗号分隔。
[兼容] 未知版本禁用 真 补丁时间 在未列出的版本上,仅运行测量、发送速率上限和常量交换。

工作原理

每一行都是一个已测出的问题及其对应的修复补丁。

问题接问题
原版中的问题 ValheimTune 的功能 在包含69万个对象的世界中测得
服务器帧率硬性上限为30帧,因此每轮同步都要等待一个慢帧。 目标帧率 旋钮 30 -> 60 帧/秒,约 3% CPU
每一轮同步都会重新扫描每个玩家附近的所有对象 脏套装:仅考虑自上一轮以来发生变化的对象;完整扫描仅在加入、区域变更以及每30秒时进行 4.1毫秒 -> 每名玩家每回合0.07毫秒
10 KB 发送窗口以及每连接隐藏的 150 KB/s Steam 上限 两端均已提升,所有玩家现在每50毫秒处理一次,而非每帧处理一个。 加入直播速度提升2.8倍
每个玩家发出的每次更新都会转发给附近的其他所有玩家,任何移动物体每秒约更新17次 中继节流阀非优先对象(鱼、漂浮物、碎片)最多每200毫秒向指定玩家重新发送一次;玩家和生物除外 双人基地时中继站减少约55%
自动存档在主线程上克隆整个世界,然后一个写入线程读取游戏仍在不断变化的内存(撕裂缝合存档竞态) 已保存切片:世界在主线程上以6毫秒的时间片序列化到缓冲区中;写入线程只负责写入 381毫秒的单帧卡顿 → 分布到约350帧中的每帧6毫秒
加入过程中,每一轮都会对所有候选对象进行完整排序,以选出约300个符合条件的对象。 前K项选择:有界堆保留最佳的512个,不分配内存 加入同步开销从每次调用约11毫秒降至约5.5毫秒;顺带修复了原版字段表的泄漏问题
游戏更新时,旧补丁逻辑在新代码上悄然运行 版本门槛:替换补丁仅在配置中列出的构建上运行;其他任何情况都会记录警告并运行原版加测量 在正式服务器上两种方式都测试过了
数百件掉落物和砍倒的木头永远漂浮在水面上,每一件都在每回合同步一次 一次性扫描并可选删除 已移除 1,446 个对象;空闲入站流量从 800 降至约 650 次更新/秒
已修补的11个方法

专用服务器程序集的11个方法上应用Harmony补丁,全部位于 补丁/:

方法 补丁 目的
ZDO管理器.创建同步列表 前缀 + 后缀 脏数据组,中继节流;时序
数据修订版本 / 所有者版本 设置器 后缀 标记已更改对象
ZDOMan.服务器排序发送ZDO 前缀 前K名选择
ZDO管理器.发送ZDO 转译器 + 前缀/后缀 窗口常量;计时
发送ZDO到对等端2 前缀 每轮所有玩家
更新Rpc 前缀 接收上限
ZSteamSocket.注册全局回调 后缀 Steam 发送率
反序列化 后缀 每个预制体的计数
高度图.重建渲染网格 前缀 在无头服务器上跳过渲染网格
游戏.收集资源 前缀 将每小时资源卸载推迟到服务器为空时

存档路径已不再需要修补。Valheim 1.0 会为每个区块写入一个文件,并且只克隆已修改的区块,这取代了本插件在 0.221.12 上曾使用的切片式存档方案;在一个包含 69.8 万个对象的世界中实测空闲状态,增量自动存档写入耗时 3 毫秒,而完整存档则需 2713 毫秒。

每一个补丁 替换 游戏逻辑会先检查版本门控,未开启时按原版运行。测量、发送速率上限和常量替换则始终执行。常量替换只有在与它预期的三个常量完全匹配时才会生效。

纯逻辑(脏集状态、看门狗规则、切片器、top-K堆、版本检查)位于外部 补丁/ 并且具有无需游戏即可运行的单元测试。

刻意限制

  • 中继节流阀可能会延迟 重复 将鱼或滚木的更新最多延迟200毫秒。首批更新将在下一轮发送。
  • 这里不会改变要求客户端渲染或模拟的任何内容。渲染距离、客户端速率限制以及可靠/不可靠通道都需要客户端模组,不在讨论范围内。

从源码构建

需要 .NET 8 SDK 和专用服务器的托管程序集。

# 将构建指向你服务器的 Managed 文件夹(或将 DLL 复制到某处)export GameManaged=/path/to/valheim_server_Data/Managed dotnet build ValheimTune/ValheimTune.csproj -c Release dotnet test ValheimTune.sln

输出: ValheimTune/bin/Release/netstandard2.1/ValheimTune.dll。私人游戏成员在编译时通过以下方式公开: BepInEx.AssemblyPublicizer.MSBuildBepInEx.Core 和 HarmonyX 来自 BepInEx NuGet 源(nuget.config)。

部署.sh 是参考服务器的构建-复制-重启循环;设置 主机 并调整 Docker 添加到你的设置中。

当游戏更新时

查看 docs/PORTING.md短版本:插件会检测到,关闭其替换补丁并记录。玩家会游玩原版加上统计信息行,直到重新构建将新版本添加到 已知良好构建.

许可证

麻省理工学院。与Iron Gate或Coffee Stain无关联。

欢迎其他服务器的报告——请提交一个问题,附上你的数据行。

Valheim: 英灵神殿 的热门 MOD

探索适用于 Valheim: 英灵神殿 的最佳MOD,带来新功能、升级画面,以及令人兴奋的方式来改变您的游戏体验。

使用 Xmod 解锁 Valheim: 英灵神殿 的全部潜力 — 今天就探索这些顶级 MOD!