記事レビュー依頼:入門者がつまづきやすいトリガーとコマンドのまとめ

munokura

ユーザー
入門者の多くに、人知れず悩んでいるだろう・知られていないだろうと予想されるトリガーとイベントコマンドについてまとめました。


書き始める前に自分が想像していたのと違う仕様が多数ありました。
YADOTを参考に比較することで、多くのことを発見できました。

しかし、2003からVX-Aceのこのような解説を見たことがなかったのと、細かい調査ができていない部分が多々あると思います。

ツクール歴の長い皆さんにレビューいただければ幸いです。

いただきたいレビューとしては、下記のようなところです。

・明確に間違っている記述
・漏れている注意点
・伝わりにくい表現(ここは入門者が「意味が理解できない」と思った箇所を挙げていただければと思います)

よろしくお願いいたします。
 
最後に編集:

fspace

ユーザー
お疲れ様です。読みましたが全体的にちょっと怪しい気がします。


「自動実行」と「並列処理」の違いは他の処理と並行して実行できるかどうかです(余談ですが、「並列処理」という言葉はプログラミングではツクールと別の意味で使われることが多く、ツクールの「並列処理」に当たるものは「並行処理」と呼ばれることが多いです)。

コマンドを実行する機械のようなものを仮定すると、「並列処理」のイベントがそれぞれひとつずつ機械を所有しているのに対して、「自動実行」のイベントはみんなでひとつの機械を共有します。「並列処理」はそれぞれ専用の機械を持っているのですべて同時に実行できますが、「自動実行」はみんなで機械を共有しているので誰かの処理が終わってからでなければ次の人の処理を開始できません。

「自動実行」にしても「並列処理」にしても、コマンド列を一度機械に入れると、基本的にそのコマンド列をすべて実行し終わるまで処理を続けます。ただし、ウェイトを含むコマンドを実行した際には、ウェイト完了の条件を満たすまでの間、機械は一時的に処理を停止します。この間、同じ機械で別のコマンド列を実行することはできません。ウェイト完了の条件を満たすと、機械はまた続きから処理を再開します。

また、プレイヤー操作については、「自動実行」で共有する機械が動いていない時にしかできないようになっています。

2つの自動実行イベントも同時に動いています。
これは同時に動いているわけではなく、片方が終わった直後にもう片方が実行されるので同時に実行されているように見えるだけです。何らかのウェイトを挟むと、順番に実行されているのが観測できると思います。

「自動実行」は1フレームに各イベントのコマンド列が最大1回ずつ実行されます。「自動実行」のイベントのコマンド列中でイベントページを切り替えるか一時消去を行わないと、次のフレームでまた実行対象となるため、ループしたような状態になります(そして、常に「自動実行」の機械が動き続けるためプレイヤー操作ができなくなります)。

単純にループの最中は基本的に「自動実行」と同じと考えて良さそうです。
ループに中断処理やウェイトを含まない場合、機械は永遠にその処理を繰り返して無限ループに陥るのでゲームがフリーズします。ただし、ここに少し罠があって、ツクールのコマンド処理では一定数以上のコマンドを連続で実行しようとするとゲームがフリーズしたと判断し、強制的に処理を中断して次のフレームへと移行しようとします。その結果、無限ループに陥っているにもかかわらずゲームが動いているように見えたり、本来中断されてはならない場所で中断されることでおかしな挙動をすることがあるようです。

(ループ中について)並列処理は動いている。
前述の強制中断により、本来は動かないにも関わらず動いてしまっているものと思われます。

異なるのは、ループ中は他の「自動実行」のイベントが動作しない?ようです。
ループを実行しているイベントが機械を専有してしまっているので、他の「自動実行」のイベントはその機械がコマンドを実行し終わるまで永遠に待ち続けます。

下記では、一見止まりそうな気がしますが、例外的な動作をします。
  • 「イベントの一時消去」コマンドを使用する。
  • スイッチ等で、出現条件を変更し別ページに切り替える。
機械は一度コマンド列が入力されると、コマンド列を実行し終わるまで処理を続けます。そのため、イベントの「自動実行」の条件を満たさなくなったとしても、コマンド列を実行し終わるまでは処理を継続します。

