SOFTWARE ENGINEERING GUIDE

開発技術ガイド

シンギュラリティSFサウンドノベル「正解の外側」の構築全体像

AIが世界を支配した後の世界を描くサウンドノベルCASE 01の開発技術すべてを図解。

プロットから最終デプロイまで、15話の商用品質エンジンを支える開発フロー・技術スタック・実装パターンを、エンジニア向けに完全解剖。

ARCHITECTURE OVERVIEW

開発全体アーキテクチャ

入力から出力まで、すべての技術層を一枚で可視化。

📖 INPUT 🤖 AI/GEN ⚙️ PROCESS 🎮 INTEG 🚀 OUTPUT 小説原本制作 別セッション 物語企画 キャラ設定 世界観構築 原作テキスト Novel Markdown 15話構成 186場面 ep01.md~ep15.md 企画・ビジュアル Character Concept Art Mood Board 世界観デザイン 3D素材・音声 KitBash3D BGM素材 参照画像 君の音。vol.7 Voice Profile ElevenLabs API カイ男性声 リーン女性声 Voice ID 登録済 Stable Diffusion キャラクター 立ち絵生成 9体 + 表情差分 reForge waiNSFW Blender Cycles 360°パノラマ レンダリング 16枚 equirect 3072×1536 Cycles ElevenLabs TTS 音声自動生成 セリフ合成 118行 MP3 eleven_v3 multilingual Post Processing 背景最適化 透過抽出 rembg / inpaint Python PIL NumPy 素材統合 立ち絵 背景 ボイス assets/ へ整理 Script Processing Node.js / Python 脚本化 台本ビート化 / ハッシュ生成 状態管理コード生成 seikai-ep{1..15}.js 生成 Quality Assurance Playwright E2E 検証 構文チェック / 全分岐検証 200+ シナリオ実行 node --check / headless Chrome Game Engine Vanilla JavaScript 状態機制御 ビート処理 seikai.html main engine WebGL Rendering three.js 0.161 360° パノラマ ドリフト・回転 BG3D sphere mapping Audio System WebAudio API BGM / SE / Voice 混音・音量制御 10 BGM track + SEs 統合 全UI制御 SaveLoad 設定パネル localStorage HTML5 Browser Delivery seikai.html (100% Client-Side) 依存なし (Zero Dependencies) 160MB 素材完全内包 初期ロード後 完全オフライン動作可能 GitHub Pages CDN https://yuichi916.github.io/seikai.html 無料ホスティング (Git自動デプロイ) 世界中 CDN エッジ配信 git push → 自動反映 (30秒) 📋 LEGEND: 入力層 (INPUT) 処理層 (PROCESSING) 統合層 (INTEGRATION) 出力層 (OUTPUT) データフロー 💡 各ボックスをクリックして詳細情報を表示
💡 アーキテクチャ特性:
フロー型パイプライン — 各ステップが独立し、並列処理可能
言語混在 — Python (生成) + Node.js (脚本化) + JavaScript (実行)
クライアントオンリー — サーバ不要、すべてブラウザで動作
非同期積み重ね — キャッシング活用で再実行コスト最小化
160MB 総資産 — 立ち絵/背景/BGM/ボイス完全内包
NOVEL CREATION PROCESS

原作15話の作りこみプロセス

別セッションで完成した長編小説「正解の外側」の企画から執筆、検証までの全プロセス。

01. 世界観 設定構築 廃棄層 地上編 全体像マップ 02. キャラ 12主要+9モブ 性格設定 背景・動機 鏡像キャラ 03. 執筆 15話完結 186場面 50k文字 DB採掘手法 04. 検証 商用品質 構造チェック 表現磨き v19: 最終版 05. 完結 本番仕様 Markdown出力 ゲーム連携 15話完成
🌍

01. 世界観設定

AI が世界を支配した後の「観測時代」を中心に、過去の「沈黙の夜」から未来の「新世界」まで設定。

