鼓掌之间 发表于 2026-5-16 18:17

《深海迷航2》MOD设置工具(附汉化)(2026-06-26更新)

本帖最后由 鼓掌之间 于 2026-6-26 10:35 编辑

转自:https://www.nexusmods.com/subnautica2/mods/20

在《深海迷航2》的设置菜单中添加一个"MOD"标签页,供其他MOD注册各自的设置选项。所有接入本工具的MOD都需要依赖它运行。部分设置可跨会话保存,且能实时生效,无需重新加载存档。安装完成后,任何支持本工具的MOD都会自动在该标签页中显示其配置选项。

安装说明
- 必须先安装《深海迷航2》专用的UE4SS:https://bbs.3dmgame.com/thread-6673249-1-1.html
- 下载最新版本的SN2ModSettings-vX.Y.zip压缩包。使用Vortex(或其他MOD管理器)直接安装即可,压缩包的目录结构已预设为可直接放入UE4SS的MOD文件夹。手动安装时,将文件解压至<深海迷航2安装目录>\Subnautica2\Binaries\Win64\ue4ss\Mods\。无论哪种安装方式,最终MOD文件都应位于ue4ss\Mods\SN2ModSettings\目录下。
- Linux/Proton(应该也包括Steam Deck)用户请参考这篇帖子:https://www.nexusmods.com/subnau ... m&topic_id=16880213

本工具本身不会添加任何可见内容。只有当至少有一个支持本工具的MOD注册了设置后,"MOD"标签页才会显示。

给MOD开发者的说明
如果你的项目使用了本设置工具,请给我发消息,我会在页面底部添加你的链接!:D

SN2ModSettings会在游戏内设置界面添加一个"MOD"标签页。你的MOD只需在SN2ModSettings/registrations/目录下放置一个Lua清单文件,本库就会使用与原版菜单相同的控件类渲染UI界面。数值使用滑块控件,布尔值使用开关控件,并支持可选的启用依赖控制,让主开关可以灰化其所有子选项。

每个注册的MOD都会在"MOD"标签页中拥有独立的分区,以你设置的显示名称作为分区标题(样式与原版的"显示"、"音频"等标题一致)。MOD按名称字母顺序排列,确保每次启动游戏时顺序稳定。当用户选中某个设置项(鼠标悬停或通过键盘/手柄聚焦)时,描述信息会显示在右侧面板中。

当用户修改设置时,新值会同步到UE4SS的SharedVariable(内存中的跨MOD变量),同时写入SN2ModSettings/saved/<你的MOD名>.lua文件进行持久化。你的MOD可以在一个1秒的异步循环中读取SharedVariable,并实时应用更改。无需重新加载存档,也不需要每帧执行文件I/O操作。

UE4SS为每个LuaMOD提供了独立的隔离全局环境(_G),因此你无法通过全局变量或require语句在MOD间共享表。SharedVariable是UE4SS官方的跨MOD通信通道;而保存文件则作为持久化和调试层。

文件布局

ue4ss/Mods/SN2ModSettings/
├── registrations/
│└── YourMod.lua    <- 你在加载时编写此文件
└── saved/
   └── YourMod.lua    <- 本库将用户调整后的值写入此处


编写你的清单文件
选择一个简短且稳定的名称。它会同时作为注册文件和保存文件的文件名,因此发布后不要更改,否则会导致用户已保存的设置全部丢失。

local MANIFEST_PATH = "./ue4ss/Mods/SN2ModSettings/registrations/MyMod.lua"

local function write_text(path, body)
    local dir = path:match("(.*[/\\])")
    os.execute('mkdir "' .. dir:gsub("/", "\\") .. '" 2>nul')
    local f = io.open(path, "w")
    if not f then return false end
    f:write(body)
    f:close()
    return true
end

local manifest = [=[
return {
    name    = "MyMod",
    display = "我的MOD",
    settings = {
      {
            key="Enabled",
            title="启用MOD",
            description="总开关。关闭时,下方的滑块将变为灰色不可用状态。",
            type="toggle",
            default=true
      },
      {
            key="Intensity",
            title="强度 (%)",
            description="效果强度。100 = 原版效果。",
            type="slider",
            default=1.0,
            min=0.0,
            max=2.0,
            step=0.1,
            format="percent",
            enabled_by="Enabled"
      },
      {
            key="FOV",
            title="视场角",
            description="相机视场角,单位为度。",
            type="slider",
            default=90.0,
            min=60.0,
            max=120.0,
            step=1.0,
            format="integer",
            enabled_by="Enabled"
      },
    },
}
]=]

