コマンドコードによるイベントコマンドの入力について

イベントコマンドをコマンドコードで入力する際、意図しない数の数値引数・文字列引数が渡されても、一定の条件下であれば正常に動作する。

例えば、「文章の表示」コマンドのコードは本来以下のようなコマンド文だが、

WoditorEvCOMMAND_START
[101][0,1]<0>()("表示する文章")
WoditorEvCOMMAND_END

以下のようなコマンド文も受け付ける。

WoditorEvCOMMAND_START
[101][3,4]<0>(65535, 111111, 1234567)("表示する文章","無駄な文字列","","ABC")
WoditorEvCOMMAND_END

このコマンド文をマップイベントやコモンイベントに貼り付けたあと、その行をコマンド文としてコピーすると上記の内容が復元される。

ゲーム上での動作はどちらの場合も同じ。

その他、ウディタから得られるコマンドコードとは異なるフォーマットでも、コマンドコードとして受け付けられる事がある。

コマンドコードの仕様

受け付けるコマンドコードの条件は以下のとおり。

  • コード始端が "WoditorEvCOMMAND_START" であること、コード終端が "WoditorEvCOMMAND_END" であること。

    前後に半角スペースなどを含んでいても(=コード始端が"WoditorEvCOMMAND_START "となっている等)コマンドコードとして認識されなくなる。

  • コマンドコード本体の行頭に余計な文字を含まないこと。

    各コマンドコードの行頭は "[" で始まる必要がある。

  • インデントの整合性が取れていること。

    インデント0の箇所にインデント1のコードを貼り付けることはできない。

  • 数値引数の数が126個以下であること。

    127個以上の数値引数を持つコードを貼り付けてもエラーは発生しないが、該当のマップやコモンイベントを再度読み込むとエラーが発生し、読み込めなくなる。

  • 文字列引数の数が127個以下であること。

    128個以上の文字列引数を持つコードを貼り付けてもエラーは発生しないが、該当のマップやコモンイベントを再度読み込むとエラーが発生し、読み込めなくなる。

  • 本来使用する文字列データについて、バリデーションエラーが起きないこと。

    分岐条件(文字列)の右辺やコモンイベント呼び出し時のイベント名などに長過ぎる文字列を指定するとエラーが発生する。

以下はエラーなどは発生しないものの、意図した動作をさせるために必要な条件。

  • 文字列引数が "" で囲まれていること。

    以下のようなコマンドを貼り付けたあと、

    WoditorEvCOMMAND_START
    [101][0,2]<0>()("表示する文章",文章を表示します)
    WoditorEvCOMMAND_END

    これをコマンド文としてコピーすると以下の内容に変化する。

    WoditorEvCOMMAND_START
    [101][0,2]<0>()("表示する文章","カ章を表示します) ")
    WoditorEvCOMMAND_END

以下はエラーなどが発生せず、ウディタ側がよしなに解釈・補正を行う。

  • 数値引数、文字列引数の数と実際に与えられた引数の数が異なる。

    指定された数値引数、文字列引数の数が優先される。

    足りないデータは 0 または 空文字 が設定される。

    余分なデータは切り捨てられる。(再度コマンドコードをコピーしてもその内容を復元できない)

  • 数値引数に 2000000001~2147483647 が指定されている場合。

    2000000000 に変更される。

  • 数値引数に 2147483648 以上の値が設定されている場合。

    4byte を超える部分は無視される。

    なお、ウディタ内では数値データを 符号付き32bitInteger で扱っている。

  • コード先頭以外に半角スペースが含まれる場合。

    以下のようなコマンコードは

    WoditorEvCOMMAND_START
    [121][4,0]<0>(1100000,2 55,0,4096)()
    WoditorEvCOMMAND_END

    以下のコマンドコードとして解釈される。

    WoditorEvCOMMAND_START
    [121][4,0]<0>(1100000,255,0,4096)()
    WoditorEvCOMMAND_END
  • 行末に何らかの文字列を含む場合。

    以下のようなコマンドは

    WoditorEvCOMMAND_START
    [101][0,1]<0>()("アメンボ赤いなあいうえお") # ここはコメントです
    WoditorEvCOMMAND_END

    以下のコマンドコードとして解釈される。

    WoditorEvCOMMAND_START
    [101][0,1]<0>()("アメンボ赤いなあいうえお")
    WoditorEvCOMMAND_END
  • コマンドコード番号に意図しない値を指定する。

    以下のようなコマンドコードも受け付ける。

    WoditorEvCOMMAND_START
    [456][0,1]<0>()("意図しないコマンドコード番号その1")
    [1234][0,1]<0>()("意図しないコマンドコード番号その2")
    WoditorEvCOMMAND_END

    ただしウディタ上では下図のように表示される。ゲーム上では何も起こらない。

    ウディタ上での表示
    仕様外のコード番号を与えた場合の表示

    処理負荷については後述。

    この状態でウディタを再起動すると、仕様外のコードを記述した部分が正しく選択できなくなる場合がある。

    右図のコード456のコマンドの場合

    選択すると1行上のイベントコマンドも同時に選択状態になる。

    1行上のイベントコマンドのインデントが異なる場合、選択そのものが解除される。

    このコマンドを1行目に設置した場合はウディタ上から消すことのできないイベントコマンドと化してしまう。

