この記事は何?
ゲームの大会に向けて配信・記録自動化ツールを作ったので、その背景、手法、結果などを説明する
バイブコーディングで作ったので、コーディング初心者がそれをやってみた感想を書く
役に立つかもしれない層
ゲーム大会を運営する人(特に弐寺とか音ゲーとか!)
OBSで配信をする人
生成AIでバイブコーディングして何か作る人(特に初心者!)
前提
筆者は何度か弐寺の大会(べあー杯)の運営を経験している
筆者はコーディングに関する常識、知識がほぼ無く、基本情報技術者試験をちょっと勉強してはめんどくさくて放り投げているレベルである
使用ツールはChatGPT、Codex、VS Codeです 言語などはこの後の項を見てね
べあー杯のルールがわかっていると読みやすいかもしれません
べあー杯 APPEND #2 大会概要.pdf - Google ドライブ
- 大会の様子はこちら
https://www.youtube.com/live/-w_6XW_Kpgg?si=Rrf7YQhQWjkjR881
なぜツールを開発したのか
大会スタッフが当日やらねばならないことを減らし、その場で突然発生することなどに対応する余裕を増やすためです。
今まで運営スタッフを行うなかで湧いてきた課題感は以下でした。
音ゲーの大会は基本的に「曲をプレーしてスコアが高いほうが勝ち」であることが多いが、べあー杯ではスコアの記録が完全手作業(スプシ手打ち)であった
しかも、配信中の画面(または配信youtube)を見ながら、リザルトが表示される数秒間に複数人のスコアを記録する必要があったため、スピード感が必要だった
べあー杯の大会配信ではOBSを使っているが、OBS上の変数(選手名、試合進行状況)は配信担当の手打ちで更新しており、タイプミスや反映漏れが生じることもあった
大会中には思わぬトラブルがつきものであるが、上記のような作業を行っているとそれだけで脳が消費されてしまい、パニックになりやすい
べあー杯の大会配信はフルだと7~9hくらいあるのだが、後日タイムスタンプを打つときに最初から見返して時間をメモするのが大変だった
最近の音ゲー非公式大会ではAIによる自動化がいろんな場面で進んでいたため、自分が何となく抱いていた課題もAIで解決できちゃうのでは?と思った
ツール開発における要件・制約
ツールからOBS上のテキストソースを更新したい(ただし、手打ちより楽でミスしづらい仕組みであること)
配信画面上でリザルトが表示されたら対象者のスコアを認識し、GoogleSheetsに転記したい
スコア認識・転記を動画レイアウトが異なる予選・本戦両方で使えるようにしたい(後述)
Youtubeのタイムスタンプ作成の際、作成の目安となるファイルが欲しい
べあー杯配信PCはゲーセン(レジャーランド)からの貸与物であるため、極力余分なツール・ソフトをインストールしなくても動くようにしたい
大会は止められないので、ツールが急に壊れてもすぐに過去の業務フローに復帰できる状態にしたい(ツールが過去フローを破壊しない)
あんまりあちこち画面を行き来したくない(理想はOBS、投影スライド、ツールの3種類)
今回のツール開発においては、かつて推していたグループのjuice=juice元メンバーである宮本佳林(かりんちゃん)のバイブコーディングの記録を参考にしました。
特に、「ツールに何が起きても本番を止めない仕組み・つくりにする」ことは非常に重視しました。
https://ameblo.jp/miyamotokarin-official/entry-12974432505.html?frm=theme
そのため、今回は「ツールが突然落ちたりフリーズしたり起動しなくなったとしても、ツール導入前と同じ業務フローをこなせば大会が回るようにする」を最上のルールとしました。
ツールのつくり・構成

ChatGPTに書いてもらったシステム構成図です。これ読み取れる人いる?本当に大丈夫?
ツールそのものはローカルサーバーを立てた後にブラウザで操作します。
操作口は1画面で完結しています。ツール画面は配信担当のみがPCで見ることとします。
他のスタッフが他PCなどから同じツールにアクセスできない仕組みです。
ブラウザの画面を操作すると、必要に応じてOBSやGoogleSheetにテキスト情報が送られます。
逆に、定期的にOBSやGoogleSheetsの情報をブラウザ側で取得します。
なお、スコアの記録先としてはGoogleSheetsが正となっています。
ここに入力した値は、表リンク機能を使ってGoogleSlideの本番資料上に反映されます。
もうちょっと具体的に、どう使うツールか
①OBS配信画面の編集