画面上ではイベントが消え、ループが終わったかのように見えますが、ループの処理が続いたままで、自動実行イベントも動作が始まります。
前述の強制中断で何となく動いているような状態にはなりますが、そもそも無限ループはバグなので想定外の状態に陥っています。おそらく、その辺りが原因でおかしな挙動をしてしまっているのだと思います。

こちらを覚えると、「ループ」コマンドの必要性は感じないかも知れません。
実際、機械語に近いアセンブリ言語と呼ばれるものではループにラベルジャンプを使います。ループコマンドの利点はループごとにラベルの名前を考えなくていいこととかですかね。

また、ループ中と同じ条件(下記)で「自動実行」のイベントが動作しない?ようです。
動作的にはループもラベルジャンプも変わらないので同じことが起きます。


書いてはみたものの説明難しいですね……。

あまり詳しく確認せずに書いたので、もしかしたらどこか間違ってるかもしれません。
 

munokura

ユーザー
お疲れ様です。読みましたが全体的にちょっと怪しい気がします。


「自動実行」と「並列処理」の違いは他の処理と並行して実行できるかどうかです(余談ですが、「並列処理」という言葉はプログラミングではツクールと別の意味で使われることが多く、ツクールの「並列処理」に当たるものは「並行処理」と呼ばれることが多いです)。

コマンドを実行する機械のようなものを仮定すると、「並列処理」のイベントがそれぞれひとつずつ機械を所有しているのに対して、「自動実行」のイベントはみんなでひとつの機械を共有します。「並列処理」はそれぞれ専用の機械を持っているのですべて同時に実行できますが、「自動実行」はみんなで機械を共有しているので誰かの処理が終わってからでなければ次の人の処理を開始できません。

「自動実行」にしても「並列処理」にしても、コマンド列を一度機械に入れると、基本的にそのコマンド列をすべて実行し終わるまで処理を続けます。ただし、ウェイトを含むコマンドを実行した際には、ウェイト完了の条件を満たすまでの間、機械は一時的に処理を停止します。この間、同じ機械で別のコマンド列を実行することはできません。ウェイト完了の条件を満たすと、機械はまた続きから処理を再開します。

また、プレイヤー操作については、「自動実行」で共有する機械が動いていない時にしかできないようになっています。


これは同時に動いているわけではなく、片方が終わった直後にもう片方が実行されるので同時に実行されているように見えるだけです。何らかのウェイトを挟むと、順番に実行されているのが観測できると思います。

「自動実行」は1フレームに各イベントのコマンド列が最大1回ずつ実行されます。「自動実行」のイベントのコマンド列中でイベントページを切り替えるか一時消去を行わないと、次のフレームでまた実行対象となるため、ループしたような状態になります(そして、常に「自動実行」の機械が動き続けるためプレイヤー操作ができなくなります)。


ループに中断処理やウェイトを含まない場合、機械は永遠にその処理を繰り返して無限ループに陥るのでゲームがフリーズします。ただし、ここに少し罠があって、ツクールのコマンド処理では一定数以上のコマンドを連続で実行しようとするとゲームがフリーズしたと判断し、強制的に処理を中断して次のフレームへと移行しようとします。その結果、無限ループに陥っているにもかかわらずゲームが動いているように見えたり、本来中断されてはならない場所で中断されることでおかしな挙動をすることがあるようです。


前述の強制中断により、本来は動かないにも関わらず動いてしまっているものと思われます。


ループを実行しているイベントが機械を専有してしまっているので、他の「自動実行」のイベントはその機械がコマンドを実行し終わるまで永遠に待ち続けます。


機械は一度コマンド列が入力されると、コマンド列を実行し終わるまで処理を続けます。そのため、イベントの「自動実行」の条件を満たさなくなったとしても、コマンド列を実行し終わるまでは処理を継続します。


前述の強制中断で何となく動いているような状態にはなりますが、そもそも無限ループはバグなので想定外の状態に陥っています。おそらく、その辺りが原因でおかしな挙動をしてしまっているのだと思います。


実際、機械語に近いアセンブリ言語と呼ばれるものではループにラベルジャンプを使います。ループコマンドの利点はループごとにラベルの名前を考えなくていいこととかですかね。


動作的にはループもラベルジャンプも変わらないので同じことが起きます。


