開発中のゲームがそろそろ追い込みです。5月中には公開できるかなぁ。
さて、今開発しているゲームではLuaによるレベルデザインを行っていて、過去にいろいろな記事を書いてきました
cocos2d-xのバグを直したらmergeされた話 - 5.1さらうどん
cocos2d-xのLuaバインディングについて解説してみる - 5.1さらうどん
Luaの弱み
非プログラマにゲームの実装をお願いすることで、必ず発生するのが、単純なシンタックスエラー。
今回の開発でも、文章や簡単な数値調整の大部分を非プログラマにお願いしていたのですが
「おい、また,がなくて落ちるぞ。死ね」
「うるせーお前が死ね」
などという煽り合いが日常茶飯事でした。
Luaの場合、シンタックスエラーが起きてもゲーム自体は普通に動いてしまい、そのスクリプトが呼ばれているヶ所に到達して初めてミスに気づけるので、バグの温床となっていました。良くない。
そうだ、Jenkinsだ!
というわけで、最近Jenkinsを導入してTestFlightなどを自動化してみたりしているのですが、LuaのSyntaxチェックもこれでやってしまえ、と思いつきました。
ググってみたところ、lua-checkerと呼ばれるLua向けのsyntaxチェッカーを発見できたので、Jenkinsに組み込んでみます
lua-checker - Check Lua source code for various errors. - Google Project Hosting
導入してみる
lua-checkerのビルド
環境はMac OS X 10.8
svn checkout http://lua-checker.googlecode.com/svn/trunk/ lua-checker-read-only cd lua-checker-read-only curl -O http://www.lua.org/ftp/lua-5.2.2.tar.gz tar xcvf lua-5.2.2.tar.gz mv lua-5.2.2 lua cd lua make maxosx cd ../ make
Shellスクリプトを書き換える
これで、付属しているCHECK_LUA.shを使うことで単体ファイルのシンタックスチェックは完了です!
今回、対象プロジェクトのリポジトリ下に含まれている全てのLuaスクリプトについてチェックしたいので、findなんかを使ってLuaスクリプト全てに適応します。基本はCHECK_LUA.shのコピー
#!/bin/sh SRC_DIR=$(cd $(dirname $1) && pwd) SUCCEED=1 cd $(cd $(dirname $0);pwd) function check() { if [ $? -ne 0 ]; then echo $SRC SUCCEED=0 continue fi } for SRC in `find ${SRC_DIR} -name "*.lua"`; do CLEAN_ASM="while(<>){s/^\t(\d+)\t\[\d+\]/\t\1/;s/(main|function) <[^\]]+>/function/;s/0x[0-9a-f]+//;print}" # Some shell settings set -o pipefail # Check that the simplified source is functionally identical to the original. rm -f /tmp/original.asm /tmp/simplified.asm /tmp/original.luac /tmp/simplified.luac check lua/src/luac -s -l -o /tmp/original.luac $SRC | perl -e "$CLEAN_ASM" > /tmp/original.asm check ./lua_simplifier -luac $SRC | lua/src/luac -s -l -o /tmp/simplified.luac - | perl -e "$CLEAN_ASM" > /tmp/simplified.asm check diff /tmp/original.asm /tmp/simplified.asm check # Check that the simplified source simplifies to itself. rm -f /tmp/simplified.lua /tmp/simplified2.lua check ./lua_simplifier $SRC > /tmp/simplified.lua check ./lua_simplifier /tmp/simplified.lua > /tmp/simplified2.lua check diff /tmp/simplified.lua /tmp/simplified2.lua check # Check the simplified source. ./lua_simplifier -emit_lines $SRC > /tmp/simplified.lua # ./lua_checker -const_functions /tmp/simplified.lua # 削除 check done if [ $SUCCEED -eq 0 ]; then echo ">>>>> FAILED <<<<<" exit 1 fi echo "***** SUCCEED *****" exit 0
元から付いてくるスクリプトにそのまま投げ込むと、何か一つでもエラーが見つかった時点でexit 1を返してしまい、その時点でビルドが失敗となってしまうので、全てをチェックして、どれか一つでもエラーがあったらexit 1を投げています
また、lua_checkerにかけると、未定義の変数が見つかった時点でエラーを出してしまい、C++とbindingしているコードもエラーになってしまうので、ここでは意図的に外しています。(後述)
結果的に
Luaのsyntaxが間違っていたときにビルド失敗して怒ってくれた!
さらにJenkins github pluginを導入して、githubへのpushにhookさせれば、コミットと同時にLuaのsyntaxチェックをかけてくれる環境が完成!何か文法ミスがあれば、怒ってくれるので幸福感あります。
お好みに応じてJenkins Sounds Pluginなどを導入しておくと、何かミスっていたときに音でお知らせしてくれて良い感じです。(うちの開発環境では呪われたときのSEをならしてお気の毒な感じにしています)
問題点
tolua++などを使って、C++のクラスをBindingしている部分は定義されていない変数と見なされ、シンタックスチェックで弾かれてしまいます。これらを考慮してのチェックが行えれば便利度がさらに増しそうですが、一筋縄ではいかない感じがしたのでやめました。
MoonScript良さそう
最近知ったのですがMoonScript良さそうですね!
MoonScript, a language that compiles to Lua
CoffeeScriptと同様に、そもそもこれでコンパイルが通れば、Luaのsyntaxミスに怯えなくてもいいし、
Windows向けのコンパイラも配布されているので、開発にも使いやすい感じですね!
これを使えば今回の記事は割と無意味かも。
次回の開発では取り入れていきたいなぁって思ってます。