- 複数シーンの複数ソースを指定して一括で更新できます
②予選大会画面のスコア認識・記録
今OBSから配信されている画面をキャプチャし、その画像に対して画像認識をかけます
配信画面上のプレイヤー1~4人のうち、誰かがリザルトを表示していると、誰がリザルトを出したかを認識します
リザルトを認識したら、次にそのプレイヤーのプレイサイド(左右どちらにスコアが出るか)を判断します
プレイサイドを認識したら、スコアが表示される位置を確認し、そこの数字を認識します
認識した数字を記録用のスプレッドシートに書き込みます
リザルトを自動認識できないとスコア認識が発火しないので、手動でスコア認識を動かす仕組みもあります
③本戦大会画面のスコア認識・記録
予選とおおむね仕組みは同じです。違うところはキャプチャするOBSのシーンです(後述)
アリーナの順位表とスコアの一覧を認識し、誰が何点取ったかを認識します
認識した名前-数字のセットを記録用のスプレッドシートに書き込みます
④タイムスタンプ候補の記録
- 本戦で試合が切り替わるとき(具体的には①の機能で新しい選手名に入れ替えたとき)、その時点の配信時間などをGoogleSheetsに転記します
使った技術、手法など
ブラウザ画面+画像認識における諸々の計算:Typescript
ビルド・開発:Vite、Node.js
画面認識方法:テンプレートマッチング(スコア)、Tesseract.js(プレーヤー名)
画面認識の条件探索:Python(条件決定後はTypescriptに移管)
認識したスコアのGoogleSheetsへの記録:GoogleのSheet API
記録先GoogleSheetsへの認証・アクセス:Google OAuth 2.0
OBS-ブラウザ間のアクセス:OBS Websocket
機能:OBS配信画面の編集
OBS Websocketを使うことで、ブラウザ画面で入力した内容をOBS上の特定テキストソースに反映させる
タイプミスなどを防ぐため、大会参加者一覧をツールで読み込み、参加者一覧からプルダウンで今の選手を選択できる
何試合目かどうかもあらかじめ想定されるものを一覧化して読み込んでおり、プルダウンから選択できる
各種テキストの反映は一斉に行いたいため、ここ!というタイミングで反映ボタンを押す仕組み
機能:予選大会画面のスコア認識・記録
1秒に1度OBSの特定シーンをキャプチャし、その画像に対して画像認識(リザルトか否か判定)→プレイサイド認識→スコア認識→認識したスコアをSheetsに記録する
リザルトを自動認識しなかった場合も、「XXプレーヤースコア認識」というボタンを押せば画像認識が走る
誰がどこでプレーしているかの情報は、OBS上に記載しているプレーヤー名を使って取得する
予選は1~4人が課題曲2曲を非同期でプレーするため、4枠(Viewport)ごと独立に画像認識・スコア認識を行う

自分の画面を4つ複製してテストしていた 画像・スコアの認識はキャプチャ画面を固定座標でcropしてその部分だけを読み取る
リザルト認識に使うもの:リザルトの上真ん中に出てくる「XXX STAGE RESULT」 パターンマッチングを使用
プレイサイド認識に使うもの:プレイヤーの上に出てくるグラフ パターンマッチングを使用
スコア認識に使うもの:今回のプレースコア パターンマッチングを使用
スコア認識はOCRだとかなり精度が悪く、0~9までの数字しかないし固定フォントだし等幅の文字だからパターンマッチングのほうがいいよ、というChatGPTアドバイスに従って実装した結果、行けそうだったので採用
スコア認識結果が怪しそうな場合、ツール側に確認を求めるか記録NGとなってGoogleSheetsへの書き込みが止まる(ただし、怪しそうと判断できなければ間違っていても通過してしまう。その際はチェック担当者が直す)
機能:本戦大会画面のスコア認識・記録
1秒に1度OBSの特定シーンをキャプチャし、その画像に対して画像認識(リザルトか否か判定)→各選手のスコア認識→認識したスコアをGoogleSheetsに記録する
リザルトを自動認識しなかった場合も、「手動スコア認識」というボタンを押せば画像認識が走る
予選と違って2~4人が4曲を同期してプレーすること、リザルトに4人分の名前とスコアの一覧が順位別に載ることから、監視するシーンは常に1台め筐体のプレーヤーに固定した

この左側を読む プレーヤー固定で4曲行われるため、プレイサイドの自動認識はせず、ツール側でプレイサイドを手動設定する
リザルト認識に使うもの:リザルトの上真ん中に出てくる「XXX STAGE RESULT」 パターンマッチングを使用
スコア認識に使うもの:その曲の順位表に出てくるスコア パターンマッチングを使用
プレーヤー名認識に使うもの:その曲の順位表に出てくる名前 Tesseract.jsによるOCR+読み取った候補名を今出てる選手名4人と照合する2段構え
予選同様、スコア認識結果やプレーヤー名認識結果が怪しい場合、ツール上で確認を求められる
機能:タイムスタンプ候補の記録
OBS側でテキストソースの一括反映をすると、「今の配信時間、何試合目か、出ている選手名」などが専用のGoogleSheetsに書き込まれる

