PUN2のUnityアプリをコンテナ化してDockerでbotを好きなだけ立ち上げる
PUN2のUnityアプリをコンテナ化してDockerでbotを好きなだけ立ち上げる
などなど、個人開発者にも手が届くUnityのネットワークマルチプレイ用SDKにも新顔が出てきました。UNETの呪い[2]から開放されつつあるようで何よりです。
ところで、ネットワークマルチプレイと言ったら負荷試験、負荷試験といったらネットワークマルチプレイです。
ダミークライアントを作成してアタックをキメるのが常道ですが、今回はビルド済みのアプリをコンテナ化してDockerで大量に複製したいと思います。
最初は Netcode for GameObjects でやろうと思っていたのですが、サンプルの Boss Room がちょっと読み切るの大変だったので手癖で作れる PUN2 のCloud
にしました。この記事を読むような人はみんな使ったことが使ったことがあると思うので、サンプルとしてもいいかなと思います。
今回コンテナ化するのは、こんな感じのゲーム……ゲー無[3]です。
PhotonTransformView
とPhotonRigidbodyView
を同期させています。[4]
環境
リポジトリはこちら。
動かし方はREADMEにあります。
構成はこんな感じです。
Version | |
---|---|
Unity | 2021.2.19f1 |
PUN | 2.40 |
Ubuntu | focal-20220404 |
docker version
Client:
Version: 20.10.9
API version: 1.41
Go version: go1.16.8
Git commit: c2ea9bc
Built: Thu Nov 18 21:15:43 2021
OS/Arch: darwin/amd64
Context: default
Experimental: true
Server:
Engine:
Version: 20.10.11
API version: 1.41 (minimum version 1.12)
Go version: go1.16.10
Git commit: 847da184ad5048b27f5bdf9d53d070f731b43180
Built: Fri Nov 19 03:41:34 2021
OS/Arch: linux/amd64
Experimental: false
containerd:
Version: v1.5.8
GitCommit: 1e5ef943eb76627a6d3b6de8cd1ef6537f393a71
runc:
Version: 1.0.0-rc95
GitCommit: b9ee9c6314599f1b4a7f497e1f1f856fe433d3b7
docker-init:
Version: 0.19.0
GitCommit:
Unity
Unityパートのポイントを書きます。
module
Netcode for GameObjects に合わせてか、PlatformにDedicated Server
が追加されました。今までもServer Buildがありましたが、よりサーバに最適化されているとの話です。今回はUbuntu
で動かすので、必要なLinuxのModuleをインストールしていきます。
PUN2
プロジェクトにPUN2をインポートしたりApp Idを発行したりの準備は行っておいてください。
必要な項目は動的に設定するためPhotonServerSettings
に設定する必要はありませんが、App Id
を入れておかないとことあるごとに「ない!!!!」ってアラート出してくるので適当にdummy
とか入れてあげると満足します。
arguments
いろいろ試すにあたって、以下のパラメータはビルドなしで動的に設定できるようにしたいものです。
- App Id
- Room Name
- 表示名
設定ファイルだといろいろ扱いが面倒になることが予想されるので、コマンドライン引数からパースしてDictionaryにします。本当なら専用のデータクラスにしたほうがいいですが、今回はそこまでではないのでしません。
/// -key value -> (key, value)
/// -key -> (key, null)
Dictionaryから取り出して使います。
args.TryGetValue("realtime", out var realtime);
args.TryGetValue("voice", out var voice);
args.TryGetValue("matching", out var roomname);
こんな感じで引数を手動で入力できるデバッグのデバッグ用GUI
もめんどくさがらずに作っておきましょう。生死を分けます。
Build
Editor拡張で上のメニューからビルドできるようにしておくと効率がいいです。コンテナに固めやすいように、Dockerfile
のディレクトリに出力します。
ハマりどころとして、StandaloneとDedicated Serverは別のPlatformなので設定も別です。
具体的に言うとScripting Define Symbols
が別です。PUN2
がまだDedicated Serverに対応していないため、いつものPHOTON_UNITY_NETWORKING
が自動で設定されるものと思っているとつらい気持ちになります。
あと、PUN2
をインポートするとどうもDedicated ServerのScripting Define Symbols
が上書きされちゃうっぽいので消えてたら手動で入れてください。
Unityのポイントは以上です。
GameManager.csとかPlayer.csとかがゲームの内容ですが、まあゲー無
なので……。
他のSDKも共通で試せるようあがいた痕跡が残っているのでお暇な方は笑ってください。やっぱGameManager
はだめだな。
Docker
Dockerパートのポイントを書きます。
image
Ubuntu
のlatestを使います。みんなが使っているものは問題も少ないものです。Editorが動くならビルドしたアプリも動くはず……Ubuntu
は16.04
と18.04
しか公式にサポートしてないことに今気づきましたが、まあ動いてっからよ!
ちなみにalpine
では動きませんでした。それはそう。
LD_LIBRARY_PATH
どうしてかはLinuxに詳しくないのでわかりませんが、root
ではなくユーザを作成して実行するとUnityPlayer.so
を見失ってアプリが起動できなくなります。なので環境変数でパスを教えてあげると動くようになります。
#同じディレクトリにいるのに……?
ENV LD_LIBRARY_PATH=/bot/Output
起動
いろいろビルドが完了したところで、早速実行していきましょう。
argumentsで動的に変えられるようにしておいたパラメータたちをコマンドライン引数に渡していきます。
- App Id
- Room Name
- 表示名
#docker run docked-bot:b12c32f -name {表示名} -matching {Room Name} -realtime {App Id}
#dog
docker run docked-bot:b12c32f -name dog -matching animal -realtime 012345-67890-1234-5678-9012345
#cat
docker run docked-bot:b12c32f -name cat -matching animal -realtime 012345-67890-1234-5678-9012345
#bird
docker run docked-bot:b12c32f -name bird -matching animal -realtime 012345-67890-1234-5678-9012345
サーバとの接続あるのでちょっと起動には時間かかります
App IdとRoom Nameは同じにしておかないと別のRoomに入室してしまって出会えなくなります。
また、ローカルマシンで大量に起動したらMacからなんか聞いたことない音出たので一気に大量に起動しないほうがいいです。
まとめ
Dockerでビルドする記事はそこそこあるのですが、ビルド済みのアプリをDockerで起動する記事はあんまり見当たらなかったので書きました。自分が見つけたのはこれくらいです。
- https://zenn.dev/anifalak/articles/5992fbba0fd564
- https://cloudpack.media/50956
- https://youtu.be/BI03pa3D7Vk [5]
本来ならAWS
とかGCP
を使って思うがまま量産するところまで書くべきかもしれませんが、さすがにこのゆるふわDockerfileだとセキュリティをfu●kされる危険性があるし、そこまで調べるのはなんか本筋と外れるしな……と思ってここまでにしました。
Unity → Dockerと二段階ビルドが必要なので頻繁に更新が入ると無理ですが、他の環境でも安定してbotを多重に起動したい場合やひたすら数を稼ぎたい場合は、コンテナ化は選択肢としていいと思います。どっかのレジストリにimageを上げておけば済むので。
久しぶりに記事を書きましたが、出してないだけでいろいろネタはあるのでちゃんとアウトプットしていこうと思います。特に これ とか……。[6]
おしまい。
参考
Discussion