# デッドキャットファクトリー (Dead Cat Factory)

猫しか働いていない工場の工場長になり、PDCAサイクルを回してカオスな現場を統制するシミュレーション。
本リポジトリは [Dead_Cat_Factory_Spec.md](Dead_Cat_Factory_Spec.md) を元にした **コアループの縦切りプロトタイプ** です。

TypeScript + Canvas 2D で実装しており、ブラウザで即座に動きます。グラフィックは仕様書どおり
**クォータービュー(2:1アイソメトリック)のドット絵**。ゲームロジックは描画から完全に分離してあるため、
仕様書のターゲットである Unity / Godot への移植時もルールをそのまま持っていけます。

## 動かす

```bash
npm install
```

```bash
npm run dev
```

`http://localhost:5273` を開いてください。初回は「遊び方」が表示されます。

その他のコマンド:

```bash
npm run typecheck
```

```bash
npm run build
```

## 実装済みの内容

### タイトル画面とセーブ／ロード

起動すると最初にタイトル画面が出ます。

- **最初から始める**: 新しい工場でゲームを開始します。既にセーブデータがある場合は上書き確認が入ります
- **つづきから**: 直近のセーブデータから再開します。セーブが無ければ押せません
- **クレジット**: 開発クレジットと使用技術を表示します

セーブは `localStorage` に保存され、次のタイミングで自動的に更新されます。

- 稼働中 (Do) に約8秒おき
- 画面右上の 🏠 ボタンで「保存してタイトルへ戻る」を押した時
- タブを閉じる／リロードする直前 (`beforeunload`)

決着の付いた回（ゲームオーバー・クリア）でタイトルへ戻ると、そのセーブは消えます。
「つづきから」は常に**まだ終わっていない工場**を再開するためのものです。
セーブには乱数の内部状態も含まれるため、再開後もヒヤリハットの発生などが元のシード続きで進みます。

### PDCAサイクル (仕様書 §2)

| フェーズ | 実装 |
| --- | --- |
| **Plan** | グリッドにコンベア・作業台・猫用設備を敷設し、猫を持ち場へ割り当て、定時休憩の長さを決める |
| **Do** | 1シフト = 1800ティック (約30秒 / 速度×1〜×4)。プレイヤーは介入できず観察のみ |
| **Check** | 業務日報 + ヒヤリハット・事故報告書 + 従業員コンディション + 改善提言 |
| **Action** | **Check で挙がった事案に対してだけ**対策を打つ。対象事案のリスクスコアが下がる |

**Action は事案ドリブンです。** 起きていない事案の対策は買えません。
改善フェーズには次の3種類しか並びません。

1. **本日発生した事案** — 日報の発生件数つきで並び、その事案専用の対策が選べます
2. **継続案件** — 今日は起きなかったが実効リスクが12以上残っている事案。「継続」として引き続き対策できます
3. **体制の見直し** — 定期メンテナンス契約と新規採用。特定の事案に紐付かないのでいつでも実施できます

何も起きなかった日は対策そのものが並ばず、「現場は落ち着いています」と表示されます。
つまり**まず現場で問題を出し、日報で原因を読み、その原因にだけ手を打つ**、という順序が強制されます。

### 従業員（猫）システム (仕様書 §3)

体力・機嫌・空腹・尿意・退屈・集中力・記憶力を持ち、1シフト中におおよそ
トイレ1〜2回・食事1回・休憩1回ぶん持ち場を離れます。この往復がそのまま生産ロスになるため、
**「効率の良いライン」と「猫がストレスを感じない空間」のトレードオフ**が成立します。

- **気まぐれ・八つ当たり**: 機嫌が22を切ると暴走。優先度は 段ボール箱 > 爪とぎタワー > 近くの同僚（ネコパンチ）> 機械（爪とぎ）
- **持ち場**: 猫は「作業台（現場作業）」か「事務机（事務作業）」のどちらか1つに就きます
- **コンプライアンス違反**: 持ち場に着くたび、記憶力と機嫌に応じてヘルメット着用を判定。脱ぎ捨てたまま作業すると事故確率が上がる
- **9つの命**: 重大事故で1つ消費し2〜3日休職。使い切った猫は稼働不能

