スクリプトエンジンを
つくる話
KMC例会講座 H30/04/23
1
自己紹介
▪KMC-ID: suzusime
▪京都大学理学部理学科物理科学系4回生
▪KMCでの活動:ボドゲ・文字・プログラム・root
▪好きなキャラ:
梨花ちゃん(ひぐらし)、チノちゃん(ごちうさ)、
村上椎奈さん(ステラのまほう)
2
スクリプトエンジンとは
▪ノベルゲーム・アドベンチャーゲームを作るためのもの
▪スクリプト(指示書)のようなものを解釈して、
テキストを出したり立ち絵を切り替えたり条件分岐をしたり
▪有名なやつ
• 吉里吉里/KAG3: Fate/stay night とか
• NScripter:ひぐらしのなく頃に とか
3
OS
ゲームエンジン
スクリプトエンジン
例:吉里吉里/KAG3
[wait time=200]
*start|スタート
[cm]
こんにちは。[l][r]
ごきげんよろしゅう。[l][r]
改ページしますよ。[p]
[cm]
改ページしました。
4
ラベルでジャンプする
改行や改頁、クリック待ちは
タグで行う
http://www.ultrasync.net/dee/kr2helps/kag3doc/contents/ より
例:CatSystem2
5
#file_01 //1
cg 1 ca01,1,1,1,1,1
rdraw
ミネット 「えへへ……良い朝ですね?」
唇に残る柔らかな感触に、幸せな気分が滲む。
俺はくすぐったい気持ちで口端を緩めた。
ラベルでジャンプする
コマンド類は別行立て
台詞の前にタブを入れて
発話者の名前を指定
空行や改行が意味を持つ
http://cs2.suki.jp/manual/scene/begin/0_basic.html より
Lilas
6
スクリプトエンジンを自作することにした
▪既存エンジンの挙動を学ぶのつらそう
▪文字描画をいいかんじにしたいという欲望
▪スクリプト言語の文法に「うーん」となるものが多かった
▪昔から作ってみたかった
▪ゲームエンジン部分は Altseed を使う
(C#製のいいかんじのゲームエンジン)
7
どうやって作るか
▪要するにスクリプト言語の実行環境を作ればよい
≒新しい言語をつくる
8
ゲームエンジン
(Altseed)
実行機械字句・構文解析器スクリプト
翻訳 命令
言語仕様を考える
▪KAG3 と CatSystem2 のスクリプト言語を混ぜた感じ。
LISPっぽい(と人に言われるが私はLISPをよく知らない)
9
#main_start
チノ ご注文は[if true うさぎ きつね]ですか?
なんちゃって……
[let a true]
[let b [if $a 好き 嫌い]]
あなたのことが$bです。
台詞の前にタブを入れて
発話者の名前を指定
空行や改行が意味を持つ
ラベルでジャンプする
これがさいきょーのスクリプト言語や!!!!
試行錯誤
▪最初は Sprache というC#向けパーサコンビネータライブラリ
を使って実装しようとした
• Haskellのparsecみたいなやつ。函数型でイケイケっぽいなにか
▪挫折した
• LINQよくわかんないし、そもそもライブラリが何をしているのか
よくわからないまま使おうとしていたので詰んだ
▪ちゃんと勉強して伝統的手法でパーサを作ることにした
10
翻訳の流れ
11
前処理 字句解析 構文解析
原スクリプト(入力)
構文木(出力)
整形済みテキスト
トークン列
前処理
▪改行コードをLFに統一する処理
▪今はこれだけ
12
字句解析
▪元のスクリプトを「トークン」という単位に分割する
13
ご注文は[if $a うさぎ きつね]ですか?
ご注文は
[
if
<区切り>
$a
<区切り>
うさぎ
<区切り>
きつね
]
ですか?
文法規則を書き下す
▪トークンの組み合わせがどうなるべきかを書き下す
14
LL(1)構文解析表を作る
▪この文法なら LL(1) という文法の範囲に収まっていそう
→ LL(1) 構文解析を行う手続きに従ってやっていく
15
LL(1)構文解析表を作る
16
実装
▪LL(1)文法は簡単に構文解析器(パーサ)が書ける文法なので、
そんなに難しくはない
▪「LL(1) パーサ」とかでググると実装例が出てくる
• 「パーサ 自作」みたいなふわふわした検索語でなくて、
ちゃんと「LL(1)」と書いてやるのがポイント
• 検索の前に専門用語を知っていると出てくる情報が違う
• こういうのは本で調べたり周りの人に聞いたりすると良い
17
実行機械をつくる
▪当初予定:アセンブリ言語のようなものの実行機械をつくる
→函数呼び出しが面倒(コールスタックがどうとか)
→構文木を渡したら実行できる機械にすることにした
▪フロー制御をいいかんじにするのがむずかしい
• 古人の知恵~
• 言語の用途からしてラベルジャンプだけでよさそう
18
現状
▪ようやくゲームエンジンに組み込んで動作するようになった
▪まだ函数は if くらいしか組み込んでいない
19
今後の展望
▪フロー制御系とグラフィック・サウンド系の函数を実装する
• まあすぐできるやろ
▪エラーメッセージを良い感じに出すようにする
• 現状スクリプトの構文エラーで例外を吐いて落ちる
▪セーブ機能・既読スキップ・ログを実装する
▪函数については C# Code Provider とかを使ってユーザー側で
スクリプトとして実装できるようにすると楽かもしれない(?)
20
感想
▪実装量自体はそんなに多くないが、実装する前に考えるべき
ことが多い
▪世の言語がどうなっているのかの一端が窺い知れた
• 吉里吉里/KAG3の解説とか読んでいると大変そうという気分になる
▪勉強になるし面白い
▪でも時間はかかってしまった……
21
おわりに
▪Lilas絶賛開発中です!
• https://lilas.kmc.jp/
22

スクリプトエンジンをつくる話