
钯金
Palladium是一个用于Palworld的服务器端模组框架,它将游戏内事件转化为JSON流,并允许任何外部程序——无论使用何种语言——对其作出响应并对游戏世界进行干预。
查看大图[b]Palladium[/b] 是《幻兽帕鲁》专用服务器的一个模组框架。
将包含 [i]mod.lua[/i] 的文件夹放在旁边,Palladium 就会加载它,注册其声明的权限,为其提供跨重启的存储空间,路由其聊天命令,并将每个游戏内事件传递给它。一个模组就是一个文件——无需构建步骤,无需运行进程,无需连接任何东西。
它还将其发布到磁盘,因此游戏外部的任何东西也可以驱动服务器:Discord 中继、商店机器人、网页面板,或者你自己的工具,使用任何语言编写。
UE4SS Lua 没有网络访问权限,这就是大多数《幻兽帕鲁》集成止步于“读取日志文件”的原因。Palladium 补全了缺失的另一半——它将脆弱的引擎钩子集中在一个地方,并在其两侧提供稳定的契约。
[size=6]模组就是一个文件[/size]
[code]-- Mods/GoldStreak/mod.lua
return {
name = "GoldStreak",
api = 1,
description = "坚持不懈的奖励:每第五次重生获得金币。",
-- 为你注册,并列出在权限配置中供操作员查看。
permissions = {
{ node = "goldstreak.reward", description = "在重生连续奖励中获得金币", default = "allow" },
},
-- 操作员无需触碰你的代码即可编辑这些设置。
settings = { every = 5, item = "Money", count = 50 },
on = {
["player.respawn"] = function(event, pal)
local who = event.subject.id
if not pal.can(who, "goldstreak.reward") then return end
local streak = (tonumber(pal.tag(who, "respawns")) or 0) + 1
pal.set_tag(who, "respawns", streak) -- 在重启后依然有效
if streak % pal.settings.every ~= 0 then return end
pal.give(who, pal.settings.item, pal.settings.count)
pal.message(who, ("重生 %d 次——这是 %d 金币。"):format(streak, pal.settings.count))
end,
},
commands = {
["!streak"] = {
node = "goldstreak.reward",
run = function(event, args, pal)
pal.message(event.subject.id, "重生次数:" .. (pal.tag(event.subject.id, "respawns") or "0"))
end,
},
},
}[/code]这就是整个模组,它随项目一起提供,因此你可以在编写自己的模组之前阅读它。将文件夹放入,重启,完成。
[b][i]pal[/i] 为你提供的功能:[/b] [i]call[/i](所有能力)、[i]give[/i]、[i]message[/i]、[i]heal[/i]、[i]can[/i]、[i]tag[/i]、[i]set_tag[/i]、[i]data[/i]、[i]settings[/i]、[i]log[/i]。
[size=6]存储——键/值及其他[/size]
两种形式,一个 API。模组声明它需要哪种;两者都位于 [b]模组自己的文件夹中[/b],因此配置和记录随模组一起移动,删除文件夹即可干净卸载。
[list]
[][b]标签(Tags)[/b] —— 每个玩家一个值,快速选项:[i]pal.tag(who, "count")[/i] 和 [i]pal.set_tag[/i]。按模组进行命名空间隔离,因此两个模组可以各自保存一个“count”而不会冲突。[/]
[][b]集合(Collections)[/b] —— 任何需要更多结构的数据:[/]
[/list][code]data = {
homes = {
description = "玩家设置家的位置",
fields = { x = "number", y = "number" },
storage = "data", -- 或 "config",用于你打算手动编辑的文件
},
},
-- 然后,在模组中的任意位置:
local homes = pal.data("homes")
homes:set(who, { x = "120.5", y = "88.0" })
homes:get(who) homes:all() homes:delete(who)[/code][list]
[][b]storage = "data"[/b] → [i]Mods/YourMod/yourmod.data[/i]。一个在内存中建立索引的追加日志。数千条记录,无人手动编辑。因崩溃而损坏的行会被丢弃,文件在下次加载时自愈。[/]
[][b]storage = "config"[/b] → [i]Mods/YourMod/yourmod.config[/i]。INI 格式,供操作员打开。修改会在几秒钟内被捕捉,无需重启。[/]
[/list]因为集合是 [i]声明[/i] 而非发现的,任何东西都可以列出已存在的内容、读取其结构并编辑它,而无需了解模组本身——包括面板(如果你运行 pal-up)。
[size=6]权限[/size]
一个文件,[i]Mods/Palladium/permissions.config[/i],由 Palladium 写入,你可自行编辑:
[code]; 已安装模组注册的每个权限节点及其默认值
[nodes]
goldstreak.reward = allow ; 在重生连续奖励中获得金币
pal.spawn = deny ; 每个能力也是一个节点
[groups default]
is_default = true
weight = 0
[groups moderator]
tag = MOD
weight = 50
allow = goldstreak.reward
allow = pal.spawn where species in SheepBall,Lamball and level <= 20
[players F8EAA197000000000000000000000000]
groups = moderator
deny = goldstreak.reward[/code][list]
[][b][nodes] 区块会自动填充。[/b] 安装模组,重启,所有可被门控的内容都会列出来,并带有其请求的默认值。[/]
[][b]解析顺序:[/b] 玩家自身的覆盖设置,然后按其权重加入的组,然后是默认组,最后是节点的默认值。精确节点优先于 [i]kits.[/i] 优先于 [i][/i],而拒绝(deny)在平局时胜出。[/]
[][b]约束条件会缩小授权范围[/b] 至满足条件的调用——[i]in[/i]、[i]=[/i]、[i]!=[/i]、[i]<[/i]、[i]<=[/i]、[i]>[/i]、[i]>=[/i],用 [i]and[/i] 连接。在游戏进程中强制执行,因此模组、聊天命令和 HTTP 调用都会得到相同的答案。[/]
[][b]你的修改优先于模组设置。[/b] 每次启动时重新注册不会将默认值覆盖回你的设置之上。[/]
[][b]错误的编辑会被报告,而不是静默丢弃[/b] —— 拼写错误的区块、未声明的字段、错误类型的值或不符合 [i]key = value[/i] 的行都会被记录,并显示其行号和接近的匹配名称。能解析的内容仍会加载;一个错误行绝不会导致整个文件失效。[/]
[/list][size=6]聊天命令[/size]
模组可以自行声明命令,自动带有权限控制和冷却时间。而且 [b]每个能力本身就是一个命令[/b],由自己的节点控制:
[code]!pal.spawn species=Lamball level=20
!player.give_item item=PalSphere count=5 target=F8EA…[/code]这些节点默认是 [b]deny(拒绝)[/b],因此开箱即用时,这只是一个管理界面,仅此而已。将 [i]pal.spawn[/i] 授权给管理员组,其成员即可获得该命令——无需模组,无需重启。
[size=6]从游戏外部驱动[/size]
Palladium 将事件写入一个文件,并将执行的动作写回另一个文件。这就是整个契约,无论是否使用 pal-up 都能工作。
[b]使用 pal-up[/b],你可以通过 HTTP API 访问它,并带有作用域的承载令牌:
[code]curl -H "Authorization: Bearer $TOKEN"
"http://server:3000/api/bridge/events?since=0&type=player.chat"
curl -H "Authorization: Bearer $TOKEN" -X POST http://server:3000/api/bridge/call
-H 'content-type: application/json'
-d '{"type":"player.give_item","target":"PLAYER_ID","data":{"item":"PalSphere","count":5}}'[/code]通过游标跟随流,从 [/api/bridge/schema] 发现当前可用的内容,并通过唯一的调用动词发送所有请求。用另一种语言重写消费者只需一个认证头和 JSON。通过这种方式可以访问 53 项能力,包括读写任意模组的存储数据。
[b]独立使用[/b]时,你自己读写这两个文件:
[list]
[][b]写入[/b] [i]logs/bridge-events.jsonl[/i] —— 每行一个 JSON 事件[/]
[][b]读取[/b] [i].state/bridge-actions.jsonl[/i] —— 每行一个以制表符分隔的 键=值 请求[/]
[/list]两者都相对于状态根目录,并且都应在服务器启动时清空——在你的启动脚本中截断它们。
[size=6]独立 vs. pal-up[/size]
Palladium 只需要 UE4SS。pal-up 是一个 Docker 堆栈,随附 Web 面板和 HTTP API。
[code] 单独使用 Palladium 使用 pal-up
模组加载和运行 是 是
权限、组、约束 是 是
每个模组的存储和标签 是 是
聊天命令 是 是
手动编辑 permissions.config 是 是
磁盘上的事件和操作 是 是
带作用域令牌的 HTTP API 否 是
网页面板:每个能力的表单 否 是
物品/帕鲁/特性/位置选择器 否 是
实时事件流、权限编辑器 否 是
模组页面,显示每个模组的存储内容 否 是
用 JavaScript / TypeScript 编写的模组 否 是
服务器本身:备份、更新、设置 否 是[/code]最后一行对大多数人来说才是真正的区别:pal-up 也是一个完整的《幻兽帕鲁》服务器——UE4SS 固定版本并经校验和验证、模组文件夹路由、来自环境变量的配置、安全更新、定时备份。
用 JS 或 TypeScript 编写的模组是 pal-up 的一项功能,因为它们在 [i]游戏外部[/i] 作为面板的子进程运行,这是模组唯一能访问网络的方式——UE4SS Lua 没有套接字。
[size=6]当前可用功能 (v4.0.0)[/size]
[b]已在真实服务器上测试[/b]
[list]
[]聊天、加入和帕鲁生成事件[/]
[]给予物品、读取玩家位置、广播[/]
[]列出并检查世界中加载的帕鲁[/]
[]玩家标签、保存的位置、API 令牌[/]
[/list][b]已构建并通过测试,但尚未与玩家确认[/b]
[list]
[]v4.0.0 是一次重大重构——模组框架、每个模组的存储、在游戏进程中解析的权限以及聊天命令界面都是新增的[/]
[]死亡、重生和离开事件[/]
[]私信、传送、治疗[/]
[]读取和设置玩家及帕鲁属性、物品计数[/]
[/list][b]实验性功能[/b]
[list]
[]帕鲁生成可用,并遵循等级、稀有度和特性——但生成的帕鲁获得的是基础 NPC AI 控制器,没有战斗行为:它既不攻击也不反击。[i]pal.aggro[/i] 是绕过此问题的方法,通过种子仇恨系统让帕鲁反击。[/]
[][i]pal.force_spawn[/i] 要求世界自身的生成器触发,生成一个拥有野生帕鲁 AI 的帕鲁——生成器选择物种和位置。[/]
[]通过这种方式生成的帕鲁不会出现在世界存档中,并在重启后消失。[/]
[/list][b]此加载器上无法实现的功能[/b]
[list]
[]帕鲁捕获事件——钩子目标是蓝图,而蓝图目标会导致进程崩溃而非干净地失败[/]
[]游戏内聊天中的角色前缀——写入聊天钩子的消息参数会导致此构建崩溃[/]
[]取消事件——这是观察-响应,而非拦截。没有聊天过滤器,没有防止(而非逆转)的防恶意破坏机制[/]
[]离开也没有钩子;代理会观察谁仍在世界中,并在几秒钟内报告[/]
[/list][size=6]安装[/size]
[size=4][b]选项 A——使用图形界面 (Linux, Windows, macOS)[/b][/size]
使用 [url=https://github.com/s-kiu/pal-up]pal-up[/url]:一个完整的《幻兽帕鲁》服务器,包含在 Docker 中,预装了 UE4SS 和 Palladium,以及网页面板。
[code]git clone https://github.com/s-kiu/pal-up.git && cd pal-up
cp .env.example .env # 设置 ADMIN_PASSWORD
docker compose up -d --build[/code]打开 http://your-host:3000,登录,并使用 Palladium 选项卡。将模组放入 [i]./mods[/i];它们的配置和数据会出现在项目文件夹中它们的旁边,可用你自己的编辑器编辑。在 Apple Silicon 上,它会在模拟下运行——适合测试,但对于正式服务器来说较慢。
[size=4][b]选项 B——独立安装,在现有 UE4SS 服务器上[/b][/size]
[b]Linux[/b]
[list]
[]安装 UE4SS——Linux 服务器需要原生社区移植版。[/]
[]将 Palladium 文件夹复制到 [i]<server>/Pal/Binaries/Linux/Mods/Palladium/[/i] [/]
[]如果你手动管理 mods.txt,请添加:[i]Palladium : 1[/i] [/]
[]重启服务器。[/]
[/list]状态会写入 [i]/palworld[/i](如果存在),否则写入服务器旁边的 [i]palladium/[/i] 文件夹。若想放到其他位置,请在启动前设置 PAL_ROOT:
[code]export PAL_ROOT=/opt/palworld[/code][b]为其安装模组:[/b] 将模组的文件夹放在 Palladium 旁边,并在 [i]Mods/Palladium/mods.list[/i] 中命名它,每行一个:
[code]; Palladium 加载的模组,按顺序
GoldStreak[/code]如果没有该文件,Palladium 会向加载器请求目录列表,这在 Linux 上有效,但并非所有构建都保证支持——列表是可靠的方式,这也是你控制加载顺序和在不删除模组的情况下禁用它 的方法。
[b]Windows[/b]
[list]
[]安装 UE4SS (RE-UE4SS)。[/]
[]将 Palladium 文件夹复制到 [i]<server>\Pal\Binaries\Win64\Mods\Palladium\ [/i] [/]
[]如果你手动管理 mods.txt,请添加:[i]Palladium : 1[/i] [/]
[][b]自行创建状态文件夹并设置 PAL_ROOT。[/b] 目录创建使用 Windows 没有的 POSIX 命令,因此该文件夹必须已存在。使用正斜杠。[/]
[]使用 [i]mods.list[/i] 来命名要加载的模组——目录列表回退也是 POSIX 的。[/]
[]重启服务器。[/]
[/list][code]set PAL_ROOT=C:/PalServer/palladium[/code]或将其设置为系统环境变量,以便重启后依然有效。Windows 未经测试——该模组是在 Linux 上开发和验证的。
[b]macOS[/b]
没有 macOS 版本的《幻兽帕鲁》专用服务器——它仅适用于 Windows 和 Linux。请使用选项 A(Docker)或 Linux 虚拟机。
[size=4][b]确认其已加载[/b][/size]
UE4SS.log 应显示此信息,然后是它找到的模组,然后是每个钩子一行:
[code][Palladium] v4.0.0 已加载 (信封 2),事件 -> /palworld/logs/bridge-events.jsonl
[Palladium] 框架:通过 mods.list 扫描 Mods — 1 个文件夹
[Palladium] 框架:已加载 GoldStreak (1 个处理器,1 个命令)[/code][size=6]文档[/size]
编写模组、完整的能力参考、HTTP 契约和可运行示例:[url=https://github.com/s-kiu/pal-up]github.com/s-kiu/pal-up[/url]
[b]需要 UE4SS。[/b] 针对 Linux 社区移植版 Qiiks/ue4ss-linux-palworld v1.0.3-palworld-linux 开发,该版本是 BlackBookOfficial 移植版的一个分支。已在《幻兽帕鲁》v1.0.2.101103(Steam 构建 24466863)上验证。仅限服务器端——在客户端上不执行任何操作。
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。