🐍
生成AI 3連コンボでTRPGログを可視化!ココフォリア技能集計アプリ開発録
はじめに
TRPGセッション後、「誰がどの技能をどれだけ使った?」「成功した技能は?」と気になること、ありませんか?Cocoforiaのログを手作業で集計するのは大変…。そこで、生成AIの力をフル活用して自動集計・可視化Webアプリを作りました!
本記事では、ChatGPT → OpenAI Codex → Cursor → GitHub Pagesの4段階で、どのようにアイデアを形にしたかを解説します。
1. 企画~仕様策定:ChatGPTとの対話
まずはChatGPTと要件を整理。
- 判定結果(成功/失敗/クリティカル/ファンブル)をキャラ別・技能別に集計
- ログ貼り付け→ワンクリックで表を出力
- PC/スマホ両対応のレスポンシブ設計
ChatGPTで「必要なUI」「出力フォーマット」「データスキーマ」などを具体化し、Codexへのプロンプトにも活用しました。
2. コーディング:OpenAI Codexで初期実装
Codexは「Cocoforiaの判定結果を正規表現で抽出して」など高レベルな指示でも即座にJavaScriptを出力。
生成された主な構成:
-
parser.ts
:ログ解析ロジック -
main.ts
:DOM操作とDataTables初期化 -
style.css
:ベーススタイル
パーサー実装例:
export function parseLog(src) {
// [チャンネル] プレイヤー名 : ...【技能名】...> ... > ... > 判定結果
const channelLine = /^\[([^\]]+)\]\s+([^:]+?)\s*:(.*)$/;
const skillBody = /【([^】]+)】/;
const resultBody = /(クリティカル|ファンブル|失敗|成功)/;
const rows = [];
src.split('\n').forEach((l, i) => {
const m = l.match(channelLine);
if (!m)
return;
const channel = m[1].trim();
const player = m[2].trim();
const rest = m[3];
const skillMatch = rest.match(skillBody);
const resultMatch = rest.match(resultBody);
if (!skillMatch || !resultMatch)
return;
const label = classify(resultMatch[1]);
if (!label)
return;
rows.push({ channel, player, skill: skillMatch[1], label, line: i + 1 });
});
return rows;
}
3. リファクタリング:CursorでAIペアプロ
CursorはVS CodeライクなUIで「この関数をパフォーマンス重視で書き直して」などAIと対話しながらリファクタリングできます。
TypeScriptで開発し、最終的にJavaScriptへ変換してデプロイ。
npx tsc *.ts --outDir .
4. 技術ハイライト
データ集計ロジック
export function summarize(rows: Row[]): any[] {
const box = new Map<string, Map<string, SkillStat>>();
for (const r of rows) {
const p = box.get(r.player) ?? new Map<string, SkillStat>();
const stat = p.get(r.skill) ?? { skill: r.skill, s: 0, f: 0, c: 0, b: 0 };
if (r.label === 'success') stat.s++;
if (r.label === 'failure') stat.f++;
if (r.label === 'critical') stat.c++;
if (r.label === 'fumble') stat.b++;
p.set(r.skill, stat);
box.set(r.player, p);
}
const rowsOut: any[] = [];
for (const [player, skills] of box.entries()) {
for (const stat of skills.values()) {
rowsOut.push([stat.skill, stat.s, stat.f, stat.c, stat.b, player]);
}
}
return rowsOut;
}
UI/UXの工夫
技術 | 採用理由 |
---|---|
DataTables | ソート・検索・ページネーションをワンライナーで実装 |
レスポンシブ設計 | スマホは100%、PCは最大900pxで余白と可読性を両立 |
マテリアルデザイン | CDN経由で軽量にモダンなUIを実現 |
DataTables設定例:
tableDetail = $('#resultTable').DataTable({
data: rows.map((r) => [r.skill, r.label, r.player]),
columns: [
{ title: '技能' },
{ title: '種別' },
],
rowGroup: { dataSrc: 2 }, // プレイヤー名でグループ化
responsive: true,
pageLength: 10,
});
キャラクター別テーブルの動的生成:
Object.entries(byPlayer).forEach(([player, data], idx) => {
const h = document.createElement('h2');
h.textContent = player;
summaryPane.appendChild(h);
const table = document.createElement('table');
table.id = `summaryTable_${idx}`;
table.className = 'display';
summaryPane.appendChild(table);
$(`#${table.id}`).DataTable({
data,
columns: [
{ title: '技能' },
{ title: '成功' },
{ title: '失敗' },
{ title: 'クリティカル' },
{ title: 'ファンブル' },
],
responsive: true,
searching: false,
paging: false,
info: false,
ordering: false,
});
});
5. デザイン仕上げ
CSS例:
:root {
--md-sys-color-primary: #6750a4;
--md-sys-color-secondary: #625b71;
--md-sys-color-background: #fefbff;
}
body {
background: #faf7fb;
font-family: 'Segoe UI', 'Meiryo', sans-serif;
max-width: 900px;
margin: 0 auto;
}
.display {
background: #fff;
border-radius: 10px;
box-shadow: 0 2px 12px #a5b4fc33;
overflow: hidden;
}
@media (max-width: 700px) {
h1 { font-size: 1.3em; }
h2 { font-size: 1em; }
.display td, .display th { padding: 4px 6px; }
}
6. デプロイ:GitHub Pages
GitHub Actionsで自動ビルド&デプロイ:
name: Deploy to GitHub Pages
on:
push:
branches: [ main ]
permissions:
contents: read
pages: write
id-token: write
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: '18'
- run: npm install -g typescript
- run: tsc *.ts --outDir .
- uses: actions/upload-pages-artifact@v1
with:
path: .
- uses: actions/deploy-pages@v1
7. 実際の使用感
- Cocoforiaのセッションログをコピー
- テキストエリアに貼り付け
- 「集計」ボタンをクリック
- キャラクターごと・技能ごとの統計が一瞬で表示
- 詳細タブ:全判定の一覧をプレイヤーごとにグループ表示
- キャラ別表示タブ:各キャラクターの技能統計を個別テーブルで表示
- 合計値:成功・失敗・クリティカル・ファンブルの総数を自動計算
今後のアイデア
- 📊 成功率グラフを Chart.js で可視化
- 📁 ログ貼り付け欄を drag & drop でファイル受け付け
- 🔄 Service Worker でオフライン解析
- 📱 PWA化でアプリライクな体験
- 📈 セッション間での成長度合いを可視化
まとめ
ChatGPTで仕様を固め、Codexで骨組みを生成し、Cursorで磨き上げ、GitHub Pagesに即デプロイ──生成AI × OSS × サーバーレスの組み合わせで、アイデアを"最短距離"で公開できました。
「TRPGログをもっと便利にしたい」仲間が増えることを願っています!
🎯 アプリ: https://danielvo594520.github.io/cocoforia-skill-confirmation/
Discussion