コアコンセプト
シートは唯一の信頼できる情報源である
あなたのデータには、正規の形式がただ一つだけ存在します。それが シート です。それ以外はすべて、そこから導出されます。
- IR(不変の定義群)は、シートを検証・組み立てた結果です。
- 生成された C# クラス は、IR のスキーマを強く型付けしたものです。
- ベイクされた ScriptableObject は、IR の値を読み込み可能にしたものです——ルックアップキャッシュ であって、独立した情報源ではありません。
すべての変更はシートを経由し、実際のものになるには再インポート時の検証を通過しなければなりません。ベイクされた SO を直接編集すると、二つ目の情報源が生まれ、検証を迂回してしまいます——この製品は、それをワークフローとして意図的にサポートしません。
(インスペクターの「テスト編集」トグルは 一時的な ランタイム実験のために存在します。書き戻されることはなく、再インポートすると消去されます。)
これが重要な理由: SO を情報源として扱うプロジェクトは、検証されていないデータがシートから乖離していき、それを一致させる手段がなくなってしまいます。ここでは、整合性の確保は構造的です——常にシートから再生成するのです。
IR — 不変で検証済みの組立体
IR は検証が生み出すものです。各タブごとに SheetTable(スキーマ + レコード)が存在し、そのセルはすでに型付けされた値(int、float、enum 値、レコード参照、アセット参照、リスト、プラグインのカスタム型)になっています。
主な特性:
- 部分的な組み立てはありません。 どこか一箇所でもエラーがあれば、IR は構築されません(
ImportResult.Success == false ⇔ Registry == null— これは絶対不変条件です)。 - null はありません。 空のオプションセルは、ただちにその型のデフォルト値として実体化され、
IsDefaultedとしてフラグが立てられます——利用側が null チェックをする必要は一切ありません。 - 不変です。 IR は組み立てられた後は読み取り専用になります。出口(コード生成・ベイク・エクスポート)はそれを読み取るだけで、決して変更しません。
パイプライン
fetch → parse markers/schema → parse cells → validate (keys, references,
@overlap, asset keys, domain rules) → assemble IR → codegen (.cs) → bake (SO)
└──────────────── collect ALL diagnostics ────────────────┘- 検証はすべてを収集します。 一回の実行で、問題の完全なリストが得られます——エラーごとに、どこで/何が/なぜ/どうすればよいか——「一件直しては再インポート」を繰り返す必要はありません。
- コード生成は最終段階です。
.csファイルの書き込みはドメインリロードを引き起こすため、検証と値の組み立てが終わった後に行われます。パイプラインは、リロードが安全に行われ、その後チェーンが自動的に再開されるように構成されています。 - エラーは構造化されたオブジェクトであり、文として描画されます。 各エラーには、タブ・1始まりの行・列記号 および フィールド名、問題のある値、違反したルール、そして実行可能な提案(タイプミスに対しては最も近い候補の提案付き)が含まれます。同じオブジェクトは、ログや CI 向けにマシン可読な座標としても描画されます。
自動インポートチェーン
スキーマが新規または変更されている場合、一回のインポート実行は内部的に次のことを行います。
- 生成コードを書き出す → Unity がコンパイルする → ドメインリロード。
- リロード後、チェーンは 自力で再開し、ベイクを完了させます。
手動で何かを再実行する必要は一切ありません。コンパイルが失敗した場合(例えば、名前変更で変わったばかりのフィールドをゲームコードが参照している場合)、チェーンはループする代わりに、実行可能なコンソール文とともに 安全に中断します(試行上限3回、再開ログあり)。
強い型付け、ランタイムでのパースなし
コード生成は @name / @type / @desc を読み取り、タブ Foo ごとに次を出力します。
FooDefinition— 強く型付けされたレコードクラスで、列ごとに一つのフィールドを持ちます。@descは XML ドキュメントコメントとインスペクターのツールチップになります。FooDatabase : DefinitionDatabase— タブごとのコンテナ SO で、Records、遅延評価の id ルックアップ、SchemaFingerprintを持ちます。
ベイクは実際に型付けされたフィールドを書き込みます——ランタイムでのテキストパースは一切なく、ランタイムリフレクションもありません。これにより IL2CPP セーフになります(ストリッピングの危険がありません)。
アドレスによる読み込み — キャッシュが共有可能であり続ける仕組み
ベイクされた SO は、マシンごとの GUID を持つ、マシンごとのキャッシュです。そこへの直接的なシーン参照は、マシンをまたぐと壊れてしまいます。そこで代わりに:
- インポートは各 Database SO を、Addressables グループ
SheetForgeの安定したアドレス"SheetForge/{tab}"に自動登録します(再ベイクすると、新しい GUID が同じアドレスに再リンクされ、削除されたタブはクリーンアップされます)。 - ゲームコードはアドレスで読み込みます:
SheetForgeDatabases.LoadAsync<FooDatabase>("Foo")。 - Addressables のグループアセットは gitignore 対象で、自己修復します(存在しない場合はインポートによって再作成されます)。
Baseline — ラウンドトリップがシートを保持する仕組み
インポート時に、各タブの 構造(マーカー行、列の順序、コメント、手書きのテキスト)を正規化したスナップショットが baseline として保存されます。Export は、その baseline の 構造 に現在の SO の 値 を差し込みます。
そのため、シート → インポート → Export → シートというラウンドトリップは、シートを構造的に 100% 保持し、値も意味的に保持します:
1.0↔1は値が同一であるため許容されます。- 浮動小数点数は最短のラウンドトリップ形式を使います。
- 小数点は常にロケールに依存しない
.です。
コミットされるものと再生成されるもの
| 成果物 | 方針 |
|---|---|
| シート(ローカルファイル)/ Googleシート | 情報源そのもの。 コミット/共有されます。 |
ベイクされた Database SO(Assets/SheetForgeBaked) | gitignore 対象の、マシンごとのキャッシュ — インポートを実行して再生成します。 |
生成コード(Assets/SheetForgeGenerated) | コミットすることを推奨します。 これはプロジェクト自身のソースであり、Assets/SheetForge の外にあるため製品を再インストールしても削除されず、コミットしておけば誰かがインポートを実行する前から新規クローンがコンパイルできます。出力は決定的(deterministic)なので、チームメイトのインポートも同一のバイト列を生成します。代わりに gitignore する方法も有効で、その場合は次のインポートで再生成されます。この既定値より前からあるプロジェクトは、Assets/SheetForge/Runtime/Generated が空になるまでそこへ生成し続けます — スタートガイド を参照。 |
Addressables の SheetForge グループアセット | gitignore 対象で、自己修復します。初回作成時に生じる一行の設定差分はコミットしないでください。 |
ドメインパッケージ自身の Generated フォルダー | そのパッケージ自身の判断に委ねられます。 同梱の SheetForge.PluginDemo サンプルは、クローン直後でもすぐにコンパイルできるよう、生成コードをコミットしています。 |
| インポート設定アセット | あなた自身が管理するものです。サービスアカウントキーの パス はリポジトリに含めないでください(SHEETFORGE_SHEETS_KEY 環境変数を使ってください)。 |
変更なしの拡張
登録契約により、プラグインは Core への変更ゼロ でパイプラインに参加できます:
- セルタイプパーサー(ラッパー型を含む)、ドメインバリデーター、エッジコントリビューター
- カスタム構造マーカー、「シート作成」テンプレート、インポートソースプロバイダー
- Data Studio のキャンバスオーバーライド・コードレジストリ・ウィジェット・アクション・セルウィジェット・カラープリセット・UI 文字列
Core がドメインパッケージを参照することは決してなく、この一方向の依存関係はコンパイラによって強制されます。正式な一覧——そしてその数——は プラグイン作成 にあります。
関連ページ
- シート構文 — パーサーが読み取るマーカーと型の文法
- Data Studio — このモデルの上でのオーサリング
- ソース・エクスポート・プッシュ — ラウンドトリップの仕組み
- オーサリングカーネル — オーサリングウィンドウの内部にあるエンジン