書いてはみたものの説明難しいですね……。

あまり詳しく確認せずに書いたので、もしかしたらどこか間違ってるかもしれません。

レビューいただき、ありがとうございます。
こんな面倒な仕様確認に付き合ってくださる事に、心から感謝いたします。


ちょっとお酒が入っているので、動作確認は明日、追加で行いたく思います。

1.自動実行・並行処理について

これは2つ以上の自動実行が1ルーチン終わる毎に次の自動実行が行われているという事でしょうか?
おっしゃるとおり、ウェイトを入れたりすれば確認できそうなので、後ほど確認します。

自動実行と並行処理が同時に動作するのは、例えば
自動実行1
自動実行2
並行処理1
並行処理2
と動いているのでしょうか?

それとも、
自動実行1
自動実行2
並行処理1<->並行処理2 (交互に動作している)
のでしょうか?

アクションゲームを作るくらい並列処理を駆使するレベルに使うのであれば、この理解は必要かと思います。

そこまで使わない場合、自動実行と並行処理の違いは、プレイヤーの操作が出来るかどうかの差しか表面には出ないということに思えます。
2000の仕様くらい明確だと助かるのですが、そうでも無さそうなので…

そうなると、現状の説明で間違っているのか?
どう説明すべきか?
がよく分からないでいます…
ここ難しいですが、まず自分が理解する必要がありますね。


2.ループ・ラベルについて

そうなると、ループは自動実行とは違う挙動となりますね。
ラベルの繰り返し処理は同じと考えて良いということですね。
ラベルのほうが応用範囲が広いので、ループの存在意義のメインは「名前を管理しないで済むこと」になるわけですね。

ループを実行しているイベントが機械を専有してしまっているので、他の「自動実行」のイベントはその機械がコマンドを実行し終わるまで永遠に待ち続けます。
ここが分からないのですが、ループ中は他の処理が動かないのが一般的なプログラムの考え方なのだと予想しています。
しかし、並行処理やイベントの移動ルートが動いているのは、矛盾を感じます。
(というか、実験して「なんで動いてる?」と思いましたから)

つまりバグ的な挙動をしてしまっているので、動作が異常に重くなっていると理解して良いでしょうか?

そして、重要なのは「ツールの使い手がどう使えば、想定通りに動作するのかを把握する事」だと考えています。
なので、最終的には途中経過を端折っても、「条件がこう揃うとこうなる」というケーススタディから入らないと使えるようになれないと考えています。
それには、根本的な原理を理解してから、まとめる方がより良い情報になるとは理解しています。

これを、うまく入門者に受け入れやすく書く…なかなか難関です(笑)

最後に「やっちゃダメなこと」のまとめに追加したほうが良いことがあったら助かります。

なにせ、自動実行は1つしか動かなくて、終わらないと次が動かないと思いこんでいた所から数時間で確認した内容なので、「本当の入門者にはこれでも足しにはなるだろうけど…」という感じで、一度公開したレベルなので。


入門者向けって、真理を全て伝えようとすると、弊害(長く複雑になり、最終的に読まれない)が起こりやすく「まずは、ここだけ理解しておけ」って境界線を見極めるのが難しいですね。

小学生の算数で、引き算を教える時に、いきなりマイナスの概念を一緒に教えないのは、そういうことなんだろうと思います。
 

munokura

ユーザー
リライトしました。

少しはマシになったかと思いますが、やっぱり長くなってしまいますね。

(入門者向けなので使いたくなかったのですが)console.log を使って、動作検証をしました。
ウェイトを入れると入れないとでは、実行順序が大きく変わるのが分かりました。
自動実行中でもウェイトを入れると他の自動実行や並列処理にシフトするのですね。

入れないほうがシンプルな動作ですが、厳密に並行した処理をしたい場合は、1コマンド毎にウェイトを入れる必要がありそうです。

適当だった知識に勘違いが多かったことと、ウェイトの効果が知れて良かったです。
アクションゲームを作ったりしている人は、この辺りは当然の知識なんでしょうね…
イベントコマンドで組んだりはしないのかも?
 
こんにちは。
分かりにくい時は図を描くべし……と思っているので、
とてもざっくり簡単に図を描いてみました。

