Snarky got it right once again!
I'd like to add some details. Humaldo, I guarantee you that 99.9% of the time AGS works as expected.
But there is something that is hard to understand in AGS: the order in which scripts are executed. It's hard to understand not because it's complicated, but instead because it seems so simple, that most AGS scripters overlook the details, and then sometimes get confused. You could say it's not hard but it's subtle.
The most important thing to understand in AGS is that it's basically split in two : 1) all the things that are done by the inner engine at each game cycle, and 2) all the things that are done by your custom scripts.
Most of the time, what you do in your script will take effect (at least visually, on-screen) during the next game cycle. For example, everything you do in repeatedly_execute. But there are other things that are meant to be executed immediately, no matter what. They're meant to say "fuck you I'm not waiting" to the internal AGS engine. That's the kind of scripting that you would put into "repeatedly_execute_always". And because that second category of scripts is so blocking, then it's forbidden to put blocking functions in them (Wait(); Display(); etc.)
Where am I getting at? You should imagine that all the scripting in AGS is a big heap of instructions to execute. AGS takes them from the heap in the same order as you put them, and sometimes interrupts that task to execute its internal code, once at the beginning of each game loop. Some of your scripting goes at the top of the heap, that's what happens with regular, non-blocking instructions. But there is a handful of other "special" instructions that will take effect later, at the next game cycle, because they have the courtesy of letting AGS do its stuff inbetween. The trouble is : when the game cycle is over, AGS will not "resume" the interrupted scripts during the next game cycle. They're gone.
That's precisely what happens with "CallRoomScript". You're telling AGS "don't do it now, but remember to call on_call at the next game cycle". Therefore you cannot base your thinking on the values of the variables of the current game loop. They will probably have changed during the same game loop.
(For the record I got that from the help article) :
Conclusion: whenever you write some script in AGS, always ask yourself:
- Is it meant to be executed right now and block everything? (which means the game cannot continue until this script and all the script it calls are completely finished)
OR
- Is is meant to be executed right now and forbidden to block anything? (which means, for example if you put a Wait inside, that the execution of this script might potentially be split over several game loops -- thus allowing the internal game engine to update the display and such, but not to run some of your other custom scripts. Your own local variables will keep their values, but all graphic variables such as player.x, etc. might change during the execution of that script)
OR
- Is it meant to be run later? (the engine will remember to do it at next game cycle, but then you cannot rely on any of your own variables since they might change inbetween).
I'd like to add some details. Humaldo, I guarantee you that 99.9% of the time AGS works as expected.
But there is something that is hard to understand in AGS: the order in which scripts are executed. It's hard to understand not because it's complicated, but instead because it seems so simple, that most AGS scripters overlook the details, and then sometimes get confused. You could say it's not hard but it's subtle.
The most important thing to understand in AGS is that it's basically split in two : 1) all the things that are done by the inner engine at each game cycle, and 2) all the things that are done by your custom scripts.
Most of the time, what you do in your script will take effect (at least visually, on-screen) during the next game cycle. For example, everything you do in repeatedly_execute. But there are other things that are meant to be executed immediately, no matter what. They're meant to say "fuck you I'm not waiting" to the internal AGS engine. That's the kind of scripting that you would put into "repeatedly_execute_always". And because that second category of scripts is so blocking, then it's forbidden to put blocking functions in them (Wait(); Display(); etc.)
Where am I getting at? You should imagine that all the scripting in AGS is a big heap of instructions to execute. AGS takes them from the heap in the same order as you put them, and sometimes interrupts that task to execute its internal code, once at the beginning of each game loop. Some of your scripting goes at the top of the heap, that's what happens with regular, non-blocking instructions. But there is a handful of other "special" instructions that will take effect later, at the next game cycle, because they have the courtesy of letting AGS do its stuff inbetween. The trouble is : when the game cycle is over, AGS will not "resume" the interrupted scripts during the next game cycle. They're gone.
That's precisely what happens with "CallRoomScript". You're telling AGS "don't do it now, but remember to call on_call at the next game cycle". Therefore you cannot base your thinking on the values of the variables of the current game loop. They will probably have changed during the same game loop.
(For the record I got that from the help article) :
QuoteThat's probably what happens in your case. You get mixed up between the game loops and the variables change values inbetween. And that's probably why Snarky's solution fixes the issue : you're piling up too many queued instructions (Dialogs are a whole world of their own), so it's better to call CallRoomScript only after you're sure the dialog is over. By the way CallRoomScript does not "exit" the dialog. It just piles up more things to do inside the dialog. If you're lucky they will unpile in the order you thought was to be expected. If you're unlucky something else within the dialog interrupts the game loop, hence skipping to the next game loop, and your CallRoomScript does not get called at all or causes trouble.
The function doesn't get called immediately; instead, the engine will run it in due course, probably during the next game loop, so you can't use any values set by it immediately.
Once the on_call function has executed (or not if there isn't one), the game.roomscript_finished variable will be set to 1, so you can check for that in your repeatedly_execute script if you need to do something afterwards.
Conclusion: whenever you write some script in AGS, always ask yourself:
- Is it meant to be executed right now and block everything? (which means the game cannot continue until this script and all the script it calls are completely finished)
OR
- Is is meant to be executed right now and forbidden to block anything? (which means, for example if you put a Wait inside, that the execution of this script might potentially be split over several game loops -- thus allowing the internal game engine to update the display and such, but not to run some of your other custom scripts. Your own local variables will keep their values, but all graphic variables such as player.x, etc. might change during the execution of that script)
OR
- Is it meant to be run later? (the engine will remember to do it at next game cycle, but then you cannot rely on any of your own variables since they might change inbetween).