単語定義
同じ挨拶を毎回繰り返すゴーストなんて、退屈ですわよね。 単語定義を使えば、候補の中からランダムに選ばれて、会話に彩りが生まれますの。 これぞ里々ゆずりの真骨頂。たっぷり味わってくださいまし。
単語定義は、テキストのバリエーションをランダムに選択するための機能である。定義された候補からランダムに 1 つが選ばれることで、毎回同じにならない自然な会話を作れる。@(または @)マーカーで定義・参照する。
単語の定義
グローバル単語定義
ファイルの先頭(シーン定義の前)にインデントなしで定義すると、ファイル全体から参照できる。値は読点(、)・全角コンマ(,)・半角カンマ(,)で区切る。
@挨拶朝:おはよう、ハロー、Good morning
@挨拶昼:こんにちは
*メイン
ぱすた:@挨拶朝 !
ローカル単語定義
グローバルシーン内にインデントありで定義すると、そのシーン内でのみ参照できる。シーンの先頭、会話行より前に置く。
*メイン
@挨拶朝:Hello、Good morning
ぱすた:@挨拶朝 !
複数キー単語定義
コロンの左側にカンマ区切りで複数のキーを指定すると、同一の値リストを複数のキー名に同時登録できる。辞書の重複記述を減らせる。
@女性、水の妖精:水無灯里、アリス・キャロル
@挨拶、あいさつ、greeting:こんにちは、ハロー
- キー区切りには全角読点(
、)・全角コンマ(,)・半角カンマ(,)が使える。 - グローバル・ローカル・アクタースコープのいずれでも使用できる。
- 単一キー形式(
@key:values)との後方互換性は保たれている。
単語の参照
会話行の中で @単語キー の直後に1 文字以上の空白を置くと、一致する候補からランダムに 1 つが選ばれる。
@挨拶朝:おはよう、ハロー
@挨拶昼:こんちわ
*メイン
ぱすた:@挨拶昼 。
重要: 空白がないと最長一致で単語キーを解釈し、後続まで取り込んでしまう。意図しない動作を避けるため、単語参照の直後には必ず空白(または識別子に含まれない記号)を置く。
前方一致検索
単語参照は前方一致で候補を検索する。関連する単語群を一括で参照できる。
@挨拶:こんにちは、ハロー
@挨拶_朝:おはよう、グッドモーニング
@挨拶_夕:こんばんは、Good evening
*会話
ぱすた:@挨拶 # 全候補からランダム選択
ぱすた:@挨拶_朝 # 「おはよう」「グッドモーニング」から選択
@挨→ 「挨拶」「挨拶_朝」「挨拶_夕」すべてにマッチ@挨拶_朝→ 「挨拶_朝」のみにマッチ
スコープと優先順位
参照時の検索順序は次のとおり。
- ローカル単語辞書: 現在のシーン内で定義された単語
- グローバル単語辞書: ファイル先頭で定義された単語
同名の単語がローカルとグローバルの両方にあれば、マージされて候補プールが統合される。Call と同じスコープ解決アルゴリズムに従う(Call / Jump)。
@挨拶:グローバル挨拶
*メイン
@挨拶:ローカル挨拶
ぱすた:@挨拶 ! # 「グローバル挨拶」または「ローカル挨拶」が選ばれる
動的単語参照(将来変更あり)
@$var_name 形式で、変数値を単語名として間接参照する構文が定義されている。$var_name で得た値を単語名として検索する。
将来変更あり: 動的単語参照は文法定義済みだが、実装は将来予定である。
Call との分離
単語参照(@)は単語辞書のみを検索し、シーン辞書は参照しない。逆に Call(>)はシーン辞書のみを検索する。
@挨拶:こんにちは # 単語定義
*挨拶 # 同名のシーン定義
ぱすた:やあ!
*メイン
ぱすた:@挨拶 # 単語辞書から「こんにちは」を取得
>挨拶 # シーン辞書から「挨拶」シーンを呼び出し
未定義単語の参照
存在しない単語キーを参照すると、エラーにはならず空文字列が返る(ログに警告が出力される)。
*テスト
ぱすた:@存在しない単語 # 空文字列として展開される
エスケープ
@エスケープ
@@ と書くと、リテラルの「@」が 1 文字出力される。多段階参照(@@word など)は非対応で、@@ はあくまでエスケープ専用である。
*メール
ぱすた:メールは user@@example.com です
引用符エスケープ
単語値にリテラルの引用符を含めるには、二重の括弧を使う。
@会話:「「セリフ」」 # 実行時に「セリフ」として展開される
外側の 「」 は単語値の区切り、内側の 「」 がリテラルの引用符として保持される。
ランダムの妙、堪能していただけまして? 単語ひとつで会話が生き物になりますのよ。 最後はキャラごとに表情を束ねる「アクター辞書」へ。仕上げと参りましょう!
権威的仕様: 単語定義の厳密な定義は doc/spec/10-words.md を参照。スコープ解決の共通仕様は doc/spec/04-call-spec.md も参照。