ウマサポで学ぶLuaの基礎①

このシリーズのゴール

・ウマサポの設定:デフォルト.luaに書いてあることが理解できるようになる
・自分で設定.luaにスクリプトを書いて試行錯誤できるようになる

このエントリの概要

・Luaを知ってスクリプトを弄る準備をしよう
・ウマサポの要となるテーブルの読み方を理解しよう

Luaって何?

結構昔からある動作軽量なインタプリタ言語らしい。インタプリタ言語?って人はとりあえず書いてあるコードを上から順番に実行していく言語だと思えばOK。
↓が一番わかりやすかったので基礎はここで学びました。
https://ie.u-ryukyu.ac.jp/~e085739/lua.hajime.html
とりあえず、第2回第3回の複数の戻り値の範囲が理解できればウマサポのスクリプト組む上では不足しないです。まずはさっとご一読ください。

とにかくウマサポで実践しよう

実践に勝るものはなしです。とにかく動かしてアウトプットを見ながら挙動を知るのが一番手っ取り早い。
空っぽの設定.luaにこう記述してください。

print('hello, world.')

そしてウマサポの自動操作モードを開始(以下"実行"と書きます)します。ログにこのように出るはずです。

キャプチャ_herllo

プログラム学習の定番、'hello, world.'の出力です。ウマサポの仕様として、printを実行するとログ画面に「実行日時 | printの実行結果」を出力することができます。
これを利用すると、変数やテーブルの値を調べることができるので、自分で定義した関数の挙動を確認することができます。
想定する結果にならないなって思ったら、まずはprintで気になる箇所を出力してどの処理までは想定通りに動いているかチェックしてみましょう。

スクリプトエディタを導入しよう

ここからコードを弄っていくのでスクリプトエディタを導入しましょう。ちょっとした編集はメモ帳でもできますが、コードを弄る上で様々なメリットがあるのでエディタを導入するのがおすすめです。エディタというとVisual Studio Codeが有名ですが、用途や導入のハードルを考慮するとGeanyがいいでしょう。
https://www.geany.org/
最新版をダウンロードしてインストールしてください。Geanyを立ち上げたら、文書→ファイルの種類→スクリプト言語→Lua ソースファイルを選択すれば準備完了です。

画像2

デフォルトで左のペインに関数へのシンボルを出してくれるのがgood。長いソースコードでも目的の関数のところへジャンプできる。初期フォントがクソなのでCtrl+Alt+Pで設定を開いてインターフェース→フォントで適宜変更してください。

ウマサポのテーブルを覗いてみよう

ウマサポのスクリプトはテーブル操作がキモと言っても過言ではありません。処理に使用されるほとんどのデータがテーブルに格納されているため、
・どのテーブルがどういう構造をしているか
・どんなデータがどんな形で入っているか
・欲しいデータを引き出すにはどう記述すればいいのか

これを理解することが重要です。
テーブル操作と次回解説するIf文、For文さえ押さえておけば大抵の挙動は実装できるのがウマサポのスクリプトです。ね、簡単でしょ?
それでは例として、育成キャラクター情報を格納しているg_statusテーブルを覗いてみましょう。設定.luaに以下のように記述したら育成中に実行してください。

画像12

yes! スぺchan kawaii!

function onStartTurn()

	print('育成中のウマ娘は' .. g_status[STATUS.NAME])
	abort()

end

画像3

エラーはabort()で止めているためなので気にしないでください。
3行目に「育成中のウマ娘は」という文字列にg_status[STATUS.NAME]で参照した値(=育成中のウマ娘の名前)を文字列の連結「..」でくっつけてprintした結果が出てます。
では、次はコレ

function onStartTurn()

	for k, v in pairs(g_status[STATUS.MOTIVATION]) do
		print(k .. "=" .. v)
	end
	
	abort()
end

画像4

3・4行目に注目してください。今度はFor文を使ってg_status[STATUS.MOTIVATION]の中身をprintしました。For文は次回で別途説明しますが、g_status[STATUS.MOTIVATION]のkeyとvalueを1セットずつ取り出して出力しています。なんのこっちゃ?と思うでしょう。テーブルとはつまりはこういうことです。

画像5

g_statusテーブルには複数のkey,valueのセットが格納されています。keyとvalueは必ず対になっているので、テーブルにkeyを指定すれば対になっているvalueが返ってきます。
そしてこの構造は入れ子にすることが可能です。

画像6

STATUS.MOTIVATIONのvalueは黄色全体であり、その中には複数のkey,valueのセットを持っています。従って、以下のようにSTATUS.MOTIVATIONに続いてkeyを指定するとそれと対になっているvalueを取り出すことができます。

function onStartTurn()

	print('やる気は' .. g_status[STATUS.MOTIVATION].name)
	
	abort()
	
end

画像7

ちなみにテーブルのkeyを指定する方法は2通りあります。

function onStartTurn()

	-- ① .key名
	print('①やる気は' .. g_status[STATUS.MOTIVATION].name)
	
	-- ② ["key名"]
	print('②やる気は' .. g_status[STATUS.MOTIVATION]["name"])
	
	abort()
end

画像8

どっちが良いとかはありません。注意点としては②の場合、keyは文字列でなければならないことです。例えば↓のようにすると、

function onStartTurn()

	print(g_status[STATUS.MOTIVATION][name])

	abort()
end

画像9

はい、ダメです。なぜならこの場合のnameは変数として扱われるので、nameの中身をkeyとして指定していることになります。当然nameの中身なんてないので参照するものがありません。ログに[string "メイン"]:209: bad argument #1 to 'format' (string expected, got nil)と出ていますが、"テーブルのkeyを指定している箇所に文字列を期待して見に行ったのに空っぽだよ!"というエラーです。逆に言えば、何かしらの処理でnameに値を入れておけば動的に参照したい値を制御できる、ということです。
あれ?なんでSTATUS.MOTIVATIONは平気なん?と言うと、STATUS.MOTIVATIONの中には”やる気”という文字列が格納されているからです。つまりg_statusの中身は実際はこうなっています。

画像10

そしてSTATUS.MOTIVATIONも、STATUSテーブルのkey "MOTIVATION"にvalue "やる気"が入っている構造です。テーブルがなんとなく分かって来ました?

function onStartTurn()

    -- STATUSテーブルの中身を覗いてみる
	for k, v in pairs(STATUS) do
		print(k .. "=" .. v)
	end
	
	abort()
	
end

画像11

余談1
因みにエラーが発生した場合、どこに問題があるのかを探す必要があります。さっきのエラーになったログを見ると、[string "設定"]:3: in function 'base.onStartTurn'という箇所を見つけることができます。これ、「設定.luaの3行目のonStartTurn関数の中でエラーが起きている」ということを教えてくれています。つまりエディタに行数が表示されていると便利。メモ帳以外のエディタをおすすめする理由の1つがこれです。

余談2
Luaのテーブルの構造やアクセスの仕方はJSONとほぼ同じです。JSONとは構造的なデータを文字列として表現するフォーマットで、web開発でよく使われています。一般消費者には使い道はないと思いきや、pythonとちょっと組み合わせればお手軽に便利なツールを作ることができたりします。どんなって?例えばちょっとしたキーを指定すればFANZAから胸囲100cm以上の女優のリストを取ってこれたりとかですね。

まとめ

他のテーブルについても見方は全く同じです。各テーブルの仕様は作者様が設定:デフォルト.luaに詳しく記載してくださっていますのでありがたく読んでおきましょう。今回はここまで。
次回はIf文とFor文に関連するテーブルの仕様を説明します。


この記事が気に入ったらサポートをしてみませんか?