参考用メモなのできわめてシンプルに テキストソースの一括反映をしたいタイミングが試合が切り替わるタイミングと一致するので、この仕組みを採用
テキストソースの一括反映のタイミングがタイムスタンプを押したいタイミングを完全一致するわけではない
機能:その他、ツールを支える機能
GoogleSheetsからの情報取得、書き込みが発生するため、画面上にOAuth Client IDや該当のSheet IDを入力して対象を指定する
Googleへのログイン情報が1時間しかもたないため、1時間ごとに手動でGoogle Tokenを更新する

該当画面部分 予選、本戦それぞれで監視したいOBSシーンを指定できる

該当の画面 右側のボタンは後述する当日調整用に急遽足した OBSにある全シーン、そのシーンにある全ソースの一覧を取得できるため、その一覧からプルダウンで対象を選べるようにしている
その他、重要エラーの表示、ログ表示、各種機能の準備ができているかのセルフチェックができる

今はなにも接続してないのでエラーが出まくる
当日までの流れ
1か月前~1週間前
ツール作ってみてえ~~~と思い始める
ChatGPTに相談したところ、思ったより実現できそうかも?となり、作り始める
最初にChatGPTにひたすら要件ヒアリングをさせ、何十問も質問に答えていく中でツールの概要を決定する(後で知ったけどgrillingというらしいですね)
パーツごとに作っていくか、と思い、OBS関連、画像認識関連、Google関連、のように分けて作業を始める
ChatGPTにコードを書かせていたが、差分更新ができない(私が手で差し替えると、インデントなどが知らないうちに壊れてコードが死ぬのを10回くらいやった)
上記がしんどすぎたため、2週間目くらいからCodexを導入 VS Codeの拡張機能で利用
Codexの無料枠が数日で切れたため、ChatGPT Plusに加入 なんとお試しで30日無料であった
プログラムもシステムも何にもわからないため、Codexへの良い指示方法がわからなくなる
最終的に、私がやりたいことを言う→ChatGPTが要件を整理してCodexへの指示書を作る→Codexが調査・実装する→その結果をChatGPTが見て妥当性を判断する→私が実際に動かして文句を言う→… というフローが確立した
画像認識の手法で何を使うのかが確定しておらず、youtubeをスクショしながらいろいろ試していた
しかし、youtubeスクショだと画質が若干粗く、いざOBSからキャプチャする画面で画像認識を試すと壊滅することが判明した
2週間くらい粘っていたら、ようやく画像認識の大まかな枠組みができていた
動画データを取りに行くために何度もGiGO高田馬場に行って誰も見ない配信をし続けた
1週間前~2日前
Codexを使う時間が増えた結果、Codexの利用量制限に引っ掛かり始め、Codexが死ぬまで作業する→休む→Codexが復活したら作業する→寝る みたいな生活になる
度重なるOpenAI側の使用量リセットにもかかわらず、Codexの週次量制限にも引っかかりそうになり始める
ずっと自分が使うプレイサイドの動画データしかとってなかったけど、反対側のデータもいるのでは?と気づき慌てて録画しに行く
画像認識の精度がいまいち安定せず、沼る
ようやく各種機能を統合したテストを始めたところ、ツール画面が謎の挙動をしたりボタンが押せなくて動けなくなったりとバグがオンパレードする
テストという作業のつまらなさでメンタルを病む
「ChatGPTはこう言ってるけど、具体性が増してきた今では私でもなんか変だと気付ける」点が出てくるようになり、私がChatGPTとだんだん議論しあうようになる
ツールを長時間操作しても死なないかチェックしたほうがいいことに気づくも、時すでにお寿司
大会前日
前日の大会会場セッティングに参加して本番PCでの動作確認をする
会場に行くギリギリまで何かしらバグっていたため、ひたすらCodexをしばく
本番PCではあっさり起動して、問題なく動き始めたので安心する
余裕をもって準備をし始めたはずが、ツール側で更新したいテキストソースが「AシーンにしかないテキストB」「CシーンにしかないテキストD」だが、両方同じ文字列を入れたいんだ!というケースに対応できないと気付きパニックになる
ツール以外の準備(OBSのシーンを大会用にアプデする、ウィンドウキャプチャで見るべきものを整理してcropするなど)が普通に忙しくなり、気づいたら4時間たっていた
一番怪しかったスコア認識の部分について、テストできずに前日が終了する
家に帰ってから、前日気づいたやばい点をすべてCodexに直させる(この辺で週次リセットチケットを切る)
画像認識失敗の理由が画像crop位置のずれ(OBSに配置する画面位置が練習時とずれてる)にありそうだったので、crop実画像をツールから確認できる機能を急遽追加する
ツールのボタンをたくさん操作しても死なないか確認する
ツールを起動したまま寝る
大会当日
当日の会場準備で筐体を使える時間が20分くらいしかなく、画像認識のテストでは救いきれない結果があり、運営のチャットに「最悪死ぬかも」と送る
予選:全然画像認識しないし、スコア認識の精度もカス過ぎて実用に耐えず、途中で実用をあきらめる
crop位置が4プレイヤー*2プレイサイドあり、それを確認している暇が普通になかった
本戦:やはり画像認識が危うかったので、リザルト自動認識による発火をあきらめる
スコア認識は意外と可能性を感じたので、1~2試合のうちにcrop位置を確認しては画面位置を微調整し、ようやく実用に耐えはじめる
本戦は結果として8~9割の正答率となり、スコア確認者も基本的に目視チェックで良い環境が整いつつあった
大会名簿のプレーヤー名をゲーム画面の表示と照合させるため、名簿のプレーヤー名と実際のプレーヤー名が違うと毎回要確認対象になってしまうことに気づく
OBS:全体的に想定通りの良い仕上がり。画像認識に比べてぎりぎりまで動きうる条件がなかったため、事前準備が不足しづらかった
ただし、なぜかテキストソースへ反映すると文字位置が横方向にずれる現象が起きており、そこだけ手動修正なのがだるかった でも後で調べたら直せそうな感じ
タイムスタンプ:見た感じは完璧 記録した内容の実用性はこれから
予選、本戦であわてて機能調整をしていると試合の進行を忘れ、配信画面を切り替え忘れることが何回かあったため、準備不足を恥じ入った
総括
ツールに対して
70点、というところでしょうか
予選以外はわりと良い動きであり、しっかりと配信担当の余裕を増やしてくれていたと思います
予選はやはり1画面に4プレーヤーがのる時点で認識用画像が大変小さくなってしまうこともあり、かなり難しさを感じます
1画面まるまる使えるケース(2画面であっても縮尺を変えず使えるとか)だと、けっこういい認識精度が出せるので、十分実用可能だと思いました
OBS操作が半自動になったため、基本的に配信をStream deck+ツールだけで回せるようになったのがかなり発明だと個人的には感じました
OBS Websocketが結構便利で、何より非アクティブのシーンもツール側で取得できたのが神でした これのおかげで本戦の機能が成り立ちました
スコア認識に意外と時間がかかったので、結果的にリザルト認識から自動で動かさなかったのは正解かもしれない プレーヤーがリザルト飛ばす速度が速すぎる
画面ソースの位置ずれにずっと悩まされていたため、リハに時間が割けるように他にできる仕事はすべてつぶしておくか、レジャのPCの設定を早くから確認しておけばよかった…
バイブコーディングに対して
すでに配信担当をやった経験、ゲーム自体への知識があったため、バイブコーディングで作っていってもChatGPTに騙された!と思うことはほぼなかったです 素直でシステム知識のある3年目くらいの社員と作ってる感じ
Codex便利すぎる これなしではもうやっていけないね
要件検討でChatGPTにがん詰めしてもらうの、個人的には最初、中盤、終盤と何回かに分けてその都度やるといいと思いました
わからないことしかなかったものの、その場で説明してもらえるし、Codex触れない外出中とかにもChatGPTに今の状況とか整理してもらえたので、脳みそ1mlの人間にとっても優しいなと思いました
一方で、エンジニアの同居人と定期的に進捗を会話していると全然見逃していた選択肢が出てくるケースも多々あり、やはりコーディング、運用などの経験がないと自然と漏れてしまう選択がありますね
ChatGPTにCodexへの指示書を書かせ、それをコピペしてCodexに指示し、結果をコピペしてChatGPTに説明させるのを繰り返していると、人間ってもしかしてコピペするための肉だったのか?と思う
また、バイブコーディングのいい点は何といっても対人恐怖しなくていいところですね
普段人に送るチャットとかすごく悩むタイプなので、ChatGPTに「それ全然わからないよ!」とか「おなかすいたからもう作業中断したいけど今中断すると何がやばい?」とか「この作業だるすぎる、ほんとにやる意味ある?」とかそのまま聞けるのが本当に楽だった…

なにわろてんねん ある程度整理したら今回のツールをgithubにあげたいなと思った
今度のべあー杯に向けて、1vs1の試合形式でも使えるようにしておくと、べあー杯に関してはかなり汎用的に使えるツールになると思った