以下仕様が不明なもの。

  • "本来使用しない"文字列引数の文字数上限

    5600万byte強(≒53MB以上)の文字列データを正しく読み書きできることを確認。

    特に制限が設けられていない場合、2147483647byte(≒2GB)まで扱えるはず。

仕様外イベントコードの処理負荷

結論

動作コストは「空白行」コマンドよりもわずかに高く、 "Cself0 = 0 + 0" よりも低い。

以下、筆者の環境で確認した際のメモ

「テスト対象のコード」を10万回ループさせ、その実行時間を計測する。

10万回のループそのものを12回ループし、3~12回目の実行時間を計測対象とする。

テスト時の実行環境では1~2回目の実行結果が3回目以降に比べて安定しなかったため。

計測対象コードとは別に計測用のコモンイベントを用意する。

このコモンイベントは前回実行時間(システム変数で取得できるプレイ時間)と今回実行時間の差をデバッグ出力する。常時並列実行される。

実際の計測コードは以下のようになる。

WoditorEvCOMMAND_START
[180][1,0]<0>(1)()      # 開始前に1フレームのウェイトを挟んでこれ以前の影響を受けないようにする。
[179][1,0]<0>(12)()     # テストコード計測ループ(12回ループ)
[179][1,0]<1>(100000)() # ┃ 10万回ループ
[0][0,0]<2>()()         # ┃ ┃ ここに計測コードを記述する。この場合だと空白行が計測対象コード。
[498][0,0]<1>()()       # ┃ ループ終了
[180][1,0]<1>(1)()      # ┃ 1フレームのウェイトを挟むことで、並列実行する計測コモンイベントの結果を確定させる。
[0][0,0]<1>()()         # ┃
[498][0,0]<0>()()       # ループ終了
WoditorEvCOMMAND_END

計測結果は以下のとおり。

空白行のみ 空白行なし マップイベント
Self0 = 0 + 0
コモンイベント
Cself0 = 0 + 0
仕様外コマンド
(引数なし)
1回め 0.020s 0.014s 0.097s 0.033s 0.022s
2回め 0.019s 0.017s 0.097s 0.034s 0.022s
3回め 0.019s 0.014s 0.096s 0.032s 0.020s
4回め 0.021s 0.018s 0.099s 0.033s 0.024s
5回め 0.020s 0.015s 0.097s 0.032s 0.025s
6回め 0.020s 0.017s 0.096s 0.033s 0.022s
7回め 0.021s 0.014s 0.098s 0.033s 0.022s
8回め 0.019s 0.019s 0.096s 0.033s 0.024s
9回め 0.021s 0.013s 0.096s 0.037s 0.020s
10回め 0.020s 0.019s 0.099s 0.032s 0.024s

空白行なしのイベントコード

空白行なしのイベントコード
WoditorEvCOMMAND_START
[179][1,0]<0>(12)()
[179][1,0]<1>(100000)()
[498][0,0]<1>()()
[180][1,0]<1>(1)()
[0][0,0]<1>()()
[498][0,0]<0>()()
WoditorEvCOMMAND_END