文章定義の書式 - SHIORI『真絵(mae)』仕様書
■基礎
-
SHIORI真絵の文章は、文章定義ファイルmae_corpus.txt内に記述する必要があります。基本的な書式は以下の通りです。 行先頭の1,2文字目が"//"の場合はコメント行とみなされます。 (それ以外はプログラムか文章とみなされます) 行末に"\"を置くと論理的に次の行とつながります。1行に記述しきれない場合は、"\"を使って物理的に複数行分割して記述してください。
#タグ名1 文章1 文章2 : #タグ名2 文章3 文章4 :
文章はその直前に定義されたタグに属し、イベントに合わせてタグが呼ばれたら自分に属している文章から選定します。 タグ名1が呼ばれたら、文章1,文章2...から選出されます。同じタグ名を何度使用しても問題なく、1つにまとめて文章を登録した場合と同じになします。 タグの定義で、そのタグが呼ばれる条件を追加できます。 またそのタグが呼ばれた場合に、文章を選出する前にプログラムを実行させることができます。書式は以下の通りです。
#タグ名1:case 条件1 プログラム; :end 文章1 文章2 : #タグ名2:case 条件2 :end 文章3 文章4 : #タグ名3: プログラム; :end 文章5 文章6 :
タグ名1のようにタグ名の後ろに":"を記述して、"case"で条件を記述できます。条件が真(正しい)の場合にそのタグから文章が選出されます。 タグ名の後ろに":"記述した場合、必ず":end"とだけ記述した行を置かなくてはなりません。(タグ名2のようになります) 条件がないけれどプログラムだけを実行させた場合はタグ名3のようにcase記述を省略することも可能です。 プログラムはタグ名の直後の":"から":end"までの間に記述すると考えてください。 プログラムの中は別の解析がされますので、詳細はこちらを参照してください。
■タグとイベント
-
タグ名とイベントの関係
行頭が"#"の場合はタグを定義しています。 伺か本体やSHIORI真絵のイベント名またはリソース名の先頭に"#"を付けてそのままタグ名として登録することで、 イベントが発生したときに同じ名称を持つタグが呼ばれます。 SHIORI真絵が発行するイベントがありますので、それらもそのままタグ名として登録することでそのタグが呼ばれます。 SHIORI真絵のイベントは以下の通りです。
イベント名 発生のタイミング Mae.Talk 話し出すときに呼ばれます。いわゆる通常トークはこのタグにすべて登録してください。 Mae.Response 他のゴーストに話しかけるとき(コミュニケートの開始)に呼ばれます。話しかける内容を登録してください。 Mae.ResponseAgainst コミュニケートの返答で呼ばれます。話しかけられた文章に価値観の低い単語(辞書を参照)が含まれている場合に呼ばれる可能性が高いです。 Mae.ResponseFollow コミュニケートの返答で呼ばれます。話しかけられた文章に価値観の高い単語が含まれている場合に呼ばれる可能性が高いです。 Mae.NothingToTalk 話すべきタイミングで文章が存在しないときに呼ばれます。 Mae.MikireBegin 見切れ扱いにされた瞬間に呼ばれます。 Mae.MikireEnd 見切れ扱いが解決した瞬間に呼ばれます。 Mae.Mikire 見切れ扱いが確定したときに呼ばれます。 Mae.KasanariBegin 重なった瞬間に呼ばれます。 Mae.KasanariEnd 重なりが解決した瞬間に呼ばれます。 Mae.Kasanari 重なりが確定したときに呼ばれます。 Mae.Activity 連続起動時間が時間単位で変わったときに呼ばれます。 Mae.Activity.n 連続起動時間がn時間になったときに呼ばれます。 Mae.OnHourChange 時刻における「時」が変わったときに呼ばれます。 Mae.OnHourChange.n n時になったときに呼ばれます。 Mae.SawariSakura さくら側が撫でられたときに呼ばれます。 Mae.SawariSakura.* さくら側の*部分(サーフィスで定義された識別子)が撫でられたときに呼ばれます。 Mae.SawariKero ケロ側が撫でられたときに呼ばれます。 Mae.SawariKero.* ケロ側の*部分(サーフィスで定義された識別子)が撫でられたときに呼ばれます。 Mae.OnMouseDoubleClickSakura さくら側がダブルクリックされたときに呼ばれます。 Mae.OnMouseDoubleClickSakura.* さくら側の*部分(サーフィスで定義された識別子)がダブルクリックされたときに呼ばれます。 Mae.OnMouseDoubleClickKero ケロ側がダブルクリックされたときに呼ばれます。 Mae.OnMouseDoubleClickKero.* ケロ側の*部分(サーフィスで定義された識別子)がダブルクリックされたときに呼ばれます。 Mae.OnMouseClickSakura さくら側がクリックされたときに呼ばれます。タグを定義するとダブルクリック関連のタグが使用できなくなります。 Mae.OnMouseClickSakura.* さくら側の*部分(サーフィスで定義された識別子)がクリックされたときに呼ばれます。タグを定義するとダブルクリック関連のタグが使用できなくなります。 Mae.OnMouseClickKero ケロ側がクリックされたときに呼ばれます。タグを定義するとダブルクリック関連のタグが使用できなくなります。 Mae.OnMouseClickKero.* ケロ側の*部分(サーフィスで定義された識別子)がクリックされたときに呼ばれます。タグを定義するとダブルクリック関連のタグが使用できなくなります。 Mae.OnSurfaceRestoreSakura.n さくら側のサーフィスnから基本サーフィスへ戻すタイミングがきたら呼ばれます。nを指定しない場合はイベント名であるOnSurfaceRestoreをそのまま利用してください。 Mae.OnNekodorifObjectEmergeSakura さくら側に猫どりふで可視領域内に出現したときに呼ばれます。 Mae.OnNekodorifObjectHitSakura さくら側に猫どりふでヒットしたときに呼ばれます。 Mae.OnNekodorifObjectDropSakura さくら側に猫どりふで再落下開始したときに呼ばれます。 Mae.OnNekodorifObjectVanishSakura さくら側に猫どりふでヒットした落下物が可視領域内から消滅したときに呼ばれます。 Mae.OnNekodorifObjectDodgeSakura さくら側に猫どりふでよけられてヒットしなかった落下物が可視領域内から消滅したときに呼ばれます。 Mae.OnNekodorifObjectEmergeKero ケロ側に猫どりふで可視領域内に出現したときに呼ばれます。 Mae.OnNekodorifObjectHitKero ケロ側に猫どりふでヒットしたときに呼ばれます。 Mae.OnNekodorifObjectDropKero ケロ側に猫どりふでヒットした落下物が可視領域内から消滅したときに呼ばれます。 Mae.OnNekodorifObjectVanishKero ケロ側に猫どりふでよけられてヒットしなかった落下物が可視領域内から消滅したときに呼ばれます。 Mae.OnNekodorifObjectDodgeKero ケロ側に猫どりふで可視領域内に出現したときに呼ばれます。 (任意のイベント).slot0~9 すべてのイベントはタイムスロットを付けて呼ばれます。タイムスロットについては初期設定を参照してください。 username SHIORI真絵独自のリソースではありませんが、特別な処理対象としています。ゴースト作者はデフォルト・ユーザー名をこのタグに登録してください。
■イベントリストによるタグ決定モデル
-
タグ名とイベントの関係
何かしらイベントが発生した場合、必ずイベントリストが作成されます。 イベントリストとは複数のイベントに順番を付けてまとめたもので、最終的に呼ばれるタグは文章が取得できるまでイベントリストの中でシミュレートされます。
例) 18:30に起動した場合、以下のようなイベントリストが生成されます。
1.OnBoot.slot5 (タイムスロット5 が 18 時台を含んでいるとします)
2.OnBoot
3.NothingToTalk (このイベントには例外的にタイムスロットは付きません)
#OnBoot.slot5 がタグとして存在したならば、そのタグから文章を生成しようとします。 しかしタグが存在しなかったり、条件が合わない等の理由で文章が空になった場合、#OnBootが呼ばれます。 同様にそのタグで文章が生成できなかった場合、#NothingToTalkが呼ばれます。 最後まで文章が生成できなかった場合、初期設定の"UNDEFINED_WORD"で定義された文字列が表示されます。 原則として条件の厳しいものがイベントリストで優先度が高くなると考えてください。
-
タグ名の別名定義
タグ名は基本的にイベント名のため可読性が低いです。その問題を解決するために、タグ名の別名が定義できます。 mae_action.txtにタグ名とその別名をタブで区切って記述することで、その別名が使用可能になります。 区切りにタブしか使用できない理由は、別名に半角スペースも利用可能にするためです。
例) OnBoot 起動した OnClose 終了が指示された
これにより「#OnBoot」と記述するところを「#起動した」と記述できます。
-
リファレンスを含んだイベント名
一部のイベントでは利便性を高めるためにイベント名の後ろに"."(ピリオド)を付けてReferenceの一部を結合させたイベントをより高い優先度で発生させます。 「OnKeyPress.a」は"a"が押された場合に呼ばれます。どのReferenceが後ろに付くかはイベントによって異なります。
追加情報 対象イベント Reference[0] OnBIFFFailure, OnUpdateComplete, OnUpdateFailure, OnHeadlinesenseComplete, OnHeadlinesenseFailure, OnInstallComplete, OnInstallFailure, OnInstallComplete, OnFirstBoot, OnKeyPress, OnBoot, OnBIFFComplete, OnBIFF2Complete, Mae.OnSurfaceRestoreSakura(OnSurfaceRestore) Reference[1] OnShellChanged, Mae.OnSurfaceRestoreKero(OnSurfaceRestore) Reference[2] OnHeadlinesense.OnFind Reference[4] Mae.SawariSakura, Mae.SawariKero(以上、OnMouseMove, OnMouseWheel), Mae.OnMouseDoubleClickSakura, Mae.OnMouseDoubleClickKero(以上、OnMouseDoubleClick), Mae.OnMouseClickSakura, Mae.OnMouseClickKero(以上、OnMouseClick) 特殊な指定 Mae.Response(話し掛けてきた「ゴースト名」とその「表情」を定義可能。 例えばMae.Response.first, Mae.Response.4の他にMae.Response.first.4といった複数条件タグを定義可能)
■条件
-
条件は1つのタグに対して1つ設定することができ、条件の実行結果が真(正しい)の場合にそのタグが実行されます。 同一のタグで複数の条件により別々の文章を出力したい場合、同一のタグを複数記述してそれぞれに条件が付けられます。 タグは文章定義ファイルに記述されている順番に上から条件の検証が行われます。
例) #終了メッセージ:case hour >= 4 && hour < 8 setindex( startup_count ); :end ${hohoemi}朝早くまでおつかれさまだよです。\w8\n今日も頑張って、\w8${何かを}するんだよです!\1ぴょーん!? #終了メッセージ:case hour >= 8 && hour < 11 setindex( startup_count ); :end ${hohoemi}朝早くからおつかれさまだよです。\w8\n今日も張り切って、\w8${何かを}するんだよです!\1ぴょーん!? #終了メッセージ:case hour >= 11 && hour < 17 setindex( startup_count ); :end ${hohoemi}おつかれさまだよです。\w8\n今日もまだこれからだよです。\w8\n気合いを入れて、\w8${何かを}するんだよです!\1ぴょーん!? #終了メッセージ:case hour >= 17 && hour < 19 setindex( startup_count ); :end ${hohoemi}おつかれさまだよです。\w8\n1日はここからが勝負だよです。\w8\n気合いを入れて、\w8${何かを}するんだよです!\1ぴょーん!? #終了メッセージ:case hour >= 19 && hour < 23 setindex( startup_count ); :end ${hohoemi}遅くまでおつかれさまだよです。\w8\n早寝早起きを心掛けるんだよです。\w8\n気合いを入れて、\w8明日も${何かを}するんだよです!\1ぴょーん!? #終了メッセージ: setindex( startup_count ); :end ${hohoemi}深夜までおつかれさまだよです。\nもうちょっと早く寝られるようにするんだよです。\w8\n気合いを入れて、\w8明日も${何かを}するんだよです!\1ぴょーん!? #OnClose \1\b[-1]${fuu}\0\b[0]${%event:終了メッセージ}\w8\w8\w8\w8\-
上記の例で、1:00に"OnClose"イベントが発生した場合、まず#OnCloseが呼ばれ、条件が存在しないので、このタグから文章が選定されます。 文章は1つしか登録されていないので、その文章が解釈されます。文章中に${%event:終了メッセージ}という実行変数があるので、 "終了メッセージ"というイベントが発生して、そのイベントによって出力される文章を実行変数の場所へ挿入しようとします。 "終了メッセージ"タグは複数存在するので、上から条件が検証され、真になるタグを探します。 最初のタグは4時台~8時台かどうかの条件式なので、偽(正しくない)になります。 次のタグの条件も偽となり結局条件の付いた"終了メッセージ"タグはすべて偽なので選択されません。 最後の"終了メッセージ"タグは条件がないので、最終的にこのタグから文章が選出され、実行変数に置き換わります。最終的に以下の文章が出力されます。
\1\b[-1]${fuu}\0\b[0]${hohoemi}深夜までおつかれさまだよです。\nもうちょっと早く寝られるようにするんだよです。 \w8\n気合いを入れて、\w8明日も${何かを}するんだよです!\1ぴょーん!?\w8\w8\w8\w8\-
条件式の書式はプログラムと同じです。詳しくは条件とプログラムを参照してください。
■プログラム
- プログラムは1つのタグに対して1つ設定することができ、そのタグが選出されたときにプログラムは実行されます。 文章はプログラムが実行された結果で生成されます。つまり変数の内容はプログラムの実行結果になります。
-
#Declaration
SHIORI真絵の起動時に一度だけこのイベントが発行されます。 変数の解説であるように、使用するユーザー変数は#Declarationタグのプログラムで宣言をする必要があります。
-
#Initialize
SHIORI真絵の起動時にDeclarationの次にこのイベントが発行されます。 起動時に保存された変数を読み込んだ後に実行されます。変数の初期化やSAORIモジュールのロードをここで実行してください。
例) #Initialize: cloth_counter = 0; startup_count = startup_count + 1;
上記の例ではユーザー変数cloth_counterに0を代入し、startup_countは保存されていた値に+1しています。 変数の初期値は0なので、保存されていなければstartup_countは1になります。(cloth_counterは保存されていても0になる)
書式や関数については、条件とプログラムを参照してください。 -
#Finalize
SHIORI真絵の終了時にこのイベントが発行されます。終了時に保存や変更をしたい情報があった場合、ここで実行をしてください。
例) #Finalize: setnews("Shutdown", "終了", 1); :end
上記の例ではゴーストが終了する度に、終了というNewsを登録します。
■文章
-
行頭が"#"の場合はタグの切り替えを意味します。タグが切り替えられると、それ以下の文章はそのタグに登録されます。 すべてのタグ(同名のタグも別々の扱い)はインデックスを持っており、SHIORI真絵の起動時にすべて0がセットされ、そのタグが呼ばれるたびに+1されます。 インデックスの値はSHIORI真絵が起動中は保持されます。終了時に保存はされません。
文章はそのタグのインデックスの値に従って選出されます。インデックスが2の場合は0から数えるので3番目の文章が選出されます。 インデックスの値が文章の数以上の場合、インデックスを文章の数で割った「余り」で文章を選出します。具体的には文章が 3つの場合、0→1→2→0→...の順番で同じタグが呼ばれるたびに文章が選出されます。 以上がデフォルトの文書選出モードである「順次選出モード」です。
文章選出モードには他に「重複なしランダム選出モード」と「重複ありランダム選出モード」があります。
重複なしランダム選出モードでは、そのタグに登録されている文章からランダムで選出します。 ただし、タグ内のすべての文章を選出し終えるまでは、同じ文章は選出しません。 これもインデックス同様、SHIORI真絵起動中は保持されますが、終了時に保存はされませんので注意をしてください。
重複ありランダム選出モードは単純にランダムで文章を選出するため、すべての文章を選出していなくても以前に繰り返し同じ文章を選出する可能性があります。 文章選出モードは、そのタグの中のプログラムで実行されなくては設定されません。 設定したモードは1回発話をするとリセットされて順次選出モードになりますので、 タグの中のプログラムではそのタグが呼ばれる度にモードを設定するように記述しておく必要があります。 文書選出モードはsetrandindex()で設定します。
文章の書式は以下のようになります。
(価値観 n) 文章
パラメータ 内容 (価値観 n) -5~5の9段階で表現します。後ろに続く文章が使用される基準値です。現在の気分が良ければ高い数値の文章から選出されます。
省略すると0になります。文章 SAKURAスクリプトを記述する。 SHIORI真絵は気分を持っていて、話している単語の「価値観」に従って気分は -MAX_SENTI~MAX_SENTIで変化します。 その値は内部的に-5~5に感情レベルとして変換され、それと等しい価値観を持つ文章の中から選出されます。 複数の価値観にまたがって文章が選択されることはありません。 気分から導き出された価値観が1ならば価値観1で登録された文章が存在する限りその中から選択されます。 (タグのインデックスは価値観ごとに持っています)
1つの価値観に1つの文章しか登録されていないと、その価値観のときにはいつも同じ文章が選出されます。 目的の価値観の文章が存在しない場合は、0に向けて1つずつ価値観の絶対値を下げて文章を探し、 価値観0でも文章が見つからなければイベントリストに載っている別のタグの中から選出します。