@NScripterは分かるがLuaは分からない
ANScripterもLuaも分かる
この暗黙の前提に基づき、NSLa独自の文法を解説する際に「NScripterではmov $0,""
のように値を代入しますが…」といった書き方をせず、「従来の命令に加え…」とだけ書くかもしれません。
その上で@・A両方の層に対応するために、本マニュアルは以下のような記述形態を採ることにします。
「オプションから変更できる挙動、およびNScripter目線(配布状態の動作サンプル)では正しいがLua目線(およびNSLaの実際の仕様)としては間違っている解説」には緑色のマーカーを用います。
たとえば、「NSLaは起動時に000.txt〜255.txtを読み込みます」といった具合です。
この例は同梱サンプルにおけるデフォルト挙動であり、実際には好きな名前のファイルを好きなタイミングで読み込む事ができます。
NSLuaユーザーにとっては重要な事実ですが、NSLaの実体は配列に読み込んだスクリプトを実行する(NSExec()やloadstring()のような)関数です[3.1](実際、関数としてLuaから実行できます)。
しかし混乱を避ける目的から、ある項目(追加/変更される文法や機能)についてNScripterの延長で解説できる限り、NScripter目線で記述することにします。
★は思いっきり書きかけの項目に付けている目印です。あと一か月くらいかかりそうです…
「生の文字」と書いた場合、原則として""
で括られた文字列を意味します。
「生の数字」と書いた場合も、同様に、変数記述ではない数字そのものを意味します。
「生の全角文字」と書いた場合、""
で括られてすらいない全角文字列を意味します。$0=あいうえお
の右辺がその例です。
「命令」と書いた場合、NScripterの命令全般を指します(Luaに命令という概念は(誤解を恐れずに言えば)存在しません)。
「引数」と書いた場合、命令または関数に渡される文字や数字などの値を意味します。
lsp 1,"foo.png",0,0
なら4つの引数がlsp
に渡されており、alert("text","title")
なら2つの引数がalert
に渡されています。
n番目の引数は一般に第n引数と呼ばれます。たとえばbg "foo.png",1
の第1引数は"foo.png"です。
「評価する」と書いた場合、「(該当する文字列を)処理・実行する」と読み替えて構いません。
たとえば「“$0,$1=$1,$0”の右辺を評価し、それから代入する」という文章は、
以下の二段階の操作を意味します。
「真である」「偽である」と書いた場合、前者を「条件を満たす」ないし「変数に何らかの値が代入されている」と読み替えて構いません。 Luaが分かる人は当然そのまま読んでください。
「深度」または「gosub深度」と書いた場合、「(スクリプトの開始位置を基準に)何重にgosubしているか」を表す数値を指します。
一度もgosubしていない状態は深度1、3回gosubしていれば深度4です。
「あと何回returnすればスクリプトを抜け出せるか」と言い換えることもできます。
「ネスト」または「ifネスト」と書いた場合、「(該当深度の開始位置を基準に)何重にifが記述されているか」を表す数値を指します。
NSLaにおけるifの文法に関しては当該項目を参照してください[2.7]。(NSLaではLua方式のifを使用できます。)
ifを使っていない区間はネスト0です。
Lua変数のうち、関数型については文中でhoge()
のように表記することがあります。これは純粋に視認性を目的とした表記であり、当該関数が引数を持たないことを即座に意味するものではありません。
NSNSgyo
に格納されており、NSNSsaveon
がsaveon状態か否かを管理しています。
NSNSで始まらない例として、たとえば以下のような関数を定義しています。
luadata.save() luadata.load() luadata.tload()
これらはLua変数の保存と読み出しを行う関数で、内部動作(ログ系の機能における出力)でも使用しています。
利便性のために追加した関数もあります。
string.split() table.copy() alert() ensafe()
こうした関数は内部動作に使用しておらず、必要に応じて上書きしても構いません。
デフォルトのLua関数のうち、error()とloadstring()とNSSleep()はグローバルに上書きしています。
上記以外に、NSLaの実行そのものを司る関数として以下を使用しています。
nsload() nsloadfile() ns() nsfile() nsboot()
このうちns関数が本体で、他はns関数を実行するためのラッパーです。詳細については拡張スクリプトの動的な読み込みと実行[3.2]を参照してください。
NSNSSaveHensu
で指定した番号の文字変数(通常変数が望ましい)を1つ使用します。;$V4095G2000S640,480L10000 NSNSSaveHensu=1999
この変数は内部情報(ロード時の戻り行など)を記録するための領域として予約されます。 スクリプトの可能な限り早い位置(NSLa読み込み直後、または定義節の先頭付近)で、「極力通常変数末尾に近い(使わない)番号」を割り当ててください。
NScripter変数のローカル化機能(localalias/setvar命令)[2.5]を利用する場合、指定した範囲の文字・数字変数がNSLa側の処理で使用されます。同様に「使っていない通常変数」を指定してください。同梱の000.txtでは以下のように設定されています。
localalias 1000,1255 setvar 1256,1511
defsub
やluasub
は出来なくなっています。--分岐・繰り返し if elseif elif else end outif killif for next do while repeat until switch case default fallthrough continue break nsbreak nsend --ジャンプ goto gosub return tablegoto skip jumpf jumpb --コルーチン setcoroutine resume yield --その他宣言・代入・内部処理 trap rtrap lrtrap --この辺は厳密に言うと微妙だけど予約としておく local var defsub select selgosub --内部でselnumを呼び出す。selnumは乗っ取り前提 mov reset
main domain english savedir savegame savepoint saveon saveoff loadgame systemcall setwindow setwindow2 setwindow3 clickstr linepage puttext kinsoku setkinsoku addkinsoku trap r_trap lr_trap rmode loadgosub textcolor textclear numalias stralias automode_time skipoff zenkakko --新旧ボタン関連全て セーブデータに用いるログ取り用途・環境の記録 btnwait bclear btndef spbtn cellcheckspbtn btn exbtn cellcheckexbtn btnarea getcursor getenter getfunction getinsert getmclick getpage gettab getzxc spclclk bsp bcursor bdown btrans btndown bdef btime btntime btntime2 exbtn_d kidokumode filelog labelexist ld cl bg lsp lsph csp msp amsp textspeed textspeeddefault indent texton textoff texthide textshow --音回り bgm bgmonce dwave dwaveloop bgmstop dwavestop stop bgmvol defbgmvol getbgmvol bgmfadein bgmfadeout sevol defsevol getsevol voicevol defvoicevol getvoicevol --以下はデフォルト命令ではない uselocalalias usevar loopsevol defloopsevol getloopsevol
NSCALL_animation()
NSCALL_save()
NSCALL_load()
NSCALL_end()
NSCALL_savepoint()
NSCALL_reset()
|
内部からそれぞれ
NSNSCALL_animation()
NSNSCALL_save()
NSNSCALL_load()
NSNSCALL_end()
NSNSCALL_savepoint()
NSNSCALL_reset()
を呼び出してください(呼び出し先で内部処理が実行される)。たとえばNSLaデフォルトのloadコールバックは function NSCALL_load() NSNSCALL_load() end と定義されています。 |
NScall_close()
| 終了前にNSNSsafeend=true と代入しておくか、NSEnd(true) と終了してください。 |
NSCALL_text0() |
文頭で呼び出されます。 文字列を返すとテキストがすり替わり、falseを返すとテキスト表示を中止します。 |
NSCALL_tag() |
文頭で呼び出されます。 NSCALL_tagにラベル名または関数が代入されていた場合、 pretextgosub/zenkakko命令相当の処理を期待してタグ内部のテキストが渡されます。 ※Nスク本来の挙動(クリック待ち毎の判定)と異なるため注意してください。 |
NSCALL_textは使用されず、呼び出されません。入力待ちをカスタマイズする関数としてNSNSclickwait()
が用意されています[2.6.6]。
■「NScripter風に動く」スクリプトを新規に作成する場合
■既存のスクリプトをNSLaに対応させたい場合(NSLaの組み込み)
■NSLua主体のプロジェクトにNSLaを組み込む手順に関しては、[3.1.1]を参照してください。
;以下のように書く
;[[
ここから
ここまで
;]]
; [[
このように
解除が容易
;]] 入れ子にもできます。 ;[[
入れ子にする場合は
;[=[
このように任意個のイコールを挟むことで
;]=]
多重に記述できます。
;]] Lua風の書き方(--、ハイフン2つ)も利用できます。 --このように
--[[
まったくのLua風な表記も
--[==[
通るように
--]==]
なっています。
--]]
同梱ファイルをそのまま利用できます。
dllフォルダ
NSLaを含むライブラリが入っています。
UIフォルダ
NSLa_novelがセーブ/ロード画面やオプション画面、バックログやテキストウインドウに使用する素材が入っています。
lua51.dll/lua5.1.dll
dllフォルダ内の一部プラグインが利用しています。
system.lua
「NScripterであるかのように」[3.1.2]NSLaを呼び出し、実行しています。
000.txt〜255.txt
ここに拡張スクリプトの定義節・実行節を記述します。
表に出しておきたくない場合、テキストアーカイブではなくns2ファイルアーカイブに格納してください。
00.txt
上部メニューの設定(insertmenu/resetmenu等)とレイヤープラグインの定義はこちらに記述します(処理順の都合)。最小構成例では1行目の初期定義と上部メニューの非表示、NSLaの初期実行(NSCOM_main()の呼び出し)のみ行っています。
NSLaはほとんど使用していませんが、NScripter本体の動作安定に不可欠です。
NScripterと仕様が異なる部分のうち、コンバートツールで自動変換されない内容について、手作業で確認修正する必要があります。
適用したいスクリプトが以下の条件にあてはまっていないか確認してください。
★コンバートツールの警告検知機能をもう少し更新する
★システムカスタマイズ関連の処理について
システムカスタマイズ(※)している
(※…クリック待ちの乗っ取り)NSLaではクリック待ちの乗っ取り方が異なります。
若干量を手作業で修正する必要があります。既存の命令をdefsubしている
予約語やluasub命令との衝突を確認する必要があります。 既にNSLuaを利用している
コールバックやluasub命令の衝突を確認する必要があります。 自動変換できない非互換性を含む
手作業でスクリプトを修正する必要があるかもしれません。 NSLa非対応文法(※)を含む
(※…主にテキストボタン)NSLaを適用することはできません。 2.1.2 - 最小構成例の起動
●00.txt…NSLa読み込み前に読み込まれる領域です。
前項[2.1.1]で説明した通り、00.txtでは
@初期定義(;$V4095G2000S640,480L10000)
A上部メニューの操作
Bレイヤープラグイン定義
CNSCOM_main関数の呼び出し
のみを行っています。
●000.txt…「定義節で行うべき処理」のほとんどが記述されています。
*defineからreturn(game相当の離脱処理)までの処理に相当します。
●100.txt…「実行節」の例です。全画面ウインドウと下部ウインドウ両方の構成例を示しています。
*start以降の処理に相当します。
2.1.3 - 大文字・小文字に関する注意
NSLaは、NScripter本体と概ね同じように行・列を解釈します。
ただし、原則として小文字で命令を記述してください。
(コンバートツール[2.17]は自動で変換を行います)。
特にfor/gotoなどの予約語[1.2.3]は大文字を認識しません。
2.1.4 - コメントアウト/複数行コメントアウト(; -- ;[[〜]] --[[〜]])
複数の行をまとめてコメントアウトできます。
(唯一の例外として、「%0--」
のような記述は「dec %0」
の略記と見なされます[2.3.4]。)
mov %0,10
の略記です。%0=10
●まとめて代入%0=10 :$0="あいうえお"
の略記です。%0,$0=10,"あいうえお"
●右辺が余った(項が左辺より多い)場合%0,%1=0,1,2,3 -->%0=0,%1=1
●右辺が不足している(項が左辺より少ない)場合%0,%1,%2,$3=0,1 -->%0=0,%1=1,%2=0,$3=""
●左右の辺で型が合わない場合%0,%1,$2="123","あいうえお",456 -->%0=123,%1=0(変換失敗),$2="456"
●左辺の範囲指定%0,%1,%2
の略記です。%0-2=0,1,2
●左右の範囲指定%0-2=%10#12
●同じ型の変数を連続で指定する場合($%)
を省略しても構いません。%0,2,$10=0,2,"あいうえお"
●文字変数に全角文字を代入する場合$0=あいうえお
●右辺に四則演算を記述する場合()
で括る必要があります(処理順の都合)。%0=(15-1)*3/4 -->10 $0="あいう"+(15-1) -->"あいう14" $0="あいう"+15-1 -->エラー!
●代入略記における結合"+"(NScripter式)
と".."(Lua式)
のどちらを用いても構いません。$0="あ"+"い".."う" -->"あいう"
代入処理は、内部的にはNSNSmov()関数への文字列渡しです。
右辺に値や変数ではなく「*」を指定すると、当該変数の初期化(0または"")を意味します。
右辺不足時に実際に補われているのはこの記号です。
%0,$0=*,*
右辺の変数/値/*の直後には、特別な末尾オプションを付加できます。
%0! | 左辺の残った項すべてに同じ値(%0 )を代入します。 |
%0@ | 左辺の当該項以降に同じ型(数値変数)が続く限り、同じ値(%0 )を代入します。 |
%0@数字 | 指定した個数分の項に一括代入します。"あ"@3 は"あ","あ","あ" と等価です。 |
# @ ! 表記いずれかの後に追加のオプション「?(数字)」を指定できます。
「?(数字)」を指定すると、連続して代入される値が(数字)または1
ずつ増減します。負の値を指定しても構いません。
0@3?10 は 0,10,20 と等価です。
文字に対してこのオプションが指定されると、末尾に半角で番号を付与します。
【"ぬ"@3?】 は 【"ぬ1","ぬ2","ぬ3"】 と等価です。
【"ぬ"@3?4】 は 【"ぬ4","ぬ8","ぬ12"】 と等価です。
# @ ! を記述せずに?(数字)のみ指定した場合、「@?(数字)」の略記と見なします。
(左辺の型が変わるまで連続代入+(数字)ずつ増加or連番付与)
同様に、!(数字)は!?(数字)の略記と見なされます。
(左辺の残り全てに連続代入+加算または連番付与)
add,sub,mul,div,mod
に略記が用意されています。
%0+=100
はadd %0,100
の略記です。
%0-=100
はsub %0,100
の略記です。
%0*=100
はmul %0,100
の略記です。
%0/=100
はdib %0,100
の略記です。
%0%=100
はmod %0,100
の略記です(見づらいため注意)。
このうち+=
のみは文字変数に対しても適用できます。他はエラーを返します。
剰余(割ったあまりの数、mod)を%
で表すのはLua風の表記です(実際のところ、計算はLuaに投げています)。ところが%
は数字変数の語頭でもあるため、NSLaでは剰余と数字変数の記号が衝突しています。
この衝突は、以下のような記述(数字変数による変数番号の指定)において、意図に反した動作を招くおそれがあります。
;【問題1】 %0=3 if(10 % %0==1) -->10 % 3==1 ;条件を満たす end if(10%%0==1) -->103==1 ;条件満たさず end ;【問題2】 %3=5 if(10 % 3==1) ;条件を満たす end if(10%3==1) -->105==1 ;条件満たさず end
これはif/for条件節が内部的にLuaスクリプトとして処理される仕様に由来する問題です[2.16.5]。「` (Windowsキーボードではshift+@)」
を「(数字変数ではない)%」
として解釈させる回避手段も用意されていますが、剰余を扱う際は極力半角スペースやタブを間に挿入すべきです。
一方代入略記[2.3.1]では独自に項を切り分けて処理されるため、剰余の直後に数字変数を記述しても正しく解釈されます。
%1=10%%0 -->%1=1
%0++
はinc %0
の略記です。%0--
はdec %0
の略記です。
%0-- %0--;あいうえお %0----あいうえお
| 「%0 を1 減少させる(+注釈)」を表します |
%0 -- %0--あいうえお %0 --あいうえお
| 「%0 というテキスト(+注釈)」を表します |
実際はLuaのグローバル変数(テーブル型)を埋め込んで使用しているだけです。[2.16.2]したがって以下の記述は読み飛ばして問題ありません。
NSLaで配列を用いるには、
foo={}
のように定義を行う必要があります。このとき使用する名前は原則としてエイリアスと重複しないようにしてください。
配列に値を代入する場合は
foo[1]="bar"
のように表記します。代入する値の型は文字でも数字でも構いません。
命令の引数として値を呼ぶ場合はlsp 1,&foo[1],0,0
のように&
を付けて表記します。
この例ではfooという配列変数の1番に代入された値を呼び出しています。
添え字(上記例でいう1
の部分です)に文字列を使うこともできます。&foo["あいうえお"]
のように記述します。一般に、これは連想配列と呼ばれます。
★多次元配列の定義方法 dimの場合★
★値の初期値は0ではない(nilである)点
★1オリジンにすべきである点
★保存方法
$$0 %$0
のように変数を記述することができます。つまり、エイリアス名を文字変数で指定することができます。$%0 %%0
つまり変数による変数番号指定もそのまま使えます。
*label let hoge --現在のifネスト/gosub深度以下で$hoge,%hogeを使用できる --何か処理をする return
一時的に値を格納したいだけの場合など、コード全体から見えなくてもよい変数を定義節でいちいちnumaliasせずともよくなります。let 名前
と記述します。if($0==1) let hoge $hoge="あいうえお" 値は「$hoge」です。 -->値は「あいうえお」です。 end gosub *label 値は「$hoge」です。 -->未定義エラー! *label 値は「$hoge」です。 -->値は「あいうえお」です。 return
複数のローカル変数を同時に定義できます。let hoge,fuga --$hoge,$fuga,%hoge,%fugaが用意される
定義時に初期値を代入できます。let hoge,fuga=15,"あいうえお" --[[ @$hoge="15" A$fuga="あいうえお" B%hoge=15 C%fuga=0 が用意される --]]
--一度もgosubしていない場所は深度1です gosub *label1 値は「$hoge」です。 -->未定義エラー! ---------------------------------------------------- *label1 --ここは深度2です if(true) --同一深度内のどこで宣言しても有効です var hoge="あいうえお" end 値は「$hoge」です。 -->値は「あいうえお」です。 gosub *label2 値は「$hoge」です。 -->値は「あいうえお」です。 return *label2 --ここは深度3です 値は「$hoge」です。 -->未定義エラー! return
local $0 --$0が一時的にローカル変数化
NSNSclickwait(frommyselnum,voicewaiting,notfromtextwait)
この関数は俗にシステムカスタマイズと呼ばれる処理のうち、
「クリック待ち時の動作を変更する」
に相当します。
つまり、「テキスト中のクリック待ち(@¥)」または「自作selnum」から呼び出され、以下の処理を担う関数です。
@(必要であれば)常駐ボタンを定義する
A(bexec命令で)クリックやキーやボタン押下等の「入力」を検知する
B結果(何が入力されたのか)をNSLaに返す
NSLaデフォルトの関数は実装例としてのサンプルを兼ねています。
NSLaでは、単に常駐ボタンを実装するだけなら常駐ボタン設置関数[2.6.5]を使用して配置・取得する事ができます。
その場合クリック待ち関数を修正・自作する必要はありません。つまり、この関数を改変する場合は
「有効なキー入力を追加・変更したい(Zキーで読み進めたい、F12リセットは要らない等)」
「ゲームパッド主体のジャンルにおいて、テキスト表示時にゲームパッドの入力を検知したい」
どちらかの状況にある事が想定されます。
■引数について
第一引数(bclearを行わずtrapを発火させないフラグ)
自作selnum等から呼び出して使う場合はtrueを渡してNSNSclickwait(true)とします。これはtrapの発火を防ぐためです。
第二引数(オートモードのボイス待ちミリ秒)
オートモード[2.12]中であり、かつボイス待ちを行う(クリック待ち関数を再帰的に呼び出す)場合に次回確認までの待ち時間(ミリ秒)を渡します。デフォルト関数では100ミリ秒ごとにボイス再生の有無を判定しています。
外部からの呼び出し時は(何か特別な演出を用いるのでない限り)使用しません。
第三引数(常駐ボタンを起動しないフラグ)
判定に常駐ボタンを用いたくない場合はtrueを渡します。これは自作バックログからの呼び出し等を想定しています。
これらの引数は全てデフォルト関数内で利用しています。したがって、関数を自作する場合はこの限りではありません。
第四引数(テキストクリック待ちから呼ばれた場合にクリック待ち記号が渡される)
NSLaデフォルトのオプション環境では「@ \ @ ¥」の四種類いずれかが渡されます。
一部のテキスト系命令で自動挿入されるクリック待ちについてはその機能に準じます。
(つまり ("@" または "@")で一致判定を行えばとりあえず問題ありません。)
これはispage命令相当の機能ですが、標準で定義している関数では特に利用していません。
■NSLaデフォルトの関数で行っている処理
NSLaにおいて、デフォルトの「クリック待ち」が担う処理は以下の3つです。
@(必要であれば)常駐ボタンを定義する | デフォルトの関数では常駐ボタン設置関数[2.6.5]を(定義されていれば)自動で呼び出しますが、 そちらで定義したくない特別な理由があればここで直接定義しても構いません。 | A(bexecを用いて)クリックやボタン等の入力を取得する | bexecそのものです。特別な理由があれば代わりに旧ボタンを用いても構いませんが、様々な理由(反応速度の差、常駐ボタン設置関数との兼ね合い等)から推奨はしません。NSLaはテキストボタンを使用できない[2.18.2]点にも注意してください。 | BNSLaに結果を返す | bexecの結果に応じて起こすべきアクションを決めます。以下で詳しく解説※します。 |
●(常駐)ボタンを押したか?
常駐ボタン設置関数を呼び出してチェックしています。
特別な理由がない限りは常駐ボタン関数に任せてよいはずですが、必要であれば関数内に直接記述しても構いません。
以下に該当箇所のコードを(若干書き換えつつ)引用します。
--100番を押していた場合 if(bkekka=="S100")then --●何らかの入力を検知させたい場合 --右クリック扱いしたい場合 --bkekka="RCLICK" --ホイール上入力扱いしたい場合 --bkekka="WHEELUP" --スキップしたい場合のみsystemcallではなくこちらで行います --bkekka="SKIP" --●systemcallしたい場合(標準メニューを呼ぶ等) --NSNSrclickmove_systemcall="windowerase" --※倍角テキストモード[2.6.8]中にデフォルト回想を呼ぶとエラーを招くため、 -- lookbackのみは以下のように書く必要がある -- if(not NSNSbsmm_mul)then NSNSrclickmove_systemcall="lookback" end --●任意の命令で割り込みたい場合 (基本的には自作selnumからの呼び出しで発火させるべきではない) -- NSNSdotrap=NSNStrap --trapの発火 -- NSNSdotrap=NSNSrtrap --r_trapの発火 -- NSNSdotrap=NSNSlrtrap --lr_trapの発火 -- NSNSdotrap='caption "常駐ぼたんくりっく"' --割り込む命令を直接指定する例 -- NSNSdotrap='押 し た な ?' --テキストも通る(使い所はやや乏しい) -- NSNSdotrap='%20=57' --NSLa特有の略記やLuaコードも通る -- NSNSdotrap='*何らかのラベル' --ラベルを記述するとgotoジャンプする -- NSNSdotrap='gosub *trapによるgosubジャンプ' --[[ 【割り込む際の注意】 ※ボタンウェイトおよび標準selnumの実行中はtrapが発火しない(本来の挙動と同様)。 ※trapで割り込む命令にgosubを指定した場合のみ、やや特殊な挙動になる @「飛び先からreturnで戻るまでずっと」「trap発火中」と見なされる。 A「trap発火中は右クリックメニューが発火しない」 「独自右クリックメニュー[2.11.4](※1)の中ではtrapが発火しない」 というセーフティ機能が存在する。 詳しくはtrapによる命令割り込み[2.11]を参照。 --]] --200番を押していた場合 elseif(bkekka=="S200")then end --常駐ボタン関数[2.6.5]がセットされていたらそちらでも判定する if(not notfromtextwait and type(NSNSpermanentbuttons)=="function")then local newkekka=NSNSpermanentbuttons("check",resnum) if(newkekka)then bkekka=newkekka end end
●オートモード関連の処理
オートモード[2.12]中であるか、オートモードの切り替わりが発生するかどうかを判定します。NSLaにおけるオートモードの扱いは当該項目を参照してください。
if(bkekka=="AUTO" or (bkekka=="TIMEOUT" and NSNSautomode))then if(bkekka=="AUTO" and NSNSautomode)then NSNSautomode=false else bkekka="WHEELDOWN" NSSystemCall("automode") --「ボイス鳴ってる間は待つ」の処理(自身を再帰的に呼び出す) --NScripterDS.dllまたはNSOgg2.dllが前提、前者はろだのラッパー(nds関数)利用が前提 if((type(NSNSexistogg2)=="string" and type(nds)=="function" and nds("isplaying",NSNSexistogg2)==1) or (NSNSexistogg2 and NSOggIsPlaying(0)))then return NSNSclickwait(frommyselnum,100) end end end
●デフォルトおよびNSLa追加分の入力判定
以下の判定を行っています(コードは省略)。
クリック(相当のキー)
右クリック(相当のキー)
ホイール上(回想呼び出し)
F11(デバッグコンソール呼び出し)
F12(リセット)
単に特定のキーをクリック扱いする場合などはここに加筆すると良いでしょう。
ツクール系列に揃えたZキー読み進めなどを足しておくと便利かもしれません。
●オートモードを止める入力だった場合はskipoffする
●結果をreturnする
bkekka(文字),resnum(数字)
の二つを返しています。
以上がデフォルト関数で行われている処理です。
大多数を占めるであろうノベル用途では、デフォルト関数(と常駐ボタン設置関数[2.6.5]の調整)でおよそ事足りると思います。
■関数を改変すべき場合
ここで想定するシチュエーションは
「ゲームパッド主体のジャンルにおいて、ゲームパッドの入力をテキスト送りに使いたい」
というものです。
たとえばNScripterで弾幕STGを制作するならば、当然プラグインを用いてゲームパッドに対応するべきです。
しかしデフォルトのクリック待ち(およびbexec)はパッドの入力を検知出来ません、標準テキストの利用に問題が生じます。
その場合標準テキストを諦めるか、検知可能なbexecを自作するか、この関数を改変または自作する必要があります。
繰り返しになりますが、この関数を自作する場合、最低限行うべき処理は以下の3点です。
@(必要であれば)常駐ボタンを定義する
Aクリックやキーやボタン押下等の「入力」を検知する
B結果(何が入力された事にするか)を返す
入力検知、つまりAの箇所を改変する場合、
btimeを短く設定した上でbexecとプラグイン側の入力チェックを同時に行う
bexecを使わず自力で入力を取得する
といった方法が考えられます。
text0 | テキストの先頭で呼ばれ、これから処理する予定の文字列が引数として渡されます。文字列を返せばそのテキストにすり替え、falseを返せばテキスト表示を中止します。 ★zenkakko、pretextgosubとの兼ね合い |
text | 呼ばれません ※クリック待ち時の挙動はNSNSclickwait()[2.6.6]で処理されます。 |
puttext |
非推奨です(テキストも: で区切れるため意味がない&テキストに伴うべき機能が一部働かない)
|
;パターン1 IF (条件式の否定) :skip (以下の処理をちょうど飛ばすだけの行数) 〜条件を満たした場合の処理〜 IF (条件式の否定) :skip (以下の処理をちょうど飛ばすだけの行数) 〜条件を満たした場合の処理〜 ;パターン2 IF (条件式) :〜条件を満たした場合の処理〜 :goto *label IF (条件式) :〜条件を満たした場合の処理〜 :goto *label *label ;パターン3 IF (条件式の否定) :jumpf 〜条件を満たした場合の処理〜 ~
NSLaの条件分岐には大きく文法が追加され、複雑な分岐を容易に記述できます。
NSLaにおけるifの最も基本的な形は以下の通りです。
「if節の処理を複数行に分けて書ける」点が素のNScripterとの大きな差です。
if(条件式) 〜 条件を満たした場合の処理 〜 end
条件式にはNScripterおよびLuaとほぼ同じ演算子を使用できます。
(実際には条件式の記号を内部で置換し、Luaコードとして真偽を判定します。)
【>】 【>=】 【<】 【<=】 | 「大小(または辞書順)の判定」 |
【==】 | 「等しい」 |
【~=】 【!=】 【<>】 | 「等しくない」 |
【and】 【&&】 | 「かつ」 |
【or】 【||】 | 「または」 |
【(〜) 】 | 「括弧内の判定結果(真偽)を一つの項と見なす)」 (多重に記述可能) |
【not hoge】 | 「否定(項hogeが偽である)」 |
【+】 【-】 【*】 【/】 | 数値の加減乗除を行います。 |
【%】 | 剰余(割った余り、mod)を計算します。 数値変数と区別するために%の直後には空白を入れてください。 |
【%変数名】 【$変数名】 | NScripter変数へのアクセスを意味します。 |
【変数名】 | Lua変数へのアクセスを意味します。 エイリアス参照ではない点に注意してください。 |
「else
」は「条件を満たさなかった場合に以下を処理する」を意味する予約語です。ifと組み合わせて使用します。
if(条件式) 満たした場合の処理 else 満たさなかった場合の処理 end
「elseif
」または「elif
」は「直前までの条件式を満たさなかった場合にのみ判定」を意味する予約語です。ifやelseと組み合わせて使用します。
言語によって表記が様々であるため方言として二語を予約していますが、基本的にはどちらか一方のみ用いてください。
if(条件式A) Aを満たした場合の処理 elseif(条件式B) Aを満たさず、Bを満たした場合の処理 elseif(条件式C) A・Bを満たさず、Cを満たした場合の処理 else どれも満たさなかった場合の処理 end
if〜end
までの一連の処理をifネストと呼びます。
ネストの中に別のif
を記述できます(ifの入れ子)。
if(条件式A) Aを満たした場合の処理 if(条件式B) A・Bを満たした場合の処理 end end
endは従来のNScripterにおいて「本体の終了」を意味する命令でしたが、NSLaにおいては★ネスト★を閉じるための予約語として機能しています。
従来のendに相当する命令は「nsend
」および「nsbreak
」です[2.15]。
この非互換性はコンバートツールによって補正されます[2.17.1]。
NSLaのifネストには、
@「内部にラベルを記述してはいけない」
A「skipの飛び先は同一ネストでなければならない」
という制約が課されています。
詳しくはラベルの記述位置に関する注意[2.9.4]を参照してください。
そうした制限下で小規模なネスト内ジャンプに対応するために、以下の予約語が作られています。
何らかの理由からifネストの外まですぐさま離脱したい場合、「outif
」命令を利用できます。
これはforにおけるbreak
のように働く予約語です。
;ネスト0
if(条件式A)
;ネスト1
Aを満たした場合の処理
if(条件式B)
;ネスト2
outif
end
end
--outifを呼ぶとここまで離脱する
そうではなくネストを部分的に離脱したい場合、「killif
」命令を利用できます。
killifが呼ばれると、直後の引数に指定した数(省略時は2個)だけネストを離脱します。
;ネスト0
if(条件式A)
;ネスト1
Aを満たした場合の処理
if(条件式B)
;ネスト2
if(条件式C)
;ネスト3
killif 2
end
ここは飛ばされる
end
--ここまで離脱する
Aを満たした場合の処理の続き
end
条件式の直後には、必ず「改行」「:
」「then」のうちいずれかを記述する必要があります。
従来のNScripterでは:
を省略可能でしたが、NSLaでは省略できません。この非互換性はコンバートツールによって補正されます[2.17.1]。
したがって、従来通り単一の行に記述したい場合、以下のような表記をすることになります。
if(条件式) :(命令) :end
この表記を醜く思う場合、従来と同じ動作をする大文字のIF[2.7.4]の使用を検討できます。
原則として小文字で命令を記述するNSLaにおいて、唯一の例外がIFです。
IF(条件式) :満たせば以下を実行、満たさなければ次行へ移動
見ての通り互換用の命令です(「満たさなければ次行へ」という命令ですが、必要に応じて利用しても構いません。
また、IF以下はネストと見なされません(ネストが加算されません)。
この仕様は前項のネスト部分離脱処理[2.7.3]と組み合わせる際に便利かもしれません。
;ネスト0
if(条件式A)
;ネスト1
Aを満たした場合の処理
if(条件式B)
;ネスト2
Bを満たした場合の処理
IF(条件式C):killif 1
Bを満たした場合の処理の続き
end
;Cを満たした場合ここに離脱する
end
Luaのdo(ブロック要素)と似ています。
ローカル変数[2.5.1]や名前ありローカル変数(ローカルエイリアス)[2.5.2]のために存在する制御文で、
ネストを1増加させる他は何も行いません。
役割上は「if(true)」と同義です。
;ネスト0
do
;ネスト1
end
switch文はNScripterにもLuaに備わっていない構文ですが、少なからぬ言語で採用されています。 「最初に[switchの値]==[caseの値]を満たしたcase文」の直下のみを実行します。 条件分岐のための構文であり、if〜elseif〜else〜endのif節に似た機能を持ちます。
以下にswitchによる条件分岐とifによる条件分岐の比較を示します。
switch(%0) case 0 %0==0であった場合に読まれます。 case 1 case 2 複数のcaseを一つの実行分に紐付けることもできます(条件式のorに相当)。 この場合は%0==1または%0==2であった場合に読まれます。 ;case 1,2 ; カンマ区切りにすることで、複数の条件を一つのcaseにまとめても構いません。 case 3 to 10 3<=%0<=10であった場合に読まれます。 case >=100 %0>=100であった場合に読まれます。 case %1 %0==%1であった場合に読まれます。 case "あいうえお" %0=="あいうえお"であった場合に読まれます。 case あいうえお 生の全角文字に限り、""を省略しても構いません。 case abc %0==abc(半角文字はLua変数と見なされます)であった場合に読まれます。 default 条件を満たすcaseが一つもなかった場合に読まれます(elseに相当)。 default節は省略可能です。 caseとdefaultの記述順は自由です。 つまり、何れかのcaseとセットで書いても構いません。 end
if(%0==0) 0なら読まれます。 elseif(%0==1 or %0==2) 1または2なら読まれます。 elseif(%0==%1) %1なら読まれます。 elseif(%0<=10) 10以下なら読まれます。 elseif(%0=="あいうえお") "あいうえお"なら読まれます。 --elseif(%0==あいうえお) -- ※これはエラーです elseif(%0==abc) %0==abc(半角文字はLua変数と見なされます)であった場合に読まれます。 else 他に条件を満たすif節が一つもなかった場合に読まれます。 defaultと異なり、記述位置や組み合わせの自由度はありません。 end
case内部の処理を途中で終えたい場合、breakでswitch末尾のendまで離脱できます(forなどのループ中にswitchを書く場合は注意してください)。 ★case節末尾の自動breakとfallthrough命令 ★case直下はネスト0と見なされるためラベルやローカルラベルを記述できますが、
forの管理変数は暗黙的に(疑似)ローカル化され、for離脱時に元の値へ戻ります[2.5.4]。
NScripterや多くの言語同様に、breakによってループを離脱できます。
;NScripter変数で管理
for %0=1,5
ループ内部の処理
next
--Lua変数で管理(離脱時には元の値に戻る一方、内部的にはグローバル変数を利用する点に注意してください!)
for i=1,5 do
ループ内部の処理
end
「to」「step」ではなくカンマで区切ります。ステップは省略できます。
★もっといろいろ省略できる
ループ末尾はnext(NScripter風の表記)でもend(Lua風の表記)でも構いません。nextを用いれば対応関係が厳密になり相対的に記述ミスを検出しやすくなります(endはifネスト[2.7.1]の末尾にも用いられるため)が、Luaに慣れたユーザーにとってはend表記の方が自然に使えるかもしれません。
条件式の直後には、必ず「改行」「:
」「do」のうちいずれかを記述する必要があります。
管理変数にはNScripter変数、Lua変数どちらを使っても構いません。
for i in tab do
alert(tab[i]) -->変数tabの中身を次々表示する(順番は保証されない)
end
for k,v in tab do
--何らかの処理
end
for k,v in pairs(tab) do
--何らかの処理
end
--pairs以外のイテレータも使用できます。 str="1=Tanaka,2=Saitou,3=Gotou,44=松尾芭蕉" for num,value in string.gmatch(str,"(%d+)=([^,]*)") do alert(num) -->"1"→"2"→"3"→"44" alert(value) -->"Tanaka"→"Saitou"→"Gotou"→"松尾芭蕉" end ★ただし管理変数は2つまでしか記述できず、 出てくる値は事前に全て評価される(ループ途中での変更は無視される) ★困るようなら複数行埋め込みLua使ってね
--10回繰り返される %0=0 while(%0<=10)do %0++ %0回目のループです end --中身は読まれない %0=0 while(-1>999)--doはあってもなくてもいい -- end --無限ループ %0=0 while(true)do %0++ %0回目のループです end
--10回繰り返される %0=0 repeat %0++ %0回目のループです until(%0>=10) --一度だけ実行される repeat 一度だけ実行されます until(true) --無限ループ repeat %0++ %0回目のループです until(false)
jumpf/jumpb
の飛び先に名前を付けることができます。 jumpf テスト
~
ここには飛ばない
~テスト
ここに飛ぶ
goto
と拘束の弱いラベルであるかのように動作するため、NSLaでは~(チルダ)
をローカルラベルと呼ぶことにします。
例外的な挙動として、jumpf/jumpb
側で名前を指定しなかった場合、名前を問わず、最も近い場所に見つけたローカルラベルにジャンプします。
「無名のローカルラベルに絞り込んで飛ぶ」という動作ではないため注意が必要です。
jumpf
~あいうえお
ここに飛ぶ
~
ここではない
(goto/gosub/jumpf/jumpb)
は飛び先がネスト外(if
の外部)であることを期待するため、
続けてendを見つけるとデフォルトではエラーを吐きます。
この制約は、ネスト内部でスクリプト位置を移動したい場合において影響してきます。
部分的にネストを飛び出すにはkillif命令[2.7.3]を使ってください。
同一ネスト内でジャンプを行う必要がある場合、skipを用いてください。skipは同ネストへの移動を期待します。
動作オプションをNSNSjumptozeronest=nil
と設定すると、
「jumpf/jumpb
の飛び先は同じネストであることを期待する」と挙動を変更できます。
そうした場合は「ネスト内ジャンプにskip/jumpf
、ifネストからの離脱にkillif/outif
」と役割分担できますが、
一方でjumpf時にネストがずれてしまってもその場でエラーが出ず、skip同様にバグの特定が難しくなります。
以上の問題から、デフォルトではtrue(jumpfにはネスト外ジャンプを期待する)が設定されています。
gosub *テスト("あいうえお",15)
gosub *テスト "あいうえお",15
-------------------
*テスト(hoge,fuga)
$hoge,%fugaが渡されました。@
return
var hoge,fuga="あいうえお",15
gosub *テスト("あいうえお",15)
getret($0-1)
「$0」「$1」が戻ってきました。
-------------------
*テスト(hoge,fuga)
/@foo=$hoge+"かきくけこ"
return $foo,%fuga*3
trap *ラベル
NScripter命令・Luaコード・テキスト等、「NSLaにおいて単一の命令と解釈される文字列」も仕込む事が出来ます。
trap[bg "foo.png",0]
trap[$0="あいうえお"]
trap[alert("あいうえお") local a=12 alert(a)]
trap[$0="あいうえお"]
これらが発火した場合、原則として「(本来実行されるはずだった)次の命令の直前」に割り込まれます。
例外として、テキスト表示中(クリック待ち)に発火した場合は、割り込んだ命令を実行後に残りのテキストを表示します。
仕込んだ文字列の変数は(trapを定義した瞬間ではなく)発火した瞬間に評価されます。
$0="あいうえお"
trap[gosub *テスト($0)]
$0="かきくけこ"
trapさせます→@しました¥
----------------------
*テスト(str)
$strが渡されました。@/ -->かきくけこが渡されました。
return
trap "〜"
r_trap "〜"
lr_trap "〜"
"
」を含む命令に問題が出るため、対策として以下の3つが用意されています。 trap[〜]
rtrap[〜]
lrtrap[〜]
off,stop,resume
も使用できます。 trap off
trap stop
trap resume
現時点でtrap2とlr_trap2には対応していません。これはNSLaにおける非互換性の一つです。
【注】
※ボタンウェイトおよび標準selnumの実行中はtrapが発火しない(本来の挙動と同様)。
※trapで割り込む命令にgosubを指定した場合のみ、やや特殊な挙動になる
@「飛び先からreturnで戻るまでずっと」「trap発火中」と見なされる。
A「trap発火中は右クリックメニューが発火しない」
「独自右クリックメニュー(※1)の中ではtrapが発火しない」
というセーフティ機能が存在する。
※1…独自右クリックメニュー
rgosubに近い機能。
設定例は以下。
NSNSrclickmove="*hoge" --*hogeにgosub
NSNSrclickmove="rmenu" --systemcall rmenuに相当
NSNSrclickmove="" --何もしない
NSNSrclickmove=hoge() --関数hoge()を呼ぶ。【 (関数を定義してから設定する必要があります) 】
ただし、ラベルへのgosubを設定する場合はselnum命令自作が推奨される。
標準selnumでは複数の問題を起こす(※2)。
※2…独自メニューにラベルgosubを設定し、標準のselnumを使用した場合に起きる問題
selnum内で独自右クリックメニューを発火させた上で、
・飛び先ラベルでsystemcallを呼んでも反応しない
・飛び先ラベルでloadgameするとバグる(実行中だったselnumが消せずに残ってしまう)
・飛び先ラベルで多重にselnumすると元の選択肢が化ける
・飛び先ラベルでテキストを表示すると選択肢に重なって表示される
2番目の問題が比較的致命的であるため、selnumの自作を推奨することになる。
;■全て有効にする場合
;fchk()用のファイルログ
filelog "flogl.dat"
;lchk()用の既読ラベルログ
NSNSkidokulabelpath="labell"
;fchk,lchkはLua関数として条件式内で呼び出します。
;既読スキップ用のテキストログ
NSNSkidokudatapath="kidokul"
;■全て無効にする場合
NSNSkidokulabelpath=nil
NSNSkidokudatapath=nil
kidokumode 1
です。NSNSkidokudatapath="kidokul"
既読スキップを実行中、true実行のns関数[3.2.6]に遭遇した場合の挙動をオプションで指定できます。NSNSkidokutrue=true -- trueなら 「未読テキストとして読み込み、関数を抜けたタイミングでスクリプトやラベル共々破棄」 -- falseなら「全テキストを既読扱い(停止判定を省略)し、関数を抜けるまでスキップ続行」
なお、「false実行[3.2.7]で一時的に追加された仮想スクリプト」内部のテキスト既読情報は、当該関数を抜けたタイミングで一緒に破棄されます。 ★「スクリプト先頭からの行/列」で既読フラグを保存しています。filelog "flogl.dat"
より多くの命令や自作関数でログを追加したい場合、NSNSaddfilelog("ファイル名")
の形でログに追加できます。fchk("ファイル名")
の形を用います。
if(fchk("*ラベル名")) 既知のファイルです。 end
特殊文字構文として命令中に埋め込む場合、&(fchk("ファイル名") && "true.png" || "false.png")
のように用います。
lsp 1,&(fchk("ファイル名") and "true" or "false")+".png",0,0
両者の実体はLua関数です。特に後者は引数のように埋め込むLua[2.16.2]と三項演算の組み合わせです。fchk=NSNSfchk
と代入しようとします。--複数の引数を指定すると、複雑な判定を行うことができます。 NSNSlchk({"ファイル1","ファイル2","ファイル3"},true,true) --第1引数には文字列、またはラベル名文字列が並んだテーブルを渡します。 -- この文字列がNSNSlabellogテーブルに保存されているかをチェックします。 --第1引数がテーブル(=複数の値)だった場合、第2引数で判定方法を決めます。 -- 第2引数が真なら「ファイルのうちどれかが既知なら真(or)」で判定、偽なら「全て既知なら真(and)」で判定します。
--デフォルトで以下のファイル名が宣言されています。ラベルログが不要な場合は=nilとします。 NSNSkidokulabelpath="labell" --true(既定値)ならラベル名を暗号化して管理します(メモ帳などでログファイルを開いてもラベル名は読めません) NSNSfilelabellogangou=true
if節で既読判定を行う場合、lchk("*ラベル名")
の形で用います。
if(lchk("*ラベル名")) 既知のラベルです。 end
特殊文字構文として命令中に埋め込む場合、&(lchk("*ラベル名") && "true.png" || "false.png")
のように用います。
lsp 1,&(lchk("*ラベル名") and "true" or "false")+".png",0,0
fchk()と同じく実体はLua関数です。--複数の引数を指定すると、複雑な判定を行うことができます。 NSNSlchk({"*ラベル1","*ラベル2","*ラベル3"},true,true) --第1引数には文字列、またはラベル名文字列が並んだテーブルを渡します。 -- この文字列がNSNSlabellogテーブルに保存されているかをチェックします。 --第2引数がtrueならfalseログ(仮想スクリプト内でのみ読んだ事のあるラベル名)も既知と認めます(※)。 --第1引数がテーブル(=複数の値)だった場合、第3引数で判定方法を決めます。 -- 第3引数が真なら「ラベルのうちどれかが既知なら真(or)」で判定、偽なら「全て既知なら真(and)」で判定します。
※falseで多重実行したns関数内の仮想スクリプト[3.2.7]でのみ通過したラベルを記録するか否か、オプションで設定できます。NSNSkidokulabelstrict=false(既定値) --trueの場合、仮想モード中のラベルは完全に破棄される。 --falseの場合、仮想モード中のラベルはfalseとして保存され、lchk()の第二引数が真である場合のみ既知と見なす。
入力欄が空 | デバッグモードを終わります。 |
NScripter変数 |
変数の中身をウインドウ(タイトル欄)に表示します。$hoge -->$hogeの中身を表示 カンマ( , )で区切ることで複数の変数を表示できます。$foo,$bar -->$foo,$barの中身を表示 |
変数=値 | その場でNScripter変数に値を代入します。文法は代入の略記[2.3.1]に準じます。 |
ラベル名 | ラベルが存在すれば位置を、存在しなければその旨を教えてくれます。 |
Luaとして認識される文字列 | 入力内容をその場で実行します。 デフォルトではNスク変数らしき文字を変換します。 不要な場合は埋め込みLua同様「//」に続けてください。 |
「@」で始まる文字列 |
@以降の文字で命令割り込みを予約します。 入力内容はデバッグモードを抜けた瞬間に発火します。 また、特殊な制御コマンドとして 「@」現在の発火予定を表示 「@@」発火予定の消去 「@@@」実行予定の復元(デバッグモードに入る前の内容に戻す) 「@@@@」前回の入力内容を繰り返す が用意されています。 |
上記以外 | @を省略した記述(命令の割り込み予約)と見なします。 |
「F12キーでリセット」はRPGツクール2000などに見られるショートカットキーです。クイックセーブ・ロード主体であろうサウンドノベル用途での必要性はさておき、NSLa標準の処理ではF12キーをリセットに割り振っています。
具体的には
※NSLaに限らず、NSLuaを利用する際は「リセット」に気を使う必要があります。 *start
h={} --resetする度に再定義≒初期化される
h.hoge="hoge"
*start
bg black,1
alert()
このように :alert("「次のコロンまで」がコードの範囲と見なされます。") :local a,b a=1 b=2
/.
./複数行埋め込むこともできる
埋め込んだLua内部に拡張スクリプトを記述することもできる
テキストに埋め込む事もできます。
「アニメーションコールバックまたはクリック待ち処理(NSNSclickwait[2.6.6])でF12を検知する」
「連続実行防止用にNSNSF12osippa=true
とした上でresetの実行予約で割り込む」
「拡張スクリプトがresetを実行していたら自動で必要な処理(拡張スクリプトの位置調節等)を行う」
と処理されています。
したがって埋め込んだLua関数内部でリセットを検知する場合、検知した瞬間速やかに抜け出すべきです。
(Lua変数はreset命令で変動しない=自動では初期化されないため)
NSLaにおいてリセット時にLua変数を初期化したい場合、
@拡張スクリプト内部で使う変数を単一のテーブルに格納する
A実行節先頭で定義する(ことで疑似的にLua変数を初期化する)
このような手順が考えられます。
2.15 - 拡張スクリプトの終了(nsbreak/nsend)
従来のend命令に相当します(NSLaにおいて、"end"はifネスト[2.7.1]やfor[2.8]を閉じる予約語です)。
nsbreakは現在のns関数のみ終了(離脱)し、nsendは多重実行中の全ns関数を終了させようとします[3.2.5]。
NScripter目線においては両者の違いはありません。
2.16 - スクリプトにLuaを埋め込む
★
NScripter命令の内部に埋め込む(基本的には引数として)方法と、コードを直接埋め込んで命令のように実行する方法が用意されています。
2.16.1 - 命令であるかのようにLuaコードを記述する
★
通常のスクリプトにおける命令であるかのように、Luaコードを記述することができます。
NSLa側で「Luaコードか、NScripter命令か」を自動的に解釈し、前者ならloadstring()越しに実行します。
2.16.2 - 命令にLua変数/関数を埋め込む(&hoge)
★&foo
テーブル・関数も可能だがキーに注意
2.16.3 - 命令にLuaコードを埋め込む(^^〜^^)
(単一の変数ではなく)複雑な値をNScriptr命令の引数に用いたい場合、そのようにLuaコードを記述できます。
bg ^^hoge^^,1
bg ^^foo..bar^^,1
bg ^^hoge="foo" return hoge^^,1
^^〜^^
内部には
@「(そのままreturn可能な)変数」
A「(そのままreturn可能な)式」
B「最終的に値をreturnする関数の中身」
何れかを記述してください。
あいうえお^^kakikukeko^^さしすせそ@
2.16.4 - 「:」「%」に関する注意
★「:」は命令区切りが優先されてしまう
★「`」を%と見なすオプションが有効
2.16.5 - if/forの真の姿
★条件式内部はLuaとして処理している話
2.17 - 既存スクリプトのコンバート
★@ツールでコンバートできる A手で直す必要がある(が代替手段は用意されている) B完全に対応していない(移植できない) で分けた方が良いのではないか
2.17.1 - コンバートツールで自動変換される内容
2.17.2 - 非互換性(手で書き換える必要が生じるスクリプト)
2.17.3 - 内部で管理変数を書き換えているfor
2.17.4 - 引数を持つdefsub命令
2.17.5 - 既にシステムカスタマイズしている場合
2.17.6. - NSLaが用いるluasub済み命令と衝突する場合
2.17.7 - コールバックを利用している場合
2.18 - 非対応の命令・機能
2.18.1 - definereset
2.18.2 - テキストボタン
2.18.3 - テキスト直埋めの変数操作(そういうものがあります)
2.18.4 - システムカスタマイズ(クリック待ち)専用の命令群