幻獸帕魯自動暫停:停掉的是什麼,代價是什麼
《幻獸帕魯》伺服器說的「自動暫停」其實是兩種不同的功能,只有一種能讓你不在的時候帕魯不餓肚子。它怎麼做到的,又會弄壞什麼。
隔一天上線,據點一團亂:一半的帕魯餓著,兩隻生病,箱子裡堆滿了沒人要的礦石。這段時間沒有任何人上線,世界卻照樣在跑。講到這件事,被推薦的通常就是自動暫停。
不過這個說法同時指兩種不同的功能,其中一種給不了你要的結果。挑之前先把它們分開。
自動暫停指的兩件事
停的是計費。 沒人上線的那一段不計費。要讓費用停下來,總得有東西是關著的,所以世界通常也會跟著停;但這個功能主打的是價格,真正會影響你的在後面:它是怎麼降下去的,以及回來要多久。
停的是世界。 遊戲裡的時間不再前進。帕魯不吃東西,作物不長,沒人守的據點也不會有襲擊。
要分清楚對方賣的是哪一種,問兩個問題就夠了:暫停期間世界會不會前進,以及到能重新開玩要等多久。功能列表上的任何一項,都不如第二個問題能把不同做法分開。
沒人上線,世界為什麼還在動
專用伺服器就是一個一直跑著的遊戲程式。最後一個人離線之後它不會進入休息,而是照滿員時的同一個節奏繼續算整個世界:據點的帕魯繼續工作、繼續變餓,作物繼續長,沒人在的據點照樣會被襲擊。
如果你們是從遊戲內開房(一個人開世界、其他人加進去)換過來的,習慣就是在這裡對不上。那邊的世界住在那個人的遊戲裡,他一關遊戲世界就停了。專用伺服器是刻意做成相反的東西:它開著是為了讓人隨時都能進來,那就等於在沒人進來的每一個時段也一樣開著。兩種方式各把世界放在哪,寫在《幻獸帕魯》連線方式比較。
自動暫停實際上是怎麼做到的
市面上的自動暫停,主體多半是兩個作業系統訊號。
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 不用停掉任何東西就能解決。
這件事在託管上放在哪
在 KeepWorlds 的《幻獸帕魯》專用伺服器上,停掉和開起來是會員中心「我的伺服器」進去的伺服器詳情頁上的一個按鈕,按鈕背後跑的就是上面那套預告 → 存檔 → 關機:先在遊戲裡發全服公告,倒數走完先強制存檔,然後才安靜下來。這就是優雅停機,也是讓「不玩就先關著」從賭一把變成習慣的那一段。
旁邊還有兩件。備份會按排程跑、保留最近幾份(一份完整備份包含什麼),所以你關機當下的狀態,就算關機本身出了狀況也還救得回來。另外每日定時重新啟動在同一頁上,就是一個開關加一個時刻;長時間開著的伺服器會累積的記憶體問題,寫在定時重新啟動。
| 備份時間 | 大小 | 類型 | 操作 |
|---|---|---|---|
| 2 小時前 | 412.6 MB | 自動 | |
| 4 小時前 | 410.2 MB | 自動 | |
| 6 小時前 | 398.1 MB | 手動 |
僅顯示最近 3 個備份。
這裡沒有的是自動閒置關機——沒有東西會盯著線上人數替你關掉,得有人去按那個按鈕。如果你們固定週五、週六才開,那就是一週按兩次,而中間這段時間世界不會變老。反過來,要是你根本不想讓它停,把它一直撐著的三套機制寫在《幻獸帕魯》伺服器 24 小時不關機。