🐳

PUN2のUnityアプリをコンテナ化してDockerでbotを好きなだけ立ち上げる

2022/04/20に公開

PUN2のUnityアプリをコンテナ化してDockerでbotを好きなだけ立ち上げる

などなど、個人開発者にも手が届くUnityのネットワークマルチプレイ用SDKにも新顔が出てきました。UNETの呪い[2]から開放されつつあるようで何よりです。

ところで、ネットワークマルチプレイと言ったら負荷試験、負荷試験といったらネットワークマルチプレイです。
ダミークライアントを作成してアタックをキメるのが常道ですが、今回はビルド済みのアプリをコンテナ化してDockerで大量に複製したいと思います。
最初は Netcode for GameObjects でやろうと思っていたのですが、サンプルの Boss Room がちょっと読み切るの大変だったので手癖で作れる PUN2Cloudにしました。この記事を読むような人はみんな使ったことが使ったことがあると思うので、サンプルとしてもいいかなと思います。

今回コンテナ化するのは、こんな感じのゲーム……ゲー無[3]です。
PhotonTransformViewPhotonRigidbodyViewを同期させています。[4]

環境

リポジトリはこちら。
動かし方はREADMEにあります。

https://github.com/nekomimi-daimao/DockedBotTestBed

構成はこんな感じです。

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にします。本当なら専用のデータクラスにしたほうがいいですが、今回はそこまでではないのでしません。

ArgumentParser.cs

/// -key value -> (key, value)
/// -key       -> (key, null)

Dictionaryから取り出して使います。

SetupPhoton.cs

args.TryGetValue("realtime", out var realtime);
args.TryGetValue("voice", out var voice);
args.TryGetValue("matching", out var roomname);

こんな感じで引数を手動で入力できるデバッグのデバッグ用GUIもめんどくさがらずに作っておきましょう。生死を分けます

Build

BuildSystem.cs

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が動くならビルドしたアプリも動くはず……Ubuntu16.0418.04しか公式にサポートしてないことに今気づきましたが、まあ動いてっからよ!
ちなみにalpineでは動きませんでした。それはそう。

LD_LIBRARY_PATH

どうしてかはLinuxに詳しくないのでわかりませんが、rootではなくユーザを作成して実行するとUnityPlayer.soを見失ってアプリが起動できなくなります。なので環境変数でパスを教えてあげると動くようになります。

Dockerfile

#同じディレクトリにいるのに……?
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で起動する記事はあんまり見当たらなかったので書きました。自分が見つけたのはこれくらいです。

本来ならAWSとかGCPを使って思うがまま量産するところまで書くべきかもしれませんが、さすがにこのゆるふわDockerfileだとセキュリティをfu●kされる危険性があるし、そこまで調べるのはなんか本筋と外れるしな……と思ってここまでにしました。
Unity → Dockerと二段階ビルドが必要なので頻繁に更新が入ると無理ですが、他の環境でも安定してbotを多重に起動したい場合やひたすら数を稼ぎたい場合は、コンテナ化は選択肢としていいと思います。どっかのレジストリにimageを上げておけば済むので。

久しぶりに記事を書きましたが、出してないだけでいろいろネタはあるのでちゃんとアウトプットしていこうと思います。特に これ とか……。[6]

おしまい。

参考

https://forum.unity.com/threads/unity-2021-2-dedicated-server-target-and-stripping-optimizations-now-live-please-share-feedback.1143734/
https://gametukurikata.com/ui/layoutgroup

https://qiita.com/minamijoyo/items/c599e81f8803e690f3e1
https://www.wakuwakubank.com/posts/395-linux-ldd-ldconfig/

脚注
  1. PUNを早くもLegacyに叩き込んでおられる…… ↩︎

  2. サンプルコードを読んだだけで使ったことないですが、フォロワーたちを見る限り相当ひでえ設計だったのでは? と思っています。実際褒めてる人見たことない。 ↩︎

  3. 案外たのしい ↩︎

  4. 本当はPhotonVoiceもbotに組み込みたかったんですが、ビルドが通らなくて諦めました。なんかの.soがなんかだめらしい。 ↩︎

  5. あんま内容見てないけど右下で喋ってるのが妖精さんみたいで面白い ↩︎

  6. 実装が完成したあたりでシーフード溢れる狭間の地に踏み込んだと思われる ↩︎

Discussion