Files
TheTree_mock/docs/FACILITY_DATA_DESIGN.md
T

208 lines
11 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 施設詳細データ設計
- 文書ID: DATA-FACILITY-001
- 版: 0.2.0
- 状態: 実装基準
- 最終更新日: 2026-08-27
## 1. 目的と正本範囲
本書は、施設の静的定義、設置後の可変状態、日次・累計統計を分離し、施設追加やバランス変更でセーブデータを壊さないための正本である。ゲームルールは`GAME_SPECIFICATION.md`、実行順と障害時処理は`SYSTEM_SPECIFICATION.md`を優先する。
施設の数値は次の3層へ分ける。
| 層 | 所有者 | 例 | 保存 |
| --- | --- | --- | --- |
| Definition | コンテンツ | サイズ、建設費、提供サービス、必要職種 | `.tres`。原則不変 |
| Instance | セーブデータ | 座標、レベル、耐久、配置職員、行列、現在Policy | Snapshotへ保存 |
| Statistics | 運営履歴 | 当日売上、処理客数、平均待ち時間、事故数 | 日次締めで集約して保存 |
Definitionへ「現在の汚れ」や「今日の売上」を置かず、Instanceへ表示名や基礎価格を複製しない。実行中サービスだけは開始時の価格、品質、所要時間、PolicyをSnapshotとして保持する。
## 2. Schema Version
| version | 用途 | 検証 |
| --- | --- | --- |
| 1 | 既存施設の互換読込 | 従来必須値のみ |
| 2 | 詳細施設定義 | 本書の詳細項目を厳密検証 |
`definition_schema_version = 2`を宣言した定義は、不足値を暗黙補完しない。古い定義はversion 1のまま読み込めるため、施設を1件ずつ検証して移行できる。versionを上げるだけの一括変換は禁止する。
## 3. FacilityDefinition version 2
### 3.1 識別・分類
| フィールド | 型 | 規則 |
| --- | --- | --- |
| `id` | StringName | 小文字snake_case、永続的に変更しない |
| `display_name` | String | UI表示名 |
| `description` | String | プレイヤー向け説明 |
| `category` | StringName | `lodging`、`guest_service`、`production`等 |
| `service_types` | Array[StringName] | 施設が提供できるサービスID。1件以上 |
| `default_service_type` | StringName | `service_types`内の既定サービス |
| `service_profiles` | Dictionary | 全service typeに1対1で対応 |
| `tags` | Array[StringName] | 検索、隣接、ルール判定用の一意なID |
### 3.2 配置・接続
| フィールド | 規則 |
| --- | --- |
| `zone` / `layer` | 地上・境界・地下とFRONT・BACKを別軸で指定 |
| `footprint` | 未回転状態の幅・高さ。各辺1以上 |
| `allowed_rotations` | 0/90/180/270の重複なし配列 |
| `guest_access_offsets` | 客がサービスへ入るFootprint内セル |
| `staff_access_offsets` | 職員・物流が入るFootprint内セル |
| `required_connection_tags` | 稼働に必須の通路・ネットワーク種別 |
| `preferred_adjacency_tags` | 効率や選好の加点候補 |
| `forbidden_adjacency_tags` | 配置拒否または重大減点となる隣接 |
Access offsetは未回転Footprintの左上を`(0, 0)`として記述し、配置時にoriginとrotationからWorld座標へ変換する。通過設備を除く施設は、客用または職員用Accessを最低1つ持つ。
### 3.3 建設・維持・成長
`construction_cost`はGoldとMaterials、`build_minutes`は工期、`weight_per_cell`は構造負荷を表す。`demolition_refund_percent`は未予約資産に対する標準返却率で、事故・強制撤去補正は実行時に別途適用する。
`max_level`は1~5、`upgrade_costs`はLv1→2から順に正確に`max_level - 1`件を持つ。アップグレード後もDefinitionは変えず、Instanceの`level`とレベル別補正式で性能を求める。
維持費は`maintenance_gold`、Manaは`maintenance_mana`、停電時の配電順は`power_priority`で表す。
### 3.4 人員・営業
`staff_min`未満では新規サービスを開始せず、`staff_max`を超える職員を稼働人員へ数えない。`required_roles`は必要職種、`primary_skill`は品質計算の主技能である。
`opening_schedule`は次の3キーだけを持つ。
| キー | 意味 |
| --- | --- |
| `morning` | 06:00の日次境界から始まる朝営業 |
| `day` | 昼営業 |
| `night` | 夜営業 |
日次締めは06:00に行い、同じ境界で前夜営業を閉じて朝営業へ切り替える。具体的な時刻帯はClockの正本に従い、Definitionへ時刻を重複保持しない。
### 3.5 Service Profile
各`service_profiles[service_type]`は次の5項目を必須とする。
| 項目 | 型・範囲 | 意味 |
| --- | --- | --- |
| `duration_minutes` | int、1以上 | 1回の基礎所要時間 |
| `base_quality` | int、0~100 | 人員・環境補正前の品質 |
| `base_price` | int、0以上 | Policy補正前の基礎価格 |
| `capacity_units` | int、1以上 | 同時処理人数または1バッチの生産単位 |
| `need_effects` | Dictionary[StringName, int] | 欲求ごとの変化量、各-100~100 |
`need_effects`は負値を欲求不足の解消、正値を悪化として統一する。厨房のような中間生産は、客の欲求を直接変えないため0を指定し、実際の在庫産出は`inventory_outputs`で表す。
例:
```gdscript
service_types = [&"check_in", &"check_out"]
default_service_type = &"check_in"
service_profiles = {
&"check_in": {
&"duration_minutes": 8,
&"base_quality": 60,
&"base_price": 20,
&"capacity_units": 1,
&"need_effects": {&"sleep": 0},
},
&"check_out": {
&"duration_minutes": 6,
&"base_quality": 60,
&"base_price": 0,
&"capacity_units": 1,
&"need_effects": {&"sleep": 0},
},
}
```
旧`base_service_minutes`、`base_quality`、`base_price`、`capacity`はversion 1と現Runtimeの互換入口として当面残す。version 2の新規処理はservice profileを正本とし、移行期間中は既定profileと旧値の差分をテストで監視する。
### 3.6 在庫・環境・リスク
- `inventory_inputs` / `inventory_outputs`: 1サービスまたは1バッチの予約・産出量。
- `cleanliness_decay_per_service` / `noise_per_service` / `heat_per_service`: 完了時の発生値。
- `beauty_effect` / `security_effect` / `concealment_effect`: 設置中の環境寄与。
- `incident_weights`: 事故IDと非負の相対重み。確率そのものではない。
### 3.7 Policy
`policy_schema`はPolicy IDごとに型と既定値を宣言する。
```gdscript
&"reservation_only": {&"type": &"bool", &"default": true}
&"price_mode": {&"type": &"enum", &"default": &"standard"}
&"quality_target": {&"type": &"int", &"default": 55}
```
現在の必須キーは`type`と`default`で、typeは`bool`、`enum`、`int`のいずれかとする。選択肢、最小・最大、解禁Level、変更猶予は次のSchema拡張で追加し、未知キーを読込側で勝手に解釈しない。
### 3.8 客層・成人向け安全境界
`allowed_guest_tags`と`forbidden_guest_tags`は候補抽出の入口であり、予約・入室・サービス開始の3地点で再検証する。`adult_content = true`の施設は必ず`adult_only`タグと、一般向け表示へ置換できる`content_replacement_id`を持つ。置換先は成人向け施設を参照してはならない。
### 3.9 解禁と統計
`unlock_rank`は1~7、`research_requirements`は全件満足を原則とする。`statistics_keys`は施設固有の収集項目を宣言し、共通の売上・稼働率と分離する。定義に存在しない統計キーをセーブから消さず、旧版履歴として読取専用保持する。
## 4. FacilityInstance
Instanceは最低限、次を持つ。
- 識別: `instance_id`、`definition_id`、`created_at`
- 配置: `origin`、`rotation`、`occupied_cells`
- 成長: `level`、`durability`
- 稼働: `state`、`state_reasons`、`opening_override`
- 人員: `assigned_staff_by_shift`、`active_staff_ids`
- 接客: `queue_entries`、`active_services`
- 運営: `policy_current`、`policy_pending`
- 資源: `local_inventory_id`
- 集計: `statistics_today`、`lifetime_statistics`
Instanceは必ず`definition_id`から現行Definitionを引き、Definition変更で処理中サービスが変わらないよう、開始済み`ServiceInstance`だけは算出済みSnapshotを持つ。
## 5. 日次履歴
06:00の日次締めで`statistics_today`から`FacilityDaySummary`を生成する。推奨キーは次の通り。
- `business_date`、`facility_instance_id`、`definition_id`、`level`
- `open_minutes`、`active_minutes`、`downtime_by_reason`
- `services_started`、`services_completed`、`services_failed`
- `guest_processed`、`average_wait_minutes`、`average_quality`
- `gross_revenue`、`refunds`、`maintenance_cost`、`net_contribution`
- `inventory_consumed`、`inventory_produced`、`spoilage_quantity`
- `incidents_by_type`、`heat_generated`
日次履歴は締め後に書換えず、修正は訂正レコードで行う。Definitionのバランス変更後も過去の売上や品質を再計算しない。
## 6. 検証と失敗方針
Definition Registryは起動時に全定義を検証し、致命的エラーの定義を検索・建築候補へ公開しない。エラーはcode、definition ID、resource path、field、messageを持ち、順序を決定的にする。
version 2では、ID形式、Access範囲、Upgrade件数、営業時間キー、Service Profile、Policy型、成人向け置換境界を必須検証する。欠損を0や空配列へ補完して稼働させない。
## 7. 現在の移行状況
| 施設 | version | 詳細化の狙い |
| --- | --- | --- |
| 受付 | 2 | 複数サービス、客・職員Access、価格Policy |
| 厨房 | 2 | BACK生産、入力・出力、バッチ単位 |
| 成人向け個室 | 2 | 夜営業、客層制限、成人向け置換、リスク |
| その他MVP 13施設 | 1 | 互換読込中 |
| 拡張16施設 | 1 | 通常パレット未解放、順次移行 |
次の移行順は、一般客室・食堂・酒場・浴場、倉庫・警備、通路・昇降機、地下拡張施設とする。売上施設を先に移行すると、客AI・価格・在庫の縦断検証を早い段階で固定できる。
## 明示階段(D-036、2026-09-09)
基礎16施設と任意拡張16施設の定義順は保持し、追加インフラ2種を `data/facilities/infrastructure/` と `FacilityCatalog.INFRASTRUCTURE_FACILITY_PATHS` に分ける。通常Runtimeの登録数と建築パレットは基礎16+階段2の18種。既存Registryの既定ディレクトリ単独走査は基礎16のまま。
| ID | 表示 | サイズ | 設置層 | 建設G/資材/分 | 通行容量 | cost/維持魔力 |
|---|---|---:|---|---|---:|---|
| guest_stairs | 客用階段 | 1×1 | FRONT | 40/0/10 | 3 | 150/0 |
| service_stairs | 業務用階段 | 1×1 | BACK | 50/0/10 | 2 | 150/0 |
置くセルが上部踊り場で、同じx/layerのy-1へ接続する。下部足場が必要。業務用はstaff権限。旧保存の既設階段は施設定義へ置換せず、旧速度・権限を持つ別の接続所有記録として保存する。