$30 off During Our Annual Pro Sale. View Details »

Apex Legendsにハマっています / I'm addicted to Apex Legends

Apex Legendsにハマっています / I'm addicted to Apex Legends

2022年3月27日に行われたtraP LT 2022で発表した資料です。
他の発表資料などは https://connpass.com/event/242713/

to-hutohu

March 27, 2022
Tweet

More Decks by to-hutohu

Other Decks in Technology

Transcript

  1. Apex Legendsにハマっています @to-hutohu traP LT

  2. 3 Apex Legendsにハマっています このスライドは88枚あります! 最後のLTです! お疲れさまでした!

  3. 自己紹介 4 Apex Legendsにハマっています ◼ とーふとふ(@to_hutohu) ◼ ex-traP (16B 2018年代表

    2019年SysAd班リーダー) ◼ 社会人2年目 ◼ Vtuberが好き ⚫ 花譜・神椿が最推し ⚫ 昨日のライブが最高すぎた
  4. Apex Legendsとは 5 Apex Legendsにハマっています ◼ Respawn Entertainmentが開発、Electronic Artsが リリースしている基本プレイ無料のFPSバトル

    ロワイヤルゲーム ◼ PC・Xbox・PS4/PS5・Swtichで遊べる ◼ 2021年1年間でのプレイ人数は1億7500万人 https://www.ea.com/ja-jp/games/apex-legends
  5. Apex Legendsのゲームの流れ 6 Apex Legendsにハマっています 1. レジェンド選択 2. 3人1部隊で 飛行機から降下

    3. 落ちている武器を 拾って装備を整える 4. 他の部隊と戦う 5. 最後の1部隊になったら チャンピオン
  6. ApexとVtuber 16 Apex Legendsにハマっています ◼ ゲーム配信系Vtuberの多くがプレイしている ⚫ コラボ・イベントツールとして活躍 ◼ Vtuber最協決定戦やCRカップ他Vtuberが参加するイベントも

    たくさん開催されている ⚫ 大会だと乾伸一郎推しなので前回の最協決定戦は良かった… ⚫ 似たような役目のゲームとしては前はPUBG, 最近はValorant
  7. 就職してからの話 18 Apex Legendsにハマっています ◼ 自由(だと感じられる)時間が増えた ⚫ 労働の時間とそれ以外がきっちり分かれる ◼ ゲームを遊ぶ時間が増えた

    ⚫ 自分の好みのゲームも遊ぶが、よく見ている配信者が遊んでいるゲームを 遊ぶことも多い ⚫ サクナヒメ・Vampire Survivors・壺・アルセウス・Apex…
  8. とーふとApex Legends 19 Apex Legendsにハマっています ◼ FPS初ゲーム ◼ PC・キーボード/マウス操作 ◼

    形から入る派なのでデバイスは揃えた ⚫ RTX3070/165Hzのモニター/ゲーミングマウス ◼ プラチナ4床ペロ
  9. プレイのスタッツを確認したくなる 20 Apex Legendsにハマっています ◼ ゲーム内だとシーズンごとの統計しか見ることができない ◼ 外部サイトでもシーズン×レジェンドごとの統計までしかわからない https://dak.gg/apex/profile/pc/FEUFPS_TTV

  10. LoLやValorantだと 21 Apex Legendsにハマっています https://valorant.op.gg/profile/name=MamyPoko&tagLine=jboyy&region=ap&rank=1 https://jp.op.gg/summoners/jp/%E3%81%B2%E3%82%87%E3%82%93%E3%81%98%E3%82%85%E3%82%93

  11. Apexでもゲームごとの 情報を見たい

  12. 類似事例:Ikalog 23 Apex Legendsにハマっています ◼ 「スプラトゥーン」(いわゆるスプラ1)の キャプチャをリアルタイム解析する ◼ 解析データをstat.inkという別サービスに送って 集約することができる

    ◼ Python+OpenCVに加えて機械学習とかも 取り入れていて強そう… https://hasegaw.github.io/IkaLog/
  13. 24 Apex Legendsにハマっています これのApex版を作ろう! ここまで強いのは無理だけど…

  14. 作りました 27 Apex Legendsにハマっています http://localhost:3000/

  15. Apex Legendsにハマっています 28 Apex Legendsにハマっています ハマったのでブラウザ上でApexのゲーム画面をリアルタイム解析して ゲームの記録を取ってくれるApeLogを作りました

  16. 目次 29 Apex Legendsにハマっています 機能紹介 ApeLogの機能を紹介します 技術概要 ApeLogに利用している技術の全体像 技術詳細 ApeLogの実装内容を紹介します

    開発あれこれ ApeLog開発中にあったあれこれ 終わりに 社会人としてApeLogを開発して&ApeLogのこれから
  17. 目次 30 Apex Legendsにハマっています 機能紹介 ApeLogの機能を紹介します 技術概要 ApeLogに利用している技術の全体像 技術詳細 ApeLogの実装内容を紹介します

    開発あれこれ ApeLog開発中にあったあれこれ 終わりに 社会人としてApeLogを開発して&ApeLogのこれから
  18. 31 Apex Legendsにハマっています ApeLog概要 ◼ 右上のSTART LOGGINGを押すと画面選択 する画面が出る http://localhost:3000/

  19. 32 Apex Legendsにハマっています ApeLog概要 ◼ 右上のSTART LOGGINGを押すと画面選択 する画面が出る ◼ Apexの画面を選択して共有すると

    Apexの各種データがロギングされる http://localhost:3000/
  20. ApeLog概要 33 Apex Legendsにハマっています ◼ 過去のゲームの一覧から結果を選択 ◼ マップ内の移動経路やファイト時の 動画を確認できる ◼

    時間がなくて UIに全然手が回っていない… http://localhost:3000/
  21. ロギングの機能(現状) 34 Apex Legendsにハマっています ◼ レジェンド構成記録機能 ◼ 装備切り替え・部隊数・キルアシスト・ヘルスなど 基本情報ロギング機能 ◼

    マップ内移動経路記録機能 ◼ 安置スクリーンショット機能 ◼ リザルト画面記録・スクリーンショット機能 ◼ ダメージ・キル/アシスト・ラスト2部隊などを検知して約5秒前から 録画する自動インスタントリプレイ機能
  22. レジェンド構成記録機能 35 Apex Legendsにハマっています ◼ どういう構成で部隊が編成されたかを記録 レジェンド名

  23. 基本情報ロギング機能 36 Apex Legendsにハマっています 残り部隊数 キル/アシスト 与ダメージ 武器 体力

  24. マップ内移動経路記録機能・安置スクショ機能 37 Apex Legendsにハマっています ◼ マップ内でどのように移動したか確認できる ◼ ラウンドごとにマップ画面を開いたときに 安置を記録する

  25. リザルト画面記録・スクショ機能 38 Apex Legendsにハマっています 部隊順位 部隊キル数 個人のキル・アシスト・ ノックダウン 個人の与ダメージ

  26. インスタントリプレイ機能 39 Apex Legendsにハマっています ダメージを与える5秒前からの録画

  27. 目次 40 Apex Legendsにハマっています 機能紹介 ApeLogの機能を紹介します 技術概要 ApeLogに利用している技術の全体像 技術詳細 ApeLogの実装内容を紹介します

    開発あれこれ ApeLog開発中にあったあれこれ 終わりに 社会人としてApeLogを開発して&ApeLogのこれから
  28. 技術概要 41 Apex Legendsにハマっています ◼ UI周りはTypeScript+React(Viteバンドル) ⚫ 普通の構成&全然実装していないので割愛 ◼ それ以外の機能は大きく分けて2つに分けられる

    ⚫ 画像のリアルタイム処理系→Wasm(C++/Emscripten/OpenCV) ⚫ 画像・動画の保存系→JavaScript
  29. 技術概要 42 Apex Legendsにハマっています OffscreenCanvas Media Capture and Streams API

    MediaStreamTrack API Wasm(OpenCV) リアルタイム画像認識 Stateに応じて各タスクを実行 画像・動画の保存系 IndexedDB 画面のキャプチャ Streamのクローン フレームの取得・間引き 10フレームに1回 モノクロ化 イベント通知 インスタントリプレイ スクリーンショット 保存 ゲーム管理 ゲーム終了通知 ゲーム結果取得 ゲーム結果記録 画像リアルタイム処理系 MediaStream Recording API
  30. Media Capture and Streams API 44 Apex Legendsにハマっています ◼ WebRTC関連のAPI

    ◼ 画面のキャプチャを取ることができる ⚫ Chromium系なら音声も取れる ◼ ここで取得したStreamを後段の各種APIで利用する https://developer.mozilla.org/ja/docs/Web/API/Media_Streams_API
  31. MediaStreamTrack (Insertable) API 45 Apex Legendsにハマっています ◼ エンコードされる前の生のフレームデータを取得できる ◼ 本来は動画のリアルタイム編集(バーチャル背景とか)に使う

    ◼ ApeLogでは各フレームのデータをWasmにわたすために利用 ◼ 流れてくるデータはYUV_I420 ⚫ 輝度と青色成分の差・赤色成分の差を持っている ◼ Chromium系でしか使えない! https://developer.mozilla.org/ja/docs/Web/API/MediaStreamTrack https://www.w3.org/TR/mediacapture-transform/
  32. Wasm(OpenCV) 46 Apex Legendsにハマっています ◼ C++で書いてEmscriptenでぐっとビルドするとできる ◼ OpenCVも公式でWasmビルド可能 ⚫ Zennの記事に感謝

    https://docs.opencv.org/4.x/d4/da1/tutorial_js_setup.html https://zenn.dev/kounoike/articles/20201209-opencv-js-wasm
  33. MediaStream Recording API 47 Apex Legendsにハマっています ◼ MediaStreamを動画バイナリ化できる ◼ ApeLogではインスタントリプレイのために利用

    ◼ 動画フォーマットやビットレートを指定して記録を開始 ◼ 得られるBlobをファイルとして保存するとwebmファイルとして見る ことができる https://developer.mozilla.org/ja/docs/Web/API/MediaStream_Recording_API
  34. OffscreenCanvas 48 Apex Legendsにハマっています ◼ Canvas APIをメインスレッドでもWebWorkerでも使えるようにしたもの ◼ ApeLogでは動画中からスクリーンショットを取得するために利用 ⚫

    StreamをVideoで再生→フレームをCanvasに描画→APIでPNG Blobを取得→IndexedDBに保存 ◼ 今回はメインスレッドでしか使ってません https://developer.mozilla.org/ja/docs/Web/API/OffscreenCanvas
  35. IndexedDB 49 Apex Legendsにハマっています ◼ ブラウザから利用できる簡易的なDB ◼ Blobも保存できるので動画・画像を保存 ⚫ Blob取り出しの速度とかはそこまで早くない…

    ◼ ドメインごとに保存 ◼ Dexieというライブラリから利用 https://developer.mozilla.org/ja/docs/Web/API/IndexedDB_API
  36. 目次 50 Apex Legendsにハマっています 機能紹介 ApeLogの機能を紹介します 技術概要 ApeLogに利用している技術の全体像 技術詳細 ApeLogの実装内容を紹介します

    開発あれこれ ApeLog開発中にあったあれこれ 終わりに 社会人としてApeLogを開発して&ApeLogのこれから
  37. 技術概要 52 Apex Legendsにハマっています OffscreenCanvas Media Capture and Streams API

    画像・動画の保存系 IndexedDB 画面のキャプチャ Streamのクローン イベント通知 データの蓄積・破棄 録画 スクリーンショット 保存 ゲーム管理 ゲーム終了通知 ゲーム結果取得 ゲーム結果記録 MediaStream Recording API MediaStreamTrack API Wasm(OpenCV) フレームの取得・間引き 10フレームに1回 モノクロ化 画像リアルタイム処理系 リアルタイム画像認識 Stateに応じて各タスクを実行
  38. タスク:画像系 53 Apex Legendsにハマっています ◼ 指定範囲を矩形で取得 ◼ しきい値で二値化(したりしなかったり) ◼ 各画像で以下の処理を行う

    ⚫ ターゲット画像との差分(絶対値)を取る ⚫ しきい値(30くらい)で二値化 ⚫ 0ではないピクセルの数を数える ◼ 指定した値以下かつ最も値が小さいものを 結果とする 取り出して二値化 対象画像 差分
  39. 処理のコード(抜粋) 54 Apex Legendsにハマっています

  40. タスク:文字系 55 Apex Legendsにハマっています ◼ 指定範囲を矩形で取得 ◼ しきい値で二値化(白黒化) ◼ 指定サイズ範囲内の矩形を取得

    cv::findContours ◼ 各矩形で以下の処理を行う ⚫ 対象画像サイズに合わせてパディング ⚫ すべての対象画像と差分を取って 一番小さいものを結果とする ◼ すべての結果を合わせたものが結果 ・・・ 取り出して二値化 ターゲット画像
  41. 処理のコード(抜粋) 範囲を矩形で取得→二値化→指定サイズ内の矩形を取得 56 Apex Legendsにハマっています

  42. 続き:各矩形でパディング→対象画像と比較 57 Apex Legendsにハマっています

  43. タスク:マップ 58 Apex Legendsにハマっています ◼ OpenCVのSIFT(Scale-Invariant Feature Transform) というアルゴリズムを利用 ⚫

    チュートリアルに沿って書くとできる ⚫ SURFやORB、AKAZEを試して一番精度が出た(感覚) ◼ マップ上での位置推定は↓の記事を参考に https://qiita.com/grouse324/items/74988134a9073568b32d
  44. タスク:状態遷移 59 Apex Legendsにハマっています ◼ 所定の位置に特定のマーカーが表示されたら 状態を遷移させたり変化させる

  45. Stateの遷移 60 Apex Legendsにハマっています 設定画面開いているとスキップする部分もあって難しい ロビー マッチング レジェンド 選択 ゲーム通常

    ダウン中 バナー 全滅 マップ 画面 その他UI (バッグなど) リザルト マッチタイプ判定 マップ判定
  46. 技術概要 61 Apex Legendsにハマっています Media Capture and Streams API MediaStreamTrack

    API Wasm(OpenCV) Stateに応じて各タスクを実行 IndexedDB 画面のキャプチャ Streamのクローン フレームの取得・間引き 10フレームに1回 モノクロ化 イベント通知 保存 ゲーム管理 ゲーム終了通知 ゲーム結果記録 画像リアルタイム処理系 OffscreenCanvas 画像・動画の保存系 インスタントリプレイ スクリーンショット ゲーム結果取得 MediaStream Recording API OffscreenCanvas
  47. インスタントリプレイ:MediaStream Recording API 62 Apex Legendsにハマっています ◼ デフォルトでは録画終了時にデータがまとめて来る ◼ start関数に数値を渡すとそのミリ秒ごとにデータが流れてくる

    ⚫ recorder.start(1000)とすると1000ミリ秒ごとにondataavailableメソッド が呼ばれる ◼ データの形式はWebM
  48. WebMのコンテナフォーマット 63 Apex Legendsにハマっています ◼ Matroska(マトリョーシカ)のサブセット ◼ MatroskaはEBMLという形式 ⚫ XMLを元にしたデータ格納方式

    ◼ ↓フォーマットイメージ(すごいてきとう) Header SimpleBlock Timecode SimpleBlock SimpleBlock ︙ SimpleBlock Timecode SimpleBlock SimpleBlock ︙ 動画のヘッダー (いろいろ入っている) Cluster 動画の本体 これがまとめて Blobとして渡される Clusterの開始秒数・ 長さが入っている
  49. インスタントリプレイの実現 65 ◼ データをBlobからEBMLにパースしておく ◼ Timecodeの中身を見て保持しておく秒数を越えていたらClusterを消す SimpleBlock Timecode SimpleBlock SimpleBlock

    ︙ SimpleBlock Timecode SimpleBlock SimpleBlock ︙ SimpleBlock Timecode SimpleBlock SimpleBlock ︙ 変更前 開始秒数 1.7s 開始秒数 3.5s 開始秒数 5.3s SimpleBlock Timecode SimpleBlock SimpleBlock ︙ 開始秒数 0s Header 変更後 開始秒数 0s 開始秒数 1.8s 開始秒数 3.6s 削除 SimpleBlock Timecode SimpleBlock SimpleBlock ︙ SimpleBlock Timecode SimpleBlock SimpleBlock ︙ SimpleBlock Timecode SimpleBlock SimpleBlock ︙ Header
  50. コード(抜粋) 66 Apex Legendsにハマっています

  51. 録画シーケンス 67 Apex Legendsにハマっています 1. Wasmのタスクから録画開始の通知が来る 2. そのタイミングのスクショを 3. 前を捨てていく処理を停止

    4. 20秒後にstopする ⚫ 20秒以内に再度録画開始の通知が来たら延長する 5. EBML形式のデータをBlob化 6. IndexedDBに保存
  52. スクリーンショット 68 Apex Legendsにハマっています 1. Wasmのタスクからスクリーンショットの通知が来る 2. スクリーンキャプチャのStreamを再生開始する 3. 1フレームだけ再生されたタイミングでそのフレームをCanvasに

    レンダリング 4. PNGのBlobに変換してIndexedDBに保存
  53. コード(抜粋) 69 Apex Legendsにハマっています

  54. 目次 70 Apex Legendsにハマっています 機能紹介 ApeLogの機能を紹介します 技術概要 ApeLogに利用している技術の全体像 技術詳細 ApeLogの実装内容を紹介します

    開発あれこれ ApeLog開発中にあったあれこれ 終わりに 社会人としてApeLogを開発して&ApeLogのこれから
  55. 開発中のあれこれ 71 Apex Legendsにハマっています ◼ インスタントリプレイ ◼ 色変換が重い ◼ ネイティブ版との比較

    ◼ PythonとC++ ◼ ランクとカジュアルの罠 ◼ Clionでの開発 ◼ プレイ映像ならでは
  56. インスタントリプレイ周り 73 Apex Legendsにハマっています ◼ getDisplayMediaで取ってくる音声はデフォルトでエコーキャンセ ラーやノイズ抑制が働いている ⚫ 直に聞く音と異なる ⚫

    これで2日くらい溶かした ◼ VP8/VP9は重い ⚫ FHDだと60FPSで処理できない ⚫ H264を採用(画質は落ちる…)
  57. 色変換が重い 74 Apex Legendsにハマっています ◼ 最初は一部タスクをカラーで処理するために YUV_I420→BGR→GRAYの変換をしていた ◼ YUV→RGBの変換式 ◼

    YUV→GRAYの変換式 ◼ YUV→GRAYのみにして処理はすべて グレースケールで行うように OpenCV(Wasm)で YUV_I420→BGR に変換するだけ
  58. ネイティブ版 75 Apex Legendsにハマっています ◼ 画面キャプチャ以降の処理はすべてC++側で 行われている ◼ JS部分のちょこっとだけをC++で再実装すれば ネイティブ版が実現

    ⚫ ネイティブ専用の実装は100行くらいでできた ネイティブ版 (デバッグ表示あり)
  59. ネイティブ版との比較 76 Apex Legendsにハマっています ◼ CPU使用率は倍くらい ◼ GPUはインスタントリプレイ向けのエンコードに食われていそう(後述) ネイティブ版 Wasm版

    マップ認識のフレーム 起動前 起動後
  60. 実行中のFPS比較 77 Apex Legendsにハマっています ◼ ほとんど影響はない ◼ 自分のモニターは165Hzなので(この視点では)無影響 ⚫ 普段は165fpsで制限かけている

    ←この視点で比較 起動無し ネイティブ版 Wasm版
  61. Wasm版の利点 78 Apex Legendsにハマっています ◼ ブラウザのAPIとの連携ができる ⚫ 今回でいうと録画スクショ周りやIndexedDBなど ◼ C++版で映像・音声をキャプチャするのはムズい

    ⚫ C++では音声と動画を同時にキャプチャして動画ファイルに エンコードする方法がわからなかった… ◼ インストールが不要 ⚫ ブラウザ版を体験版にして低負荷にしたい方ははこちら→C++版みたいなことができるかも
  62. OpenCVのPythonとC++ 79 Apex Legendsにハマっています ◼ OpenCVのAPIであればPythonとC++でほぼほぼ同じAPIが使える ◼ Pythonでプロトタイピング的にアルゴリズムを実装したり しきい値や精度の確認をしてC++に実装しなおすのが楽だった アルゴリズムやしきい値の確認

    適当アノテーションツール
  63. ランクとカジュアルの罠 81 Apex Legendsにハマっています ◼ 左右での違いわかりますか? ◼ ランクとカジュアルでキル・アシストのフォントサイズが違う ⚫ 元々カジュアルで開発しててランクに持ち込んだときに精度がめちゃ落ちてビビった

  64. Clionでの開発 82 Apex Legendsにハマっています ◼ Windows側にリポジトリを作ってWindowsネイティブのビルドとWSLでの Wasmビルドを設定するとネイティブ版・Wasm版を並行して開発できる ⚫ ただしWasm版のビルドはWSL側にリポジトリを作ってビルドするよりめちゃくちゃ遅くなる ⚫

    WasmのビルドはDockerでやるようにしたら良かったかも? Win側のリポジトリを開く WSL側でEmscripten ビルドする設定を追加 ビルド設定でネイティブと Emscriptenを設定 設定>ツールチェーン ビルドコンフィグ
  65. プレイ映像ならでは 83 Apex Legendsにハマっています ◼ ほしい映像を自分を撮らないといけない ⚫ チャンピオンの映像とか ◼ まだリザルト画面の8キル・9キルが取れてない

  66. 目次 85 Apex Legendsにハマっています 機能紹介 ApeLogの機能を紹介します 技術概要 ApeLogに利用している技術の全体像 技術詳細 ApeLogの実装内容を紹介します

    開発あれこれ ApeLog開発中にあったあれこれ 終わりに 社会人としてApeLogを開発して&ApeLogのこれから
  67. 社会人として 86 Apex Legendsにハマっています ◼ (ゲームも開発も)ハマると生活が崩壊する ◼ 体力 =仕事+趣味+人間生活 時間

    =仕事+趣味+人間生活 モチベ =仕事+趣味+人間生活を実感する ◼ わからん~してて気づいたら朝4時とかになっていると終わり
  68. これから 87 Apex Legendsにハマっています ◼ フロントUIをもっとちゃんとする ◼ 実はインスタントリプレイもっと簡単に実装できたっぽい ◼ 統計とかデータのとり方とか改善

    ◼ 精度改善 ⚫ アークスターとかのスロウで誤判定をしないようにしたい ⚫ その前にテスト書きたい ◼ 公開する ⚫ 動画バンバン上がるので安く済ませる方法に悩んでいる ⚫ 自作サービス盆栽生活したい
  69. まとめ 88 Apex Legendsにハマっています ◼みんなもApex Legendsをやろう!

  70. スライドテンプレート ◼ URANUS:https://thepopp.com/free-template-uranus/