KeepWorlds

幻獸帕魯自動暫停:停掉的是什麼,代價是什麼

《幻獸帕魯》伺服器說的「自動暫停」其實是兩種不同的功能,只有一種能讓你不在的時候帕魯不餓肚子。它怎麼做到的,又會弄壞什麼。

隔一天上線,據點一團亂:一半的帕魯餓著,兩隻生病,箱子裡堆滿了沒人要的礦石。這段時間沒有任何人上線,世界卻照樣在跑。講到這件事,被推薦的通常就是自動暫停。

不過這個說法同時指兩種不同的功能,其中一種給不了你要的結果。挑之前先把它們分開。

自動暫停指的兩件事

停的是計費。 沒人上線的那一段不計費。要讓費用停下來,總得有東西是關著的,所以世界通常也會跟著停;但這個功能主打的是價格,真正會影響你的在後面:它是怎麼降下去的,以及回來要多久。

停的是世界。 遊戲裡的時間不再前進。帕魯不吃東西,作物不長,沒人守的據點也不會有襲擊。

要分清楚對方賣的是哪一種,問兩個問題就夠了:暫停期間世界會不會前進,以及到能重新開玩要等多久。功能列表上的任何一項,都不如第二個問題能把不同做法分開。

沒人上線,世界為什麼還在動

專用伺服器就是一個一直跑著的遊戲程式。最後一個人離線之後它不會進入休息,而是照滿員時的同一個節奏繼續算整個世界:據點的帕魯繼續工作、繼續變餓,作物繼續長,沒人在的據點照樣會被襲擊。

如果你們是從遊戲內開房(一個人開世界、其他人加進去)換過來的,習慣就是在這裡對不上。那邊的世界住在那個人的遊戲裡,他一關遊戲世界就停了。專用伺服器是刻意做成相反的東西:它開著是為了讓人隨時都能進來,那就等於在沒人進來的每一個時段也一樣開著。兩種方式各把世界放在哪,寫在《幻獸帕魯》連線方式比較

自動暫停實際上是怎麼做到的

市面上的自動暫停,主體多半是兩個作業系統訊號。

kill -STOP <pid>   # 就地凍住
kill -CONT <pid>   # 從原地接著跑

SIGSTOP 不是《幻獸帕魯》的指令,遊戲根本不知道發生過這件事。核心只是不再排 CPU 給它。記憶體、開著的檔案、UDP 連接埠都還握在手上,只是不執行。收到 SIGCONT 之後,它從被凍住的那一道指令接著往下跑,完全不知道中間過了多久。

放進你已經知道的兩個狀態之間,是這樣:

凍住已停止執行中
遊戲程式還在,只是不執行沒了執行中
記憶體照樣占著釋放占用中
遊戲連接埠核心握著,封包排隊關閉服務中
世界時間停住停住前進
回來要多久幾秒一次啟動加載入世界

這兩行要用得安全,旁邊還得有三件事:

  1. 凍之前先強制存檔。 SIGSTOP 攔不住、擋不掉、也不能忽略——它可靠就可靠在這裡,代價是伺服器連一瞬間的收尾時間都沒有。還在記憶體裡、沒落到硬碟的東西就留在記憶體裡。這時候要是斷電,那一段就沒了。
  2. 得有東西盯著網路。 凍住的遊戲程式沒辦法回應連線,自然也不知道有人來了。得另外有東西趴在網路介面上,看到進來的封包就送 SIGCONT。等於在遊戲伺服器旁邊多養一隻用 root 跑的封包側錄程式。
  3. 還得有東西讓它留在列表上。 伺服器發給遊戲後台的訊號也跟著停了,所以凍住的伺服器會從社群伺服器列表消失。要讓它繼續出現,就得有別的東西冒充它,用它的憑證、照它原本會送的內容,繼續跟後台通訊。

這幾件都不是發行商提供的功能。官方 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《幻獸帕魯》專用伺服器上,停掉和開起來是會員中心「我的伺服器」進去的伺服器詳情頁上的一個按鈕,按鈕背後跑的就是上面那套預告 → 存檔 → 關機:先在遊戲裡發全服公告,倒數走完先強制存檔,然後才安靜下來。這就是優雅停機,也是讓「不玩就先關著」從賭一把變成習慣的那一段。

旁邊還有兩件。備份會按排程跑、保留最近幾份(一份完整備份包含什麼),所以你關機當下的狀態,就算關機本身出了狀況也還救得回來。另外每日定時重新啟動在同一頁上,就是一個開關加一個時刻;長時間開著的伺服器會累積的記憶體問題,寫在定時重新啟動

會員中心裡的備份紀錄,關機當下的狀態也在裡面

這裡沒有的是自動閒置關機——沒有東西會盯著線上人數替你關掉,得有人去按那個按鈕。如果你們固定週五、週六才開,那就是一週按兩次,而中間這段時間世界不會變老。反過來,要是你根本不想讓它停,把它一直撐著的三套機制寫在《幻獸帕魯》伺服器 24 小時不關機

其他語言版本

不想自己維護?

選好遊戲與方案就能開伺服器,整機獨享,備份、遊戲更新與期限提醒都由我們盯著。

查看方案