7D2D 24()

7D2D 24()

什么是24小时周期硬上限

如果你知道你在找什么, 可以直接跳转到标题
Ⅰ. 修复游戏硬编码的上限

来跳过介绍

七日杀中的24小时周期设置官方给的最大值是120分钟, 也就是只有2小时, 这2小时也就是官方给的默认上限并且允许通过mod来修改.

虽然可以通过创建mod添加更长时间的选项, 但是可用的最大值只能达到400分钟(6.6小时), 也就是硬上限, 当设置超过400分钟后1.0版本中会导致游戏世界的时间暂停且一直为夜晚状态(旧版本中为锁定1日 0:00), 这是因为官方在游戏计时代码中使用的数据类型不同导致.

在代码中当24小时周期为400分钟时, 每 1秒 现实世界时间只会增加 1单位 游戏世界时间, 也就是400 × 60 × 1 = 24000 , 分成游戏中的24小时就是 1000单位/游戏时 . 如果你使用过控制台的 settime 指令, 那么你会发现这刚好是游戏中的 1天 和 1小时 的值.

当周期超过400时, 游戏代码中的无法将 (24000 ÷ 周期秒数) 计算为整数, 你肯定会说这个结果小于1要带小数点啊, 但是问题就在这里, 游戏代码里写这个 每秒增加的时间单位值(TimeOfDayIncPerSec) 的类型是整形, 当计算整数除法时会舍弃小数部分, 当结果小于1结果就是0, 这就导致即使mod更改了DayNightLength到1440也没有效果甚至会暂停计时.

为什么要修改它

长话短说, 就是我想玩24h末日生存服

我在找相关mod的时候发现这些mod最高只支持360分钟, 我随便下载了个改了个1440分钟玩, 进档待了俩小时才发现 時間靜止 了, 然后去网上找了下也有人在问怎么设置时间周期更长, 但是 没人回答而且还觉得长了有什么好玩的 , 国外的帖子也有人想要把周期延长但是没人回答如何修改, 但是我看到了有人回答说是游戏硬编码设置, 于是研究了半天找到了解决方法.

Ⅰ. 修复游戏硬编码的上限


7D2D 24() image 12
7D2D 24() image 13
7D2D 24() image 14部分
同样找到该部分
7D2D 24() image 17
7D2D 24() image 18
7D2D 24() image 19SliderSpeed_OnValueChanged
7D2D 24() image 21

指南内描述的操作可能并不详细, 但搜索引擎可以解答你的所有疑问

该指南所述的mod需要修改游戏本身程序, 可能无法通过EAC验证, 并且可能并不直接兼容原版, 所以请不要修改后随意进入其他公共服务器或将自己的服务器公开

社区指南图片无法显示或GitHub无法加载请使用加速器或302等工具, 小图可以点击放大

准备工具与备份下载dnSpy (你能下载Steam并购买七日杀已经打败99%的人了, 别告诉我你下载不了一个开源工具)

找到游戏根目录, 如果你修改的是服务端则打开服务端根目录

在游戏文件夹中打开 7 Days To Die\7DaysToDie_Data\Managed 文件夹

服务端则是 7 Days to Die Dedicated Server\7DaysToDieServer_Data\Managed

备份 Assembly-CSharp.dll 文件, 可以直接改名为 Assembly-CSharp_orig.dll , 然后打开dnSpy, 将该文件拖入至dnSpy左方的"程序集资源管理器" , 如果是第一次用可能会加载一段时间, 然后点击"程序集资源管理器"中的 Assembly-CSharp_orig 此处以服务端为例, 客户端我已修改, 实际并无差别

1.初始化类型修复点击工具栏中的 编辑-> 搜索程序集

输入 GameStats.initPropertyDecl 双击唯一的一个搜索结果 Ctrl + F 使用小搜索框搜索

new GameStats.PropertyDecl(EnumGameStats.TimeOfDayIncPerSec, true, GameStats.EnumType.Int, 20), 右键这行, 选择编辑方法, 在新的编辑框中找到这行, 修改为

new GameStats.PropertyDecl(EnumGameStats.TimeOfDayIncPerSec, true, GameStats.EnumType.Float, 20f), 然后点击 编译 按钮

2.AI活动时间修正同样使用搜索程序集搜索

AIDirector.GetActivityWorldTimeDelay打开后找到该: (float)GameStats.GetInt(EnumGameStats.TimeOfDayIncPerSec)编辑方法, 将这更改为

GameStats.GetFloat(EnumGameStats.TimeOfDayIncPerSec)点击 编译 按钮

3.游戏计时器类型修复搜索程序集搜索

GameManager.updateTimeOfDay打开后同样找到该: (float)GameStats.GetInt(EnumGameStats.TimeOfDayIncPerSec)编辑方法, 将这更改为

GameStats.GetFloat(EnumGameStats.TimeOfDayIncPerSec)点击 编译 按钮

然后会报错 我就知道你会编译报错的 , 如果没有报错或者你会解决且已经解决了请直接跳到第4步

如果报错, 点取消, 还是右键该行, 点击 编辑IL指令

然后找到该行(如果你当时点击的位置没有错应该如下图所示, 不要管行号): 操作码 操作符 call int32 GameStats::GetInt(valuetype EnumGameStats) 点击这行, 在弹出的菜单中点击方法

在这个搜索框中搜索

GameStats.GetFloat结果应该只有一个, 我在服务端之前修改客户端所以加载了客户端和服务端两个, 如果你也加载了客户端和服务端的DLL, 鼠标移上去查看哪个是当前DLL的目录就点哪个, 然后点击确定, 该行就会变成这样

