追記: 図のコメントが間違ってたので修正

teslawireではゲームロジックの記述は基本的にSchemeで行おうと思っている。というのは、ネイティブコードを受け付けない2Dゲームエンジン、要するに

HSP3 (の、HSP3Dish)

プチコン3号

GameMaker (の、HTML5/JavaScriptバックエンド)

への移植をスムースに進めるために適当な高級言語が必要で、こういう時に使うのはSchemeと相場が決まっているため。

... この手の言語もだいぶ収斂が進んでしまった気もする。もうちょっと環境を追加したいが良い2Dエンジンが見つかっていない。(Unityは別枠で移植する予定)

NScLisper の構造 タイムリーに数年振りの更新が有ったNScLisperはNScripter上に実現された(Scheme風の)Lispで、NScripterの伝統的なゲームVM( http://d.hatena.ne.jp/mjt/20111226/p1 )の制約の中でGC付きのLispを実現している。 https://github.com/zick/Magical-Language-Lyrical-Lisp

http://lambda.bugyo.tk/anlog_0508.pdf - 内部の解説(同人誌)、採用する保守的GCのアルゴリズムについても説明されている。 ... 意外とGC付きのこの手のLispは少なく、Mal( https://github.com/kanaka/mal/ )でもGCは基本的に省略されている。

NScripterはいわゆるADVゲーム用のスクリプトエンジンなので、↑の同人誌で書かれているような制約が適用される。 整数演算のみ、ビット演算なし

整数と文字列で別々の変数領域

整数と文字列それぞれで最大4096個の変数が使用可能

関数なし 、ラベルによるgoto/gosubのみ。

、ラベルによるgoto/gosubのみ。 変数名なし。変数のラベルとしては数値のみが使用できる。 (ちなみにNScripter2ではLuaとBASICをサポートし、もっと高度なスクリプトが書けるようになっている - このBASICの仕様はかなりプチコンに近い)

必然的に、NScLisperは4096個までのオブジェクトしか使用できない(実際にはもっと少い)。関数が存在しないことについては、一部の変数領域をスタックとして使用することで解決している。



(たぶんソースコードのコメントの方がわかりやすい - https://github.com/zick/Magical-Language-Lyrical-Lisp/blob/master/0.txt )

NScripterの重要な言語機能としては変数の間接参照が可能であることが挙げられる。NScripterの変数番号は0〜4095が使用できるが、全ての命令で1段までの間接参照(= 変数による変数番号の指定)が行えるため、擬似的なポインタを実現することができる。逆に、これが無いとスタックすら実現できない。

NScripterは32bit符号付き整数を使用するが、NScLisperの数値はGCのマークビットとタグ、符号ビットの分引かれて25bitsになる。いわゆるbignumは存在しない。

同人誌で説明されていない重要な機能追加としてはGVARの導入が有る: http://blog.bugyo.tk/lyrical/archives/1525

https://github.com/zick/Magical-Language-Lyrical-Lisp/commit/efffd0aac8869ad288f43b57ccce7abdcc906694 - 該当コミット NScLisperのデザインはアクションゲームを作るには少々厳しいが、大いに参考になる。

SmileBASICとHSP3 / GameMaker Language(GML)の機能的な違い いづれの処理系もBASICを意識した機能性を備えているものの、細かい違いは多い。 GMLにはgotoが無い GMLには構文としてのラベルが存在しないため、当然gotoも存在しない。switchのようなC言語風構文は備えるので少々意外な気もする。

ついでに、GMLはソースコード中で関数が宣言できず特殊コメントとして設定したタイトルを指定して関数のようにプログラムを呼ぶ機能だけがある。幸いこの機能は16個までの引数渡しと1個のreturnが可能。 HSPだけがlabel as valueを行える 今回のユースケースにはあまり実用的価値が無いが、HSPにはlabel as valueとして使用できる"ラベル型"変数が存在する。SmileBASICでも文字列変数をラベルとして使用できるが、多分実行時のラベル引きが有るのでそれほど早くないと思われる(試していない)。 SmileBASICは動的に配列を生成できない これはかなり困る。SmileBASICはメモリ制約のある環境を意識しているのか、動的に配列を生成することができない。要するにSchemeで言うところのvector手続きというかCで言うところのmallocというかを簡単に実装できないため、工夫が必要になる。

あとSmileBASICは配列長を変更するためにはpush/popするしか無いという微妙な制約もある。例えばGMLではa[10] = 0のようにして配列を確保した後、a = 0のように通常変数として何かを代入することで拡張された配列を解放することができる。

SmileBASICの文字列は一種のu16配列であり、実はA$="HOGE"のような配列でない文字列変数も、A$[2]のように配列としてアクセスすることはできる。当然文字列は動的に確保できるため、動的な配列を文字列で代用することは一応可能となっている。(遅そう) HSPとSmileBASICは型無し配列が無い HSPとSmileBASICの配列は昔懐しのDIM命令で宣言する配列であり、文字列型配列には数値を代入することはできないし、その逆も同様となっている。これらの処理系ではNScLisperと同様のタグ付き整数によるオブジェクト表現が必要になる。

GMLでは文字列と数値は1つの配列中に同居させることができる。が、一般的に使えるtypeofが無い(is_stringの類は有るが、listのような組込みデータ構造(ds)に相当品が無い)ため結局型情報をどこかに持たせる必要は有る。