event.pngevent_auto.png

図を描いたら、
接触や決定ボタンで開始するイベントと自動実行イベントは
開始条件と終了の仕方が違うだけで、
イベント実行中は同じ……に見えますね。
 

munokura

ユーザー
こんにちは。
分かりにくい時は図を描くべし……と思っているので、
とてもざっくり簡単に図を描いてみました。

View attachment 10018View attachment 10019

図を描いたら、
接触や決定ボタンで開始するイベントと自動実行イベントは
開始条件と終了の仕方が違うだけで、
イベント実行中は同じ……に見えますね。
自分も一度書きかけたんですが、自動実行や並行処理が複数の場合にどうなるのか等の確認をしているうちに「これにループとか混ぜると書くの無理ゲーでない?」と諦めてしまいました。

提示いただいた図は分かりやすいですが、それぞれが複数になった場合には、ここまで直感的に書く自信がありません。
ウェイトを入れるとなおさら…

1つずつのケースでウェイトも考慮しない説明で済ませたほうが入門者向けとしては正しいのかも知れませんね。
入門者では仕様確認レベルの事はやらないでしょうし…
導入部にこちらの図のような例を出して、概念を理解してもらうのが良いかも知れませんね。

記述範囲から、再検討ですかね…
 
自分も一度書きかけたんですが、自動実行や並行処理が複数の場合にどうなるのか等の確認をしているうちに「これにループとか混ぜると書くの無理ゲーでない?」と諦めてしまいました。

提示いただいた図は分かりやすいですが、それぞれが複数になった場合には、ここまで直感的に書く自信がありません。
ウェイトを入れるとなおさら…

1つずつのケースでウェイトも考慮しない説明で済ませたほうが入門者向けとしては正しいのかも知れませんね。
入門者では仕様確認レベルの事はやらないでしょうし…
導入部にこちらの図のような例を出して、概念を理解してもらうのが良いかも知れませんね。

記述範囲から、再検討ですかね…
そうですね……。

私から入門者向けに言える事は、
『自動実行は、1本の線になるように作るべき』です。

どのように実行されるのか把握できないからです。
(ぶっちゃけ、私も把握できてません)

並列処理は多少融通が利くかと思いますが、
入門者のうちは
同時に実行している処理が少ない方が把握しやすいと思います。

って、言っちゃっていいと思いますし、
これはこれでテクニックだと思います。
 

munokura

ユーザー
くろうど氏のフロー図も取り入れさせていただきました。
もう完全に入門者向けではなくなってしまったので、タイトルも変えて、導入部だけでも入門者が読んでくれれば足しになって、以降は仕様を確認したい人が読んだら良いかな…という内容になりました。
(当初の目的は達成できませんでした…)

フリーズの原因になりやすいトリガーとコマンドのまとめ

自分も並行処理がいくつも走るようなゲームを作っていませんし、普通のRPGや探索ゲームを作る分には必要ないでしょうし。

どんなもんですかねー
ホント、難しいです。
 
最後に編集:

fspace

ユーザー
お疲れ様です。やはりツクールのフリーズ対策が原因で少し混乱されている感じがします。

フリーズ時の挙動を変えるプラグインを製作してみたので、これを利用して実験してみるとわかりやすいかもしれません。

ここが分からないのですが、ループ中は他の処理が動かないのが一般的なプログラムの考え方なのだと予想しています。
しかし、並行処理やイベントの移動ルートが動いているのは、矛盾を感じます。
(というか、実験して「なんで動いてる?」と思いましたから)
これはフリーズ対策の強制中断によるものです。本来は無限ループに陥ると他の処理は一切動かなくなりますが(前述のプラグインの「継続」時の挙動)、ツクールでは強制中断によって一時的に無限ループを抜けるため、実行中のイベントとは独立した処理については動いてしまいます。

つまりバグ的な挙動をしてしまっているので、動作が異常に重くなっていると理解して良いでしょうか?
その可能性もありますが、それ以前にツクールはコマンドが十万回連続で実行されたことをもってフリーズしていると判断しているので、これ自体がそれなりに重いです。

