このトピックが適切なフォーラムかどうかはわかりませんが、とにかく聞いてみます。
以前は eval() 関数を使ってスクリプトを書く人がいたと聞きますが、MZ ではイベント内でスクリプトを書くための「スクリプト」コマンドが用意されているため、あの関数は現在では obsolete と見なされているのでしょうか?
このトピックが適切なフォーラムかどうかはわかりませんが、とにかく聞いてみます。
以前は eval() 関数を使ってスクリプトを書く人がいたと聞きますが、MZ ではイベント内でスクリプトを書くための「スクリプト」コマンドが用意されているため、あの関数は現在では obsolete と見なされているのでしょうか?
つまり、
eval("");
は MZ の機能ではなく、JavaScript のビルトイン機能です。
この関数は文字列を解析するためのものです。
そして、scriptCommands は実際にはただの Eval です。
Game_Interpreter.prototype.commandScript = functions() {
eval(parameters[0]);
}
人々が eval が良くないと話す理由は、それ自体が非常に不安全であるためです。ただし、それはまた別の話題になります。
私はそれをゲーム内のイベントベースのデバッグコンソールとして使っていました。
それは愚かでした。F12 を押せばウェブブラウザの DevTools コンソールが開けるからです。しかし、MV や MZ が登場した当初、私はそこに直接入力できることを知りませんでした。
言い訳にはなりますが、コンソールログを開くとすぐに、通常 2〜3 つの非推奨コードの警告が表示されていました。それに、XP や VXAce の古いデバッグコンソールは黒背景で、古い DOS の入力画面のように明らかな点滅カーソルがありました。一方、DevTools ウィンドウは白背景でタブ付きでした。
evalの役割は「JavaScriptのコードを実行する」ことで、実行対象は変数にもなります。つまり、ゲーム実行中に動的に実行する内容を変更できるのです。一部のプラグインでは、この関数を使ってユーザーがインターフェースの表示内容を「手動で設定」できるようにし、カスタマイズされたインターフェースを実現しています。もしJavaScriptの知識があれば、この関数を使ってゲーム中にメニューのスタイルを切り替えることも可能で、それは『Evolution』のような体験になります。
総じて言って、この関数が「時代遅れ」になることはありません。
もう一つ考慮すべき点は、eval() で実行される JavaScript は、プラグインとして記述された JavaScript と比べて数千倍も遅いということです。残念ながら RPG Maker では、ユーザーがカスタム数式を記述できるようにするために、ダメージ計算などで eval が多用されています。また、データベースに記述したプラグインでサポートされるコードは、すべて eval を通じて実行される必要があります。
必ずしもそうではない。多くのプラグインは確かに eval を使っているが、もしコードのコンパイルに load 時に Function コンストラクタを使うのであれば、eval を直接使うよりもずっと高速になるはずだ。
それは大きな「もし」の話ですね。特にYanflyのプラグインはそうはなりません。
それを使わないのが残念です。問題は、呼び出せるものが限られていること(サンドボックスのように動作するため)にあると思います。
わあ、もう古いフォーラムにあった「複数引用返信」機能が恋しくなってきました。
eval() はもうあまり使われていないと思っていたのですが、皆さんが指摘してくれたことと、それが「高度な設定」>「スクリプト…」でどのように処理されるかを考えると、並列イベントをプラグインに変換し始める必要がありそうです。皆さん、ありがとう!
複数引用もできます。引用したいテキストを選択すると、このオプションが表示されます。私は20個以上の個別の投稿に引用返信して、痛い目を見てから学びました(笑)。
evalの使用は問題ありません。パフォーマンスを過度に心配する必要はありません。同じevalを毎フレーム実行しない限り、大丈夫です。もしかしたら、毎フレーム実行することすら問題ないかもしれません。
ただし、すべてのイベントが毎フレームevalを実行するような場合、それは絶対に避けるべきです。
いえ、実はそうじゃないんです。プレイヤーが移動しているかどうかを確認する並列イベントで実行しています。現状はこんな感じです:
そこにたどり着く前に面白いことに気づいたのですが、プレイヤーキャラクターが各タイルの正確な .0 座標に到達すると、ゲーム内では「移動していない」と判定されてしまいます(そのため、プレイヤーに2タイル移動するよう指示すると、移動→停止→移動→停止という動きになります)。そして、なぜか前者のチェックの方が後者よりも更新が遅いのです。
私の唯一の問題は、これをプラグインにどう変換すればいいかよくわからないことです。少なくとも実践面では、前回の試みはほぼ失敗に終わってしまいました。
ふむ、あの2番目のifの代わりに、前のコマンドのelseを使ってみるのはどうだろう?
……なるほど。なぜそれに気づかなかったんだろう。試してみても、まだ同じように動きます。
スイッチや変数を変更するたびに、マップ上のすべてのイベントに対して更新リクエストが送信されることに注意してください。動作が遅く感じられる場合、それが原因である可能性が高く、イベント数が多いマップほどこの影響が蓄積されます。これが、私が通常、イベントシステムを使ってゲームのメカニクスをコーディングすることを避けるよう推奨する主な理由の一つです。
そのイベントシステムが持つ一般的な要件を考えると、少なくとも思い付く限りでは、その更新は1フレームに1回以上実行されるべきではありません。通常、変数やスイッチの変更はフラグを有効化し、エンジンに次のフレーム(またはその頃)にすべてのイベントを再更新するよう要求するものです。
少なくともRGSSではそのように実装されていました。何か別の事情で、即時にすべてを再更新する必要があると判断された場合を除きます。
その意味がわかりませんか?それは確かにサンドボックスとして機能しますね。つまり、プラグインの内部がカスタムコードに誤って公開されることはありません。しかし、ここで「不調(wonky)」という言葉が何を意味するのかは理解できません。
それが行う処理です。つまり、50個の変数を一度に変更し、それらがすべて更新を要求した場合でも、実際に実行される更新は1回だけです。
しかし、イベントの場合、1フレームごとに実行されるコマンドは1つだけです。したがって、50個の「変数の操作」コマンドが連続してある場合、それは50回の更新になります。一方、1つの「変数の操作」コマンドで50個の変数を変更する場合、それは1回の更新です。
スコープに関する話ですが、eval よりも function() の方がより厳格であるという点もあります。以前、奇妙なエッジケースに遭遇したことがありましたが、今すぐには思い出せません。
Function コンストラクターには、完全な関数である必要があるという欠点があります。eval とは異なり、最後のステートメントの結果だけを返すわけではありません。あなたが考えているのは、もしかしてこれでしょうか?
はい、そうだったと思います。ただし、eval/関数による文字列パースでテストしたのは、かなり昔のことです。
これは場合によっては機能しますが、すべてで機能するわけではなく、eval には new Function() よりもいくつかの利点があります。主に使いやすさです。パフォーマンスが重要な処理(フレームごとのループで毎回呼び出される処理など)を行っていないのであれば、eval は問題なく、パフォーマンスに目に見える低下をもたらすことはありません。
不必要に new Function() を使用すると、場合によってはコードの取り扱いや保守が困難になる可能性があります。