DSL と Lua の使い分け
最後の関門ですわ。Pasta では同じことを DSL でも Lua でも書けてしまう場面が多々ございますの。 さて、どちらを選ぶべきか――迷ったあなたへ、わたくしが明快な物差しを差し上げましょう。 フンッ、これさえ覚えれば、もうあなたは立派なゴースト職人ですわよ。
Pasta DSL(.pasta)と Lua は役割が異なる。DSL は宣言的で読みやすく、Lua は手続き的で柔軟である。
基本方針は「まず DSL、それで足りなければ Lua」。DSL のほうが可読性が高く保守しやすいため、
表現できる範囲では DSL を優先し、DSL の制御構文では届かない領域で Lua に切り替える。
判断基準
| ケース | 推奨 | 理由 |
|---|---|---|
| 数個の単語定義 | DSL(@単語:値1、値2) | 宣言的で簡潔 |
| 数十〜数百件の単語一括投入 | Lua(WORD.create_*) | ループ・外部データ読み込みが必要 |
| 基本的なシーン定義 | DSL(*シーン名) | 可読性が高い |
| 条件分岐を含む複雑なロジック | Lua(シーン関数) | DSL の制御構文は限定的 |
| カスタム SHIORI イベント処理 | Lua(REG テーブル) | DSL ではイベントハンドラを直接定義できない |
| 外部データ(JSON / YAML)の読み込み | Lua(@json / @yaml) | DSL に外部ファイル操作機能はない |
DSL が向く場面
- 静的な会話・単語の宣言: 「いつ、誰が、何を話すか」を並べるだけの素直なシーンや、少数の単語定義。
DSL の
*シーン名とアクション行、@単語:値…記法が最も読みやすい。 - イベントに対応するシーン:
*OnBoot、*OnHour12のようにイベント名・時報名でシーンを定義すれば、 ランタイムのフォールバックや仮想ディスパッチャが自動で呼び出す。多くの場合 Lua は不要。
Lua が向く場面
- 大量・データ駆動の単語投入: 数十件を超える単語や、外部ファイルから読み込むデータは、
Lua のループ(
WORD.create_*+entry)で投入する。scripts/ の記述パターン を参照。 - 複雑な条件分岐・状態管理:
saveを使った永続フラグでの分岐、ランダム以外の選択ロジックなど、 DSL の限定的な制御構文では表しにくい処理は Lua のシーン関数で書く。 - カスタムイベントハンドラ: 標準のフォールバックでは扱えないイベント処理は
REGテーブルに登録する。 - 外部データ連携: JSON / YAML の読み込み・整形は
@json/@yamlを使う Lua の領域である。
両者の連携
DSL と Lua は分断されていない。DSL のシーン本体に ```lua ``` ブロックを埋め込めば、その部分だけ
Lua で書ける。また DSL のシーン・単語定義は内部的に Lua(SCENE.xxx 関数や WORD.create_* 呼び出し)へ
変換されて実行される。つまり「DSL で骨格を組み、要所だけ Lua で肉付けする」という併用が自然な形である。
-- DSL の ```lua ブロック内で書くシーン関数も、scripts/ の関数も同じ定型
function SCENE.func_name(act)
local save, var = act:init_scene(SCENE) -- 必須
act:talk(act.ぱすた.actor, "セリフ")
act:yield()
end
迷ったときの指針: 読みやすさが保てるなら DSL、表現力が要るなら Lua。 そして両者は併用できることを忘れないこと。
これで Lua 編は修了ですわ。よく最後までついていらっしゃいました。 ……フンッ、別に褒めているわけではなくてよ。けれど、あなたならきっと素敵なゴーストを作れますわ。 さあ、胸を張って、あなただけの物語を紡いでまいりましょう! ごきげんよう。