### 技術開発と開発ツリー

最初に置けるのは基本的なライン設備（コンベア・作業台・配電盤・猫用設備・事務机・開発室）だけです。
**開発室**に猫を割り当てると**研究ポイント(RP)**が貯まり、開発ツリーを進めることで
扱える機械・素材・製品・電力設備が増えていきます。

ツリーは16ノードで、5系統に分かれています。

| 系統 | 主なノード | 解禁される内容 |
| --- | --- | --- |
| ライン設備 | 構内物流の基礎 → 工程間バッファ理論 → 自動化制御 | 分岐機・合流機・ストッカー・段積み |
| 加工技術 | 切削加工 → 塑性加工 / 産業用ロボット / 梱包工程 | 旋盤・プレス機・アームロボット・梱包機 |
| 構内物流 | パレチゼーション → 構内車両の導入 → 出荷バース整備 | パレット置き場・フォークリフト詰所・トラックバース |
| 素材と製品 | 合金材 → 電子部品 → 航空宇宙品質 | グレード1〜3の素材と製品 |
| エネルギー | 受電設備の増強 → 自家発電 → 太陽光発電 | 契約電力+8・ディーゼル発電機・太陽光パネル |

開発室に猫を1匹回すぶん生産は落ちます。**いつ研究に人を割くか**が中盤の判断になります。

### 素材と製品

搬入口が調達する素材はPLANフェーズで切り替えます。
グレードが上がるほど**必要な工程数**と**必要な加工精度**が増えますが、単価は跳ね上がります。

| 素材 | 製品 | 工程数 | 必要精度 | 調達費 | 単価 |
| --- | --- | --- | --- | --- | --- |
| 鉄材 | 単純部品 | 2 | 0 | — | ¥1,400 |
| 合金材 | 精密部品 | 3 | 4 | ¥420 | ¥3,400 |
| 電子基板材 | 電子部品 | 4 | 8 | ¥1,250 | ¥7,200 |
| 特殊合金材 | 宇宙船部品 | 5 | 13 | ¥3,100 | ¥15,500 |

加工精度は機械ごとに決まっています（作業台・旋盤 +1、プレス機・アームロボット +3、梱包機 +0）。
工程数か精度が足りないまま出荷すると**不良品**になり、調達費のぶん丸損になります。
つまり高グレードの製品は「工程を増やす」だけでなく「精密機械を通す」ラインが要ります。

### 電力（発電と送電）

機械が動くには2つの条件が揃っている必要があります。

1. **送電** — **配電盤**の届く範囲（半径5マス）にあること。範囲外の設備は⚡マークが出て動きません
2. **発電** — 系統契約と自家発電の合計が需要を上回っていること

需要が供給を超えると**全設備が一律に減速**し（例: 供給が需要の6割なら全機械が60%の速度）、
やがて**停電事故**が発生します。停電は重傷まで至る労災です。

| 電源 | 供給 | コスト |
| --- | --- | --- |
| 系統契約 | 14（開発で+8、対策で+6/回） | 使った分だけ ¥260/単位・日 |
| ディーゼル発電機 | +12 | 燃料費 ¥4,200/日（定額） |
| 太陽光パネル | +5 × その日の日射(55〜100%) | 0 |

系統は従量制、自家発電は定額なので、**需要が大きいほど自家発電が得**になります。
消費電力はタイルごとに違い、アームロボットが最も食います（作業台の4.5倍）。

### 製造機械 (仕様書 §6)

加工機械はどれも「入力バッファから1個取り、加工段階を1つ上げる」点は共通で、
速度・電気代・仕上がり・危険性で性格を分けています。