最後に「やっちゃダメなこと」のまとめに追加したほうが良いことがあったら助かります。
前にも書きましたが、そもそも無限ループに陥っていること自体がバグなので、ループコマンドを使ったり、ラベルを使ってループさせる時には、必ずループから脱出する方法を用意しないといけません。記事中のループやラベルジャンプが不具合を起こすのも、そもそもの原因はループから脱出するコマンドが含まれていないためです。

(プレイヤーの操作ができなくなる条件について)
  • ループ中
  • ラベルでの繰り返し中
これらは自動実行のイベント実行の一部なので、「自動実行のイベント実行中」のみでいいと思います。「並列処理」のループ中にウェイトを仕込んだ場合などは普通に操作可能なはずなので。

  • ループ、ラベルによる繰り返しを、完全に終了してから別ページの出現条件を満たすようにイベントを組みましょう。
    繰り返し処理が残ってしまい、動作が重くなります。
出現条件を満たすのはループ中でも特に問題なかったと思います。ただし、前述の通り、必ずループから脱出する必要があります。

  • 自動実行のイベントを複数同時に動作させると、想定外の動作になりやすいです。
    出現条件を整理して、動作の順序を明確にして使うとトラブルを避けやすいでしょう。
記事中でこの結論に至った流れをみると、どちらかというと問題なのは「自動実行」イベントの実行中にイベントページを切り替えなかったことにあるような気がします。ただ、複数の「自動実行」を同時に起動させると動作順序がわかりづらくなるというのは確かです。

使い分けについても、2000と同じです。
  • 自動実行:プレイヤーの操作(移動やメニュー表示)ができない
  • 並列処理:プレイヤーの操作(移動やメニュー表示)ができる
個人的にはこんな感じかなと思ってます。
  • 自動実行:何らかの変化が起きた時あるいはマップ読み込み時に処理をしたい場合
  • 並列処理:毎フレーム何かを更新したい場合、あるいは何らかの値を監視したい場合
 

Attachments

  • BehaviorOnFreeze.js
    1.7 KB · 閲覧: 5

munokura

ユーザー
そうですね、まだ分かりにくい箇所・怪しい箇所があると思っています。

ツクールはコマンドが十万回連続で実行されたことをもってフリーズしていると判断しているので、これ自体がそれなりに重いです。
この処理はどこかで説明はされていないのでしょうけれども、コアにあるのですよね?
簡単に読者に示す事はできるでしょうか?(公式の説明がある方が望ましいですが)

追記
頂いたプラグインを見て「Game_Interpreter.prototype.checkFreeze」に書かれていることを確認できました。

前にも書きましたが、そもそも無限ループに陥っていること自体がバグなので、ループコマンドを使ったり、ラベルを使ってループさせる時には、必ずループから脱出する方法を用意しないといけません。記事中のループやラベルジャンプが不具合を起こすのも、そもそもの原因はループから脱出するコマンドが含まれていないためです。
それは理解しているつもりで、無限ループから脱出する方法を書いたつもりなのですが、現状では伝わらないということですね。

これらは自動実行のイベント実行の一部なので、「自動実行のイベント実行中」のみでいいと思います。「並列処理」のループ中にウェイトを仕込んだ場合などは普通に操作可能なはずなので。
「ウェイトを入れる」という必須条件(なくても重くなるだけで動きはしますが)があるので、その注意点をつけるべきでしょうか。

出現条件を満たすのはループ中でも特に問題なかったと思います。ただし、前述の通り、必ずループから脱出する必要があります。
そのとおりですね。
ただ、ループの途中で出現条件を満たしたくて、しばらくループしてからループを中断するケースが思いつかなかったので、こちらの方が無難だと思いました。

記事中でこの結論に至った流れをみると、どちらかというと問題なのは「自動実行」イベントの実行中にイベントページを切り替えなかったことにあるような気がします。ただ、複数の「自動実行」を同時に起動させると動作順序がわかりづらくなるというのは確かです。

一応、記事中に自動実行を止める方法の例として「イベントの一時消去」「セルフスイッチによるページ切替」を挙げて、ページ切替を説明するページへリンクしているのですが、現状だと伝わらないということですね。

自動実行:何らかの変化が起きた時あるいはマップ読み込み時に処理をしたい場合
並列処理:毎フレーム何かを更新したい場合、あるいは何らかの値を監視したい場合
使い方の方針としては、そうだと思います。