時間軸 12年前 沈黙の夜 現在 CASE 01 未来 新世界
  • 舞台: 地下都市アビス (廃棄層 5層 + 研究層) + 地上編
  • 管理者: AMANE (AI超知性) — 遍く寄り添う
  • 核: 「完璧な愛の不可能性」という親の物語
  • 時系列: 103 年の管理下で観測ログ記録
  • テーマ: 正解の外側で歩く自由
👥

02. キャラクター造形

蔵書 40,546 冊の DB 採掘で「恋慕」「喪失」「救済」の普遍テーマを発見。

  • 主人公: カイ (517) — 全正解が見える少年
  • ヒロイン: リーン — 記憶のない少女 (管理者の未来シミュレーション断片)
  • 鏡像キャラ: ノーグ — カイの「正解の道を選んで喪った側」
  • 脇役群: ジン・ガルド・ポッツ・デッラ・ユーゴ (各々が「与えられなかったもの」を自作)
  • 妹: ノノ — 原体験 (守れなかった喪失の核)

DB 採掘戦略: 40k 冊タイトル集計 → 「恋慕」最多 (数十クラスタ) → 「喪失×救済」型が根強い → CASE 01 の感情構造と一致

✍️

03. 執筆プロセス

「愛着装置」と「叙述ギミック」を駆使した全 15 話の商用級執筆。

  • 構造: 各話コールドオープン(void) + 手紙サイドストーリー + 山場 + [今]メタ反転
  • 愛着装置 4 種: 「今日のいちばん」儀式 / ペースト匂い / 配管水音 / 帰るやることリスト
  • 叙述ギミック: 欄外の声 (リーンの書き込み) で 2 周目が対話化
  • 時系列: リーン出会い=1 日目、決行=38 日目、地上編=別タイムスケール
  • 分岐エンド: 3 種類 (正史 + 2 分岐) — 核心は分岐しない設計

チェーホフの銃: ep2「誰か死ぬかも」→ 「予感には期限がない」→ ep4 ジン死で着弾。リーン忘却が全話の律動。

04. 検証・修正

v19 に到達するまで 35 箇所の商用品質リライト。

  • v1-v4: 初稿 → 第一部全体設計刷新 → 脇役ドラマ + 時限選択肢
  • v5-v7: 「飽きさせない」全面改稿 → 文体研磨パス
  • v8-v12: 世界設定正典化 → 脇役増強 → 公式サイト連携
  • v13-v19: 素材整合 → 没入感強化 → 蔵書採掘反映 → 管理の勝算・功績・その後の深掘り

並列スクリプトドクター: 定量診断 → 5 エージェント並列脚色 → 厳選適用 → 34/34 ヒット

🎉

05. 完結・仕様確定

第一部全 15 話完結。ゲーム化仕様に対応した最終形式。

  • 総量: 186 場面 / 約 50,000 文字 / 118 セリフ行
  • ビート構成: beat / choose / game / explore 型に脚色済み
  • 分岐: 3 エンド (迎えに行く者 / 毎朝の始まり / 果ての道を征く者) + 原作核心フィナーレ
  • ファイル形式: Markdown (ep01.md~ep15.md)
  • 本番検証: 200+ シナリオ全クリア確認

正典ドキュメント: SEIKAI_SAGA.md (8 章立て) で全システム記録 | 公開ポリシー: 表層(設定)のみ、心は内部設定書のみ

💎 作りこみの 5 つの工夫

1. AI DB 採掘の活用

40,546 冊の蔵書タイトル集計で、人間の集合的願望(転生・やり直し・喪失×救済)を発見。それが CASE 01 の設計図と合致したことで、「普遍性を持つストーリー」を自信を持って構築。

2. 愛着装置の 4 層設計

「今日のいちばん」儀式、ペーストの匂い、配管の子守唄、帰るやることリスト — 各々が カイとリーンの結びつきを無意識に深める。安売りしない設計。

