# Discord マーダーミステリー

> Discord上で遊べるマーダーミステリー。BotとActivityの両方から同じ卓を進行できます。

- 制作: [ワカメ](https://wakame.dev/)（個人で企画・開発）
- ステータス: 公開中
- 制作期間: 制作・運用
- カテゴリ: Game, Discord, Web
- 使用技術: Discord Bot, Discord Activity, Cloudflare Durable Objects, Cloudflare Pages, WebSocket, Node.js
- 担当: ゲーム企画, アーキテクチャ設計, Bot開発, Activity開発, 認証・接続設計

## 概要

既存のコミュニティがある場所で、追加のインストールなしにマーダーミステリーを遊べるようにしたシステムです。ゲームの状態とルールをCloudflareのDurable Objectに一本化し、Discord BotとDiscord Activityを同じAPIを叩くクライアントとして実装したため、どちらから操作しても同じ卓が進みます。BotとActivity間は共有シークレットで認証し、Activityへの接続にはWebSocketの署名付きチケットを使っています。

## Bot と Activity の二重実装を避ける

Discordでマーダーミステリーを遊ばせる方法は、チャットのコマンドで進めるBotと、Discord内で開くアプリ画面（Activity）の2つがあります。両方を用意すると、同じゲームのルールを2箇所に書くことになり、片方だけ直して卓が食い違う事故が起きます。

そこで、ゲームの状態とルールをCloudflareのDurable Objectに一本化しました。BotもActivityも同じAPIを叩くだけのクライアントという位置づけで、どちらから操作しても同じ卓が進みます。ルールを直す場所は常に1箇所です。

## リアルタイム通信が死んでもゲームは続く

Activityの画面更新はWebSocketで行い、接続時には署名付きのチケットを使います。ただし署名鍵が未設定の環境ではWebSocketを諦めて、5秒間隔のポーリングに自動で切り替わります。

リアルタイム通信は、設定漏れや環境差で最初に動かなくなる部分です。そこが落ちた瞬間にゲームが進行不能になる作りにはせず、遅くはなっても卓が続くようにしました。

## 本番の鍵を手元に置かずに疎通確認する

デプロイ後に、チケットの発行からWebSocket接続までが通っているかを外から確認するコマンドを用意しました。署名鍵が手元にある場合は実際に接続するところまで確認し、無い場合は認証がきちんと弾いているかだけを確認します。

本番の鍵をローカルに落とさないと動作確認できない作りだと、鍵が手元のファイルに残り続けます。鍵なしでもできる確認を分けておくと、そこを避けられます。

## 1人でテストできるようにする

マーダーミステリーは複数人が揃わないと始まりません。開発中に毎回人を集めるのは無理なので、Discordの認証なしでテスト用の卓を作れる1人テストモードを用意しました。

ただし常時有効だと誰でも卓を作れてしまうため、既定では無効にしてあり、必要なときだけ環境変数で有効化して、終わったら消す運用にしています。

## 成果

- BotとActivityから同じ卓を操作できる構成を実装
- Durable Objectでゲーム状態を一元管理

## リンク

- [サイト](https://murder-mystery-activity.pages.dev)

## このサイトについて

- [ワカメの詳細プロフィール](https://wakame.dev/ai-profile/index.html.md)
- [llms.txt](https://wakame.dev/llms.txt)