現状の説明では、「具体的にこうなる」が先に出ていて、その後に「だから、こういう使い方をする方が良い」という流れになっています。
(Yadotをベースに書いたので、そうなった感じですね)


やはり、入門者向けの部分は単体で切り離して書き直したほうが良さそうですね。
ウェイトを入れれば、挙動が変わって使えるというのは、かなり使い込んだ人向けの説明だと思います。

今日は、初心者向けに切り出した記事を別に切り出します。
その後に、その応用ができる裏技的仕様(自分はウェイトを入れるのは普通は場面で待たせるために使うと思っています)を説明するための記事として、現記事から、入門者向けの箇所を削ろうと思います。
 

munokura

ユーザー
切り分けました。
頭が整理しやすくなったように感じます。


見返して、ループの検証がイマイチなので、条件を洗い出し直してみます。
そもそも、並列処理と自動実行全体がループするわけで、必要性のある条件を…

むしろ、ループ処理のトリガーが並列処理・自動実行で使われる事が考えにくいので、別トリガーで実行する場合の並列処理との関係性や注意点の方が価値がある内容に?
 
最後に編集:

fspace

ユーザー
お疲れ様です。



自動実行と並列処理の違いの方は概ねよさそうです。

ただ、若干次の部分は気になります。
(他のトリガーについて)トリガーとなる条件が満たされた時に、「一度だけ」実行内容のイベントが実行されます。
「自動実行」や「並列処理」の特徴部分の記述との対比なのはわかるのですが、「自動実行」や「並列処理」も一度だけ実行されるという挙動には変わりなくて、単に(イベントページが変わったりしない限り)常に条件が満たされているというだけです。実行を終えた直後にまた条件が満たされるので繰り返されているように見えるだけで、原理的には「イベントから接触」のイベントが最速でプレイヤーにぶつかり続けているのと同じような状態です。しかし、まあ……こういう正確な説明をすべきかどうかは微妙なところです。

「自動実行」「並行処理」と大きく違うのはこの点です。
イベント実行中はプレイヤーが動けません。
この二行の間に空行を入れた方がいいかもしれません。最初「この点」の対象を読み違えました。



仕様調査の方はフレームが切り替わるタイミングも含めて動作順を確認するとわかりやすいかもしれません。ウェイト系のコマンドが入った時にコマンド実行が一時停止されるのが確認できると思います。あとはcheckFreezeのフリーズ判定の条件を20回くらいに書き換えて実験するとログが読みやすくなると思います。

ループに関しては動作が重い軽いというよりも、無限ループはバグだと言ってしまった方がいいと思います。現在の記述だと、重いからやめましょうというように読めてしまいます。ツクールのフリーズ緩和処理はバグが発生した際の影響を抑えるためのものであって、それを前提とした処理を書いていいわけではないので。
 

munokura

ユーザー
レビューありがとうございます。

ただ、若干次の部分は気になります。

「自動実行」や「並列処理」の特徴部分の記述との対比なのはわかるのですが、「自動実行」や「並列処理」も一度だけ実行されるという挙動には変わりなくて、単に(イベントページが変わったりしない限り)常に条件が満たされているというだけです。実行を終えた直後にまた条件が満たされるので繰り返されているように見えるだけで、原理的には「イベントから接触」のイベントが最速でプレイヤーにぶつかり続けているのと同じような状態です。しかし、まあ……こういう正確な説明をすべきかどうかは微妙なところです。

言われてみて、「あぁ、そういう事なのか…」という感覚はあります。
しかし、記事を分けた理由となる読者対象には混乱を増やすだけのように思えます。
また、そこを理解していなくても、ツールの使い方としては弊害がないと考えて、ここはそのままにしようと思います。

この二行の間に空行を入れた方がいいかもしれません。最初「この点」の対象を読み違えました。
行を空けて、少し強調気味な文章に変えました。

仕様調査の方はフレームが切り替わるタイミングも含めて動作順を確認するとわかりやすいかもしれません。ウェイト系のコマンドが入った時にコマンド実行が一時停止されるのが確認できると思います。あとはcheckFreezeのフリーズ判定の条件を20回くらいに書き換えて実験するとログが読みやすくなると思います。
取り急ぎ、現状のスクリーンショットから読み取れる実行順を書き出しました。
これで、少しは伝わりやすくなったでしょうか?

