このプログラムは、マリオカート8デラックス(MK8DX)のレース結果を自動的に取得・分析し、チームスコアを管理するNext.jsアプリケーションです。 主にMK8DX 150cc Loungeでの使用を目的としています。
- OBS WebSocketとの連携: 配信画面からスクリーンショットを自動取得
 - AI画像解析: Google Gemini APIを使用してレース結果画面を自動解析
 - チームスコア管理: プレイヤーをチーム別に分類し、合計得点を自動計算
 - リアルタイム表示: 配信オーバーレイとして使用可能なUI
 
- フロントエンド: Next.js 15、React 19、TypeScript
 - スタイリング: Tailwind CSS、Framer Motion
 - AI分析: Google Gemini Vision API
 - 配信連携: OBS WebSocket
 - 状態管理: React Hooks
 - フォーム管理: React Hook Form
 
このアプリケーションを実行するには、以下のソフトウェアがインストールされている必要があります:
- 
Node.js (v18.17.0以上推奨)
- 公式サイトからLTS版をダウンロード・インストール
 - インストール確認: 
node --version 
 - 
pnpm (v8.0.0以上推奨)
- Node.js インストール後、以下のコマンドでインストール:
 
npm install -g pnpm
- インストール確認: 
pnpm --version 
 
- 
OBS Studio (v29.0以上推奨)
- 公式サイトからダウンロード・インストール
 - WebSocketプラグインが内蔵されているバージョンを使用
 
 - 
