00.Lua講座記事リンク 01.NSLuaの恩恵/簡単な解説 02.animation 03.defsub/luasub 04.loadgosub/NSExec("_luacall load") 05.連続描画で演出抜け 06.スキップ確認はLuaで 07.渡す引数は厳密に 08.NSOgg系は既存のDS同様 09.百分率でデシベル計算 10.numaliasされた変数をLuaで参照 11.definereset 12.一行目はファイル名 13.引数を読むタイミング 14.if文とBoolean 15.NSGosub/NSGoto/NSReturnテスト1 16.NSGosub/NSGoto/NSReturnテスト2 17.NSDDLLは64回まで 18.NSGetClick()について 19.luacall end について 20.関数の有無チェック 21.nil 22.NSExec('_movie "????",click') 23.NSSp2GetInfo
※ 注意
ここではver2.93以降に機能追加された、NSLuaについての個人的なメモを纏めております。
NScripterと連携する上での基本的な情報のみを扱っています。
Luaそのものについては
Lua 5.1 リファレンスマニュアル
など他サイト様を参照ください。
NScripter利用者に向けられたLua講座記事。めちゃくちゃ有り難いです。感謝して読もう!
senzogawaさん 特別講座 NScripterからLuaへの道標
2010/02/10 senzogawaのNな日々さん 導入
2010/02/12 senzogawaのNな日々さん 変数/関数
2010/02/19 senzogawaのNな日々さん ブロック/スコープ
2010/02/27 senzogawaのNな日々さん データ型/テーブル
2010/03/08 senzogawaのNな日々さん 関数/メソッド
2010/03/15 senzogawaのNな日々さん モジュール/ライブラリ
むいむい。さん NScriptしか知らない人向けのLua講座に挑戦
2010/03/16 永字八法さん (仮原稿)
2010/03/16 永字八法さん if編
2010/03/25 永字八法さん for〜next編
と想像していたけれど、いざ触ってみたら快適すぎてわらけてくるからお薦め。
ちょっとでも複雑な処理なら労力1/10くらいに減ります(※効果には個人差があります)
NScripterで組むと滅茶苦茶大変だったものが驚く程楽になります(※効果には個人差があります)
(そもそも頑張れば色々出来すぎるNScripterがおかしいんですがw)
大きく目に見える効果としてはシステムを組む時間の短縮が挙げられます。
元々シナリオスクリプト部分の簡潔さがNScripterを利用する大きな利点の一つでしたが、
NSLuaのお陰でシステムスクリプト部分でも楽になったため、制作スピード面で非常に恩恵があります。
NScripterでやっていたことをLuaに置き換える程度の利用なら、whileやrepeatのループに、
テーブル(配列)と文字列操作と数学関数とipairs、pairsあたりを押さえるだけで一気に楽になります。
(演算子に != が使えないのだけは個人的に不満)
以下、素のNScripterでは出来ない恩恵をいくつか記しておきます。
・浮動小数点が扱える(整数だけの縛りが無くなります)
・数学関数が扱える(atan sqrt等が楽に!)
・変数の限度がなくなる。変数にスコープがある。
・テーブル(連想配列)が超便利(色んな型を配列に突っ込める)
・可変長配列が便利(勝手に拡張してくれる)
・animationによる並列演出ができる
・luacallによる動作の乗っ取りが出来る(例えばtextでは表示前の文字列を扱える)
・NSOgg〜〜系によって音声演出の幅が広がる
こんな感じで何かと便利ですから、知識と必要に応じて取り入れていくのがいいと思います。
Luaコードが実行されるタイミングは下記3パターンです。
・起動時。system.luaに裸で書かれたコードを実行します。[EOF]到達で抜けます。(※1)
・luasubされた命令文を呼んだ時。当該関数を実行して、関数のendで抜けます。
・luacallされた動作を行った時。当該関数を実行して、関数のendで抜けます。
抜けた後は普段のNScripter動作に戻ります。
luasubはdefsubの高機能版と考えてください。
単にいつもdefsubで作っていた命令をLuaで書けるだけです。
luacallはシスカマ(つまりtextgosubやloadgosubなど)の高機能版と考えてください。
単にいつもシステムカスタマイズ飛び先ラベルで作っていた動作をLuaで書けるだけです。
Luaに行った時は、NScripter側はコードを止めて待機してます。
Luaの当該関数がendになったところで元のNScripterコード行に復帰します。
ざっくばらんに言うとLuaで書いた文へgosubしてるだけの動作です。
(※NSGoto(*???)などありますが、lua側の関数がendになってNScripterに復帰してから初めてgotoします)
リリース時に.luaコードは生データで置いておく必要はありません。ns2アーカイブにつっこめます。
これについては「初級TIPS 21.リリース時のアーカイブ化」を参照してください。
(※1)[EOF]はエディタ使ってれば末尾に表示出てるはず。それのこと。
よくある「裸で書かれた」という表現の意味は、簡単に言えば関数の外に書かれたコード全部。
このあたりの概念はsenzogawaさん講座の「ブロック/スコープ」の解説ページを参照のこと。
後述の「15.NSGosub/NSGoto/NSReturnテスト1」の1つめのサンプルコード例でいえば、
「NSExec("_luasub nsgosubtest")」の行だけが関数ブロック外のいわゆる裸の部分にあたる。
これによって*define節でluasub文を書いたのと同様の意味になる。
nscr2.95 2010,05,16 (2011,01,05 update) △page top
NSExec("_luacall text")先で、NSExec('_puttext "'..変数..'"')で表示してるという前提条件。
するとテキスト表示中はアニメが止まる。(というかLua側ではNSExecAnimation()無いと動かない)
NSExecしてる間はNScrに一度返してるってワケではなく普通にLua側らしい。
てことで、同様にwaitなどをluasub上書きしてしまうとアニメも止まってしまう。
nscr2.95 2010,05,16 △page top
defsubにて作成した命令をNSExecで呼ぶと落ちるが、luasubにて作成した命令は通る。
ただし、[NSLua解説1〜2.txt]にあるように↓が起きないように注意しとこう。
>命令がLuaを呼び出してもかまいませんが、そこからNSExecを二重に呼んではいけません。
nscr2.95 2010,05,16 △page top
ロード挙動はまずNSCALL_load関数を処理してからloadgosubの設定ラベルに行く。
textやtagあたりと違って無視されない。
まずLuaのテーブルをNSCALL_load関数内で復帰させてから、loadgosub先で色々再開させると楽(?)
Luaの変数回りは外部ファイル使わないならNScrの文字列変数に持って貰った方が楽だと思う。
あと、Lua環境の初期化は行われないのでグローバルな変数と配列は真っ先に初期化しとこう。
RESETの方でも同様にやっとこう。
nscr2.95 2010,05,16 △page top
どうにも連続でスプライトを描くと途中から画が固まって、演出終わったころに帰ってくることがある。
当方のオンボログラボだけなのかもわからないが、中盤〜終盤の演出がすっぽ抜けるという残念な動作。
そこでNSUpdate()後にNSSleep(1)挟んでも飛ぶ。NSSleep(10)でも変わらず、NSExec("_wait 1")でも同様。
何故かNSExec("_wait 2")以上を与えると問題なし。
(再現スクリプトを貴史たま+MEさんに確認していただいたのですが、先方では再現せず。
(つまり環境依存の線でまず決まりでしょう。貴史たま+MEさんありがとうございました。
nscr2.95 2010,05,16 △page top
既読スキップの既読判定はLua側のコードには行わない。
そのため、skipやctrl時にreturn――といった具合に気を使っていたような演出でのif文は
全部Luaにやらせてしまえば、既読スキップで止まることもなく、
また、その対策の為に冒頭の裏で強制的に読ませる力業な作業も大幅に減らせる。
nscr2.95 2010,05,16 △page top
可変引数万歳!ではあるものの、例えばNSPopInt()に文字列を渡すと落ちる。
同様にNSPopStr()に数値で落ちる。pcallで括ってもダメで残念。
NSPopID()だけは文字列を与えた場合に落ちない。
先にID内容をチェックして合わなければ。NSPopStrに行くという順で利用する。
そういえばNSPopStrは勝手に¥を¥¥に変換してくれてる様子。
同じようにNSPopIDは勝手にstring.lowerしてくれてる様子。お陰で楽。
逆に、NSPopLabel()はエスケープ文字の関係か、アスタリスクが自動削除されてる様子。
goto利用時に文字列の先頭に追加しとく手間が増えるのでちょっと不便。
ちなみに、IDと数値を共存させたい場合、NScr側でnumaliasしといて定数にしてしまえばいい。
IDの要件はnumalias要件と同様に半角英数字なので普通にそれで対応出来る。
(※ これはdefsub時代のNScr小技ですね。bgやld乗っ取りでの回避策がそのまま使えます)
nscr2.95 2010,05,16 △page top
別チャンネルではなく、既存のDirectSoundと共通した0〜49chを使う。
例えば、NScr側でdwaveloop 5,"loop.wav"の再生中に、
Lua側でNSOggFade(5,0,-3000,5000,false)すると、普通にフェードされることで分かる。
命令文にNSOggという名前がついているものの、oggファイルだけでなくwavファイルも読める。
(NSOggIsPlayingは現状0番chの状態しか取得できない)
nscr2.95 2010,05,19 △page top
百分率でデシベル計算(DirectSound用に100倍)
vol = (10 * math.log10(vol/100)) * 100
0は除算できず、謎な値は対数に投げられないので0の時は定数(-10000あたり)にしとこう。
あとDirectSound用にmath.floorもしとこう。
(上のdBから百分率に戻す)
100を、基数:10,指数:dB÷-1000でべき乗して出た値で割ってmath.ceil。定数時は0にしとこう。
(上のdBからNScripter用の音量に変換する)
100からdB÷-24.9の値を引くだけ。
nscr2.95 2010,05,19 △page top
受け渡しの関数
function na(Str)
NSExec("chk_alias "..Str)
return a
end
NSExec("luasub chk_alias")
function NSCOM_chk_alias()
a = NSPopInt()
end
実際の利用例
-- %hoge $hoge
local a = NSGetIntValue(na("hoge"))
local b = NSGetStrValue(na("hoge"))
NSSetIntValue(na("hoge"),9999)
NSSetStrValue(na("hoge"),"test")
上のような変数用エイリアスじゃなく、定数を設定したnumaliasやstraliasでも似た手順で参照できる。
けれど、定数なんだからそのまま手動で書いちゃった方が早いんじゃないかと思う。
もしくは外部ファイルに書いてLuaの頭で読んでNScripter用のaliasとLua用の変数代入一気にやるとか。
(追記 H22,07,19 上記コードを利用する場合の注意)
注目して欲しいのはコード中にNSExecが入っていること。二重NSExecが発生すると0行目帰還になるので注意。
nscr2.95 2010,05,22 △page top
Luaを利用する場合はdefineresetを使わない。
理由はLuaで書いたdefine節のみの命令が読めなくなったり、NScrのdefine節命令を重複実行したりするため。
ちなみにgame命令をうんたらかんたらすれば上記の問題もなく行ける。
しかしながら普通はdefinereset自体を使わないと判断する方が平和。
nscr2.95 2010,05,22 △page top
Luaスクリプトのファイルの一行目に書いた内容がエラーメッセージに出力されるので、
一行目に必ずファイル名を下のように書いとこう。NL_dofileでファイル分けする場合に必須。
-- system.lua
で、例としてはこんな感じになる。
nscr2.95 2010,05,22 △page top
NSCOM_***系の自作関数の引数は、NSCOM_***関数からさらに呼んだ関数の先でNSPopIntしても問題ない。
nscr2.95 2010,05,22 △page top
Luaは元々、if文の評価式にブーリアンを返す関数を利用できるが、
if NSCheckComma() then
といった具合に、NSLuaで用意されている関数でも同様に利用できる。
そもそも返り値がブーリアンな自作関数が評価式で利用出来るのだから当然と言えば当然。
if NSGetClick() then NSOkBox("left","Click") end
また、上記のように戻り値が複数である関数を評価式とした場合、一つめの戻り値内容で判定してくれる。
ついでに、Lua仕様としてfalseとnil以外はすべて「真」として扱われることも覚えておくと楽かも。
a = 0
if a then
NSOkBox("","true")
else
NSOkBox("","false")
end
-- ゼロも空文字列も真
nscr2.95 2010,06,07 △page top
lua中で書かれたgosub文はスタックに積まれているのか、
NScripterに帰ってから全てのgosubが実行される。
「後入れ先出し」なので、下のサンプルでいうと、3-2-1-の順でgosubが実行される。
--system.lua
NSExec("_luasub nsgosubtest")
function NSCOM_nsgosubtest()
NSGosub ("*kekka1")
NSGosub ("*kekka2")
NSGosub ("*kekka3")
end
*define
game
*start
nsgosubtest
終了¥
end
*kekka1
mov $0,"*kekka1"
goto *labelchk
*kekka2
mov $0,"*kekka2"
goto *labelchk
*kekka3
mov $0,"*kekka3"
goto *labelchk
*labelchk
caption "ラベル名:"+$0
結果¥
return
ちなみに、NSGotoは最後に書いたNSGotoラベルのみが有効。(これはまあ予想通りかと)
--system.lua
NSExec("_luasub nsgototest")
function NSCOM_nsgototest()
NSGoto ("*kekka1")
NSGoto ("*kekka2")
end
*define
game
*start
nsgototest
*kekka1
mov $0,"*kekka1"
goto *labelchk
*kekka2
mov $0,"*kekka2"
goto *labelchk
*labelchk
caption "ラベル名:"+$0
結果¥
end
NSReturnについては書いた回数分のreturnがNScripterに帰ってから実行される。
gosubのスタックを意図的に削りたい場合に便利かも。
--system.lua
NSExec("_luasub nsreturntest")
function NSCOM_nsreturntest()
NSReturn()
NSReturn()
end
*define
game
*start
gosub *depth1
mesbox "*start","現在地"
end
*depth1
gosub *depth2
mesbox "*depth1","現在地"
end
*depth2
nsreturntest
mesbox "*depth2","現在地"
end
nscr2.95 2011,01,04 △page top
組み合わせて使った場合はどうなるのか。動作チェックしてみたい。
--system.lua
NSExec("_luasub nsreturntest")
function NSCOM_nsreturntest()
NSGoto ("*out")
NSReturn()
NSReturn()
end
*define
game
*start
gosub *depth1
mesbox "*start","現在地"
end
*depth1
gosub *depth2
mesbox "*depth1","現在地"
end
*depth2
nsreturntest
mesbox "*depth2","現在地"
end
*out
mesbox "*out","現在地"
return
まずは上記、GOTO+RETURNのパターン。結果は"*start"が出る。NSGoto分は無視されてますね。
--system.lua
NSExec("_luasub nsreturntest")
function NSCOM_nsreturntest()
NSGosub ("*out")
NSReturn()
NSReturn()
end
*define
game
*start
gosub *depth1
mesbox "*start","現在地"
end
*depth1
gosub *depth2
mesbox "*depth1","現在地"
end
*depth2
nsreturntest
mesbox "*depth2","現在地"
end
*out
mesbox "*out","現在地"
return
次に、GOSUB+RETURN。結果は"*depth1"が出る。最後のNSReturn()しか効いていない様子。
「"*out"→"*start"で終わる」または「"*start"で終わる」という予測が外れた。
--system.lua
NSExec("_luasub nsreturntest")
function NSCOM_nsreturntest()
NSReturn()
NSGoto ("*out")
end
*define
game
*start
gosub *depth1
mesbox "*start","現在地"
end
*depth1
gosub *depth2
mesbox "*depth1","現在地"
end
*depth2
nsreturntest
mesbox "*depth2","現在地"
end
*out
mesbox "*out","現在地"
return
RETURN+GOTO。結果は"*out"表示後に"*start"が出る。
goto処理後にスタックのreturnが生きている様子。
--system.lua
NSExec("_luasub nsreturntest")
function NSCOM_nsreturntest()
NSGosub ("*fin")
NSGoto ("*out")
end
*define
game
*start
gosub *depth1
mesbox "*start","現在地"
end
*depth1
gosub *depth2
mesbox "*depth1","現在地"
end
*depth2
nsreturntest
mesbox "*depth2","現在地"
end
*out
mesbox "*out","現在地"
return
*fin
mesbox "*fin","現在地"
end
GOSUB+GOTO。結果は"*out"表示後に"*depth2"が出る。
「"*out"→"*fin"で終わる」または「"*depth1"で終わる」という予測が外れた。
--system.lua
NSExec("_luasub nsreturntest")
function NSCOM_nsreturntest()
NSReturn()
NSReturn()
NSGosub ("*out")
end
*define
game
*start
gosub *depth1
mesbox "*start","現在地"
end
*depth1
gosub *depth2
mesbox "*depth1","現在地"
end
*depth2
nsreturntest
mesbox "*depth2","現在地"
end
*out
mesbox "*out","現在地"
return
RETURN+GOSUB。結果は"*out"表示後に"*start"が出る。
gosub処理後にスタックのreturnが二つとも生きてる様子。
--system.lua
NSExec("_luasub nsreturntest")
function NSCOM_nsreturntest()
NSGoto ("*fin")
NSGosub ("*chk")
end
*define
game
*start
nsreturntest
mesbox "*start","現在地"
end
*chk
mesbox "*chk","現在地"
return
*fin
mesbox "*fin","現在地"
end
ラスト、GOTO+GOSUB。こちらも結果は"*chk"表示後に"*fin"が出る。
gosub処理後にスタックのgotoが生きてる様子。
以上6通りをテストしてみた。
スタック的な「後入れ先出し」を想定していれば案外そのままかと思ったが半数がズレた。
特に、先にNSGosubが書かれていた場合の2パターンはかなり想定外の動作をするので注意。
基本的に組み合わせない方が無難。
2chのNScripter Ver.18.00スレッド794-796にて、この動作についての解説が投稿されています。
http://toro.2ch.net/test/read.cgi/gamedev/1311914551/794-796
上記動作の全てに説明がついて膝を打ちました。悩んでいる方は一読をおすすめします。
nscr2.95 2011,01,04 △page top
--------------------------- NScrLuaエラー --------------------------- [string "--system.lua..."]:568: NSDDLLの登録数が上限64を超えました。 --------------------------- OK ---------------------------
このエラー、素直に「NSLua直接描画命令.txt」のサンプル通りやってれば出ることはない。
あとは、DLLを65個以上登録するケースくらい?(しかし、こちらはまずないかと)
nscr2.95 2011,02,10 △page top
利用例:「長めの演出中にその演出をカットできるよう監視させたい」などの形で利用できる。
重要なのは「最後に入力された」マウスクリック情報を取得する点。
上の例で考えると、このままでは演出に入る前のクリックによって、演出が常にカットされてしまう。
回避するには最後に入力された情報を一度消す必要があるが命令が見あたらない。さあ困った。
……ということがあるかもしれないが解決法は簡単。
一度NSGetClick()を呼べばマウスクリック情報はそこでクリアされる。単にこれだけ。
演出ループに入る前に一度呼んで消化しておいて、ループ中に改めて監視すればOK。
あと、マニュアル「NSLua解説3.txt」に書かれているNSGetClick()のコード例が
何故かNSGetMouse()になっている誤植があるので、コピペで書いてるひとはご注意ください。
nscr2.95 2011,04,06 △page top
いわゆるレジュームとかコンティニューとか言われる機能の実装で利用できる。
呼ばれるケースは4通り。
メニューバーの[終了]、ウィンドウの[X]、NScripterのendやNSluaのNSEnd()、命令ミスなどのエラー落ち。
つまりはプログラムが終了するタイミングです。
すべて、NScrのウィンドウが消えてから最後にコールバック。NSCALL_end()を走らせる。
ちなみに前者二つは終了確認ダイアログで「はい」を選んだ後に実行される。
--------------------------- 終了確認 --------------------------- 終了しますか? --------------------------- はい(Y) いいえ(N) ---------------------------
NSCALL_end()は終了確認ダイアログをグラフィカルに実装するための命令ではないので注意。
それをやりたい場合はNSCALL_close()で実装します。
あと、NSCALL_end()内でコードをミスると、NScripterを落とせなくなって再起動するしかないので注意。
nscr2.95 2011,09,07 △page top
Luaの仕様として関数もテーブルに格納されているので_Gから直接実行や参照ができる。
_Gに与えるのは文字列。()付けると実行できる。type確認時点では付けない。
実行させたい場合、先に有無をチェックしてから、存在する場合のみ実行させるとよい。
--system.lua
function hoge()
NSOkBox("hoge関数内","")
end
NSExec("_luasub test")
function NSCOM_test()
local func_name = "hoge"
if type(_G[func_name]) == "function" then
NSOkBox("関数あるよ",type(_G[func_name]))
else
NSOkBox("関数ないよ",type(_G[func_name]))
end
end
nscr2.96 2011,11,13 △page top
人様のコードに触れる機会があってその時にしたアドバイス。
というか私にLuaについて聞くのは明らかに人選ミスだと思われます。
local hoge
NSOkBox(hoge or "nil","hoge値")
Luaは数値も状況に合わせてに文字列変換してくれるため楽ですが、nilは型変換してくれません。
テスト用にダイアログで値を確認していくにも、nil落ち頻発で泣ける場合、
上記のような感じで or でnil時に代わりに与えたい値を併記しましょう。そんだけ。
これは、単に論理演算子の下記の動作です。
c = a or b --a値が「真」ならa値がcに代入される。a値が「偽」ならb値がcに代入される
nscr2.96 2011,11,17 △page top
「18.NSGetClick()について」に関連した動作。
lua側のNSExecから_movieを実行する場合は、NSExecの前に
一度NSGetClick()を実行しておいてキー押下情報をクリアしておこう。
そうしておかないと、clickタグ利用のムービーが一瞬で消えてしまうといった動作になる。
nscr2.96 2011,12,17 △page top
NScripter側の拡張スプライトではアニメーションは扱えない。
[NSLua解説3.txt]を見るとNSSp2GetInfoの戻値(の例文ではなく説明文の方)に「セル数」があったので
一応チェックしてみたが、やはりNSLua側でも同じくアニメーションが扱えない。
ちなみにセル分けNSSp2LoadしてNSSp2Moveした画面上の表示はセル分けした0番が出る。
隠れてNSSp2Cellとかいう命令が地味にあるんじゃないかと思ったが試したところ無かった。
で、NSSp2GetInfoの第三戻値のセル数だが取得できない。nilになるので使用しないこと。
単純にマニュアル作成時のコピペ文面削り忘れではないかという予想はしていたけれどやはり……
w,h,c=NSSp2GetInfo(1)
NSOkBox("w:"..w.."|h:"..h.."|c:"..(c or "nil"),"NSSp2GetInfo")
--cはnil
nscr2.96 2013,03,05 △page top
マの素養皆無なんで手探りで概念を学び中。レベル低くてもキニシナイ(゚ε゚)
C言語……<条件式>?<真>:<偽>
Lua ……<条件式>and<真>or<偽>
until行末までがブロック内なので、ループの評価式にループ内のローカル変数を参照できる
ナニソレ喰えるの(゚ε゚)?って感じだったので、ダイアログ挟んで書いてみた。
function hoo(n)
NSOkBox(tostring(n),"n")
local f = n
return function(x)
NSOkBox(tostring(x),"x")
return x + f
end
end
foo = hoo(7)
NSOkBox("開始","開始")
NSOkBox(tostring(foo(3)),"結果")
n→開始→x→結果の順
そうか、単に関数生成装置なのか。returnで返る無名関数の動作をするようになるのね。なるほど。
しかも要らなくなったらnil代入で消せるし確かに便利かもしらん。
テーブルの最後の値ですよ〜って判定はnilかどうかでやってるらしいと聞いた。
ということはtable.insertで途中posにnil代入でそれ以降全削除も可能か? と実験してみた↓
t = {1,2,3,5,8,13,21}
table.insert(t,3,nil)
for i=1,8 do
NSOkBox(tostring(t[i]),"test1:"..i)
end
for i=1,#t do
NSOkBox(tostring(t[i]),"test2:"..i)
end
for k,v in ipairs(t) do
NSOkBox(tostring(v),"test3:"..k)
end
ってことで、配列途中で以下削除って動作にはならん様子。test1・test2は8つ普通に出る。
nilがあるとtest3のgeneric forの時に困る様子。2つだけでループが終わった。
なので配列途中で値無しを入れたいときはfalseあたりを入れとくとよさげ。
コルーチンはyieldだけでなく普通にend到達で帰ってきてもtrue。
も一度resumeしてはじめてfalseになる。false状態でまたresumeするとエラー。
false時の2つ目以降の返値タプルは"cannot resume dead coroutine"になるのでtrue時の値は別で確保。
ところでコルーチンを頭に戻す関数ないのか。同じ変数にcoroutine.createで誤魔化せたけどいいのか?
deadまで回ったコルーチンオブジェクトはどうなるんだろ? 勝手にガベコレしてくれるのかな?
あー、でもcoroutine.statusで見たらdead返るんだしやっぱそのまま残ってそう。
リファレンス見ても削除する関数見つからんが、Luaなんだからnil代入でよさげと期待してしまう。
あと、よく分からんが、リソース負担大きいらしいんで、少ないコルーチンを使い回すように方針転換。
無限ループのコルーチン作っておいて、引数とifで分岐、または関数の中身すげ替えで対処の予定。
自分用メモ。知らないと焦る(2回ほどやった)のでサイトに明記。
これ、当然ながら
Lua 5.1 リファレンスマニュアル
にちゃんと明記されてんですけど、
精読しないで打ち始めたので引っかかりました。
NSExec("_luasub test")
function NSCOM_test()
local a = 1
local b = a
b = 999
NSOkBox(a,"a値")
local tbl_a = {1,2,3,4,5}
local tbl_b = tbl_a
tbl_b[1] = 999
NSOkBox(tbl_a[1],"tbl_a[1]値")
end
-- a値は1 / tbl_a[1]値は999
このとおり、変数は値渡し、テーブルは参照渡しな動作になることを注意。
なのでunpack使うか、またはipairsで一度バラして代入すればオッケーです。
教訓。マニュアル読もう。
ファイルパスの¥マーク操作などで一瞬迷ったのでチェックしてみた。
test = string.len ("hello!¥nnslua")
NSOkBox(test,"test値")
-- 結果:12
まあ当然なんでしょうけど、確かめないと不安なもので……。
local a = 10 % 24
local b = 24 % 24
local c = 28 % 24
local d = 48 % 24
NSOkBox(a..","..b..","..c..","..d,"結果")
--結果:10,0,4,0
いえね……非マなので10/24の余りはどうなるのかと試してみないと不安だったもので……。
table命令を使った方法は結局分からなかったが、下記二つでいけた。
T = {}
rawset(T,"HOGE",{X=0;Y=0;Z=0;})
T = {}
T["HOGE"] = {X=0;Y=0;Z=0;}
配列有無確認はtypeで出来た。