ループに関しては動作が重い軽いというよりも、無限ループはバグだと言ってしまった方がいいと思います。現在の記述だと、重いからやめましょうというように読めてしまいます。ツクールのフリーズ緩和処理はバグが発生した際の影響を抑えるためのものであって、それを前提とした処理を書いていいわけではないので。
取り急ぎ、文脈で変にならない場所には「バグ」というワードを差し込むようにしました。
ウェイトを入れると動く(狙ってループさせる)ケースもありそうなので、片っ端からバグというのは難しいなーという印象です。

今回、最も意外だった仕様

ループ中に「出現条件」を満たしたイベントで、「トリガー:自動実行」は動かないが、「トリガー:並列処理」は動く。

素人的には、これが不自然に感じました。
 

munokura

ユーザー
ループ中に「出現条件」を満たしたイベントで、「トリガー:自動実行」は動かないが、「トリガー:並列処理」は動く。
ここ、ちょっと怪しいので、再検証します。
 

fspace

ユーザー
取り急ぎ、現状のスクリーンショットから読み取れる実行順を書き出しました。
これで、少しは伝わりやすくなったでしょうか?
えと、すみません。これに関しては記事がわかりづらいという意味ではなく、フレーム移行のタイミングも含めて確認するとmunokuraさんの理解が深まるのでは、という意味でした。ところどころ理解が怪しそうな部分があったので、もしかしたら1フレームあたりの処理内容が理解できていないのではと思った次第です。

記事については、スクショから読み取るより見やすくなったので、これはこれでいいと思いますが。

ウェイトを入れると動く(狙ってループさせる)ケースもありそうなので、片っ端からバグというのは難しいなーという印象です。
「自動実行」内で無限ループをつくった場合には、ウェイトがあっても操作できなくなってしまうので明らかにバグですね。「並列処理」内で無限ループをつくった場合には、ウェイトを入れると一応動くはずなので確かにバグとは言い切れないかもしれません。ただ、そもそも「並列処理」自体が毎フレーム実行される処理を表していて、ループをつくらずとも繰り返し実行されることを考えると、わざわざループとウェイトによって内部に同じような仕組みを構築するのはかなり特殊な書き方だとは思います。少なくともコアスクリプトを読めない読者が書くべきではないかな、と。

ループ中に「出現条件」を満たしたイベントで、「トリガー:自動実行」は動かないが、「トリガー:並列処理」は動く。
ループから脱出さえしていれば「自動実行」でも動きそうな気がしますが、何か別の「自動実行」のイベントが終了していないのでは?
 

munokura

ユーザー
ループ中に「出現条件」を満たしたイベントで、「トリガー:自動実行」は動かないが、「トリガー:並列処理」は動く。
検証しなおし、トリガーに関わらず動く事が確認できました。
多分、検証途中で設定ミスをして勘違いしたのだと思います。
この箇所は削除しました。

並行処理内のループについては、確かにかなり無理がある作りだと思います。

記事中に「自動実行」「並行処理」でのループは使用例を書いていない。
ウェイトで動いてしまうという事実。
それを理解している人が初見で読んだ場合「いや、動くからバグじゃないだろ」と思う。

という点から、これ以上追記しなくて良いのでは?(これ以上をやりたかったら、自分で検証するでしょうし)という考えで、この記事はこの辺りで仕上がったと考えています。
 
最後に編集:

munokura

ユーザー
今回、仕様確認をして「自分だったら、こうは作らないが、やったらどうなる?」を色々試して、ダメなことや、意外とOKだったことがあり、学びがありました。
また、自動実行が複数でも順に動作するというのも同様です。

ご指摘いただいてから、ログで確認していくことで、かなり理解が進んだと思います。
(自分がこんな複雑な処理を使うことがあるか疑問はありますが…)

トリガー単体の記事については、入門者に読んでいただけるように仕上がったと感じていて、入門者がつまづきそうな点をクリアできたかな?と思っています。
 

munokura

ユーザー
過去に並列処理だったかのイベント全体をループさせて不具合がある質問者がいたのを思い出しました。

