2024.10.21
お互い疑心暗鬼になりがちな、経営企画と事業部の壁 組織に「分断」が生まれる要因と打開策
リンクをコピー
記事をブックマーク
R.Y.氏(以下、R.Y.):よろしくお願いします。それでは「リアルタイムサーバーチームが初の大規模ローンチに向けてやってきたこと」というタイトルで発表します。
自己紹介です。株式会社コロプラでバックエンドエンジニアをしています。2020年に新卒入社をしたあと、Prizmという内製のリアルタイムフレームワークを作ったりするチームに所属しています。今回は、このPrizmを使ったゲームのローンチに関わる話をしていこうと思います。
今日話すことについて説明します。少し前に、先ほど説明したPrizmのチームが開発に関わったゲームがリリースされました。このタイトルのPrizmに関わる特徴としては、そもそもPrizmを用いてPvPを実装しているところであったり、あとはOpen Matchというk8s nativeなOSSを利用してマッチメイキングをしているところがあります。
今回はこのPrizmを作っているチームのメンバーとして、このゲームのリリースに向けてやってきたことについて紹介できればなと思います。紹介する内容としては、このリリースに役立ったPrizmの機能や、先ほどもあったような負荷対策、負荷試験についてPrizmチームとして向き合って得られた知見といった2つについて大まかに話せればと思っています。
まずはリリースに役立ったPrizmの機能についてお話しします。その前に、Prizmについて軽く紹介させてください。Prizmとは、コロプラで開発しているリアルタイムのゲームを作るためのフレームワークです。サーバーはGo、クライアントはUnityで作られていて、サーバーを介してクライアントがroomという単位に分割されます。そのroomの中でクライアントがメッセージを送り合うようなことを想定したアプリのフレームワークになっています。
基本機能としては、クライアントからサーバー、サーバーからクライアントでメッセージを送り合うという機能があったり、あとはサーバー側にロジックを実装するような機能があったりします。他にもいろいろ機能はあるのですが、そちらについては2022年3月に発表したものがあるので、そちらを参照してもらえればと思います。今回は、リリースにあたって特に役立った機能や、リリースを受けて開発した機能を紹介していければなと思います。
まず1つ目に、通信の遅延やロスをシミュレートする機能について紹介します。Prizmのクライアントに、通信の遅延やロスなどをシミュレートする機能を実装しています。メッセージを更新する前やメッセージを受信したあとにライブラリ側で遅延やロスを挟み込むような機能になっていて、こうすることによってクライアントのアプリだったり、サーバー側から見ると、ネットワークで遅延やロスが起きたのと同じ挙動に見える内容になっています。
(こうした機能が作られた)背景として、コロプラは主にモバイル系のゲームを作っていて、そうした環境では遅延やロスが発生しやすいので、それを前提に作る必要があるということがあります。ただ一方で、開発中は環境が良い社内ネットワークを使って開発するので、こうした問題を認識することや、認識できたとしてもデバッグすることが難しい問題があります。そのためにこういう機能を使っているわけです。
この機能には、開発をする時のアプリにある「デバッグメニュー」みたいなものがあり、そこから「遅延がいくら」とか、「ロスの割合がいくら」みたいなものを設定できるようにしてもらったので、直接開発に携わっているわけではないPrizmチームでも動かせて、「こんな感じの挙動になるんだ」ということを確認できました。
また、リリース後に「ネットワークの調子が悪い時にこういう問題が起きるんじゃないか」みたいなところを検証するためにも使ってもらったようで。いろいろ使い道がある機能になっているのではないかと思っています。
次に、コネクションの切断に対する対応の話をします。前提として、Prizmではリアルタイム通信を実現するために、コネクションを張り続けています。TCPではシンプルにコネクションを張り続けているし、本来コネクションレスなUDPでは、送信元のIPとポートの組を覚えておいて、疑似的に「このIP/ポートから来たのはこの人だ」みたいなことでコネクションを実現しています。
しかし、このようなコネクションは、ゲームの途中で簡単に切れてしまうという問題があります。原因としては、Wi-Fiとモバイル回線の切り替えであったり、モバイル回線でも基地局のハンドオーバーであったり、Wi-Fiのルーターの調子が悪くて通信が一瞬切れてしまうとか。他にもいろいろあると思いますが、その原因はさておき、「切れてしまう」ということが問題になります。
開発中にもコネクションの切断が問題になったので(すが)、(それは)ライブラリ側でサポートができるのではというところで、コネクションが切断してもセッションを維持する機能を実装しました。
やっていることはわりと単純で、TCPやUDPのコネクションが切れた時に、エラーを返すのではなくて、内部的に再接続をしてPrizmレイヤーでのセッションを維持するようなことを実現しました。これによって、ゲームを開発する人たちはL4のコネクションを気にしなくてもよくなる効果が得られました。
もう1つ、切断している間に本来送れるはずだったメッセージが送れなくなってしまうので、そうしたもののうち、Reliableなものについてはライブラリ側でメッセージを再送することで、切断時に起きてしまう嫌なことを防ぐ機能も実装しています。
こうした機能ですが、少し問題点があると感じたので、それについても紹介します。なにかというと、(スライドを示して)このコネクションの再接続に時間が数秒程度かかってしまう問題です。コネクションの切断ですが、そもそも切断をはっきりと取れない場合があるので、Prizmではpingを送り合って、クライアント・サーバーでも、サーバー・クライアントでも状態をお互いに推測することをしています。
この推測ですが、切断(されたこと)で「これはもうダメだな」と判断するまでに、何秒か猶予時間を持つ必要があります。というのも、推測の中身的には「pingを送ったのに返ってこないな」「pingが送られるはずなのに返ってこないな」みたいな感じなので、そこですぐに「ダメだ」と判断することができないからです。たまたまネットワークの調子が悪いだけの時に1回や2回pingが失敗してしまうようなケースはあり得るので、それを排除する必要があります。
何秒か待つところは、ゲーム性によっては許されないことはあると思っています。この前リリースしたゲームはターン制なので、数秒の猶予は許容できるのではないかというところで、こうした実装にしました。ただ、アクション性の強いゲームだったりすると「この数秒も待っていられないよ」という話になると思うので、別の対応を考える必要があるのではないかと思っています。
別の通信頻度の計測についてのお話をしていきます。マルチプレイのゲームを作るにあたって、通信頻度はなるべく最小化したいという前提があります。最小化することによって、インフラコストやクライアント側の消費電力などを減らすことができるので、とてもうれしいです。
しかし、ゲーム開発をしている中で、通信頻度を意識するのはとても難しいという課題があります。原因として、負荷対策よりも「これはそもそもおもしろいゲームなのか」というところの検証を優先することにモチベーションがあったり、開発は社内ネットワークなので通信環境が良くて、たくさん通信をしていても問題が顕在化しづらいことなどがあります。
あとは、とりあえずOnUpdate()のマイクフレームデータを送信すれば動くので、動くものをさらに変えていくようなところも、モチベーションとして湧きづらいです。
ただ、この通信頻度を減らす作業はけっこう重くて、リリース直前に急に「減らしてくれ」と言われても大変なので、事前に早めに気づけるようにしたいところで、計測する仕組みを作るようにしました。
(この時に)「気をつけようね」と定期的にアナウンスするbotになってもいいのですが、意外な理由で通信量が増えるケースがあり、気をつける・気をつけないの問題ではないものもけっこうあったので、「計測したほうがいいよね」というところで計測する仕組みを作りました。
(スライドを示して)「リリースする直前に減らすのは大変」というところについては、いくつか理由があると思っています。まず、そもそもの仕様がたくさん通信しないと厳しいものであって、仕様のレベルで改善をしなきゃいけないとか、通信頻度を減らせるにしても、送っていない間のデータの補完などをしなきゃいけないとか、実装が別で必要になる場合もあるので、早めに発見して早めに対策をしたいところがあったりするので、早めに気づきたいです。
それで「どうやって気づくの?」という話なのですが、サーバーとクライアントのそれぞれに機能を用意しています。サーバーでは、クライアントが通信しすぎていたらワーニングログを出す機能を入れました。クライアントごとに5秒間のリクエスト数、RPSを計測して、一定の値を超えたらワーニングログを出す機能です。
この閾値はデフォルトが10RPSになっているのですが、これは設定で変更可能になっているので、ゲームの仕様に合わせることができるようになっています。サーバー側の機能の意図としては、詳細よりも大まかな傾向をつかむことを目的にしていて、サーバーで大まかな傾向をつかめたら、次のクライアントの機能を使って、より詳細を知る流れを意図しています。
クライアントではなにができるかというと、通信まわりのプロファイルを取得したり、表示したりする機能を入れています。このプロファイルでは、メッセージごとに何回通信しているのか、1秒間にどれだけ通信しているのかといった頻度を知ることができて、サーバーよりも粒度の高い情報を得ることができます。
また、取得するだけではなく、Unityの拡張で表示する機能も入れているので、そのあたりの実装もいらないかたちになっています。こうすることによって、サーバーでは取得しづらい詳細な情報をハンドリングできるので、それぞれ役割を持っていて良い感じなのではないかなと思っています。
機能についてのまとめです。1つ目に、通信の遅延やロスをシミュレートする機能があります。これについてはモバイルのゲームでは特に重要なのではないかと思っています。
2つ目に、セッションを維持する機能を入れました。L4のコネクションが切断されてしまうので、それへの対応です。
3つ目に、通信の頻度を計測する機能を実装しました。これは重要な話ですが気づくのがなかなか難しいので、「計測して気づけるようにしようね」ということもやっていきました。
(次回に続く)
関連タグ:
2024.11.13
週3日働いて年収2,000万稼ぐ元印刷屋のおじさん 好きなことだけして楽に稼ぐ3つのパターン
2024.11.21
40代〜50代の管理職が「部下を承認する」のに苦戦するわけ 職場での「傷つき」をこじらせた世代に必要なこと
2024.11.20
成果が目立つ「攻めのタイプ」ばかり採用しがちな職場 「優秀な人材」を求める人がスルーしているもの
2024.11.20
「元エースの管理職」が若手営業を育てる時に陥りがちな罠 順調なチーム・苦戦するチームの違いから見る、育成のポイント
2024.11.11
自分の「本質的な才能」が見つかる一番簡単な質問 他者から「すごい」と思われても意外と気づかないのが才能
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
2024.11.18
20名の会社でGoogleの採用を真似するのはもったいない 人手不足の時代における「脱能力主義」のヒント
2024.11.19
がんばっているのに伸び悩む営業・成果を出す営業の違い 『無敗営業』著者が教える、つい陥りがちな「思い込み」の罠
2024.11.13
“退職者が出た時の会社の対応”を従業員は見ている 離職防止策の前に見つめ直したい、部下との向き合い方
2024.11.15
好きなことで起業、赤字を膨らませても引くに引けない理由 倒産リスクが一気に高まる、起業でありがちな失敗