幻兽帕鲁自动暂停:停掉的是什么,代价是什么
《幻兽帕鲁》服务器说的「自动暂停」其实是两种不同的功能,只有一种能让你不在的时候帕鲁不饿肚子。它是怎么做到的,又会弄坏什么。
隔一天上线,据点一片狼藉:一半的帕鲁饿着,两只生病,箱子里堆满没人要的矿石。这段时间没有任何人上线,世界却照样在跑。说起这件事,被推荐的通常就是自动暂停。
但这个说法同时指着两种不同的功能,其中一种给不了你要的结果。挑之前先把它们分开。
自动暂停指的两件事
停的是计费。 没人上线的那一段不计费。要让费用停下来,总得有东西是关着的,所以世界通常也跟着停;但这个功能主打的是价格,真正影响你的在后面:它是怎么降下去的,以及回来要多久。
停的是世界。 游戏里的时间不再前进。帕鲁不吃东西,作物不长,没人守的据点也不会有袭击。
要分清楚对方卖的是哪一种,问两个问题就够了:暂停期间世界会不会前进,以及到能重新开玩要等多久。功能列表上的任何一项,都不如第二个问题能把不同做法分开。
没人上线,世界为什么还在动
专用服务器就是一个一直跑着的进程。最后一个人离线之后它不会进入休息,而是按满员时的同一个节奏继续算整个世界:据点的帕鲁继续干活、继续变饿,作物继续长,没人在的据点照样会被袭击。
如果你们是从游戏内开房(一个人开世界、其他人加进去)换过来的,习惯就是在这里对不上。那边的世界住在那个人的游戏里,他一关游戏世界就停了。专用服务器是刻意做成相反的东西:它开着是为了让人随时都能进来,那就等于在没人进来的每一个时段也一样开着。两种方式各把世界放在哪,写在《幻兽帕鲁》联机方式对比。
自动暂停实际上是怎么做到的
市面上的自动暂停,主体多半是两个操作系统信号。
kill -STOP <pid> # 就地冻住
kill -CONT <pid> # 从原地接着跑
SIGSTOP 不是《幻兽帕鲁》的命令,游戏根本不知道发生过这件事。内核只是不再给它排 CPU。内存、打开的文件、UDP 端口都还握在手上,只是不执行。收到 SIGCONT 之后,它从被冻住的那一条指令接着往下跑,完全不知道中间过了多久。
放进你已经知道的两个状态之间,是这样:
| 冻住 | 已停止 | 运行中 | |
|---|---|---|---|
| 进程 | 还在,只是不执行 | 没了 | 执行中 |
| 内存 | 照样占着 | 释放 | 占用中 |
| 游戏端口 | 内核握着,数据包排队 | 关闭 | 服务中 |
| 世界时间 | 停住 | 停住 | 前进 |
| 回来要多久 | 几秒 | 一次启动加载入世界 | — |
这两行要用得安全,旁边还得有三件事:
- 冻之前先强制存档。
SIGSTOP拦不住、挡不掉、也不能忽略——它可靠就可靠在这里,代价是服务器连一瞬间的收尾时间都没有。还在内存里、没落到硬盘的东西就留在内存里。这时候要是断电,那一段就没了。 - 得有东西盯着网络。 冻住的进程没法响应连接,自然也不知道有人来了。得另外有东西趴在网卡上,看到进来的数据包就送
SIGCONT。等于在游戏服务器旁边多养一个用 root 跑的抓包程序。 - 还得有东西让它留在列表上。 服务器发给游戏后台的信号也跟着停了,所以冻住的服务器会从社区服务器列表消失。要让它继续出现,就得有别的东西冒充它,用它的凭据、按它原本会送的内容,继续跟后台通信。
这几件都不是发行商提供的功能。官方 REST API 有 /save、/shutdown、/stop、/announce、踢人和封禁,没有暂停(完整端点列表)。上面这些全是从游戏外面做的,而游戏对此一无所知;游戏一次更新,三个步骤里的任何一步都可能踩空。
放在自己家里的机器上,这是划算的交换,因为那边的目的是电费。但在一台付钱请别人运维的服务器上,你是为了一个本来就有别条路能拿到的结果,连同上面三件事和它们的故障方式一起买回来。
更简单的版本:直接关掉
大家要「暂停」,想要的几乎都是我们没在玩的时候世界也别跑。关掉服务器就是这件事,而且一点机关都不需要:世界落到硬盘上,没有东西在执行,游戏时间也就无从前进,下次开机从那份存档接着玩。
安全关机的顺序,跟定时重启用的是同一套。
PW='a-long-password'
API='http://127.0.0.1:8212/v1/api'
# 1. 先用倒计时预告还在线上的人
curl -s -u "admin:$PW" -X POST "$API/announce" \
-H 'Content-Type: application/json' \
-d '{"message":"60 秒后关闭服务器,请先移动到安全的地方"}'
# 2. 把世界强制写进硬盘
curl -s -u "admin:$PW" -X POST "$API/save"
# 3. 倒计时 60 秒后优雅停机
curl -s -u "admin:$PW" -X POST "$API/shutdown" \
-H 'Content-Type: application/json' \
-d '{"waittime":60,"message":"60 秒后关闭服务器"}'
存档要排在关机前面,是因为官方文档没有说明关机时会不会存档。同一个顺序也写在 REST API 指南和定时重启的做法里。
代价也没什么好遮的:回来要等一次启动加载入世界,不是一秒。如果你们是晚上约好一起玩,先到的人开起来、顺手去倒杯水就差不多了。如果是随时有人不打招呼就进来的服务器,那一分钟正是选择冻住的理由。
把「关掉」那一半自动化
用手关,对晚上才开的团来说就够了。如果想让它自己跑,要自动化的是关掉那一半,不是冻住那一半:一个定时器问服务器现在几个人,再按答案行动。用 systemd timer 或 cron 每 5 分钟跑一次。
#!/bin/bash
set -o pipefail
PW='a-long-password'
API='http://127.0.0.1:8212/v1/api'
STATE=/var/lib/palworld-empty-rounds
MAX=6 # 6 次 x 5 分钟 = 30 分钟没人
n=$(curl -sf -u "admin:$PW" "$API/metrics" | jq -r '.currentplayernum') || exit 0
case "$n" in ''|*[!0-9]*) exit 0 ;; esac # 不是数字就什么都不做
[ "$n" -gt 0 ] && { rm -f "$STATE"; exit 0; }
rounds=$(( $(cat "$STATE" 2>/dev/null || echo 0) + 1 ))
echo "$rounds" > "$STATE"
[ "$rounds" -lt "$MAX" ] && exit 0
curl -s -u "admin:$PW" -X POST "$API/save"
curl -s -u "admin:$PW" -X POST "$API/shutdown" \
-H 'Content-Type: application/json' \
-d '{"waittime":10,"message":"当前没有玩家在线,服务器即将关闭"}'
rm -f "$STATE"
有两处是关键,而第一处正是陷阱。查不到不等于没有人——可是管道回报的是 jq 的退出码,不是 curl 的,而 jq 对一个挂掉的端点会回 null 然后正常结束。少了 pipefail 和那行数字检查,null 就变成「不大于 0」,于是端口打个嗝就能把一台十个人在玩的服务器关掉。第二处:计数放在文件里而不是 sleep 循环里,重启才不会留下一个数到一半的倒计时。
难的那一半不在这支脚本里,是怎么开回来。 这里没有任何东西能把服务器叫起来,因为关掉的机器根本没有东西在听。选项是另一台机器盯着流量、一个在那台机器上有 shell 的 bot,或者有人去敲 systemctl start。关掉是一行 cron、开起来是一个判断——这个不对称正是冻住那条路存在的理由,也是它非得用 root 跑一个抓包程序的理由。
你可能两种都不需要
如果真正困扰你的不是「世界跑了」这整件事,而是其中一部分,配置文件可以直接处理掉——而且跟暂停不一样,这些在你正在玩的时候也生效。
| 配置 | 改到什么 |
|---|---|
PalStomachDecreaceRate | 帕鲁变饿的速度。调低之后隔一晚回来,喂食箱不会见底(拼错是游戏那边的事) |
bEnableInvaderEnemy | 据点袭击事件。关掉之后,没人守的据点就不会被袭击 |
WorkSpeedRate | 据点帕鲁的工作速度,也就是「不在的时候进度跑太多」的另一半 |
完整的选项、默认值,以及哪些会吃性能,都在《幻兽帕鲁》服务器设置全解。
常见问题
没人上线的时候,《幻兽帕鲁》服务器还会继续跑世界吗?
会。专用服务器不管有没有人连着都照样算整个世界,所以空着的服务器上帕鲁照吃、作物照长、袭击照来。要让它停下来只有两条路:冻住进程,或者关掉服务器。
自动暂停是《幻兽帕鲁》自带的功能吗?
不是。专用服务器没有暂停命令,官方 REST API 也没有对应端点。所有挂着自动暂停名字的做法都是在游戏外面完成的:要么用操作系统信号把进程冻住,要么关掉服务器、要玩的时候再开。
没人上线的时候,可以让《幻兽帕鲁》服务器自己关掉吗?
可以。一个定时器用 /metrics 查在线人数,空着满一定次数之后调用 /save 和 /shutdown,十五行左右就够。开回来那一半没办法用同样的方式自动化——关掉的服务器没有东西在听你的请求。
关掉《幻兽帕鲁》服务器会不会掉进度?
先存档就不会。用倒计时预告、POST /save,然后才关机,硬盘上的世界就是最新的,开回来从那里接着玩。会掉进度的是写到一半被切断,比如断电,或者没存档就直接打 /stop。
把服务器停掉,帕鲁就不会饿了吗?
停着的期间是这样,世界里没有任何东西会前进,肚子饿也一样。但它不会改变你正在玩的那段时间。如果你在意的是每次回来喂食箱都见底,PalStomachDecreaceRate 不用停掉任何东西就能解决。
这件事在托管上放在哪
在 空岛灵境 的《幻兽帕鲁》专用服务器上,停掉和开起来是会员中心我的服务器里进去的服务器详情页上的一个按钮,按钮背后跑的就是上面那套预告 → 存档 → 关机:先在游戏里发全服公告,倒计时走完先强制存档,然后才安静下来。这就是优雅停机,也是让「不玩就先关着」从赌一把变成习惯的那一段。
旁边还有两件。备份按计划跑、保留最近几份(一份完整备份包含什么),所以你关机当下的状态,就算关机本身出了状况也还救得回来。另外每日定时重启在同一页上,就是一个开关加一个时刻;长时间开着的服务器会累积的内存问题,写在定时重启。
| 备份时间 | 大小 | 类型 | 操作 |
|---|---|---|---|
| 2 小时前 | 412.6 MB | 自动 | |
| 4 小时前 | 410.2 MB | 自动 | |
| 6 小时前 | 398.1 MB | 手动 |
仅展示最近 3 个备份。
这里没有的是自动闲置关机——没有东西会盯着在线人数替你关掉,得有人去按那个按钮。如果你们固定周五、周六才开,那就是一周按两次,而中间这段时间世界不会变老。反过来,要是你根本不想让它停,把它一直撑着的三套机制写在《幻兽帕鲁》服务器 24 小时不关机。