BELENUS Companion Bridge 利用ガイド
Companion Bridgeは、ゲーム内のQRコードからスマホで参加し、BELENUSのプレイヤーへクエストやアイテムを届けるローカル連携ツールです。ゲームを購入していない人も、スマホのブラウザーから参加できます。
現在は、ゲームとサーバーを同じPCで動かし、同じLAN内のスマホから接続する構成です。依頼や参加者情報はSQLite、納品写真はPC内のフォルダーへ保存します。EOS認証、Tursoへの実データ移行、GCP Cloud Storageへの接続は今後の対応です。
すぐに起動する
PowerShellを開き、次のコマンドを実行します。
Set-Location 'E:\UnrealEngine\BELENUS2\Tools\CompanionBridge'
node server.mjs --port 8787 --host 0.0.0.0 --public-url http://192.168.2.100:8787
192.168.2.100 は、このPCで以前の起動に使用したLANアドレスです。PCのアドレスが変わっている場合は、現在のアドレスに置き換えてください。
正常に起動すると、端末に次のような表示が出ます。
COMPANION_READY http://192.168.2.100:8787 (SQLite/Turso adapter; local owner authentication)
Game config: E:\UnrealEngine\BELENUS2\Saved\CompanionBridge\local-client.json
この端末を開いたままゲームを起動し、ポーズメニューの QUEST を開きます。スマホではゲーム内のQRコードを読み取ってください。サーバーのトップページを開くだけでは、参加先のプレイヤーは指定されません。
停止する場合は、サーバーを実行している端末で Ctrl+C を押します。再開するときは同じ起動コマンドを実行します。依頼・納品画像は保存先に残ります。PC再起動後の自動起動や常駐サービス登録は行いません。
必要な環境
スマホからこのガイドを読む場合は、サーバー起動中に http://192.168.2.100:8787/guide を開きます。PCのIPアドレスが異なる場合は読み替えてください。スマホの参加ページの下部にある 使い方・利用ガイド からも開けます。見出しへ移動する目次があり、長いコマンドや表は横へスクロールできます。
| 対象 | 条件 |
|---|---|
| ゲーム用PC | このプロジェクトと、Web連携を含むビルド済みゲームまたはEditor |
| サーバー | Node.js 24以降とnpm |
| スマホ | ブラウザーとQRコードを読み取る機能 |
| ネットワーク | PCとスマホが相互に通信できる同じLAN。スマホは同じWi-Fiへ接続 |
ゲーム用PCが有線接続でも、同じルーターのWi-Fiにつながるスマホから利用できます。現在の試作では、スマホ側のSteam・Epicアカウントは必要ありません。
初めて設置する環境や、依存ライブラリーを入れ直す場合は、先に次を実行します。
Set-Location 'E:\UnrealEngine\BELENUS2\Tools\CompanionBridge'
node --version
npm ci
SQLiteはNode.jsの標準機能を使うため、SQLiteサーバーを別途起動する必要はありません。
ディレクトリーと役割
プロジェクトのルートは E:\UnrealEngine\BELENUS2 です。
E:\UnrealEngine\BELENUS2
├─ Tools\CompanionBridge\ サーバーとスマホ用Web画面
│ ├─ GUIDE.md この利用ガイド
│ ├─ README.md 実装と検証の技術資料
│ ├─ start.ps1 PowerShell用の起動スクリプト
│ ├─ export-guide.ps1 Markdown資料をスマホ用HTMLへ変換
│ ├─ server.mjs HTTPサーバー、API、QR生成
│ ├─ repository.mjs 参加者、依頼、支援、納品の管理
│ ├─ db.mjs SQLiteとTursoの保存処理
│ ├─ photo-store.mjs 納品PNGの検証とローカル保存
│ ├─ catalog.mjs 依頼テンプレート、贈り物、受付上限
│ ├─ package.json / package-lock.json Node.js依存関係
│ ├─ public\ スマホに表示する画面
│ │ ├─ index.html ページ本体
│ │ ├─ app.js 参加、依頼送信、写真表示
│ │ └─ style.css 画面の見た目
│ ├─ test\ APIと写真保存のテスト
│ ├─ verify-engine.mjs Unrealとの通信・障害時の検証
│ ├─ verify-capture.mjs ゲーム画面の撮影・納品の検証
│ └─ node_modules\ npm ciで導入するライブラリー
├─ Source\BELENUS2\
│ ├─ JourneyCompanion\ ゲーム側のWeb通信と写真処理
│ ├─ JourneyPause\ QUEST画面のQR・撮影・納品操作
│ ├─ JourneyQuests\ クエストの受注と達成管理
│ └─ JourneyInventory\ 支援アイテムの受け取り
└─ Saved\CompanionBridge\ 通常起動時のデータ保存先
├─ companion.sqlite 参加者、招待、依頼、納品記録のDB
├─ companion.sqlite-wal / -shm SQLiteが使用する補助ファイル
├─ local-client.json ゲーム接続先とゲーム側の接続キー
├─ photos\ サーバーに納品された写真
├─ Outbox\ ゲーム側の写真下書きと送信待ち
├─ Verification\ Unreal通信検証の結果
└─ RenderVerification\ 撮影・納品検証の結果
photos など、一部のフォルダーは実際の保存・検証時に作成されます。サーバーを再起動するだけなら、保存フォルダーを削除する必要はありません。
local-client.json にはゲーム側の接続キーが入っています。スマホへ配布したり、公開リポジトリーやスクリーンショットに載せたりしないでください。QRコードには、このキーを含めません。
起動方法と設定
起動スクリプトを使う
プロジェクトのルートから実行します。通常の利用では、この方法でも起動できます。
Set-Location 'E:\UnrealEngine\BELENUS2'
& .\Tools\CompanionBridge\start.ps1 -PublicUrl 'http://192.168.2.100:8787'
-PublicUrl を省略すると、サーバーがPCのネットワーク情報からアドレスを選びます。VPNや仮想ネットワークがあるPCでは、スマホから届かないアドレスを選ぶ場合があるため、LANアドレスの明示が確実です。
PowerShellの実行設定でスクリプトを起動できない場合は、冒頭の node server.mjs ... を直接実行してください。
アドレスとポートの意味
| 設定 | 役割 |
|---|---|
--host 0.0.0.0 |
PC内だけでなく、LAN側からの接続も受け付ける待受設定 |
--port 8787 |
サーバーが使用するポート |
--public-url http://192.168.2.100:8787 |
スマホ用の参加URLとQRに入れる接続先 |
http://127.0.0.1:8787 |
同じPC上のゲームからサーバーへ接続するアドレス |
スマホ用URLに 127.0.0.1 や 0.0.0.0 を指定しないでください。スマホからはPCのLANアドレスを使用します。--public-url はQRに入るアドレスの指定であり、インターネット公開やポート転送を行う機能ではありません。
現在のLANアドレスは、PowerShellで ipconfig を実行し、使用しているWi-FiまたはイーサネットのIPv4アドレスを確認します。アドレス変更後は、新しい --public-url で再起動し、ゲームでQRを再表示して読み取り直します。
その他の指定
直接起動する場合は、次のオプションを使用できます。
| オプション | 既定値と注意点 |
|---|---|
--name |
初回プレイヤー登録時の表示名。既定は 旅人。既存プレイヤー名の変更処理ではありません |
--data-dir |
サーバー側の保存先。既定は E:\UnrealEngine\BELENUS2\Saved\CompanionBridge |
--data-dir を変えた場合、ゲームにもそのフォルダーの local-client.json を読ませる必要があります。ゲームの起動引数 -CompanionConfig="接続設定ファイルの絶対パス" で指定します。写真の Outbox は引き続きゲーム自身のSavedフォルダー内に作られます。
通常起動時、ゲームは自身のSavedフォルダー内の CompanionBridge\local-client.json を読みます。パッケージ版や -UserDir 指定時には、プロジェクト直下と保存先が異なる場合があります。現在のゲーム接続は http://127.0.0.1:ポート に限定されているため、別PCやクラウドのサーバーへ接続するにはゲーム側の変更も必要です。
ゲームとスマホでの使い方
参加と通常クエスト
- PCでサーバーを起動します。
- ゲームを開始し、ポーズメニューの QUEST を開きます。
- QRが出ていない場合は R/QRを表示 を選びます。
- 同じLANのスマホでQRを読み取り、呼び名を入力して参加します。
- スマホで依頼を選び、必要ならメッセージを添えて送信します。
- プレイヤーはQUESTの「進行中」「すべて」に届いた 受注待ち の依頼を選び、受注します。
- 受注後の行動で目標を達成します。達成時の報酬は癒しの欠片1個です。
| 依頼名 | 受注後の達成条件 |
|---|---|
| 少し遠くの景色へ | 100m移動する |
| 旅の素材を集めよう | アイテムを3個入手する |
| ひとつ、手作りのお土産 | アイテムを1個合成する |
| 旅先の景色を見せて | 写真を撮影し、サーバーへ納品する |
スマホの「届けた便り」は、ページを表示している間、約5秒ごとに進行状況を確認します。ゲーム終了中に送られた依頼や支援も、サーバーで受け付けられたものはDBに残ります。
招待の有効期間は24時間です。Shift+R/更新 は以前の参加コードを失効させるため、更新後は新しいQRから参加し直してください。写真の閲覧にも有効な招待が必要です。
アイテムを贈る
スマホで ハーブを贈る を選びます。ゲームが受信すると、静心のハーブ1個が INVENTORY → 素材 に追加されます。現在贈れるアイテムは、この定型のハーブです。
写真を頼んで納品する
- スマホで 旅先の景色を見せて を選び、撮ってほしい景色をメッセージに書いて送信します。
- プレイヤーがその依頼を受注し、撮影する場所へ移動します。
- QUESTで対象の写真依頼を選び、F/撮影 を押します。
- メニューが一時的に閉じてゲーム画面を撮影し、QUESTへ戻って写真を表示します。
- 写真を確認して T/この写真を納品 を押します。納品前ならFで撮り直せます。
- サーバーへの保存とゲーム側の達成保存が成功すると完了します。依頼者はスマホで写真を見て、タップして拡大できます。
| 操作 | キーボード | コントローラー |
|---|---|---|
| 撮影・撮り直し | F | 左フェイスボタン。PS系では□、Xbox系ではX |
| 写真の納品 | T | 上フェイスボタン。PS系では△、Xbox系ではY |
撮影しただけでは送信しません。納品操作後は送信待ちとして保存し、再接続時に再送します。送信待ちになった写真は撮り直せません。撮影にはゲーム画面が必要なので、Editorの編集画面だけでは利用できません。
写真はPNGで長辺2048px以下、最大8MiBです。依頼文と写真内容の一致を自動判定する機能や、依頼者の承認・差し戻しはありません。写真の納品成功が達成条件です。
起動確認とトラブル対応
サーバーを動かしたまま、別のPowerShellで確認します。
Invoke-RestMethod -Uri 'http://127.0.0.1:8787/health' -TimeoutSec 5
Invoke-RestMethod -Uri 'http://192.168.2.100:8787/health' -TimeoutSec 5
(Invoke-WebRequest -Uri 'http://192.168.2.100:8787/' -TimeoutSec 5).StatusCode
SQLiteで動作していれば、ヘルスチェックは ok: true、database: sqlite、mode: local-prototype を返し、最後のページ確認は 200 を返します。PC自身からのLANアドレスへの成功と、スマホ実機から接続できることは別なので、最後にスマホでQRからの参加も確認します。
| 症状 | 確認すること |
|---|---|
node が見つからない |
Node.js 24以降が使える端末か確認し、node --version を実行する |
| ライブラリーがない | ツールのフォルダーで npm ci を実行する |
EADDRINUSE が出る |
8787番で既にサーバーが動いていないか /health で確認する。関係のないプロセスを停止しない |
PCでも /health が開かない |
サーバーを実行中の端末に出たエラーと、使用ポートを確認する |
| PCでは開くがスマホでは開かない | LANアドレス、同じWi-Fiか、ゲストWi-Fiの端末間隔離、WindowsファイアウォールのNode.js通信許可を確認する |
| ページは開くが参加できない | トップページではなくゲーム内QRの /join/... を使う。期限切れなら新しいQRで参加する |
| ゲームにQRが出ない | Web連携を含むビルドか、ゲームが正しい local-client.json を読んでいるか確認する |
| 依頼が進まない | ゲームで受注済みか、受注後の行動で条件を満たしているか確認する |
| 写真が納品待ちのまま | サーバーの応答と保存先の空き容量を確認する。送信待ちのOutboxを削除しない |
| 写真をスマホで見られない | 依頼を発行したブラウザーで、有効な招待から参加しているか確認する |
| 受付上限になる | 参加者ごとに依頼・支援が各UTC日3回まで。受取人全体は1日50件、未処理20件まで |
サーバーは起動端末へ状態やエラーを出力します。ファイアウォールの変更、外部公開、バックグラウンド常駐は起動コマンドでは行いません。
サーバー停止中の動作
通信は非同期で、通常のゲーム進行をサーバーの応答待ちにしない設計です。Webが停止しても、通常の移動・操作・既存クエストは続行できます。既に受注した写真依頼はオフラインでも撮影・保存・納品予約でき、納品の完了はサーバー復旧後になります。
ゲーム側は通常通信を8秒、写真送信を15秒でタイムアウトさせ、失敗時は3~60秒間隔で再接続します。通常通信は最大4件、写真送信は1件ずつ処理します。同じ依頼や写真の再送で重複付与しないための記録も保存します。
保存先とバックアップ
| データ | 通常の保存先 |
|---|---|
| 参加者・招待・依頼・支援・写真情報 | E:\UnrealEngine\BELENUS2\Saved\CompanionBridge\companion.sqlite |
| ゲームの接続キー | E:\UnrealEngine\BELENUS2\Saved\CompanionBridge\local-client.json |
| 納品写真 | E:\UnrealEngine\BELENUS2\Saved\CompanionBridge\photos\<ハッシュ先頭2文字>\<SHA-256>.png |
| 写真下書きと送信待ち | E:\UnrealEngine\BELENUS2\Saved\CompanionBridge\Outbox\<接続キーとセーブ名に対応する識別子>\<依頼UUID>.png と .json |
バックアップ前にゲームを終了し、サーバーもCtrl+Cで停止します。DB、存在する場合は companion.sqlite-wal と companion.sqlite-shm、local-client.json、photos、Outbox を同じ時点のセットでコピーしてください。ゲーム側のクエスト・素材のセーブも別途保管します。
稼働中にSQLite本体だけをコピーすると、WALに残っている更新を取りこぼす場合があります。DBと写真は別に保存しているため、DBのコピーだけでは写真を復元できません。復元するときもゲームとサーバーを止め、対応するデータと接続キーをまとめて戻します。
現在は1台のPC・1つの進行データを想定しています。ゲームセーブだけを過去へ戻しても、サーバー側の処理済み記録は巻き戻りません。New Gameや複数スロットごとの独立した宛先管理は今後の対応です。
TursoとGCPへの移行
Turso
DBへのアクセスは db.mjs に分離されています。Turso用アダプターはありますが、実際のTurso接続・データ移行は別途行います。
- サーバーを止め、SQLiteと関連データをバックアップします。
- SQLiteのスキーマと既存データをTursoへ取り込みます。
- サーバーを起動する端末へ次の環境変数を設定して起動します。
/healthがdatabase: tursoを返すことに加え、参加・依頼・納品の往復を確認します。
Set-Location 'E:\UnrealEngine\BELENUS2\Tools\CompanionBridge'
$env:TURSO_DATABASE_URL = 'libsql://YOUR-DATABASE.turso.io'
$env:TURSO_AUTH_TOKEN = 'YOUR-TOKEN'
node server.mjs --port 8787 --host 0.0.0.0 --public-url http://192.168.2.100:8787
環境変数の切り替えだけでは、既存のSQLiteデータは移送されません。SQLiteを使う端末には TURSO_DATABASE_URL を設定しないでください。Tursoの認証情報はサーバーだけに渡します。Tursoへ移行しても、Webサーバーと写真の保管先は別途必要です。
GCP Cloud Storage
photo-store.mjs の LocalPhotoStore と同じ put(bytes, metadata)・get(objectKey) を提供するアダプターを実装し、createBridge({ photoStore }) に渡す構成です。バケット名や認証設定を指定するだけで切り替わる機能は、まだありません。
既存画像はDBに保存したオブジェクトキーを保って転送します。バケットは非公開にし、写真を見せる前の依頼者認証は引き続きAPI側で行います。
検証と開発の入口
APIテストを実行する場合は、次のコマンドを使用します。通常のサーバー起動には必要ありません。
Set-Location 'E:\UnrealEngine\BELENUS2\Tools\CompanionBridge'
npm test
ビルド済みUnrealとの通信や実画面撮影を検証する場合は、次を使用します。必要なEditorバイナリーがあり、ソースの変更をビルド済みであることが前提です。
node verify-engine.mjs
node verify-capture.mjs
既定のUnreal実行ファイルは E:\UE\UE_5.8\Engine\Binaries\Win64 配下です。別の場所なら、通信検証は UE_EDITOR_CMD、撮影検証は UE_EDITOR に実行ファイルの絶対パスを設定します。
過去の検証記録は Saved\CompanionBridge\PhotoVerificationSummary.json と、その参照先にあります。API、ゲームとの通信、写真の実撮影・納品、スマホ幅の画面表示の結果を確認できます。実機スマホでのWi-Fi接続、現在のソースでの再検証、製品版のCook・パッケージ確認は、それぞれ別の確認です。
実装上の上限、保存処理、障害時処理は 技術README を参照してください。EOS認証やインターネット配信を導入する際には、現在のローカル接続キー方式とゲーム側のループバック接続制限も見直します。
スマホ向け資料の更新
GUIDE.mdまたはREADME.mdを編集したら、次のコマンドで公開用HTMLを更新し、サーバーを再起動します。変換にはPowerShell 7の ConvertFrom-Markdown を使用します。生成済みHTMLが同梱されているため、通常のNode.jsサーバー起動にはPowerShellは不要です。
& 'E:\UnrealEngine\BELENUS2\Tools\CompanionBridge\export-guide.ps1'
生成先は public\guide.html と public\technical-guide.html、表示用のスタイルは public\guide.css です。サーバーは、この公開用HTMLと許可されたファイルだけを配信します。接続キーやSQLiteファイル、写真保存フォルダーを直接公開しません。