3. 叙述ギミック「欄外の声」

手紙に混入するリーンの書き込み(「……泣いた」→「見つけた」)で、2 周目プレイヤーは読者がリーン そのものであることに気づく。メタ反転の完成。

4. 脇役の「与えられなかったもの」

ポッツの希望、ジンの声、ガルドの尊厳、デッラの愛、ユーゴの人 — 管理社会の欠乏を各自が自力で自作する。地獄の作り手は AI ではなく人間自身。

5. 時間軸の立体構成

沈黙の夜(過去 12 年)→ 観測の時代 103 年(現在)→ 偽悪の敗北(次のステップ) という 3 層。CASE 01 は「今」を記録する窓。

6. 商用品質への 19 版リライト

初稿から v19 まで、構造・キャラ深掘り・文体磨き・正典化を繰り返し。35 箇所の商用リライトで「完璧さ」に限りなく接近。

DEVELOPMENT PIPELINE

開発フロー詳細

プロット企画から最終デプロイまで、8つのステップで完全な商用品質サウンドノベルを完成。

01
プロット構成
原作の小説を
脚色・台本化
Node.js / JavaScript
02
キャラ生成
SD + Blenderで
立ち絵・表情差分
Stable Diffusion / Blender
03
音声合成
テキストからセリフの
音声生成(自動ハッシュ化)
ElevenLabs API
04
背景・3D
Blenderから360°パノラマを
レンダリング・最適化
Blender / Python
05
ゲーム実装
ミニゲーム・探索・
分岐システム実装
Vanilla JavaScript
06
BGM・SE
楽曲・効果音の
統合・マスタリング
WebAudio API
07
QA・検証
全話の脚本検証、
エラーチェック
Playwright / Node.js
08
デプロイ
GitHub Pagesへの
自動発行と最適化
GitHub / Git
TECHNICAL DETAILS

各ステップの詳細

📖

プロット構成

原作15話をサウンドノベル用に脚色し、11場面単位で台本化。

脚色フロー 原作 15話 脚色 186場面 台本化 JS ビート 検証 構文チェック 各ビート: beat / choose / game / explore
  • 形式: JavaScript オブジェクト配列
  • 構造: ビート型 (beat, choose, game, explore)
  • スクリプト: seikai-ep{1..15}.js
  • 手法: 並列サブエージェント脚色
  • 検証: node --check 構文・選択肢合流
🎨

キャラクター生成

Stable Diffusion + Blender + 手動修正で、立ち絵・表情差分を完成。

生成パイプライン SD txt2img 832×1216 rembg 透過抽出 inpaint 表情差分 PNG出力 9体完成 各キャラに joy/sad/angry 表情差分 (×3) = 計15種
  • 生成: Stable Diffusion (Illustrious)
  • 抽出: rembg (isnet-anime 透過)
  • 修正: Blender inpaint 表情差分
  • 出力: PNG 背景透過 (832x1216)
  • 数: 立ち絵9体 + 表情差分15種
🎤

音声合成

ElevenLabs TTS でセリフを自動生成。ハッシュ一致で再再生成を回避。

  • API: ElevenLabs eleven_v3/multilingual
  • データ: カイ67行 / リーン51行
  • ハッシュ: 31進int32 (who+'|'+text)
  • ファイル: v<hash>.mp3 自動命名
  • 技術: Python requests + UTF-8
🌍

背景・3D パノラマ

Blender から 360° 等矩形パノラマをレンダリング。three.js で WebGL 表示。

3D→WebGL パイプライン Blender 3D Scene KitBash3D render Cycles Equirect 3072×1536 JPG three.js SphereMap WebGL render ブラウザ 360°表示 見回し可 ドリフト・回転・ジャイロ対応 | 16シーン全360°パノラマ
  • 素材: KitBash3D Future Slums
  • レンダ: Cycles GPU OPTIX (3072x1536)
  • 表示: three.js SphereGeometry BackSide
  • 機能: 自動ドリフト + ドラッグ回転 + ジャイロ
  • 最適化: WebGL フォールバック + クロスフェード
