BreedHumans - 两个人类制造一个人类

BreedHumans - 两个人类制造一个人类

两个人类在繁殖场中产出一个随机人类,而不是Chikipi。一个pak将人类注册为可以被出生的生物——基础游戏从未如此——而Lua模组为每个蛋都会随机一个不同的。服务端:客户端无需安装任何东西,包括主机玩家。

[size=5][b]繁殖农场中的两个人类会生出一个人类,而不是一只鸡鸡帕鲁[/b][/size]



你可以在《幻兽帕鲁》中捕获人类——商人、士兵、猎人——并将他们放入繁殖农场。机器会接受他们,运行繁殖周期,然后产出[鸡鸡帕鲁]的蛋。永远如此。

这是因为游戏会从一张以父母双方[种族]为索引的表格中选择子代,而“人类+人类”没有对应的条目。由于没有匹配项,它会回退到默认值。

这个模组创建了该条目,并为每个蛋随机生成一个人类。

[size=4][b]服务器端。客户端无需安装任何东西。[/b][/size]

`.pak`文件放在服务器的`~mods`文件夹中,Lua模组在服务器上的UE4SS环境下运行。PC、Xbox和PlayStation玩家无需改动任何文件,即可获得相同的游戏行为。

[b]已在原生Linux专用服务器上经过生产环境测试[/b],使用的是[url=https://www.nexusmods.com/palworld/mods/5393]我们的GLIBC 2.28 UE4SS构建版本[/url]——该页面提供的组件是让这一切在Linux上运行的关键,此处已将其列为前置要求。在Windows专用服务器上,则使用官方UE4SS。

在《幻兽帕鲁》[b]v1.0.2.101103[/b]版本、UE4SS 3.0.1、原生Linux(BisectHosting)环境下进行的测试。

[line]

[size=4][b]两个组成部分,且两者都必不可少[/b][/size]

[code]
BreedHumans_P.pak 创建配对关系并将人类注册为可繁殖生物
没有它:模组不生效

Lua模组 为每个蛋随机生成不同的人类
没有它:每次诞生的都是同一个人[/code]
[b]`.pak`文件是模组存在的基础。[/b]Lua脚本仅用于增加多样性。

[size=4][b]安装方法[/b][/size]

[b]1. `.pak`文件[/b]

[code]
Pal/Content/Paks/~mods/BreedHumans_P.pak[/code]
[b]2. Lua模组[/b]

[code]
ue4ss/Mods/BreedHumans/
|- enabled.txt <- 空文件,但必需
|- Scripts/
|- main.lua
|- config.lua
|- humans.lua <- 可生成人类的列表[/code]
安装时请先停止服务器。启动后,`UE4SS.log`中应包含以下内容:

[code]
Loaded; row=20000, reroll=2s, excluded=4 pattern(s)
found row 20000 from the pak, current child: Female_Soldier01
roster: 143 usable (0 absent from this build, 93 not registered by the pak)
next human egg: Believer_Bat[/code]
[b]第二行是关键。[/b]如果你看到的是以下内容:

[code]
row 20000 is missing from DT_PalCombiUnique; BreedHumans_P.pak is not installed[/code]
说明`.pak`文件未被加载,Lua模组将无法正常工作。

[size=4][b]工作原理[/b][/size]

`.pak`文件添加了三个协调一致的表格行,在游戏加载其数据表时生效:

[code]
DT_PalCombiUnique 人类 + 人类 -> <一个人类>
DT_PalBPClass <人类> -> BP_NPC_<...>_C
DT_PalMonsterParameter <人类> 种族 人类,属性从鸡鸡帕鲁克隆[/code]
第一行创建了配对关系。其他两行则是没有人预料到需要的部分:[b]就游戏而言,人类并不是一种可以被“诞生”的生物[/b]。人类只存在于`DT_PalHumanParameter`表中,而繁殖路径永远不会查询该表。如果不将人类注册到其他两个表中,游戏在选定子代后,会去查找需要实例化的对象,结果一无所获——然后[b]根本不会产出任何蛋[/b],甚至连原来的鸡鸡帕鲁蛋也没有。

然后,Lua模组每2秒重写一次该表格行的子代,从`.pak`文件注册的人类中随机选择。

[size=4][b]配置[/b][/size]

所有配置都在`Scripts/config.lua`文件中。

[code]
modEnabled true 开启或关闭模组
combiRowName "20000" `.pak`文件创建的表格行
rerollIntervalSeconds 2 子代变更频率(秒)
startupDelaySeconds 20 首次随机前的等待时间
excludePatterns TestNPC, Arena_, Quest, BOSS_, Reward_ 从随机池中排除的项
logRerolls false 每次随机是否记录日志(验证后关闭)
logLimit 40 日志行数上限
forcedChild nil 固定生成某个特定人类,用于测试[/code]
[list]
[*][b]我想让人类Boss被生出来[/b] - 从`excludePatterns`中移除“BOSS_”[/*]
[*][b]在验证时查看每次随机结果[/b] - 设置`logRerolls = true`[/*]
[*][b]测试模组是否工作[/b] - 设置`forcedChild = "Female_Soldier01"`,然后每个蛋都会孵出这个人[/*]
[/list]
[b]内部名称并非游戏内显示名称。[/b]表格使用内部名称索引:鸡鸡帕鲁是`ChickenPal`,企鹅王是`CaptainPenguin`,火绒狐是`CuteFox`。配置为“Chikipi”将匹配不到任何内容,且症状是静默的——没有蛋,也没有错误。日志会列出它找到的内部名称;请使用这些名称。

[line]

[size=4][b]已知限制[/b][/size]

[b]同期创建的蛋会孵化出同一个人。[/b]表格以种族为索引,而游戏中所有433个人类都共享种族336——因此单一行就能服务所有配对,并且在任何时刻只能指定一个子代。在同一随机窗口期内创建的两个蛋会得到相同的子代。在2秒的间隔下,大多数蛋都能获得自己的随机结果,但相同的配对仍然会发生。

[b]不存在“人类A + 人类A = 人类A”的配方。[/b]原因同上:游戏无法区分不同的人类个体,对表格来说他们都是“人类”。要做到这一点需要为每个人类分配一个独立的种族,而`EPalTribeID`是一个编译进二进制文件的枚举——`.pak`文件只能编辑数据,不能创建新的枚举值。

[b]后代拥有鸡鸡帕鲁的属性。[/b]生命值、攻击力和体型均从鸡鸡帕鲁的表格行克隆而来。功能上没问题,但新生士兵和鸡一样脆弱。可以通过重新构建`.pak`文件来调整。

[b]236个人类中有143个在随机池中。[/b]其余的人类没有可通过名称映射到NPC蓝图。日志会报告被排除的数量。

[b]人蛋看起来和普通蛋一样。[/b]蛋的模型不会改变。

[size=4][b]为什么`.pak`文件是必需的——四次仅Lua的尝试,均经过测量,全部失败[/b][/size]

[code]
启动后30秒添加表格行 行完整且可读取,但从未被查询
加载后0.5秒添加表格行 同样失败 - 不是时序问题
重写真实行的种族 值被写入并读回,但无实际效果
在蛋内部写入子代 值被接受,但孵化出鸡鸡帕鲁
在出生时交换CharacterID 值被接受并读回,但孵化出鸡鸡帕鲁[/code]
将两个种族的配对关联到表格行的索引是在[表格加载时]构建的,基于该时刻存在的行。Lua模组总是迟于这个时机。

基于PalSchema的模组之所以有效,是因为它们在加载前写入表格——但PalSchema只提供`main.dll`,没有`.so`构建版本。在Linux服务器上这条路行不通,因此这些表格行必须通过`.pak`文件提供。

[size=4][b]重新构建`.pak`文件[/b][/size]

如果你想获得不同的随机池、不同的属性,或者游戏更新后,则需要重新构建。所需工具(均无需系统级安装):[url=https://github.com/trumank/retoc]retoc[/url],
[url=https://github.com/trumank/repak]repak[/url],
通过.NET 8运行的[url=https://github.com/atenfyr/UAssetAPI]UAssetAPI[/url],以及一个《幻兽帕鲁》的Mappings.usmap文件。`.usmap`文件是必需的——这些表格使用无版本属性,没有映射文件,资源将作为原始字节打开。

仓库README中有完整的分步指南。

[size=4][b]如果你正在为Linux服务器编写模组,请阅读以下内容[/b][/size]

并非所有UE4SS机制都能在Linux构建版本上工作:

[code]
RegisterHook 可用
ExecuteInGameThreadWithDelay 可用
ExecuteWithDelay / LoopAsync 永不触发
ForEachProperty/ForEachFunction 静默返回零
CanProceedBreeding (2个类) 注册后永不触发[/code]
详细信息及解决方案参见
[url=https://www.nexusmods.com/palworld/mods/5393]UE4SS Linux构建版本页面[/url]。

[size=4][b]源代码[/b][/size]

完整源代码、技术文档和问题跟踪器:
[url=https://github.com/prado1506/palworld-BreedHumans]github.com/prado1506/palworld-BreedHumans[/url]

这是一个在原生Linux专用服务器上验证过的服务器端《幻兽帕鲁》模组合集的一部分。它们所依赖的加载器在[url=https://www.nexusmods.com/palworld/mods/5393]这里[/url]。