| 機械 | コスト | 加工時間 | 担当猫 | 電力 | 特徴 | 固有の労災 |
| --- | --- | --- | --- | --- | --- | --- |
| 作業台 | ¥2,600 | 1.17秒 | 必要 | ×1 | 遅いが安全 | — |
| 旋盤 | ¥4,200 | 0.77秒 | 必要 | ×2.5 | 最速級だが不良率が高い | 巻き込まれ（死亡あり） |
| プレス機 | ¥5,000 | 1.07秒 | 必要 | ×2.2 | 不良率が1/3に下がる | 挟まれ（死亡あり） |
| アームロボット | ¥9,500 | 0.67秒 | **不要** | ×4.5 | 猫を他の持ち場に回せる | 激突（死亡あり） |
| 梱包機 | ¥4,800 | 1.53秒 | 必要 | ×1.6 | 通した完成品は**単価+20%** | 閉じ込め（死亡あり） |

梱包機だけは完成品（一次加工を2回終えたもの）も受け取れるので、
「旋盤 → プレス機 → 梱包機」のように最後に通す使い方ができます。
アームロボットは担当が要らないぶん、猫を事務室や別ラインへ回せるのが強みです。

### ライン設計 (仕様書 §4)

- **グリッド敷設**: コンベア（ドラッグで連続設置、再クリックで回転）、分岐機、合流機、一時保管ストッカー、各種加工機械
- **分岐機（スプリッター）**: 背面から受け取り、正面・左・右へラウンドロビンで振り分けます。1本の幹線を複数の加工系統へ分けるのに使います
- **合流機（マージャー）**: 3方向から受け取って正面へ流します。待避スロットを3つ持つため、
  単なるコンベアの合流で起きる「上流の早い者勝ち」による飢餓が緩和されます
- **加工段階**: 原材料 → 一次加工品 → 完成品。作業台を2つ通らずに出荷口へ入ると不良品
- **経路探索**: ダイクストラ法。稼働中コンベアとボイラー室に高コストを付けており、
  安全な正規ルートが無い場合にだけ猫は危険なショートカットを通ります
- **キャットウォーク**: 任意のマスに重ねて敷ける猫専用の空中通路。敷いたマスは経路コストが安全扱いになり、
  抜け毛混入・巻き込みが発生しなくなります
- **一時保管ストッカー**: 8個まで溜めて払い出すバッファ。猫が席を立つ間の滞留を吸収します

### 事務室と事務作業

ヒヤリハットも事故も、起きるたびに**報告書が1件**積まれます。
**事務机**に猫を割り当てると事務作業が始まり、書類を1件処理するたびに
その事案の**リスクスコアが下がり、信頼度が少し戻ります**（＝現場で回すPDCAの Check → Action）。

- 処理速度は担当猫の**集中力と記憶力**で決まります
- 処理しきれなかった書類は翌日へ持ち越され、**1件あたり¥450の是正費用**が毎日かかります
  （立て直せなくなるのを避けるため、1日に請求されるのは最大16件まで）
- 8件を超えて滞留すると「書類の滞留」として是正勧告を受け、信頼度が下がります
- Actionフェーズの「事務代行サービスの契約」で、毎朝いくらか肩代わりしてもらえます

事務机に付けた猫はラインに立てません。**生産に何匹回して事務に何匹残すか**が判断どころです。

### 休憩室と休憩時間

シフトの中ほどに**定時休憩**が入り、全員が**休憩室**へ向かいます。
休憩中はラインが止まりますが、体力・機嫌・空腹・退屈がまとめて回復します。

- 休憩室は**1マスに1匹**。入れなかった猫は「休憩の未確保」として計上され、機嫌が大きく削れます
- マスを**隣り合わせて敷くほど1つの部屋として広くなり**、回復量が上がります
  （バラバラに置いても効果は薄い）
- 休憩の長さは PLAN フェーズで4段階から選べます

| プラン | 長さ | 性格 |
| --- | --- | --- |
| 休憩なし | — | ラインは止まらないが猫が保たない |
| 短い休憩 | 約2.8秒 | 滞留は起きにくいが回復はほどほど |
| 標準の休憩 | 約5秒 | しっかり回復するぶん作業台の前に部品が溜まる |
| 長い休憩 | 約7.5秒 | 機嫌は大きく回復するが生産は確実に落ちる |

