はじめに
パルワールド(Palworld)の専用サーバー(Dedicated Server)を身内で運用していると、こんな悩みに直面することがあります。
- 「今、サーバーに誰かログインしているのかな?」
- 「自分がいない間にみんながどれくらい遊んでいるか知りたい」
- 「ゲームの外(Discordなど)からサーバー内にアナウンスを飛ばしたい」
パルワールドには標準で「REST API」という外部からサーバーの情報を取得・操作できる強力な機能が備わっています。今回は、このAPIを活用して、Ubuntu上の自作サーバーとDiscordを連携させ、プレイヤーの入退室通知やステータス表示を全自動化する「パルワールド管理Discord Bot」を開発した全記録をお届けします。
同じように「サーバー管理を快適にしたい」「Pythonでちょっとした自動化ツールを作ってみたい」という方の参考になれば幸いです。
1. パルワールド専用サーバーで「外部連携」を行うメリット
パルワールドの専用サーバーは、ただ立ち上げるだけでもある程度遊べますが、外部のAPI機能を使ってDiscordなどのGUI(画面やチャットインターフェース)と連携させることで、管理効率とコミュニティの快適性が劇的に向上します。
① ゲームを開かずに「島の状況」が一目でわかる
通常、サーバーに誰がいるかを確認するには、ゲームを起動してサーバーにログインするか、黒い画面(CUIコンソール)を開いて複雑なコマンドを叩く必要があります。 しかし、Discord Botと連携させることで、スマホやPCのDiscord画面を見るだけで「現在のログイン人数」や「誰がオンラインか」がリアルタイムに把握できるようになります。

② 管理者コマンドの「民主化」とハードルの低下
サーバー内アナウンスの送信やプレイヤー確認などの管理者コマンドは、本来ゲーム内で特殊なコマンドを打ち込む必要があります。これをDiscordのチャット経由(例:!announce メッセージ)で行えるようにすることで、黒い画面に抵抗がある人でも安全かつ直感的にサーバーの管理操作ができるようになります。
③ サーバーの「生きてる感」が伝わり、コミュニティが活性化する
誰かがログインした時にDiscordに「📥 ログイン: 〇〇がサーバーに参加しました。」と自動で通知が飛ぶようになると、それを見た他のメンバーが「あ、アイツが入ったなら自分もやろうかな」と、ゲームに集まるきっかけが生まれます。サーバーの稼働状況が可視化されること自体が、コミュニティを盛り上げる強力なガジェットになります。