继续点击确定, 该行就会变为

GameStats.GetFloat(EnumGameStats.TimeOfDayIncPerSec)

4.游戏所有模式的初始化计时器类型修复搜索程序集搜索

GameModeAbstract.Init打开后找到该行

GameStats.Set(EnumGameStats.TimeOfDayIncPerSec, 24000 / (GamePrefs.GetInt(EnumGamePrefs.DayNightLength) * 60));编辑方法 将该行改为

GameStats.Set(EnumGameStats.TimeOfDayIncPerSec, 24000f / ((float)GamePrefs.GetInt(EnumGamePrefs.DayNightLength) * 60f));点击 编译 按钮

5.创建模式的初始化计时器类型修复搜索程序集搜索

GameModeCreative.Init打开后找到该行

GameStats.Set(EnumGameStats.TimeOfDayIncPerSec, 4);编辑方法 将该行改为

GameStats.Set(EnumGameStats.TimeOfDayIncPerSec, 4f);点击 编译 按钮

6.世界编辑器的初始化计时器类型修复搜索程序集搜索

GameModeEditWorld.Init打开后找到该行

GameStats.Set(EnumGameStats.TimeOfDayIncPerSec, 1);编辑方法 将该行改为

GameStats.Set(EnumGameStats.TimeOfDayIncPerSec, 1f);点击 编译 按钮

7.调试菜单计时器选项修复搜索程序集搜索

XUiC_InGameDebugMenu.Update打开后找到该

(float)(GameStats.GetInt(EnumGameStats.TimeOfDayIncPerSec) - 1)编辑方法 将将这更改为

(GameStats.GetFloat(EnumGameStats.TimeOfDayIncPerSec) - 1f)点击 编译 按钮

继续在搜索程序集搜索

XUiC_InGameDebugMenu.打开后找到该行

int value = this.SliderSpeed_Value();编辑方法 将该行改为

float value = UnityEngine.Mathf.Clamp(this.sliderSpeed.Value, 0f, 0.99f) * 500f + 1f;点击 编译 按钮

"UnityEngine."这个会自动消失, 不用管它

鼠标移到下一行的Set, 出现的提示框中"_value"前的"int"变为"float"即为修改正确

8.保存修改点击工具栏中的 文件 -> 全部保存

在弹出的选项中取消勾选 共享方法体, 然后检查文件名中的路径与文件名是否正确, 建议保存为Assembly-CSharp_modif.dll, 然后点击确认, 当游玩或开服时将原版文件移出或改名并将该文件改名为 Assembly-CSharp.dll 覆盖, 还原时使用原来的文件重新覆盖即可

Ⅱ. 创建Mod文件添加选项


7D2D 24() image 80

在七日杀与七日杀服务端根目录下的Mods文件夹下新建一个文件夹名称随意, 在该文件夹下新建一个ModInfo.xml文件, 然后编辑内容, 在其中添加

<?xml version="1.0" encoding="UTF-8" ?> <xml> <Name value="自定义24H周期" /> <DisplayName value=" " /> <Description value=" " /> <Author value=" " /> <Version value="1.0" /> <Website value=" / " /> </xml>然后保存

在该文件夹下新建一个名为Config的文件夹, 在Config文件夹中再新建一个名为XUi_Menu的文件夹, 在XUi_Menu文件夹下新建一个名为windows.xml的文件, 打开编辑, 在里面添加:

<configs> <set xpath="/windows/window[@name='newContinueGame']/rect[@name='tabs']/rect[@name='tabsContents']/rect[@tab_key='xuiGameSettingsGeneral']/grid/gameoption[@name='DayNightLength']/@values">10, 20, 30, 40, 50, 60, 90, 120, 180, 240, 300, 360, 420, 480, 540, 600, 660, 720, 780, 840, 900, 960, 1020, 1080, 1140, 1200, 1260, 1320, 1380, 1440, 2880, 5760, 11520</set> <set xpath="/windows/window[@name='serverBrowser']/panel[@name='serverfilters']/panel[@controller='TabSelector']/rect[@name='tabsContents']/rect[@tab_key='xuiGameSettingsBasic']/grid/browsergameoptioncombined[@name='DayNightLength']/@values">10, 20, 30, 40, 50, 60, 90, 120, 180, 240, 300, 360, 420, 480, 540, 600, 660, 720, 780, 840, 900, 960, 1020, 1080, 1140, 1200, 1260, 1320, 1380, 1440, 2880, 5760, 11520</set> </configs>然后保存

其中添加了3-24小时中每个小时和2, 4, 8 天的长度, 保存后进入游戏即可正常游玩, 且调试工具和settime调节时间也正常可用.

tip: 调试工具中的时间速度在周期大于400分钟时最好不要调整, 因为这个破滑块不仅难调而且还不支持小数点, 不能精确调整到零点几几 , 一旦调了周期最小就只有400分钟要重进重新读取地图配置才能还原

多人情况下需要双方使用相同的DLL才能使配置正常生效, 如果文件不同可能会导致双方游戏内时间不同步(或者游戏内时间反复跳动, 因为修改后没有强制类型转换, 使用浮点计算每单位粒度更细, 而原版会丢失精度) , 目前单人情况下一切正常多人我不知道, 好像朋友不想和我打僵尸 :(

Source: https://steamcommunity.com/sharedfiles/filedetails/?id=3323946076					

More 7 Days to Die guilds