2024.12.19
システムの穴を運用でカバーしようとしてミス多発… バグが大量発生、決算が合わない状態から業務効率化を実現するまで
リンクをコピー
記事をブックマーク
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.12.20
日本の約10倍がん患者が殺到し、病院はキャパオーバー ジャパンハートが描く医療の未来と、カンボジアに新病院を作る理由
2024.12.19
12万通りの「資格の組み合わせ」の中で厳選された60の項目 532の資格を持つ林雄次氏の新刊『資格のかけ算』の見所
2024.12.16
32歳で成績最下位から1年でトップ営業になれた理由 売るテクニックよりも大事な「あり方」
2023.03.21
民間宇宙開発で高まる「飛行機とロケットの衝突」の危機...どうやって回避する?
PR | 2024.12.20
モンスター化したExcelが、ある日突然崩壊 昭和のガス工事会社を生まれ変わらせた、起死回生のノーコード活用術
2024.12.12
会議で発言しやすくなる「心理的安全性」を高めるには ファシリテーションがうまい人の3つの条件
2024.12.18
「社長以外みんな儲かる給与設計」にした理由 経営者たちが語る、優秀な人材集め・会社を発展させるためのヒント
2024.12.17
面接で「後輩を指導できなさそう」と思われる人の伝え方 歳を重ねるほど重視される経験の「ノウハウ化」
2024.12.13
ファシリテーターは「しゃべらないほうがいい」理由 入山章栄氏が語る、心理的安全性の高い場を作るポイント
2024.12.10
メールのラリー回数でわかる「評価されない人」の特徴 職場での評価を下げる行動5選
Climbers Startup JAPAN EXPO 2024 - 秋 -
2024.11.20 - 2024.11.21
『主体的なキャリア形成』を考える~資格のかけ算について〜
2024.12.07 - 2024.12.07
Startup CTO of the year 2024
2024.11.19 - 2024.11.19
社員の力を引き出す経営戦略〜ひとり一人が自ら成長する組織づくり〜
2024.11.20 - 2024.11.20
「確率思考」で未来を見通す 事業を成功に導く意思決定 ~エビデンス・ベースド・マーケティング思考の調査分析で事業に有効な予測手法とは~
2024.11.05 - 2024.11.05