Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
cocone TECH TALK Vol.6 - リアルタイム対戦xバックエンドアーキテクチャ
Search
cocone
May 08, 2023
Technology
730
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
cocone TECH TALK Vol.6 - リアルタイム対戦xバックエンドアーキテクチャ
cocone
May 08, 2023
More Decks by cocone
See All by cocone
Cocone_Research_Center_2025.pdf
cocone
0
370
20240301_cocone_EMゆるミートアップvol6_LT資料
cocone
0
950
2024_cocone-wellbeing
cocone
0
5.2k
2023夏季合同企業説明会ココネ
cocone
0
420
cocone TECH TALK Vol.6 - ココネグループのブロックチェーン MOOI Network とのバックエンド連携
cocone
0
680
cocone TECH TALK Vol.6 - Kotlin バックエンドアーキテクチャ of アバターサービス
cocone
0
670
cocone corporation(JPN)/Handbook2022
cocone
1
31k
cocone Tech Talk vol.5 - Unity Dotsを使ってみた
cocone
0
2.6k
cocone corporation(JPN)/Letter to Planner
cocone
0
600
Other Decks in Technology
See All in Technology
C#未経験の僕がAIに読めるコードを書かせるまで
maguroalternative
0
250
[Kiro Meetup #7] Kiro Crew Dive Deep
konippi
0
240
技術的負債から考える、AI時代のエンジニアリング投資 — ビズリーチの技術的負債と向き合った経験から、変更し続けられるソフトウェアを考える/ technical-debt-con2026
visional_engineering_and_design
4
3.7k
銀行勘定系システムにおける開発プロセス刷新×AIによる環境モダナイゼーション / Development Process Transformation and AI-Driven Environment Modernization
muit
1
2.6k
AIエージェントの権限管理 3: Agentic RAG の Fine grained access control 編
ren8k
0
200
負債のメタファと2026年 / Debt Metaphor in Agentic Engineering Age 202609 Edition
twada
PRO
10
6.1k
Genieを崇めよ
kameitomohiro
0
170
サーバーレスをどこまで使う? WebRTC対戦ゲームで選んだVPSとの共存設計
kaidouji85
0
340
あけおめLINE 傾向とその対策
nasa9084
0
280
ScotSecure West 2026 - Glasgow
raybugg
0
150
JSONataとAWS Step Functionsで目指すRuntimelessな世界
mu7889yoon
0
440
【技術的負債conf】事業成長に伴う技術的負債の説明責任とAIによるモニタリング、認知的負債について
i35_267
3
2.1k
Featured
See All Featured
A Soul's Torment
seathinner
8
3.6k
Are puppies a ranking factor?
jonoalderson
2
3.9k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.3k
New Earth Scene 8
popppiees
4
2.6k
技術選定の審美眼(2025年版) / Understanding the Spiral of Technologies 2025 edition
twada
PRO
120
120k
Become a Pro
speakerdeck
PRO
31
6.3k
Bridging the Design Gap: How Collaborative Modelling removes blockers to flow between stakeholders and teams @FastFlow conf
baasie
0
700
The Invisible Side of Design
smashingmag
301
52k
Introduction to Domain-Driven Design and Collaborative software design
baasie
1
990
Chasing Engaging Ingredients in Design
codingconduct
0
320
The World Runs on Bad Software
bkeepers
PRO
72
12k
We Have a Design System, Now What?
morganepeng
55
8.3k
Transcript
リアルタイム対戦 × バックエンドアーキテクチャ RYO TOMARU
自己紹介 職歴 ゲーム系企業でクライアント /サーバーを主軸に しつつ、配信サービスのフロントエンド実装など も経験。 趣味 個人ゲーム開発、ドット絵、最近引退気味です が光の戦士。最近はGolangとFlutterが好き。 戸丸
良 / RYO TOMARU
本日の内容 • どのような技術を用いて「リアルタイム対戦」を実現したか • 通信フローについてのご紹介 • 苦労したポイント ※詳細なインフラ構成については今回の範囲外となります ...。
目次 1. リアルタイム通信をどの技術で実現するか 2. 今回採用した技術 3. 苦労したポイント 4. まとめ
リアルタイム通信をど の技術で実現するか
多彩な選択肢 最近では、ゲームエンジン側でもサポートが進むなど、開発がしやすい環境となってきてい る。 • 純粋なSocketを用いて構築する • Unity+MLAPI/Mirror/DOTSNET … • Unity
+ Photon/モノビットエンジン/MagicOnion • gRPC Bidirectional Streaming RPC • WebSocketやDatagram … etc …
選択肢が多い上に、一つ一つが難しい
多彩な選択肢 「リアルタイム通信対戦がしたい」だけであれば、どの手段でも実現は可能。 ここに「サービス・ゲームデザインとしてはどうか 」「運用保守の面でどうか」「UXとしてどう か」など、様々な要素を加えて選択していく必要がある。 (難しい・・・) 今回は担当プロダクトにおいて、どのような選択をしたのか、苦労話と合わせてご紹介しま す。
今回採用した技術
gRPCを利用 • 他の機能(API)はgRPCで実装していたため、同一の運用で対応したかった • Unary RPC ◦ Request/Response ◦ 一般的なAPI
• Client Streaming RPC ◦ Clientから任意にデータ送信が可能 ◦ ファイルアプロードなど • Server Streaming RPC ◦ Serverから任意にデータ送信可能 ◦ 通知など • Bidirectional Streaming RPC ◦ 双方向通信 ◦ 相互に任意のタイミングでデータ送信が可能
初期に採用したのは・・・ • 初期(モック)時点では、ゲームデザインが完全に FIXしていなかった • 単純に双方向を選択しておけば大抵なんとかなるよね、から選択 • 慣れていた gRPC Bidirectional
Streaming RPC
gRPC Bidirectional Streaming • 俗に言う双方向通信 • クライアント、サーバー相互に任意のタイミングでデータ送信が行える • oneofを使用し、一つのstreamで複数のコマンドを定義 message
Notify { // どれか1つの情報がくるので、 switchなどで処理を振り分ける oneof event { ChatInfo chat_info = 1; Actor join_actor = 2; … } } service StreamingService { rpc StartNotify(...) returns (stream Notify) {} … }
順調に実装は進んでいったが・・・
実装自体は進んだが、次第に様々な問題が発生 複雑化するコード Client/Server間のやり取りの増加 操作に対して必ず結果が必要 テストの複雑化 増えるoneof 開発コスト増加 send/recvそれぞれのgoroutineを 管理する必要 このメソッドってクライアントに何か投
げるんだっけ・・・? 増え続けるoneof 増え続けるoneof 増え続けるoneof
pickup 増え続けるoneof • Request/ResponseをC/Sのmessageへ追加する • 関係性が非常に難解 message ClientNotify { oneof
event { Say say = 1; Foo foo = 2; Bar bar = 3; Echo echo = 4; … } message Say {...} … } message ServerNotify { oneof event { SayResult say_result = 1; FooResult foo_result = 2; BarResult bar_result = 3; EchoResult echo_result = 4; … } message SayResult {...} … }
まだ間に合う・・・はず! (そもそもゲームデザイン的にあっていないのでは? )
最終的な着地点 • gRPC + Unary RPC + Server Streaming RPC
• 各種操作については、Unary RPC(Request/Response)へ変更 • 自身の操作などはServer Streaming RPCを利用して通知 • より詳細な情報が必要であれば Unary RPCで取得 gRPC + Unary RPC + Server Streaming RPC 意外とすんなりいけるはず
最終的な着地点 • gRPC + Unary RPC + Server Streaming RPC
• 各種操作については、Unary RPC(Request/Response)へ変更 • 自身の操作などはServer Streaming RPCを利用して通知 • より詳細な情報が必要であれば Unary RPCで取得 gRPC + Unary RPC + Server Streaming RPC 全部書き直した
gRPC + Unary RPC + Server Streaming RPC
Redis PubSubを利用
結果としてどうなったか • 基本的にUnary RPCを利用するため、フローがシンプルになった ◦ いつも通りの実装、テスト手法が通用した • Request/ReponseがIDLにて明示的に定義されるため、読みやすい ◦ この操作きたら何を返すんだっけ・・・が無くなった
• Unaryは操作、Streamingはサーバーからの通知と役割を切り分けられた ◦ CRUDとNotifyを切り離せたので、可読性が上がった
苦労したポイント
苦労したポイント 再接続時の復帰処理 復帰時の進行状況に応じて状態を再現する必要があった。 また切断中は自動行動を行うため、タイミングによっては進行不能になるなど、 リリース直前まで頭を悩ませられた。 細かいエッジケース対応 〜の時に〜をするとバグる、という様な話が初期は特に多かった。 最終的にはBOTを作成し、自動的にバトルを繰り返す仕組みでカバーした。 ローンチ後、大きな問題は起きていないので、良い結果が出せた。 参考:
https://qiita.com/maruc/items/2393647be5caa32623e3
苦労したポイント PubSubに悩まされた go-redisを使用していたが、コネクション数が多大になったり、 ConnectionPoolとPubSubの接続状態連携が行われていないなど ...。 最終的にはある程度自前でコントロールを行った。 負荷対策 システム上、最新のデータを取得するケースが多く、 Primaryアクセスが頻発。 キャッシュアサイドパターンを用いることで、負荷軽減を行った。
(整合性を担保する必要があるので、可能であれば避けたい所ではあった)
pickup go-redis pubsub • 1購読=1コネクションが貼られる • アクティブが1万人いたら1万コネクション ◦ パフォーマンスが著しく低下 ◦
ElasctiCacheの上限にもかかる • 最終的にAPでコネクションを自前プールするよう実装 • 一つのコネクションで複数サブスクライブできるように変更 • 内部的に各Sessionのgo:channelへpush ◦ ch <- event
まとめ
まとめ • 当たり前ですが「ゲームデザインにあった」技術選定、設計が重要。 • 表面上動くものはすぐに作れる時代ではあるが、その先が深い。 ◦ このタイミングで切断されたら・・・ ◦ 地下鉄で瞬断したら・・・ ◦
バイナリが改造されたら・・・ etc • 「どのようにテストを行うか」も初期段階で考えておくと良い。 • 開発中はクライアント担当とずっと「うーん・・・」と唸ることになる。 • ・・・とはいえ、開発自体は楽しい!
ご静聴ありがとうございました