ないならば作る
ActionScript3.0でゲームを作っているのだけれど、シナリオスクリプトとしてLuaを使いたくなった。
しかし探してみると意外にもなかなかシナリオスクリプトとして使えそうなLua実装がない。
あったかと思うとパーサーのみ公開されていたりすごく特殊な方法で動かす仕組みであったりする。
シナリオスクリプトとして使えればいいので完全な実装は必要ない。
それならなんとかなるかと思い、自分で作ることにした。
作ったもの
いちおうBeefと名づけています。
https://github.com/dotneet/as3-lua
機能
- Luaソースの実行
- LuaコードからのAS3.0コードの実行
- 仮想スレッド(ランタイムが実行コンテキストを共有できる。マルチタスクではない。)
- Unicode識別子(Lua非互換。日本語を変数や関数名に使用可能)
できないこと
あくまでゲームのシナリオスクリプトとして使えればいいので、実装していない機能が多数あります。
- メタテーブルとかコルーチンとか難しい仕様は実装していません
- ほとんどの標準ライブラリ関数の使用
- if-else/goto以外の制御構文
使い方
1.Luaコードから呼び出す機能の実装(beef.script.SystemFunctionを継承します)
// 指定したミリ秒数分だけスクリプトの実行を停止する関数
public class FuncWaitTime extends SystemFunction {
public function FuncWaitTime() {
super();
}
public override function call(runtime:ScriptRuntime, params:Vector.<Value>):Value {
runtime.stop();
var millis:Number = params[0].asNumber().value;
setTimeout(function():void{ runtime.resume();}, millis);
return BooleanValue.TRUE;
}
}
}
2. LuaコードからAS3コードを実行
var source:String = "wait_time(1000)";
var c:Compiler = new Compiler();
var fn:ScriptFunction = c.parse(source);
var runtime:ScriptRuntime = new ScriptRuntime();
// wait_timeという名前の関数として登録
runtime.addFunction('wait_time', new FuncWaitTime());
runtime.execute(fn);
今後
開発中のとあるゲーム(非商用)で実際にBeefを使って開発しています。
しばらくスクリプトのバグはでていないのでシナリオスクリプトとして使うくらいならば問題ない安定度にはなっているかなと思います。
機能的なところではforとrepeat構文が未実装というのがかなり痛い感じなので暇があれば実装したいです。
動かせるLuaコードの例
local a = 10
g = a * a + 10
c,d = a,g
a = 1
::ONEMORE::
a = a + 1
print(a)
if a < 10 then goto ONEMORE; end
function 二乗(a)
print(a * a)
end
二乗(50)