休憩中もコンベアは動き続けるので、長い休憩ほど作業台の前に部品が積み上がります。
**一時保管ストッカー**で吸収させるのが定石です。

### 労働災害 (仕様書 §5)

事案は物損で止まるとは限りません。深刻度は1本の階段になっています。

```
ヒヤリハット → 物損事故 → 軽傷 → 重傷 → 死亡事故
```

| 段階 | 休業 | 治療費・補償 | 信頼度 | 9つの命 |
| --- | --- | --- | --- | --- |
| 軽傷 | 1〜2日 | ¥3,000 | −3 | 消費しない |
| 重傷 | 3〜5日 | ¥15,000 | −9 | 消費しない |
| **死亡事故** | 5〜7日 | ¥40,000 | −25 | **1つ消費** |

- 死亡事故では猫が9つの命を1つ失い、数日後に復帰します。**使い切った猫は二度と戻りません。**
  全員が使い切ると労働力を確保できず工場は閉鎖です（一時的な休業だけでは閉鎖になりません）
- 重篤化のしやすさは猫の状態で決まります。**ヘルメット未着用 +55%、体力低下 +35%、機嫌の悪化 +20%**
- 事案の種類ごとに「ここまで至りうる」上限があります。オーバーフローや抜け毛混入は物損どまり、
  配線の噛みちぎりは軽傷どまり、危険な機械とボイラーだけが死亡に至ります
- トップバーに**無災害記録（労災ゼロの連続日数）**が出ます。1件でも起きると0に戻ります

実測では、対策を打たずに旋盤を回し続けた工場で 46日間に 軽傷12 / 重傷6 / 死亡1 が発生し、
45日目に「旋盤の回転部に巻き込まれた」死亡事故で従業員が命を1つ失いました。

### ヒヤリハット・事故 (仕様書 §5)

16種類のハザードがあり、それぞれ **リスクスコア (0〜100)** を持ちます。

1. ハザードが発生すると、リスクスコアに応じて **ヒヤリハット / 事故 / 重大事故** に振り分けられます
2. ヒヤリハットでも +6、事故なら +13 スコアが積み上がります（＝放置するほど事故になりやすい）
3. 事務作業で報告書を処理すると少し下がりますが、**根本的に下げるにはActionフェーズで対策を打つ必要があります**
4. 何も起きなかった種別は翌日 -5 され自然に鎮まります

| ハザード | 主な発生条件 |
| --- | --- |
| ライン上での就寝 | 体力切れでコンベア上に倒れ込む |
| ラインへの無断侵入 | 正規ルートが無く、コンベアを横断する経路を選んだ |
| ヘルメット未着用 | 手順を忘れる／気まぐれに脱ぎ捨てる |
| 立入禁止区域での就寝 | 暖かいボイラー室に忍び込む |
| 機械での爪とぎ | 八つ当たり先が機械しかない |
| オーバーフロー | 担当猫が席を外している間に入力バッファが満杯のまま積み上がる |
| 退屈による破壊行動 | 部品が届かず退屈が振り切れる（ケーブル噛みちぎり） |
| ネコパンチ・喧嘩 | 暴走した猫の近くに同僚がいる |
| 製品への抜け毛混入 | 積荷のあるコンベア上に猫が乗っている |
| 動線の分断 | 休憩所・トイレへの経路が見つからない |
| 休憩の未確保 | 定時休憩に休憩室へ入れない（1回の休憩につき猫1匹あたり1件） |
| 書類の滞留 | 未処理の報告書が8件を超えて溜まっている |
| 旋盤への巻き込まれ | 旋盤の稼働中（死亡に至りうる） |
| プレス機への挟まれ | プレス機の稼働中（死亡に至りうる） |
| アームロボットとの接触 | 可動範囲（隣接マス）に猫がいる（死亡に至りうる） |
| 梱包機への閉じ込め | 梱包機の稼働中（死亡に至りうる） |

### 施設・改善アイテム (仕様書 §6)

