[RMVX ACE] [SCRIPTING] WHAT CAUSES AN EVENT SCRIPT TO ABORT WHEN ITS EVENT CHANGES PAGES?

Posts

Pages: 1
(This was originally posted as a 2k question, but someone suggested looking at the VX Ace implementation, and I discovered the behavior is the same. Unfortunately, I can't find the reason for it! I'm trying to reverse-engineer a particularly annoying discrepancy, and any help tracking down what's going on would be greatly appreciated.)

I've got two scenarios here with what seems to be contradictory behavior, and I'm trying to figure out how it works.

First:

Two events on the map. One is a parallel process, that looks like this:

Page 1:
Conditions: none
Script:
Loop:
Play SFX(whatever)
Wait(30)
Loop End

Page 2:
Conditions: Switch 1 is ON
Script: none


The second is an object that's activated on player touch, that turns Switch 1 on. When I activate this event, the sound loop stops playing, suggesting that when the active page on the second event changed, it aborted the script it was currently playing. So far, so good.

Second scenario:

Two maps. First map has an event on it that activates on player touch.

Page 1:
Conditions: none
Script:
Set Switch 1 ON
Screen Tint: Sepia (60 frames)
Teleport to Map 2
Image: some image

Page 2:
Conditions: Switch 1 is ON
Script: none
Image: none

When you hit the event, it vanishes immediately, showing that the active page changed right away. And yet, after the fade, the teleport takes place, which means that the script did not abort when the active page changed.

I can't find anything in the code to account for this discrepancy. The implementation of the Screen Tint command (command_223 in Game_Interpreter) calls the same wait() method that the Wait command (command_230) does, and there's nothing particularly special in the implementation of the loop (command_112 and command_413).

Does anyone know what it is that causes a script in progress to abort in some cases but not others when the event it's on changes its active page?
SunflowerGames
The most beautiful user on RMN!
13323

The language you use to describe what your trying to do is not simple enough.

Screen Shots of the events in VX Ace would be helpful.

Edit:

If you want to stop an event you need to have a second event page after the first that is blank. This blank page can be triggered by a control switch. Maker sure it's not autorun on the second page.

You can also check out my tutorial on how to use autorun events to make a scene.

https://rpgmaker.net/tutorials/1034/
author=kory_toombs
The language you use to describe what your trying to do is not simple enough.

Screen Shots of the events in VX Ace would be helpful.


Sorry. It was a lot more clear before this stupid forum software deleted all my indentation in the code samples. :(

Images can be found at: http://imgur.com/a/EbHqz

First event: plays sound in an infinite loop, until switch 1 is set. Then it switches to page 2 and the sound stops playing.

Second event: turns on switch 1.

Third event: turns on switch 2 (which causes the page to change), then runs a tint and a teleport.

On the first event, changing the active page aborts the script, and the sound loop stops playing. On the third event, changing the active page does not abort the script, and it proceeds with the tint and the teleport.

Can any RGSS gurus explain why that is?
SunflowerGames
The most beautiful user on RMN!
13323

This is not scripting, this is event processing.

You tinted the screen prior to transferring.
You want the tint to return to normal?
Then you need an event that tints the screen back to normal.
(Because tinting the screen keeps the screen tinted forever.)

Prior to transfer =
fadeout screen
tint change to normal
fadein screen

or after transfer the next room needs an event.

I'm not 100% sure what your trying to do, so this is just an assumption.


author=kory_toombs
This is not scripting, this is event processing.

You tinted the screen prior to transferring.
You want the tint to return to normal?

No.

I'm not 100% sure what your trying to do, so this is just an assumption.


I'm trying to figure out why in the one case, changing active pages while the event is in progress causes the event processing to abort, and in the other case, it doesn't and the whole thing plays through to completion. If the behavior was consistent, I'd expect the teleport to never occur, because the Wait that gets called in the Tint operation yields control back to whatever processing is causing the other event script to abort. But the teleport does occur, and I'd like to understand why we get inconsistent behavior between the two scenarios.
Marrend
Guardian of the Description Thread
21781
What can you glean from Game_Event? I'm sure that has a number of functions concerning event-pages. Would looking through Game_Map be of any use? It has a variable that is an instance of the Game_Interpreter class, which... might be ultimately responsible for the processing you're looking at?


*Edit: I've a potentially dumb question. What makes you so sure that, in scenario 1, Event1 does not play out to completion after the switch is active? I mean, you would not be able to tell that the "Wait" command is "on the stack", since it's a parallel process. As for the sound effect, my guess is that it would finish playing regardless.

*Edit2: Okay, that's a really dumb question after all. There's no "Break loop" follow-up command. Thus, it literally cannot finish it's processing. However, I still believe it's possible that it finished a cycle of the loop before moving on to page 2. Given what you observed with scenario 2, maybe that's what happened? Though, given the contents of that loop, I figure it would be difficult to determine.

I dunno.
author=Marrend
What can you glean from Game_Event? I'm sure that has a number of functions concerning event-pages. Would looking through Game_Map be of any use? It has a variable that is an instance of the Game_Interpreter class, which... might be ultimately responsible for the processing you're looking at?


Game_Map has an interpreter, but so does Game_Event, and Game_Event can create its own interpreters, so it's not just the same variable being shared in different places.

*Edit: I've a potentially dumb question. What makes you so sure that, in scenario 1, Event1 does not play out to completion after the switch is active?


Because it's an infinite loop that can't be completed.
Marrend
Guardian of the Description Thread
21781
Yeah, I sorta caught that now. Welp.


Ugh, my head aches from this.

*Edit: I did a bit of playtesting. Similar situation as scenario 1, only the loop contained...


Play SE: Attack1
Wait: 30
Play SE: Attack2
Wait: 30
Play SE: Attack3
Wait: 30

...something like that, with the secondary event's first page containing...


Switch 1 - ON
Self-switch A - ON

...with a page 2 whose only change to it's conditions was a requirement of Self-Switch A being enabled. It's event-commands follows.


Switch 1 - OFF
Self-Switch A - OFF

What I observed in this instance is that I could run into Event2 (it was on the same level as the actor), and it basically continuously played "Attack 1". So, no, it did not complete the loop before going to page 2. I tried setting Event2 (both pages) to be triggered via action button, and I'm fairly sure it finished playing out whatever SE it was on before it went silent.


So, no, that's not consistent with what was observed with Scenario 2 at all! Welp. I'm no help.
SunflowerGames
The most beautiful user on RMN!
13323
Looking at the event pages=

Event 001
Will play SE until control switch 1 is on.
(won't this SE play without the loop thing because it's a parallel process? I have never used loop in any of my games so far... And I have made a lot.)

Event 002
Tints screen
Transfers Player
(I think you have placed the control switch too early in this process.)
-Try placing it after tint screen
-Try placing it after transfer
No, Kory, you still don't understand.

I'm not trying to change the behavior here. I'm trying to figure out what's causing it.
SunflowerGames
The most beautiful user on RMN!
13323

Am I the only one confused by this thread at this point?
You want to understand how an event works, but you don't need help fixing it?

???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????
???????????????????????????????????????????????????????????????????????????????????


Yes, that is what he wants. lol It's about learning about the behavior of RM's inner workings.

A similar question would be:
If I create event A that constantly sets variable #1 to 10,
and event B that constantly sets variable #1 to 20,
what happens when I talk to this event C, and have it check the value of variable #1?

And I believe the answer to this unrelated, similar question would be "it depends on where in GameMap's events array events A, B and C exist. If C is between A and B, variable #1 will be 10. If it's anywhere else, it will be 20."

He's searching for this answer, not "just disable event B, and you'll always get the value 10."
author=kory_toombs
Am I the only one confused by this thread at this point?
You want to understand how an event works, but you don't need help fixing it?

Yes, exactly.

I'm building an engine that clones RPG Maker, and while testing an existing game, (which I didn't write and so I can't change,) I'm getting tripped up by these two cases. If I abort when the page changes, it breaks one case, and if I don't, it breaks the other one. So I'm trying to figure out what the actual rule is so I can make them both work properly.
After a bunch of testing and trying to narrow down and isolate different factors, it seems the the thing that makes the difference is the page's "Trigger" attribute: its event script will only be aborted if it's a Parallel Process.

Still not sure where the relevant code for that is, but that appears to be the determining factor.
No idea if you already solved this question 6 months later but here a public answer:

Correct, only parallel processes are aborted when the page changes.

Assuming you have a PP with


Page 1, no condition, PP:

Switch 1 ON
Switch 2 ON
Wait
Switch 3 ON

Page 2, Switch 1 ON condition.

!!! Version difference !!!
Result for XP/VX Ace: Switch 1 and 2 are on, 3 is off.
Result for 2000/2003: Switch 1 is on. 2 and 3 are off.

Reason: When a Switch or Variable (and some other stuff) are modified they set a "map needs refresh" flag. When that flag is checked depends on the version.

When the map refresh refreshes all events and this reevaluates the runnable page and when the page of an event changes the parallel interpreter is destroyed which halts the execution as you observed.

The main interpreter (not a PP) is immune to this because there are checks that prevent the replacement until the script finished executing.

VERSION DIFFERENCE: RPG XP & VX (Ace)
(no idea about MV)

To reach the refresh the interpreter must yield. In RPG XP a yield was indicated via returning false from a command, in VX it's through a fiber yield. Everything that interrupts the event execution (wait, transfer, Show message, etc.) does a yield.

The refresh check happens at the beginning of the frame, when 2 PP events have a 2nd page that depends on Switch 1 ON and the 1st event that runs toggles that switch the 2nd will execute code until it reaches a yield, too:


EVENT 1
Page 1, no condition, PP:

Switch 1 ON
Switch 2 ON
Wait
Switch 3 ON

Page 2, Switch 1 ON condition.

EVENT 2
Page 1, no condition, PP:

Switch 4 ON
Wait
Switch 5 ON

Page 2, Switch 1 ON condition.

Result: Switch 1, 2 and 4 are ON, 3 and 5 are OFF because the other ON code is before a yield (the wait command).

CORNER CASE

When the yield cause is a message box no other interpreter will run anymore this frame because a waiting message yields any interpreter:


EVENT 1
Page 1, no condition, PP:

Switch 1 ON
Switch 2 ON
ShowMessage
Switch 3 ON

Page 2, Switch 1 ON condition.

EVENT 2
Page 1, no condition, PP:

Switch 4 ON
Wait
Switch 5 ON

Page 2, Switch 1 ON condition.

Result: Only Switch 1 and 2 are ON, the messagebox interrupts anything.

VERSION DIFFERENCE: 2000 / 2003

When a map refresh is pending it is directly executed after the command. (Problem: This makes Switch/Var operations slow because after each line you refresh the whole map & common events :/).


EVENT 1
Page 1, no condition, PP:

Switch 1 ON
Switch 2 ON
Wait
Switch 3 ON

Page 2, Switch 1 ON condition.

EVENT 2
Page 1, no condition, PP:

Switch 4 ON
Wait
Switch 5 ON

Page 2, Switch 1 ON condition.

Result: Switch 1 is ON, all others OFF.

No idea how the current running parallel interpreter is notified about this, I guess it's event list is simply cleared.

Feel free to discuss which implementation makes more sense to you :)
Pages: 1