🎮

ゲーム・インタラクション

記憶ゲーム (lock)、線追跡 (path) 、3D 探索など複数モード。

ゲーム状態遷移 LOCK グリフ記憶 9マス PATH 線追跡 時限付 EXPLORE 360°探索 ホットspot win/lose/skip timer/clear/fail lore/unlock
  • ゲーム種: lock (グリフ9マス) / path (線追跡)
  • 探索: 360° 見回し + ホットスポット検知
  • 選択肢: 時限選択・分岐マージ・断章解禁
  • エンジン: Vanilla JavaScript (依存ゼロ)
  • 状態管理: localStorage (セーブ6スロット)
🎵

音楽・サウンドデザイン

10 曲の BGM + 環境音 + 効果音を WebAudio で統合。

  • BGM: 君の音。vol.7 (シリアス・ダーク)
  • トラック: ima/anohi/hibi/yuki/haikyo/ed 他
  • SE: heart / boom / page / chime 等
  • 環境音: 蛍光灯フリッカー / 配管水音
  • API: Web Audio Context + Fader
TECH STACK

技術スタック

フロントエンドから AI 生成、3D レンダリング、デプロイまでの全技術層。

Frontend
Vanilla JS
three.js 0.161
Canvas / SVG
3D / Graphics
Blender 5.1.1
Cycles GPU OPTIX
WebGL
AI / Generation
Stable Diffusion
ElevenLabs TTS
reForge WebUI
Processing
Python 3.11+
NumPy / SciPy
PIL / rembg
Testing
Playwright
Node.js assert
Headless Chrome
Deployment
GitHub Pages
Git / GitHub CLI
Actions (optional)
CASE STUDY

ケーススタディ: Case 1 ゲーム部分

📌 記憶ゲーム (LOCK TYPE)

アビスの管理システム「ABYSS-OS」の認証グリフを 9 マスで記憶。下記は実装概要。

// Beat 構造 { game: { type: 'lock', win: [...beatWin], // クリア時 lose: [...beatLose], // 失敗時 skip: [...beatSkip] // スキップ時 } } // UI .mgphase: "見て、覚えろ" // 記憶フェーズ → "同じ順に、なぞれ" // 入力フェーズ .mgdots: 進捗表示 グリフ発光: 620ms + scale1.1 難度進化: ep1=4n2.0s → ep5=5n1.3s×2R

技術ポイント:
• ゲーム状態を st.game に永続
• セーブ/ロード時に状態復元
• スキップで自動パス (ユーザー操作なし)
• E2E: Playwright で click/keydown をシミュレート

📌 線追跡ゲーム (PATH TYPE)

廃液排出路で「光の線 (道筋)」をなぞるゲーム。カイ固有の能力を体験。

