スクリプトの動作が不安定な理由がわかりません

スクリプトの動作が不安定な理由がわかりません

- teddy Dragoone の投稿
返信数: 6
いまShimakamiリージョンにてハントを行っていますが、それに使用しているスクリプトについて。
昨日までは正常に思惑通りに動作していました。

簡単に説明します。
1.メインプリム ← ここに boo(オバケのオブジェクトを入れて、タイマーでREZします)


2.boo ← 3種類あって、いずれもREZされると、回転を始めて誰かがタッチするまで待ちます。
      60秒たっても誰もタッチしないとllDie()で消します。
      (1)クイズに正解するとカボチャをREZするか、もしくはなにもしないもの。
      (2)黄色いbooは正解すると10JPが送られます
      (3)タッチしても何もおこらず、ただ消えてしまいます。

今回の動作が不安定なのは、1のメインプリムがREZしたbooのスクリプトが起動されたりされなかったりする現象です。
REZされても回転が始まらず、タッチも効きません。
同じbooを入れた他のメインプリムでは正常に起動したりします。

同じ条件のものなのに動いたり動かなかったりする理由がわからず困っています。

1のメインプリムはすでにbooがREZされている状態では追加でREZしないようにしていますので、先にREZしたbooのスクリプトが起動せず消えないのでは、ずっと何も出来ず仕舞いになっています。

シムを再起動すれば直るのであれば再起動をお願いします。
この現象がオープンシムだから起きるのかどうなのか。よくわからないです。

teddy Dragoone への返信

Re: スクリプトの動作が不安定な理由がわかりません

- teddy Dragoone の投稿
自己レスです

色々ためしてみましたが、on_rezという部分がラグで実行されないのが理由じゃないかなという結論になりました。

前回の4000個浮遊事件の際もon_rezでのTEMP設定が反映されてなかったみたいですし。

これを教訓にon_rezはあまりあてにしないようなスクリを作ろうと思います。

勝手に独り言になってしまいましたが、どうもお騒がせしました。

インワでアドバイスくれたyinさんどうもありがとうございました。
teddy Dragoone への返信

Re: スクリプトの動作が不安定な理由がわかりません

- Shinobar Martinek の投稿

私の経験上で言うと、llSetTimerEvent が動作しないことはままあります。

コンパイル直後には動くんだけど、その後リセットが掛かった後などで動かないことがあります。こんなときに起こりやすいとか、こうすれば起こりにくいとかあるみたいですが、決定的な回避策はよく分かってません。

起こりやすい一つの例は、TimerEventを動かしたまま、llResetScriptを掛けた場合です。それが分かってからは、必ず明示的にllSetTimerEvent(0)で止めてから、かつ数秒置いて llResetScript()を掛けるようにしましたが、これでもダメな場合があるようで…。

最近はリセットを掛ける旨のフラグを立てておいた上で timerイベントが発生させてから llSetTimerEvent(0)で止め、llResetScript()を掛けるという複雑なことをしています。

integer ResetFlg = FALSE;
...
Reset()
{
llSetTimerEvent(0);
ResetFlg = TRUE;
llSetTimerEvent(1.0);
return;
}
...
timer()
{
llSetTimerEvent(0);
if (ResetFlg) llResetScript();
...
}

 

Shinobar Martinek への返信

Re: スクリプトの動作が不安定な理由がわかりません

- Shinobar Martinek の投稿

経験上 llSetTimerEvent が動作しないことは、たしかにありました。しかし再現性ははっきりしません。上記対処法がまったく見当外れの可能性も大きいです。参考程度としてください。

Shinobar Martinek への返信

Re: スクリプトの動作が不安定な理由がわかりません

- teddy Dragoone の投稿
その都度いろんな不具合に対しての対処法を考えないといけないと思っていますが、
なるべく怪我の少ないようにプログラムすることが大事だなと痛感しました。
Shinobar Martinek への返信

Re: スクリプトの動作が不安定な理由がわかりません

- Xpyoda Janus の投稿

> コンパイル直後には動くんだけど、その後リセットが掛かった後などで動かないことがあります。

http://wiki.secondlife.com/wiki/LlSetTimerEvent によると、ステートの遷移がおこってもタイマーは残るけど、スクリブトがリセットされたら取り除かれるとあります。
あと llSetTimerEvent の 英文Wiki の Caveats(警告) を見ると、気になることが書いてあります。

(1)
・Setting a new timer replaces the old timer and resets the timer clock.
    ・If you repeatedly call this function at some interval less than sec the timer event will never fire.

・新しいタイマーを設定したら、古いタイマーは置き換えられ、タイマーカウントはリセットされる。
    ・もし、1秒以下の間隔でこの関数を頻繁に呼び出したら、タイマーイベントは決して発生しない。

(2)
・The timer event is not an interrupt, it will not pause the execution of the currently running event to execute the timer. The current event must finish executing before the timer executes.

・タイマーイベントは、割り込みではない。タイマーイベントを実行するために、現在実行中のイベントを一時停止することはない。現在実行中のイベントは、タイマーが実行される前に終了していなくてはならない。

だそうです。


(1)は、要するに、時間がくるまえに次のタイマーセットしてしまったら、前のタイマーは置き換えられるしタイマーカウントはリセットされてしまう。timerイベントは、秒単位の粒度でしか発生しないので、1秒以下の頻度でllSetTimerEvent()を実行したら、何時まで経ってもタイマーイベントがfireしない。
まあ、なんとなくわかるけど、そんな条件の事はあんまりないような気もします。

(2)は、書いてあることはわかるけど、タイマーが実行される前に終了してしないといけないのはちょっと厳しすぎないのかなぁ、とも思う。
Windowsとかの昔のタイマー(WM_TIMERだったっけ)のタイマーイベント処理とかは、時間経過したことがイベントループにフラグとしてマークされ、時間経過したとしても、一つにまとまって、すくなくとも1回は実行されたように、おぼろげながら記憶してるんだけど、なんか理由があるのでしょうか。時間経過をこえてしまって、終わってしまってるイベントだから、もう捨てちゃえ....なのかしら???。
それとも、繰り返し発生するから、今回のはみのがしたとしても、次回のtimer()で拾えるから、許せ、というような仕様なのかしら???。

という、解決に役に立つのか立たないのか解らないようなことを考えてみました。

Xpyoda Janus への返信

Re: スクリプトの動作が不安定な理由がわかりません

- Xpyoda Janus の投稿

今回とは、直接関係ないとおもいますが、YourTV作ってるときに、リージョンを再起動すると、スクリプトの初期化がうまくいかないことがあるという不具合に、すこし手間取ってました。
まあ、URLの代わりに、手動で 「reset」 コマンドを入力すればスクリプトリセットかかるので、致命的な問題というほどではないのですが...あまりよろしくもないなと思ってました。

いろいろ試行錯誤した結果、changedイベントで、スクリプトリセットかけるときに、ちょっと時間待ちを入れるようにししたところ、なんとなく解決したような感じなのです。

changed(integer change)
{
    if(change & CHANGED_REGION_START) {
        llSleep(15.0 + llFrand(5.0));      // スタート直後は忙しいだろうから、ちょっと待つ。
        llResetScript();    // スクリプトをリセット
    }
}

リージョンが、リスタートした直後は、スクリプトが一斉に走り出すでしょうから、ちょっと乱数で実行開始を散らしてやりました。

1つのスクリプトは、1つの実行スレッドを持つので、各々に非同期で動作しています。リンクメッセージで同期させるにしても、相手がそれを受け取れる状態になっているような、「待ち」が必要になるのかもしれません。