マリオカート8デラックス
- Nintendo Switch
 
 
- Google Gemini API
- Google AI StudioでAPIキーを取得
 
 
Windows の場合:
# Node.js公式サイトからインストーラーをダウンロードして実行
# https://nodejs.org/
# PowerShellまたはコマンドプロンプトで確認
node --version
npm --version
### 1. 環境構築
```bash
# リポジトリをクローン
git clone <your-repository-url>
cd mk8dx-bot
# 依存関係をインストール
pnpm install
# 環境変数を設定
cp .env.example .env.local- Google AI StudioでAPIキーを取得
 .env.localに設定:
GEMINI_API_KEY=your_gemini_api_key- OBSで「ツール」→「WebSocketサーバー設定」を開く
 - WebSocketサーバーを有効化
 - 認証を設定し、
.env.localに追加: 
# OBS WebSocket設定
OBS_IP=localhost
OBS_PASSWORD=your_obs_password
OBS_SOURCE_NAME=ウィンドウキャプチャ
# Google Gemini API
GEMINI_API_KEY=your_gemini_api_keyOBS設定の詳細:
OBS_IP: OBSが動作しているPCのIPアドレス(同一PCの場合はlocalhost)OBS_PASSWORD: OBS WebSocketサーバーで設定したパスワードOBS_SOURCE_NAME: スクリーンショットを取得するOBSソース名- 例: 
ウィンドウキャプチャ,画面キャプチャ,Game Captureなど - OBSのソース一覧で確認できる名前を正確に入力してください
 - キャプチャボードから認識する場合は
映像キャプチャデバイス 
- 例: 
 
# 開発サーバー起動
pnpm dev
# 本番ビルド
pnpm build
pnpm start- 
OBS設定
- MK8DXのゲーム画面をOBSでキャプチャ
 - キャプチャソース名を 
.env.localのOBS_SOURCE_NAMEに設定 - レース結果画面が見える状態にする
 
 - 
アプリケーション操作
- ブラウザソースに
http://localhost:3000を入力 - 対話(操作)から「レース結果を取得」または「チーム合計点を取得」ボタンをクリック
 - プレビューを操作しボタンが見えない大きさと位置に移動
 - アプリが自動的にOBSからスクリーンショットを取得し、AI分析を実行
 
 - ブラウザソースに
 - 
チームスコア管理
- レース結果が自動的にチーム別に分類される
 - 各レースの得点が累積される
 - 「チーム合計点を取得」で総合結果を更新可能
 
 
正確なレース結果を取得するために、以下のタイミングでボタンを押してください:
最適なタイミング: レース結果画面が完全に表示された瞬間
注意点:
- ✅ 良いタイミング: 順位とプレイヤー名が完全に表示されている
 - ✅ 良いタイミング: 得点が全て表示されている
 - ❌ 悪いタイミング: アニメーション中や読み込み中
 - ❌ 悪いタイミング: 画面が切り替わっている最中
 
※事前に撮影したスクリーンショットを映しても大丈夫です。
最適なタイミング: 総合結果画面(累積得点画面)が表示された瞬間
注意点:
- ✅ 良いタイミング: 全プレイヤーの累積得点が表示されている
 - ✅ 良いタイミング: 順位が確定している状態
 - ❌ 悪いタイミング: レース途中の結果画面
 - ❌ 悪いタイミング: 画面が不鮮明な状態
 
- URLを配信ソフトのブラウザソースとして追加
 - リアルタイムでスコアが更新される透明なオーバーレイとして機能
 
src/app: Next.js App Routerのページとレイアウトsrc/components: 再利用可能なUIコンポーネントsrc/hooks: カスタムReactフック(useTeamScoreListなど)src/constants: 設定値とプロンプト定義src/infra: 外部API連携(gemini.ts、firebase.tsなど)src/types: TypeScript型定義
src/app/page.tsx: メインページsrc/app/api/fetch-race-results/route.ts: Gemini API連携(総合スコア取得)src/app/api/obs/route.ts: OBS WebSocket連携src/hooks/useTeamScoreList.ts: スコア管理ロジックsrc/constants/prompt.ts: AI分析用プロンプト
総合スコア画面から全プレイヤーの累積得点を取得するAPIエンドポイント。
POST /api/fetch-race-results?useTotalScore=true
Content-Type: application/json
{
  "imageUrl": "data:image/png;base64,..."
}// 成功時
{
  "success": true,
  "response": {
    "results": [
      {
        "id": "string",
        "rank": number,
        "name": "プレイヤー名",
        "team": "チーム名",
        "score": number,
        "addedScore": 0,
        "isCurrentPlayer": boolean
      }
    ]
  }
}
// エラー時
{
  "success": false,
  "error": "エラーメッセージ"
}- 共通接尾辞検出: 複数プレイヤー名の末尾に共通単語がある場合に抽出
 - 共通接頭辞検出: 複数プレイヤー名の先頭に共通単語がある場合に抽出
 - フォールバック: 共通パターンがない場合は名前の最初の1文字を使用
 
- プレイヤー行の背景色(黄色系)を分析
 - 透明度や色の混合を考慮した判別ロジック
 
- 
OBS接続エラー
- OBS WebSocketサーバーが有効になっているか確認
 - IPアドレスとパスワードが正しいか確認
 - ソース名が正確か確認: OBSのソース一覧で表示される名前と 
OBS_SOURCE_NAMEが一致しているか確認 
 - 
スクリーンショット取得エラー
- 指定したソース名がOBSに存在するか確認
 - ソース名に全角文字や特殊文字が含まれている場合は、正確にコピーして設定
 
 - 
Gemini API エラー
- APIキーが正しく設定されているか確認
 - API利用制限に達していないか確認
 
 - 
画像認識の精度
- レース結果画面が鮮明に表示されているか確認
 - 他の画面要素が重なっていないか確認
 
 
| エラーコード | 原因 | 対処法 | 
|---|---|---|
| 400 | imageUrlが未指定 | リクエストボディにimageUrlを含める | 
| 429 | API利用制限 | 時間を置いて再試行 | 
| 500 | 画像解析失敗 | 画面が正しく表示されているか確認 | 
- 得点システム: 
src/constants/mk8dx.tsで順位別得点を変更可能 - AI分析精度: プロンプトを調整してより高精度な認識を実現
 - UI: Tailwind CSSクラスで見た目をカスタマイズ
 
主要な型はsrc/types/index.tsで定義されています:
interface TeamScore {
  id: string;
  rank: number;
  name: string;
  team: string;
  score: number;
  addedScore: number;
  isCurrentPlayer: boolean;
}
interface RaceResult {
  name: string;
  team: string;
  score: number;
  isCurrentPlayer: boolean;
}AI分析の精度向上のため、以下の要素を含むプロンプトを使用:
- 具体的な指示: JSONフォーマットの明確な指定
 - ルールベース: チーム名判別の優先順位を明記
 - エラーハンドリング: 認識できない場合の代替動作
 - 文脈理解: MK8DXの画面構成に特化した説明
 
MIT License
プルリクエストや Issue の報告を歓迎します。
質問や問題がある場合は、Issuesでお知らせください。
このプログラムはmk8dx-botから着想を得ました。 Thanks keisuke071411 !