write_text(MANIFEST_PATH, manifest)


顶级清单键说明
- name:内部ID和保存文件的基础名称。简短、稳定,发布后不要更改。
- display:在"MOD"标签页中显示的分区标题(例如"消耗速率"、"简易制作")。
- settings:设置定义数组。

单个设置项键说明
- key:保存文件中使用的字段标识符。
- title:控件旁边显示的标签。省略时将使用key作为替代。
- description:用户选中设置项时在右侧面板显示的描述。可省略。
- type:控件类型,可选值为"slider"(滑块)或"toggle"(开关)。
- default:滑块的默认数值,开关的默认布尔值。请确保此值与你在Lua代码中的默认值保持一致。
- enabled_by(可选):同一MOD中另一个设置项的key。当该设置项的值为假(开关关闭或数值为0)时,当前控件将变为灰色并停止响应输入。

滑块额外参数
滑块还接受min、max、step和format参数:
- step:数值增量(例如0.1表示保留一位小数)。浮点数/百分比格式默认值为0.1,整数格式默认值为1.0。
- format(可选):滑块数值在轨道旁的显示方式:
- "float"(默认):显示原始小数值。适用于距离、视场角度数、不需要显示为百分比的乘数等。
- "integer":显示四舍五入后的整数。适用于计数和毫秒数。
- "percent":将数值乘以100并添加%后缀。仅当你的滑块在语义上表示百分比时使用(例如1.0代表100%原版效果的乘数)。

最小值和最大值会显示在滑块轨道的两端。

读取保存的值
提供两种读取方式,选择最适合你MOD的一种。两种方式会保持同步。

方式1(推荐):UE4SS SharedVariable,按设置项存储原始值
从v1.0.8版本开始,本库会将每个设置项单独作为原生Lua基本类型进行同步,键格式为"SN2ModSettings/<你的MOD名>/<设置项key>"。无需序列化、无需load()、无需pcall()。只需直接获取值,会返回数字、布尔值或字符串。内存读取几乎没有性能开销,因此即使有数十个MOD同时轮询也不会影响性能。本库会在启动时使用你的默认值初始化所有SharedVariable,因此在用户本次会话中拖动任何滑块之前,第一次读取就会返回有效数据。

local Config = {
    Enabled= true,-- 默认值;会被SharedVariable读取结果覆盖
    Intensity = 1.0,
}

local function LoadFromShared()
    if not ModRef then return false end
    local changed = false
    for k, _ in pairs(Config) do
      local v = ModRef:GetSharedVariable("SN2ModSettings/MyMod/" .. k)
      if v ~= nil and type(v) == type(Config) and Config ~= v then
            Config = v
            changed = true
      end
    end
    return changed
end

LoadFromShared()-- 启动时初始化

LoopAsync(1000, function()
    -- 在异步循环线程中进行轻量检查(内存读取不需要游戏线程)
    -- 仅当配置实际发生变化时才安排应用操作
    if not LoadFromShared() then return end
    ExecuteInGameThread(function()
      print("[我的MOD] 配置已更改,正在重新应用")
      -- 应用 Config.Enabled / Config.Intensity 等设置
    end)
end)


方式2(传统):文件轮询
本库仍会在每次设置变更时写入SN2ModSettings/saved/<你的MOD名>.lua文件。如果你希望方便调试(直接打开文件查看)或需要直接访问持久化层,可以使用此方式。每次轮询会产生磁盘I/O操作,以及一次load()/pcall()解析过程:

local Config = {
    Enabled= true,-- 必须与清单中的默认值一致
    Intensity = 1.0,
}

local function LoadSavedConfig()
    local f = io.open("./ue4ss/Mods/SN2ModSettings/saved/MyMod.lua", "r")
    if not f then return false end
    local content = f:read("*all")
    f:close()
    if not content or content == "" then return false end
    local loader = load(content)
    if not loader then return false end
    local ok, data = pcall(loader)
    if not ok or type(data) ~= "table" then return false end

    local changed = false
    for k, v in pairs(data) do
      if Config ~= nil and type(v) == type(Config) and Config ~= v then
            Config = v
            changed = true
      end
    end
    return changed
