原生时间加速(更快的睡眠与等待)

原生时间加速(更快的睡眠与等待)

一个轻量级SFSE插件,原生加速睡眠/等待时间。特性包括动态热切换以即时更改Turbo速度、自动唤醒系统,以及无缝切换回原版速度以实现精确时间跳跃而不会导致日历溢出。

[center][size=6][b][color=#e6a822]原生时间加速[/color][/b][/size]
[size=4][color=#87cefa](更快的睡觉与等待)[/color][/size][/center]
[line]
[center][size=3][i]你是否厌倦了在金星上等待24小时让容器装满时,盯着缓慢的界面发呆?[/i][/size][/center]

[b]原生时间加速[/b]是一款轻量级、原生编译的 SFSE 插件,它直接修改创造引擎2中一个仅用于大幅加速睡觉/等待菜单的内部变量([i]iSecondsToSleepPerUpdate[/i])。

[size=5][color=#e6a822]⭐ 主要功能[/color][/size]
[line]
[list]
[][color=#87cefa][b]动态热切换与自动唤醒(新):[/b][/color]你可以在游戏过程中实时更改你的极速档位!按住你的修饰键(默认为 Shift)并按下键盘/小键盘上的 [b]2、3 或 4[/b],即可立即调整速度并自动唤醒极速模式。需要精确控制?按下 [b]修饰键 + 1[/b] 可立即强制切换为原版速度(1小时视觉跳跃)。[/]
[][color=#87cefa][b]全局动态切换:[/b][/color]你还可以随时按下 [b]Shift + T[/b](完全可配置),在原版速度和上次使用的极速速度之间无缝切换。你可以在打开菜单之前切换模式,甚至可以在等待计时器正在运行时切换![/]
[][color=#87cefa][b]活动窗口过滤:[/b][/color]异步热键检测器非常智能。它仅在 Starfield 是活动前台窗口时读取你的输入,防止你在 Alt-Tab 切换到浏览器或 Discord 时意外触发切换。[/]
[][color=#87cefa][b]100% 安全安装/卸载:[/b][/color]完全使用 C++ 构建,零 Papyrus 脚本冗余。它不会将任何数据烘焙到你的存档文件中,这意味着你可以在游戏过程中随时安全地安装或移除它。[/]
[][color=#87cefa][b]完全可配置:[/b][/color]通过附带的 [i].ini[/i] 文件轻松调整每刻小时数倍率、修饰键(Shift、Ctrl、Alt)和主切换键。你甚至可以禁用修饰键以使用单键切换。[/]
[/list]
[size=5][color=#e6a822]⚠️ 兼容性:Starfield Engine Fixes[/color][/size]
[line]
如果你正在使用 [b]Starfield Engine Fixes[/b](强烈推荐所有玩家使用),你必须调整其配置文件以防止与本模组冲突。

[list]
[][color=#ff6347][b]你必须禁用的内容:[/b][/color]打开你的 Engine Fixes 配置文件,找到修补睡觉/等待时间计算的设置。你必须将 [b]bFixSleepWaitTimeCalculation=0[/b](位于 [b]Fixes[/b] 部分下)。如果你保持启用此选项,两个模组将争相向引擎的单一变量注入各自的值,导致行为异常并破坏切换逻辑。[/]
[][color=#32cd32][b]你应该启用的内容(以获得最大性能):[/b][/color]在本模组极端时间跳跃的开发和严格测试过程中,发现创造引擎2严重依赖后台脚本来正确计算和填充前哨站容器。确保 Engine Fixes 中 [b]Features[/b] 部分下与加载优化相关的设置(如 [b]bEngineLoadOptimizer=1[/b])和 Papyrus 脚本限制(如 [b]bPapyrusArrayNoLimit[/b])保持[b]启用[/b]状态。这会优化引擎无缝处理我们庞大的3到4小时时间块的能力,而不会丢弃后台任务或中止模拟循环。[/]
[/list]
[size=5][color=#e6a822]❓ 常见问题与技术细节[/color][/size]
[line]
[spoiler]
[color=#87cefa][b]为什么需要切换模式?(时间块引擎限制)[/b][/color]
本模组以异步方式运行,对游戏的 UI 菜单完全“视而不见”。它不知道你在屏幕上选择了多少小时。相反,它只是拦截你的热键按下,并向专门控制睡觉或等待期间时间流逝的特定引擎变量注入一个巨大的值。

在原版游戏中,这个时间步长变量被设置为1800(每个内部引擎刻恰好0.5游戏内小时)。由于引擎每小时更新两次,这导致了你在 UI 菜单上看到的1小时视觉跳跃。本模组的极速速度使用巨大的值(例如,每次视觉跳跃3或4游戏内小时)。因此,引擎被迫以大的“块”来处理时间。

虽然引擎在技术上可以处理分配给该变量的任意秒数,但极速速度被有意设计为默认值(1800)的大倍数,以便完整的时间块能整齐地融入24小时周期,不留下任何时间。由于模组注入的是固定的、巨大的块大小,游戏的等待循环将处理尽可能多的完整块。然而,它会完全忽略你在 UI 滑块上选择的、不构成完整极速块的任何剩余小时。这不是 bug,而是在 UI 计算等待循环时注入大型静态时间步长的直接后果。

本模组通过切换模式解决了这个问题。默认情况下,它以高度加速的[b]极速[/b]运行,以实现大规模跳跃。但如果你需要精确等待5小时而不损失一点时间,只需按下 [b]修饰键 + 1[/b] 即可立即强制切换为[b]原版[/b]速度,无需离开游戏即可实现精确控制。

[line]

[color=#87cefa][b]详细分析:“盲”块缺陷[/b][/color]
由于模组注入的是静态块大小,引擎将截断任何不构成完整块的剩余时间。这意味着如果你使用极速模式进行精确等待,你实际上会“丢失”或跳过一些小时。

以下是这种引擎限制如何根据你的输入影响实际经过小时数的确切情况:

[table][tr][th]选择的等待时间[/th]
[th]HoursPerTick = 2(2小时块)[/th]
[th]HoursPerTick = 3(3小时块)[/th]
[th]HoursPerTick = 4(4小时块)[/th]
[/tr]
[tr][td]1小时[/td]
[td]0小时(忽略)[/td]
[td]0小时(忽略)[/td]
[td]0小时(忽略)[/td]
[/tr]
[tr][td]2小时[/td]
[td]2小时[/td]
[td]0小时(忽略)[/td]
[td]0小时(忽略)[/td]
[/tr]
[tr][td]3小时[/td]
[td]2小时(忽略1小时)[/td]
[td]3小时[/td]
[td]0小时(忽略)[/td]
[/tr]
[tr][td]4小时[/td]
[td]4小时[/td]
[td]3小时(忽略1小时)[/td]
[td]4小时[/td]
[/tr]
[tr][td]5小时[/td]
[td]4小时(忽略1小时)[/td]
[td]3小时(忽略2小时)[/td]
[td]4小时(忽略1小时)[/td]
[/tr]
[tr][td]6小时[/td]
[td]6小时[/td]
[td]6小时[/td]
[td]4小时(忽略2小时)[/td]
[/tr]
[tr][td]7小时[/td]
[td]6小时(忽略1小时)[/td]
[td]6小时(忽略1小时)[/td]
[td]4小时(忽略3小时)[/td]
[/tr]
[tr][td]24小时[/td]
[td]24小时(完美匹配)[/td]
[td]24小时(完美匹配)[/td]
[td]24小时(完美匹配)[/td]
[/tr]
[/table]
[i][b]结论:[/b]当你需要等待的小时数无法被你选择的块大小整除时,请始终使用热键切换回原版速度![/i]

[line]

[color=#87cefa][b]为什么不动态计算剩余小时数?[/b][/color]
理论上可以让模组动态缩小最终时间块,使引擎识别确切的剩余小时数。然而,这样做需要模组通过直接挂钩睡觉/等待菜单的 UI 内存来读取你在屏幕上选择的确切小时数。挂钩 UI 需要内存偏移量,这些偏移量会在每次游戏更新时失效,导致立即崩溃(CTD),并会破坏与流行 UI overhaul 模组的兼容性。通过保持“盲”状态并使用安全 GMST 注入的手动切换,本模组几乎不受更新影响且高度兼容。

[color=#87cefa][b]为什么使用这个而不是完全绕过引擎限制的模组?[/b][/color]
当你强制引擎在单个现实世界秒内处理数天的游戏内时间时,你通常只是在快进 UI 时钟。在幕后,创造引擎2依赖严格的时间步长间隔来正确运行后台 Papyrus 脚本、补充商人库存和计算前哨站采集。

试图完全绕过此限制会导致引擎内部日历和模拟数学出现大规模溢出。这会导致严重损坏的场景:要么时钟移动但你的前哨站容器仍然完全为空,导致循环过早中止,要么出现大规模数学错误,打破容量限制。

我们选择了更安全的设计。本模组在加速时间的同时严格保留引擎所需的时间步长逻辑,旨在尽可能准确地维持后台模拟。然而,不可预见的情况仍可能产生意外行为——这正是为什么能够随时无缝切换回原版速度如此重要。

[color=#87cefa][b]为什么 HoursPerTick 设置仅限于 2、3 或 4?[/b][/color]
通过大量测试,这些值代表了引擎稳定性的绝对极限:
[list]
[][b]2小时/刻(7200):[/b]前哨站采集器模拟的最大稳定性。[/]
[][b]3小时/刻(10800):[/b]推荐的安全默认值。在引擎开始丢弃后台任务之前的绝对统计平衡极限。[/]
[][b]4小时/刻(14400):[/b]非常快,提供少量采集加成但略微降低稳定性。[/]
[/list]超过4小时的选项已从本模组中永久移除,因为它们保证会导致上述大规模日历溢出和模拟失败。

[color=#87cefa][b]为什么使用原生 DLL 而不是 ESM 或 CCR(控制台命令运行器)模组?[/b][/color]
ESM 文件将更改直接烘焙到你的存档文件中(存档膨胀)。CCR 或 bat 模组通常只运行静态命令。本模组是一个原生 C++ 插件,它异步动态拦截键盘输入以实时更改引擎变量。它对你的存档文件零足迹,运行速度显著更快,并允许标准脚本无法实现的实时键位绑定逻辑。[/spoiler]

[size=5][color=#e6a822]🔬 研究数据与引擎异常[/color][/size]
[line]
[spoiler]
[color=#87cefa][b]前哨站采集实验[/b][/color]
为了找到最稳定的等待时间,我们进行了大量测试:在一个拥有3个铕采集器(每小时40产量)和26个容器(容量75质量单位)的前哨站睡觉24个本地小时。在该位置,1本地小时等于5小时52分钟 UT。在睡这24小时之前,本地时间为17:41,UT时间为22:44。

以下是加载同一存档文件的实证结果:

[table][tr][th]设置[/th]
[th]本地时间[/th]
[th]UT 时间[/th]
[th]使用的容器[/th]
[th]最终容器质量[/th]
[th]其他容器质量[/th]
[th]铕总量[/th]
[/tr]
[tr][td]原版游戏(无模组)[/td]
[td]17:20[/td]
[td]19:28[/td]
[td]14[/td]
[td]77[/td]
[td]77(x12),7[/td]
[td]1,008[/td]
[/tr]
[tr][td]HoursPerTick = 2[/td]
[td]17:20[/td]
[td]19:28[/td]
[td]12[/td]
[td]93[/td]
[td]93(x11)[/td]
[td]1,116[/td]
[/tr]
[tr][td]HoursPerTick = 3[/td]
[td]17:20[/td]
[td]19:28[/td]
[td]12[/td]
[td]92[/td]
[td]92(x11)[/td]
[td]1,104[/td]
[/tr]
[tr][td]HoursPerTick = 4[/td]
[td]17:20[/td]
[td]19:28[/td]
[td]9[/td]
[td]124[/td]
[td]124(x8)[/td]
[td]1,116[/td]
[/tr]
[tr][td]HoursPerTick = 6(已移除)[/td]
[td]11:25[/td]
[td]08:18[/td]
[td]9[/td]
[td]93[/td]
[td]93(x8)[/td]
[td]837[/td]
[/tr]
[tr][td]HoursPerTick = 12(已移除)[/td]
[td]05:30[/td]
[td]21:07[/td]
[td]3[/td]
[td]187[/td]
[td]187(x2)[/td]
[td]561[/td]
[/tr]
[tr][td]Starfield Engine Fixes(等待补丁)[/td]
[td]17:20[/td]
[td]19:28[/td]
[td]3[/td]
[td]375[/td]
[td]375(x2)[/td]
[td]1,125[/td]
[/tr]
[/table]
[color=#87cefa][b]发现的其他引擎异常:[/b][/color]
[list]
[]即使在基础原版游戏中,容器在睡觉或等待时也可能超过75质量单位的最大限制。对于铕,该值在76到77之间波动。[/]
[]使用加速速度时,这种容器溢出效应被大幅放大。根据设置不同,容器会将92到124质量单位塞入75容量的容器中。[/]
[]当模组激活时在着陆的飞船内睡觉,容器通常会以不均衡的方式超过其容量,链接中的最后一个容器通常比其余容器多容纳一些单位。[/]
[]基础游戏似乎在睡觉/等待时间跳跃期间严重惩罚或错误计算资源采集。使用本模组的加速速度略微抵消了这种惩罚,尽管它会导致资源分布不均,将更大量的资源集中到更少的容器中。[/]
[]当使用极端加速速度(超过4小时/刻)时,商人库存有时需要等待超过48小时才能完全补货。[/]
[]当将引擎推至超过每刻4小时时,本地和 UT 时间计算变得完全混乱。引擎不是落在数学上精确的时间,而是强制提前中止循环。[/]
[/list][/spoiler]

[size=5][color=#e6a822]⚙️ 需求与安装[/color][/size]
[line]
[b]需求:[/b]
[list]
[][color=#87cefa][b]Starfield Script Extender(SFSE):[/b][/color]插件加载绝对必需。[/]
[][color=#87cefa][b]Address Library for SFSE Plugins:[/b][/color]插件动态查找游戏内部内存地址所必需。[/]
[][i]注意:作为原生 C++ 插件,本模组可能需要随 Starfield 重大游戏补丁一同更新。我会尽力保持更新![/i][/]
[/list]
[b]安装说明:[/b]
[list=1]
[]确保你已安装最新版本的 [b]SFSE[/b] 和 [b]Address Library[/b]。[/]
[]使用你偏好的模组管理器下载本模组,或手动下载。[/]
[]如果手动安装,请将 .zip 文件的内容解压到你的 Starfield 游戏目录中。[/]
[]文件必须恰好位于此处:[b][Starfield 文件夹]\Data\SFSE\Plugins\[/b]([i]NativeTimeAcceleration.dll[/i] 和 [i]NativeTimeAcceleration_T.ini[/i])[/]
[][i](可选)[/i]用任意文本编辑器打开 [i].ini[/i] 文件,自定义你的热键和偏好的等待速度。[/]
[/list]
[size=5][color=#e6a822]📝 故障排除 / 日志[/color][/size]
[line]
如果你遇到任何问题,此插件会自动生成详细的日志文件。你可以在以下位置找到它:
[code]%USERPROFILE%\Documents\My Games\Starfield\SFSE\Logs\NativeTimeAcceleration.log[/code]
[size=5][color=#e6a822]💻 源代码[/color][/size]
[line]
你可以在 GitHub 上查看此插件的源代码:
[url=https://github.com/concex2/NativeTimeAcceleration_ToggleMode.git]https://github.com/concex2/NativeTimeAcceleration.git[/url]

[size=5][color=#e6a822]💖 致谢[/color][/size]
[line]
[list]
[]衷心感谢 [b]SFSE 团队[/b](Ianpatt、behippo 及贡献者)构建了使原生模组成为可能的基础脚本扩展器。[/]
[]特别感谢 [b]meh321[/b] 为 SFSE 插件提供的 Address Library,这是现代原生模组的绝对基石。[/]
[]非常感谢 [b]CommonLibSF[/b] 仓库的贡献者为映射创造引擎2所做的持续努力。[/]
[/list]