はじめに
Lua言語は、いろいろな組み込み系のプログラムや、ゲームのロジック部分、nginx内で完結できてしまうちょっとした処理など、様々な場所に使われています。
Factorioという工場を建設するゲームのMod作成にも、Lua言語が使われています。
自分でもいくつかModを作ったり修正していく中で、変数の型やエディタの補完をもっとしてくれたらうれしいなぁと思っていました。
そんななか、TypeScriptToLuaというパッケージを発見したので、作っていたCoastal Erosion(海岸浸食)というFactorioのModをTypeScriptで書き直してみました。
TypeScriptで書けるようにすること自体は簡単にできたので、導入のポイントと小ばなしを紹介します。
ポイント
以下のリポジトリでTypeScript化したコードを公開しています。
Tei1988/factorio-coastal-erosion
詳しくはリポジトリの中をみてもらうとして、FactorioのModをTypeScriptで書くためのポイントは二つです。
package.jsonの devDependencies
にある typescript-to-lua
と、 @types/factorio
です。
typescript-to-lua
typescript-to-lua
は、TypeScriptで書いたソースをLuaに変換してくれるトランスパイラです。このパッケージで入るtstlコマンドでLua言語に変換を行います。
TypeScriptToLua/TypeScriptToLua
内部的にはTypeScriptからASTを構築して、それをLuaのASTに変換してLuaのコードとして出力する処理になっているようです。
また、一部のTypeScriptの標準ライブラリはLuaで使えるようにLua側でも実装されており、対応している物は使えるようになっています。
package.json
の scripts
に変換用のコマンドをあらかじめ定義しているので、 npm run-script build
で変換できます。
FactorioのLuaは5.2のため、 tsconfig.json
の tstl
の項目に"luaTarget": "5.2"
を指定しています。
@types/factorio
@types/factorio
は、FactorioのLuaのAPIの型定義を提供してくれるパッケージです。
この型定義のおかげで、とても書きやすくなります。
小ばなし
ここからは、実際にTypeScriptに書き直した時に詰まったところなどをいくつか紹介します。
Mapが使えない
Coastal Erosionは、マップ上に存在する海岸(水に設置しているタイル)の座標を連想配列で保持しているのですが、これを Map<number, Map<number, number>>
として置き換えたところ、ゲーム実行時にエラーになりました。
どうやら、クラスのMapはLuaで実装されていないようなので、Hashに置き換えました。
オブジェクトが破壊できない
Coastal Erosionでは、陸地が浸食されてタイルが水没すると、その上に載っていたオブジェクトを破壊するようにしています。
TypeScriptに置き換えた後、そこでエラーが出るようになってしまい、小一時間悩んだのですが、よくよくコードを見ると、 e.destory()
となっていました。型定義のほうが間違っていたという話でした。
とりあえず
困ったら最終的に吐き出されたLuaをみましょう。
おわりに
いかがでしたでしょうか。これでFactorioのModをTypeScriptで作れるようになったかと思います。
Modつくる人が増えたらいいな、と思います。