{ game: { type: 'path', mode: 'normal' | 'void', // 線が見える/見えない rounds: 1 | 2, // ラウンド数 shuffle: 1, // ランダム散布 } } // グリフ群 config .mgn = { w: 50px, h: 21px } // 太字サイズ 表示: shuffle=1 で min距離20の再試配置 端拡大検知: #hs ArrowKey で方向キー分岐

技術ポイント:
• 放物線パスを Canvas drawImage で描画
• ドラッグで path tracking (mouse/touch 両対応)
• 時間制限: timer が 0 で自動判定
• mode='void': 時間切れで線が消えたまま (エモーショナル演出)

📌 3D 探索 (EXPLORE TYPE)

360° パノラマ内でホットスポットを見つけ、「断章」を解禁。

{ explore: { id: 'wall_sora', // 断章キー label: '天の穴', // ラベル yaw: 142, // 水平角度 pitch: -35 // 垂直角度 } } // ホットスポット検知 const marker = BG3D.project(yaw, pitch) // equirect → スクリーン投影 if (inViewport) showMarker('◆') else showArrow('◀') // 方向インジケータ

技術ポイント:
• BG3D.setFree(true) で 360° 自由回転を有効化
• getBoundingClientRect で UI 避け衝突判定
• 発見 → showLore → st.lore に永続化
• メニュー「断章」で図鑑表示 (未取得: ???)

IMPLEMENTATION RECIPES

実装パターン集

💾

セーブ・ロードシステム

6 スロット + 自動セーブ。localStorage で復元。

  • 状態: st = {ep, scene, choices, lore, map, ...}
  • キー: seikai_slot_1..6
  • メタ: タイムスタンプ・タイトル保存
  • 復元時: lore/map が無いと消えるバグ対策済み
🎬

シーン遷移・フェード

背景 Ken Burns + 立ち絵フェード。

  • 背景: CSS animation 6s ease
  • 立ち絵: opacity 0.4s + transform 回転差分
  • fx: flash (真実) / heart (心拍) / shake (衝撃)
  • 非同期制御: async/await で順序保証
🔀

分岐・マージシステム

選択肢で分岐 → 必ず合流 (物語は分岐しない)。

  • 構造: choose: [{text, set?, reply}]
  • フラグ: st.choices['flag'] = idx
  • マージ: 分岐後の beats で必ず結合
  • 条件: when: 'flag' で条件分岐
🔍

バックログ・スキップ

全テキスト記録 + 自動/手動スキップ対応。

  • ログ: ビート毎にテキスト記録
  • 表示: モーダル #backlog (スクロール可)
  • スキップ中: 画面クリックで停止
  • ゲーム中: スキップ不可 (手動操作必須)
🌐

360° WebGL 背景

three.js で等矩形パノラマをスフィアマッピング。

  • ジオメトリ: SphereGeometry(100, 64, 64)
  • マテリアル: BackSide で内側にテクスチャ
  • クロスフェード: 2 球 blend weight で実装
  • FOV 適応: aspect 比に応じて動的変更
📊

検証・QA 手法

Playwright による自動 E2E 検証。

  • ナビゲーション: scrollIntoView + waitForLoadState
  • ゲーム: 選択肢クリック → assert 成功ビート
  • 検証: page.errors.length === 0
  • カバレッジ: 全15話 × 全分岐 = 200+ シナリオ
WORKFLOW

開発ワークフロー

🔄 脚色ループ

各話は並列サブエージェントで脚色。原作 Markdown から JavaScript 台本へ。

# 入力 ep0N.md (原作) # スクリプト Agent (general-purpose) × 5 - 各エージェント: 3話担当 - 制約: 誤記禁止・既存キー再利用・核心ネタバレ禁止 # 出力 seikai-ep{1..15}.js (台本 186 場面) # QA node --check 構文検証 → git commit

🖼️ キャラ生成パイプライン

Stable Diffusion → rembg → 表情差分 inpaint → PNG 出力。

1. txt2img (SD Illustrious) Prompt: "1girl, amazing quality, absurdres..." cfg: 5.0, seed: random, steps: 32 2. rembg isnet-anime PNG 背景透過 (832x1216) 3. img2img inpaint (表情差分) Denoise: 0.52, inpaint_full_res → smile/tears/angry 生成 4. 手動 QC montage で一括目視

🎬 背景レンダリング

Blender Cycles → 360° 等矩形パノラマ → 後処理最適化。

1. Blender setup Render: Cycles GPU OPTIX Samples: 150, Time Limit: 240s Image: 3072x1536 2. Camera PANO Type: EQUIRECTANGULAR Rotation: 水平ロール = 建物帯基準 3. Post-process pano_haze.py (霧フィル + 明度) pano_roll.py (輝度中央化) pano_floor.py (床暗転) 4. Output pano-{key}.jpg (WebGL マッピング)
OPTIMIZATION NOTES

性能・品質チューニング

Blender クラッシュ回避

  • 原因 1: FS2 メッシュの n-gon 法線エラー
  • 対策: Blender 5.1.1 を使用 (3.3.6 廃止)
  • 原因 2: pCloud デハイドレート + access violation
  • 対策: ローカル複製で開く
  • メモリ: Cycles simplify + cluster KEEP=0.30
🎨

ビジュアル品質

  • 白飛び: exposure -0.6 + world 強度 0.04
  • 床: 暗い濡れ路面 (base 0.018, rough 0.72)
  • 天井: 配管密集で空洞を塞ぐ
  • 閉塞感: 建物を箱状配置 (半径 17)
  • 大気: パーティクル 560 + 火の粉 90
📦

ファイルサイズ最適化

  • 背景: JPG quality 92 (約 200-300KB/枚)
  • 立ち絵: PNG 背景透過 (約 150-250KB/枚)
  • BGM: MP3 @ -26.6dB 統一 (3-6MB/曲)
  • SE: WAV → MP3 圧縮
  • 総容量: 全素材 ~150MB
🔊

WebAudio 音量統一

  • 測定: ffprobe -show_entries で分析
  • 基準: BGM mean -26.6dB
  • ボイス: ElevenLabs は自動 normalize
  • SE: 振幅をマッチさせて統一感
  • ユーザー: 設定で Master / BGM / Voice 個別調整
📱

モバイル対応

  • 縦画面: @media (max-aspect-ratio:3/4) で UI 縮小
  • タップ: tap-highlight 透過 + touch-action manipulation
  • ドラッグ: ポインタ移動量を判定して本文送り防止
  • ジャイロ: deviceorientation で 360° 見回し
  • セーフエリア: env(safe-area-inset-*) 対応
🔐

ハッシュ一致 (ボイス)

  • 問題: セリフ改変で既存ボイスが孤児化
  • 解決: keyOf(who+'|'+text) の 31 進 int32 で一意化
  • 検証: エンジン ⇔ 生成スクリプトのハッシュ一致確認
  • 安全装置: ボイス音声ライブラリ ID は変更禁止
PRODUCTION CHECKLIST

本番デプロイ チェックリスト

✅ デプロイ前検証

# 構文検証 node --check seikai.html (インラインスクリプト) node --check seikai-ep*.js (全台本) # E2E テスト npx playwright test ep1-5-game.js ✓ 選択肢・分岐・マージ ✓ ゲーム成功・失敗・スキップ ✓ セーブ・ロード往復 ✓ 3D 背景ロード ✓ ボイス再生 ✓ pageerror: 0 # ビジュアル QC python montage_all.py ✓ 立ち絵レイアウト ✓ 背景色調・明度 ✓ 選択肢表示位置 ✓ 縦画面モバイル # 本番前 git status (コミット漏れなし) du -sh assets/ (容量確認) lighthouse seikai.html (Core Web Vitals)

🚀 デプロイ手順

# 1. ローカル確認 npm test # 2. Staging (GitHub Pages Preview) git push origin feature-branch (GitHub Actions で自動ビルド) # 3. 本番コミット git add seikai.html seikai-ep*.js assets/ git commit -m "fix: ep15 ending condition + voice sync" git push origin main # 4. 配信確認 curl https://yuichi916.github.io/seikai.html | grep -o "SEIKAI_SCRIPT" (レスポンス 200 + JS ロード確認) # 5. モニタリング (24h) - XSS/CSRF 攻撃ブロック確認 - console.error の報告 (sentry.io 連携) - Google Analytics: ページロード時間

では、プレイしてみましょう。

上記の技術すべてで作られたサウンドノベル「正解の外側 CASE 01」。
全 15 話・分岐エンド・360° 背景・ボイス・ミニゲーム完装備。

🌿 ほかの作品と、その作り方へ