段ボール箱 / 自動給餌器 / キャットタワー（爪とぎ）/ 仮眠クッション / **休憩室** / **事務机（事務室）** /
トイレ / 壁 / キャットウォーク / 一時保管ストッカー。
Actionフェーズの対策は事案ごとに1つずつ用意してあります。

| 事案 | 対策 |
| --- | --- |
| ライン上での就寝 | ライン緊急停止装置 |
| ラインへの無断侵入 | 通路の区画線と横断ルール |
| ヘルメット未着用 | 安全教育（毎朝の朝礼） |
| 立入禁止区域での就寝 | ボイラー室の施錠 |
| 機械での爪とぎ | 機械への爪とぎ防止シート |
| オーバーフロー | 工程間の平準化 |
| 退屈による破壊行動 | 配線カバーの敷設 |
| ネコパンチ・喧嘩 | 高級猫おやつの配給 |
| 製品への抜け毛混入 | お掃除ロボットの導入 |
| 動線の分断 | 動線の見直し（管理者の巡回） |
| 休憩の未確保 | 休憩の交替制導入（休憩室1マスに2匹入れるようになる） |
| 書類の滞留 | 事務代行サービスの契約 |
| 旋盤への巻き込まれ | 旋盤の安全カバー設置 |
| プレス機への挟まれ | 両手押しボタン式への改造 |
| アームロボットとの接触 | ロボットの安全柵と光線センサー |
| 梱包機への閉じ込め | 梱包機の投入口センサー |

「体制の見直し」には 定期メンテナンス契約・新規採用に加えて、
人身災害全般の重篤化を抑える**保護具の一斉更新**があります。

### マイルストーンとクリア条件 (仕様書 §7)

累計出荷数・資金・信頼度・無事故日数に応じて工場ランクが上がり、
そのたびに**出荷単価**と**資材の搬入速度**が上がります。ランクアップした分だけ供給が増えるので、
ラインを増設していかないと作業台の前で部品が滞留します。

| ランク | 条件 | 解禁 |
| --- | --- | --- |
| おやつ代稼ぎ | （初期状態） | — |
| 町工場 | 累計出荷 30個 | 単価 +10% / 搬入 1.25倍速 |
| 中堅工場 | 累計出荷 100個 かつ 資金 ¥100,000 | 単価 +25% / 搬入 1.6倍速 |
| 自動化工場 | 累計出荷 250個 かつ 重大事故ゼロ5日連続 | 単価 +40% / 搬入 2倍速 |
| 精密機器工場 | 累計出荷 450個 かつ 信頼度 95以上 | 単価 +60% / 搬入 2.4倍速 |
| 宇宙船部品工場 | 累計出荷 700個 かつ 資金 ¥400,000 | **ゲームクリア** |

資金がマイナスに落ちるか、稼働できる猫がいなくなると倒産です。

### アートスタイル (仕様書 §8)

画像アセットは一切持たず、**全てコードで描いたドット絵**です。

- **クォータービュー**: 2:1 アイソメトリック投影。論理キャンバスは 1論理px = 1ドット で持ち、
  CSS側では整数倍にのみ拡大するため、拡大してもドットが滲みません
- **工場**: 彩度を落とした金属色でまとめた無機質な造形。壁・作業台・分岐機などは
  上面/左面/右面の3色で立体を作っています。コンベアは搬送方向へシェブロンが流れます
- **猫**: 工場の直線的な造形に対して、猫だけ丸く柔らかい輪郭にしてギャップを狙っています。
  4方向の向き、歩行の上下動、しっぽの揺れ、丸くなって寝るポーズ、段ボール箱に入って耳だけ出す姿など
- **状態表示**: 頭上のアイコンは絵文字ではなく自前のドットグリフ（zzz / 💢 / 爪あと など）で、
  ドットの解像度に合わせてあります

### サウンド (仕様書 §8)

音源ファイルは一切使わず、**WebAudio で全てその場で合成**しています。

- **BGM**: 気の抜けたボサノバ。16小節の **A - A' - B - B'** 形式で、B セクションで変ホ長調へ転調し、
  B' のターンアラウンド（Dm7♭5 - G7♭9）で元の調へ戻ります。
  ナイロン弦風コンピング（2小節周期の裏拍パターン）・ウッドベース（次のコードへ半音で寄せる）・
  シェイカー・クラーベのリムショット・気だるいリードの5レイヤー構成。
  リードはコードごとのスケールにスナップさせているので、転調しても音がぶつかりません
