言語ガイド · Story DSL v1
ストーリーをソースとして書く
Lattice は TypeApe の宣言的なストーリー言語です。読みやすい本文と、その本文を囲む正確な構造を記録するので、同じプロジェクトを編集し、検証し、体験できます。
Story同一性とプロジェクトのメタデータ
Blockナラティブの読める単位
Text波括弧の中の可視本文
Flow明示的なエッジ。ファイル順に依存しない
完全なリファレンスを使う
この概要では言語モデルを説明します。正確な宣言の形、許可される値、所有規則、復旧の指針が必要な場合は、四つのリファレンス章を使ってください。
- ソースファイルと宣言 — インポート、コメント、区切り記号、識別子、文字列、本文、メタデータ、Story フィールド、実体、Scene。
- Block と線形フロー — すべての Block フィールドと purpose、ナレーション、対話の提示、連続性の注釈、終端、Linear の完全な制約。
- CYOA リファレンス — 選択、Predicate スキーマ、接地された State、Group、初期 State、Guard、Pool、Module、Effect、網羅的なランタイム規則。
- 検証と診断 — パースと検証の違い、エラー復旧、壊れた参照、ソフトロック、ランタイムの循環、警告、検証で確認できることとできないこと。
TypeApe は現在 Story DSL v1 を読み書きします。規則が破られている場合、診断は影響を受けるソースを示し、何を直すべきかを説明します。
ファイル、インポート、値
設定された entry ファイルがルートです。プロジェクトは引用符付きの相対インポートで分割します。
# main.la
use "./story/characters.la";
use "./story/opening.la";インポートが読み込まれた後、プロジェクトには story 宣言がちょうど一つ含まれます。インポートはプロジェクト内に留まり、循環できず、同じファイルを二度読み込めません。
Lattice は少数の値の形を使います。
| 形 | 例 | 意味 |
|---|---|---|
| 識別子 | opening, ch_mara | 安定した ID と参照 |
| 文字列 | "en" | 正確な引用符付きテキスト |
| 本文 | { A light wakes. } | 改行を含むナラティブテキスト |
| リスト | [opening, resolution] | 順序付きメタデータ値 |
| 真偽値 / 数値 | true, 3 | 許可される拡張またはイベントのリテラル |
コメントは # で始まります。インポート、本体を持たない宣言、コンテンツ項目、フロー文の後にはセミコロンを付けます。メタデータのプロパティはカンマで区切ります。カスタムのメタデータキーは x_ で始まる必要があり、保持されますが組み込みの動作は変えません。
Story、実体、Scene
Story 宣言は読書の entry とプロジェクト形式を識別します。
story main (
title: "Signal Garden",
language: "en",
format: novel,
entry: opening,
prose_unit: word_like,
prose_scope: authored_body,
prose_minimum: 4500,
prose_target: 5000,
prose_maximum: 5500,
beat_order: [opening, midpoint, resolution]
);title、引用符付きの language、format、entry は必須です。initial_state は CYOA でのみ使えます。
任意の本文ゴールは、持続する執筆目標を記録します。prose_unit、prose_scope、prose_target は一緒に宣言します。word_like は単語に似たトークンを数えます。non_whitespace_graphemes は中国語の文字数で表された依頼に役立ちます。任意の最小値と最大値の境界は、目標値を含んでいなければなりません。
実体は、登場人物、場所、アイテムに安定した同一性を与えます。
entity character ch_mara (
name: "Mara",
role: protagonist,
traits: [observant, stubborn]
);
entity location loc_garden (name: "Signal Garden");
entity item it_key (name: "Signal key");Scene はナラティブの文脈をまとめます。pov は登場人物を参照し、location は場所を参照しなければなりません。
scene garden (
title: "The garden",
beat: opening,
pov: ch_mara,
location: loc_garden,
prose_target: 1200
) {
# Blocks live here.
}Block、本文、対話
Block はフローが対象にできる最小の段落です。公開できる Block には、グローバルに一意な ID、タイトル、ナラティブ上の purpose、可視コンテンツ、そしてちょうど一つの終端が必要です。アウトライン作業の間は、安定した同一性、要約、フロー、任意の本文予算を確認しながら、コンテンツを空のままにできます。
block opening (
title: "The warning",
purpose: setup,
summary: { Mara finds the signal source. },
prose_target: 500,
setup: [signal_arc]
) {
text: {
A light wakes beneath the garden.
};
dialogue ch_mara (
mode: whisper,
emotion: cautious,
stage_direction: { She leans toward the soil. }
): { Not again. };
next -> answer;
}対話の話者は、宣言された登場人物でなければなりません。mode は speech、thought、whisper、shout のいずれかです。位置、感情、表情、ポーズ、舞台指示は任意の提示メタデータです。
ナラティブの連続性の注釈
setup、requires、resolves は軽量なナラティブの約束にラベルを付けます。これらは検証が伏線と回収を推論するのに役立ちますが、フローを作ったり CYOA の State を変更したりは決してしません。
構造化イベントは、より豊かな執筆の根拠を添付できます。
foreshadowing fs_signal: event {
subject: ch_mara,
object: it_key,
predicate: notices
};
reveals rv_signal resolves fs_signal: event {
subject: ch_mara,
object: it_key,
predicate: understands
};Linear story のフロー
すべての Linear Block は、一つの自動継続か一つの結末で終わります。
next -> target_block;end;設定された entry は、分岐のない非循環の一つの連鎖を通り、ちょうど一つの結末へ至らなければなりません。Linear story は選択、合流、接続されていない Block、循環、State、Pool、Module を拒否します。
CYOA の選択と結末
CYOA は分岐し、合流できます。通常の選択には少なくとも二つの選択肢があります。
choice {
option inspect_key: { Inspect the key } -> inspect;
option leave_garden: { Leave the garden } -> departure;
}選択肢のラベルは、読者に向けた意図を表します。選択は経路のトポロジーを変えますが、読者が何を選んだかを記憶しません。後の規則がその決定に依存する場合は、宣言された有限 State としてモデル化します。
有限 State
CYOA の State は意図的に有限で、閉世界です。スクリプト、変数、カウンター、乱数、任意の式はありません。
まず Predicate スキーマと接地された State を宣言します。
predicate knows (subject: character, object: item);
state st_knows_signal (title: "Signal understood"): event {
subject: ch_mara,
object: it_key,
predicate: knows
};グループに属さない State は恒久的なフラグで、add で有効化します。State Group は相互排他的な一つのスロットで、set で変更します。
state group location (
members: [st_location_gate, st_location_garden]
);Guard は State ID のリストを使います。
requires:リストされたすべての State が有効。requires_any:リストされた State の少なくとも一つが有効。forbids:リストされたすべての State が無効。
Pool と浮動 Module
Pool は、条件を満たす一度きりの Module が利用可能になる間、メインの経路を一時停止します。再開するのは、その終了 Guard が一致したときだけです。
pool investigation (
title: "Investigate the garden",
exit_requires: [st_knows_signal]
);
scene garden (title: "The garden") {
block arrival (title: "Arrival", purpose: setup) {
text: { The buried key pulses beneath Mara's hand. };
enter investigation -> departure;
}
}Module は一つの Pool に属し、メインストーリーや別の Module へ飛び込めません。
module md_decode (
title: "Decode the key",
pool: investigation,
entry: decode,
forbids: [st_knows_signal]
) {
scene decoding (title: "The buried code") {
block decode (title: "Decode", purpose: development) {
text: { The light resolves into a patient sequence. };
complete (add: [st_knows_signal]);
}
}
}Pool への進入時と各完了後に、TypeApe はまず終了を確認し、次に条件を満たす未完了の Module を提示します。終了が偽で、条件を満たす Module がない場合、ストーリーはソフトロックされ、検証は失敗します。
パース、確認、検証、体験
まとまったソース変更の後は、同じ順序を使います。
- 設定された entry をパースします。
後の段階を解釈する前に、構文とインポートの診断を直します。 - アウトラインを検証して確認します。
本文が未完成のうちに、構造、執筆契約、正確な本文の進捗、残っている最大の局所的な不足を確認します。 - 公開に向けて検証します。
可視コンテンツの要件を元に戻し、すべてのエラーを直し、各警告を意図した体験に照らして判断します。 - 影響を受ける経路を読みます。
有効なグラフでも、創作上の意図を外していることがあります。
同一性そのものを変える必要がない限り、安定した ID を保ってください。TypeApe がエラーを報告した場合は、x_ メタデータの裏に隠さず、根本のソースを直してください。