end

LoadSavedConfig()-- 启动时读取已保存的值

LoopAsync(1000, function()
    ExecuteInGameThread(function()
      if LoadSavedConfig() then
            print("[我的MOD] 配置已更改,正在重新应用")
      end
    end)
end)


支持的控件
目前支持:滑块和开关。计划但尚未实现:下拉框(combobox)、按钮(动作触发器)、单选组(radio)。原版《深海迷航2》的设置使用了所有这些控件,因此底层控件类已经存在。快捷键绑定优先级较低,因为它需要通过EnhancedInput用户设置系统实现,流程更复杂。

注意事项
1. 本库会在启动时使用你的默认值为每个清单设置项初始化SharedVariable,即使用户本次会话中还没有拖动过滑块。因此,你的Lua代码中的Config默认值实际上只在MOD加载到第一次SharedVariable读取之间的短暂窗口内有效。
2. 保存值类型:滑块值返回Lua数字类型,开关返回布尔类型。如果你需要整数滑块,请在你的代码中进行四舍五入。
3. enabled_by仅作用于UI层面。灰化滑块只会阻止用户拖动,但不会改变MOD从磁盘读取的值。如果你的主开关关闭,MOD需要自行控制其行为。《深海迷航2-消耗速率》MOD提供了参考模式:主开关关闭时强制所有乘数为原版1.0;主开关重新打开时从保存的滑块值恢复。
4. 本库会在设置变更的瞬间写入保存文件,但实际应用更改是你MOD的责任。特别是对于GAS属性,你需要使用OnRep_<字段名>聚合器刷新技巧;《深海迷航2-消耗速率》MOD有可工作的参考实现。没有这个技巧,游戏效果捕获会保持陈旧状态,你的更改只有在重新加载存档后才会生效。
5. 发布后不要重命名你的MOD——name是保存文件的键,更改它会导致所有用户的现有设置丢失。

下载地址:

**** Hidden Message *****

Wayne072401 发表于 2026-5-16 19:20

00000000000000000000

rongshuxia85 发表于 2026-5-16 19:20

666666666666666666666666666666666666666666666666

qq3434225189 发表于 2026-5-17 11:02

感谢分享

似水痴流年 发表于 2026-5-17 11:48

32112313231232

鼓掌之间 发表于 2026-5-17 15:38

2026-05-17更新

lukehuangch 发表于 2026-5-17 16:24

谢谢分享!

luoyunpao536 发表于 2026-5-17 16:33

6666666666666

13524600w 发表于 2026-5-17 16:35

6666666666666666666

配谈. 发表于 2026-5-17 16:50

RE: 《深海迷航2》MOD设置工具(2026-05-17更新) [修改]








专属你 发表于 2026-5-17 17:30

66666666666666

12345aaak 发表于 2026-5-17 18:59

66666666666666666

skyren2005 发表于 2026-5-17 19:21

dddddddddddddddddddddddd

乒乒rose 发表于 2026-5-17 19:24

666666666666666666666666666

3dm_19390468 发表于 2026-5-17 19:35

666666666666

wtf冰峰 发表于 2026-5-17 21:33

6666666666666

触星枝 发表于 2026-5-17 22:04

66666666666666

xutaogh 发表于 2026-5-17 22:31

看一下,好东西

z1140761342 发表于 2026-5-17 22:58

5555555555555555

ali213com 发表于 2026-5-17 23:16

~~~~~~~~~~~~~~~~

sototo 发表于 2026-5-17 23:27

感谢分享!!感谢!

shawn0325 发表于 2026-5-17 23:42

感谢分享

dadiaowang12 发表于 2026-5-17 23:48

:):):):):):):):):)

3dm9w_35512612 发表于 2026-5-18 00:20

感谢分享

大鳄鱼皮 发表于 2026-5-18 10:19

11111111111111

zxylikeps33 发表于 2026-5-18 10:31

感谢分享!!!!!

BeyondのParadise 发表于 2026-5-18 11:34

66666666666

zxhaochen-n 发表于 2026-5-18 11:36

感谢分享

hexiliang33 发表于 2026-5-18 12:50

感谢大佬

king820 发表于 2026-5-18 13:08

多谢分享!!!!
页: [1] 2 3 4 5 6
查看完整版本: 《深海迷航2》MOD设置工具(附汉化)(2026-06-26更新)