- **フェーズ連動**: 稼働中(Do)はドラムとメロディまで入れたフル編成、計画中は
  コンピングとベースだけの薄い編成になり、UIの邪魔をしません
- **猫の声**: ニャー（鋸波のポルタメント＋ビブラート）、シャーッ（帯域ノイズのスイープ）、
  ゴロゴロ（低域ノイズを25Hzで振幅変調）、パニックボイス
- **工場音**: 電源ハム（50Hz＋倍音）とコンベアの唸りを重ねた環境音。稼働中の機械の数に応じて濃くなります
- **事故**: 二音サイレン。重大事故ではより長く鳴ります

サウンド層は `src/audio/reactor.ts` がゲーム状態の差分を見て鳴らす作りなので、
`sim/` 側は音の存在を一切知りません（移植時に音だけ差し替えられます）。

## このプロトタイプに入っていないもの

仕様書に書かれた要素は一通り実装済みです。プロトタイプとして割り切っている点は次のとおり:

- **セーブスロット**: 1本だけです。複数の工場を並行して持つことはできません
- **カメラ操作**: 工場全体が1画面に収まる固定カメラで、ズームやスクロールはありません
- **BGMのメロディ**: 動機をコードごとに移調・スナップする手続き生成で、作曲された固定の旋律ではありません

## ソース構成

```
src/
  core/      グリッド・経路探索・乱数・バランス定数（描画にもDOMにも依存しない）
    config.ts       バランス定数、建設パレット、ハザード表、改善策マスタ
    types.ts        Tile / Cat / Incident / DailyReport などの型
    grid.ts         タイル生成、通行判定、危険マス判定
    pathfinding.ts  ダイクストラ法。危険マスに重いコストを付ける
    rng.ts          シード付き乱数 (mulberry32)
  core/
    research.ts     開発ツリーの定義と、素材・製品のマスタ
  sim/       ゲームロジック
    state.ts        GameState とログ
    save.ts         セーブデータの直列化・復元 (localStorage)
    power.ts        電力の需給と送電範囲
    forklift.ts     フォークリフトによるパレット輸送
    effects.ts      事案の実害（労災の休業・補償・9つの命の消費、物損）
    factory.ts      搬入口・コンベア・ストッカー・作業台・出荷口
    cat.ts          猫のAI（欲求、八つ当たり、コンプライアンス）
    incidents.ts    ヒヤリハット→事故のエスカレーション
    game.ts         フェーズ遷移、建設、日報生成、改善策購入
  audio/     サウンド（WebAudioによる手続き生成）
    engine.ts       AudioContext とバス、発振音・ノイズの合成ヘルパ
    sfx.ts          猫の鳴き声・機械音・サイレンなどの効果音
    music.ts        ボサノバBGMのジェネレータ
    ambience.ts     工場の環境音
    reactor.ts      ゲーム状態の差分を見て効果音を鳴らす層
  ui/
    iso.ts          アイソメトリック投影と、菱形・箱などのドット絵プリミティブ
    sprites.ts      タイルのドット絵スプライト（生成してオフスクリーンにキャッシュ）
    render.ts       シーンの組み立てと猫の描画
    hud.ts          DOM（パレット、従業員パネル、リスク台帳、モーダル）
  main.ts    ゲームループと入力
```

## デバッグ

開発サーバー上では `window.__dcf` からゲーム状態と操作関数を触れます。

```js
__dcf.state                     // GameState
__dcf.place(8, 7, 'bench')      // タイル設置
__dcf.catwalk(12, 7)            // キャットウォークのトグル
__dcf.start(); __dcf.runShift() // 1シフトを一気に回して日報を返す
__dcf.step(16)                  // rAFが止まる環境で1フレーム進める
__dcf.audio.playSfx('hiss')     // 効果音の単体再生
```