2. 開発環境と全体のシステム構成
今回のBot開発にあたり、以下のような構成でシステムを構築しました。
- サーバーOS: Ubuntu Linux(セルフホスト環境)
- 開発言語: Python 3
- 主要ライブラリ:
discord.py,requests - 自動起動システム:
systemctl(systemd) による常時稼働・サービス化
パルワールドのREST API(ポート 8212)に対して、Pythonコードから定期的にリクエスト(HTTP通信)を送り、返ってきたJSONデータを解析してDiscordにメッセージを送信する仕組みです。
さらに、Linuxサーバー自体が再起動した際にも自動でBotが立ち上がるよう、バックグラウンドのサービスとして登録し、「メンテナンスフリーで完全に自走するシステム」を目指しました。
3. 開発中に直面した「3つの大きな躓きポイント」と解決策
一見シンプルなシステムですが、実際にコードを書いて動かしてみると、いくつかの予想外の罠(仕様)に悩まされました。ここでは、特に苦労したデバッグの記録を共有します。
📌 躓き①:ログイン・ログアウト通知がまったく反応しない
初期のコードでは、「15秒ごとにプレイヤーリストを取得し、前回との差分を計算して通知する」というロジックを組みました。しかし、いざテストしてみると、ログインしてもログアウトしてもDiscordに何も通知が飛ばないという現象が発生しました。
- 原因: Botの「初回起動時の安全策」が裏目に出ていました。Botが起動した瞬間にプレイヤーがログインしていると、それを「初期状態」として記憶してしまい、その後の変化を検知できなくなっていたのです。また、DiscordのBot権限(Intents)である「Server Members Intent」の設定が不足していたことも原因でした。
- 解決策: コード側の初期化処理(
hasattr(self, 'is_initialized'))を厳密に見直し、起動時のリスト保持と、その後のループ処理を完全に分離しました。また、Discord Developer Portal側で適切な特権インテントをONにすることで、正確にイベントを拾えるようになりました。
📌 躓き②:ログアウトは検知するのに「ログイン」だけ無視される
初期不良を乗り越えた後、次に襲ってきたのが「ゲームから出た時は通知が来るのに、入った時は通知が来ない」という奇妙なバグでした。
- 原因: パルワールドのAPIの仕様上、プレイヤーがログインした「瞬間」の数秒間は、APIが返すデータの中でプレイヤー名(
name)がまだ確定しておらず、空文字("")の状態で返ってくるタイミングがあることが判明しました。名無しのプレイヤーとして処理されていたため、ログイン判定の条件(差分チェック)をすり抜けていたのです。 - 解決策: APIから取得したデータのうち、名前がしっかりと取得できているデータのみを抽出するガード文(
if p.get('name'))を条件に加えることで、名前が確定した段階で綺麗にログインを検知できるようになりました。
📌 躓き③:Linuxエディタ(nano)でのコード差し替えの洗礼
デバッグ中、コードの修正版をLinuxサーバー上のファイルを書き換えて反映させる作業を何度も行いました。その際、標準のテキストエディタである nano を使用したのですが、Windowsの感覚で全選択削除(Alt + A 経由など)を行おうとしたところ、環境(ターミナルソフト)の相性でショートカットキーが一切効かないという地味なストレスに直面しました。
- 原因: SSH経由のターミナルでは、特定のキーバインド(Altキーなど)がエミュレータ側で上書きされたり、サーバーまで届かないことがあります。
- 解決策:
nanoの中で無理に全消去しようとするのを諦め、Linuxのコマンドライン側でリダイレクト記号を使い、ファイルを一瞬で空にする力技を導入しました。Bash: > /path/to/pal_bot.pyこのコマンドを実行してからnanoで開くことで、常に真っ白な状態から最新コードを右クリックで一発貼り付けできるようになり、開発の作業効率が爆発的にアップしました。
4. 完成した「安定版Discord Bot」の強みと機能
数々のデバッグを経て、現在は非常に安定した「パルワールド管理Bot」が稼働しています。このシステムの主な強みと機能は以下の通りです。
① 完全自動の入退室ログ(15秒精度の監視)
15秒間隔でサーバーを監視し、プレイヤーの「ログイン」「ログアウト」をDiscordの指定チャンネルに絵文字付きでスマートに通知します。誰がいつ来て、いつ帰ったのかのログが綺麗に残るため、サーバーの動向が手に取るようにわかります。
② Discordのステータス欄(アクティビティ)への人数リアルタイム表示
Bot自身のステータス(「〜をプレイ中」の部分)に、現在のリアルタイムな接続人数が「パル人数: 2/32」のように常時表示されます。チャンネルを開かなくても、メンバーリストのBotのアイコンを見るだけでサーバーの混雑状況がわかります。

③ 安全なシャットダウン連動(systemd化)
今回のBotは、Linuxのサービス(palworld-bot.service)として管理しています。そのため、サーバー自体のメンテナンスや再起動の際、サーバーの終了シグナル(SIGTERM)をBotが安全にキャッチし、Discordへ未送信のデータを残すことなく、綺麗に「ログアウト」してオフラインになる仕組みを実装しました。これにより、プロセスがゾンビ化したり、ログが破損したりするリスクがありません。
まとめ:個人開発としての振り返り
今回の開発を通じて、ただゲームを遊ぶだけでなく、「APIを使ってゲームサーバーと外部ツールを繋ぐ」という、一歩踏み込んだインフラ運用の楽しさを体験することができました。
一見すると「APIを叩いてDiscordに流すだけ」という簡単な仕組みに見えますが、いざ本番環境で動かしてみると、APIのデータの挙動のクセや、プロセスの常時稼働(デーモン化)の難しさなど、実際に手を動かさないと見えてこない学びが非常に多かったです。
自分で構築したUbuntuサーバーの上で、自分で書いたPythonコードが24時間休まずに動き、身内のDiscordを便利にしてくれているのを見るのは、個人開発者として何よりの達成感があります。
そして今回は同時にlinuxで稼働しているサーバーをwindows側で監視するというGUIも作成しました。



もし需要があればGUI作成についても触れていこうかなとおもっています!
今後は、さらにサーバーの負荷監視や自動バックアップの進捗通知など、より高度な機能も気が向いたら追加していければと思っています。パルワールドのサーバー管理をもっと自動化したいと考えている方は、ぜひREST APIの世界に飛び込んでみてください!

コメントを残す