ので、「全体を通して、注意点まとめ」に下記を追記しました。

「トリガー:自動実行」「トリガー:並列処理」のイベントでは、明確な停止処理がされるまでイベント全体が繰り返し実行されます。
このため、この中で「ループ」「ラベルジャンプ」を使用した繰り返し処理を入れるとバグが発生しやすいため、非推奨です。
 

fspace

ユーザー
並行処理内のループについては、確かにかなり無理がある作りだと思います。

記事中に「自動実行」「並行処理」でのループは使用例を書いていない。
ウェイトで動いてしまうという事実。
それを理解している人が初見で読んだ場合「いや、動くからバグじゃないだろ」と思う。

という点から、これ以上追記しなくて良いのでは?(これ以上をやりたかったら、自分で検証するでしょうし)という考えで、この記事はこの辺りで仕上がったと考えています。
すみません、無限ループをバグとした方がいいと書いたことから少し話がずれてしまいましたが、自分が問題を感じているのは、ウェイトさえ入れれば無限ループ自体は問題ないと誤解させかねない記述がいくつかあることです。

例えば、最初の注意点にある
並列処理、ループ(及びラベルによる繰り返し)は、ウェイトを入れることで、より平行な処理を行う事も可能です。
という記述は、「並列処理」以外のトリガーのイベントに、ウェイトを含むループをつくることで並行に処理が行えるように読めてしまいます。しかし、実際にこれを行うとプレイヤー操作ができなくなってしまいます。

また、この事実自体は4.2節に書かれていますが、4.3節のループを止める方法との関連性が書かれていないため、プレイヤーが操作不可になってしまう(あるいは4.1節の通り非常に重くなってしまう)からループを脱出しなければならない(無限ループにしてはならない)、という流れが明確になっていないように思います。

あと、少し「無限ループ」という言葉の使い方が変な感じがします。終了しないループのことを「無限ループ」と呼ぶので、次の部分は少し冗長です。
下記では、一見止まりそうな気がしますが、ループが完了せずに、例外的な動作をします。
これは無限ループのバグが発生します。
また、次の部分も少しおかしな表現に感じます。
ループを完了する時は、完全に完了するように処理に注意しましょう。
ループが完全に完了しないと、異常に重くなったりフリーズします。
これは処理からの観点から、無限ループのバグと言えます。
「ループは必ず終了するようにしましょう。無限ループになると、処理が異常に重くなったり、予想外の挙動をすることがあります。」くらいでいいんじゃないでしょうか。あるいは「ループは必ず『ループの中断』や『ラベルジャンプ』と一緒に使いましょう」でもいいかもしれません。

過去に並列処理だったかのイベント全体をループさせて不具合がある質問者がいたのを思い出しました。

ので、「全体を通して、注意点まとめ」に下記を追記しました。

「トリガー:自動実行」「トリガー:並列処理」のイベントでは、明確な停止処理がされるまでイベント全体が繰り返し実行されます。
このため、この中で「ループ」「ラベルジャンプ」を使用した繰り返し処理を入れるとバグが発生しやすいため、非推奨です。
イベント全体をループさせることに問題があるのであって、「ループ」や「ラベルジャンプ」自体を非推奨とするのは少し言い過ぎじゃないかと思います。また、もう少し詳細な説明がないと「このため」の意味が理解できないと思います。
 

munokura

ユーザー
ご指摘いただいた点、再考し変更しました。
こんなところで、いかがでしょうか?

  • 自動実行は1つずつ動作が完了する前提で作りましょう。
    ウェイトを入れると他の処理が動作したりするので、出現条件に関わらないように注意しましょう。
  • 並列処理はウェイトを入れることで、より平行な処理を行う事も可能です。
  • ループ(及びラベルによる繰り返し)は必ず『ループの中断』や『ラベルジャンプ』と一緒に使いましょう。
    ループが完全に完了しないと、異常に重くなったりフリーズします。
  • 自動実行と並列処理のイベントでは、明確な停止処理がされるまでイベント全体が繰り返し実行されます。
    このため、この中で「ループ」「ラベルジャンプ」を使用した繰り返し処理を入れる必要性が低く、使い方を間違えるとバグが発生しやすいため、注意が必要です。
 
トップ