Compile errors after moving dialog folders up/down in 3.3.0

Started by AGD2, Tue 01/04/2014 11:00:37

Previous topic - Next topic

AGD2

I just ran into a pretty major bug in 3.3.0 which prevents the game from being compiled.

I have a lot of dialog topics sorted into various folders, and I wanted to sort those folders by alphabetical order, so I right-clicked on each folder, one at a time, and then clicked either "Move Up" or "Move Down" until all of my dialog folders were in the right order.

Next, I tried to compile the game, but the first script instance of dialog topic 0 (dJonisMain) in the global script tripped up with this error:

QuoteGlobalScript.asc(568): Error (line 568): undefined symbol 'dJonisMain'

It seems that every single dialog topic in the game now isn't recognized at all. Yet, when I double-click on the affected dialog topics in the editor to open them, they all open fine. All options are intact and even the script names are exactly as they should be.

Even if I rename the affected dialog to something else and then change it back again, it still gives the same compile error.

Crimson Wizard


AGD2

Yeah, it gives the same compile error when it encounters a dialog name script reference, either in a room script, the global script, or any other script.

Crimson Wizard

I can reproduce this error. But after I restart Editor, it compiled well again, until I move folders.

This is actually very bad, I remember there was already a bug related to moving folders, maybe it was different...

AGD2

I can also confirm that restarting the editor and recompiling fixes the issue until moving more folders.

It would also be worth checking into whether this issue affects GUI, Inventory, Views, Character, Audio, Room folders in the same way.

AGD2

Hmmm... even though the game compiles successfully after closing the editor and reloading the game, the dialogs now seem to be riddled with issues that crash the game frequently. I keep getting fatal crashes like this, which never occurred before:

QuoteError: post_script_cleanup call stack exceeded: possible recursive function call? running _run_dialog144

This occurs completely at random. Sometimes a dialog works fine, and other times clicking options on the same dialog crashes the game.

tzachs

Yes, this was another manifestation of the previous bug. The previous fix was for folders/files dragging, but I missed the move up/down...
Committed a fix to the branch.

AGD2

Will the fix also resolve the post_script_cleanup call crashes?

From what I can tell, it seems to crash, at random, when clicking options on a dialog that was newly-added just before to its parent folder was moved up/down. (Or when clicking options on an existing dialog that was edited just before its parent folder was moved up/down.)

Crimson Wizard

Quote from: AGD2 on Wed 02/04/2014 20:22:02
Will the fix also resolve the post_script_cleanup call crashes?
I think it may resolve the problem that is leading to that, but it does not change the engine. I need to investigate that separately.

This is Editor's update: http://www.mediafire.com/download/vxh5wd9zop3371t/AGS_3_3_0_hotfix2_pre.7z
Please tell, if that's working for you.

AGD2

Thanks, I just tested it and the compile errors that resulted from moving the dialog folders up/down seems to be fixed now.

As you suggested, it didn't fix the existing "post_script_cleanup call" crashes, though, as I just encountered another one in my tests. After rebuilding all files, it greatly reduced their frequency, but it's still possible to get the crash eventually if you click through the dialog options enough times.

Crimson Wizard

Quote from: AGD2 on Wed 02/04/2014 21:18:12
As you suggested, it didn't fix the existing "post_script_cleanup call" crashes, though, as I just encountered another one in my tests. After rebuilding all files, it greatly reduced their frequency, but it's still possible to get the crash eventually if you click through the dialog options enough times.
Hmm, I think that may indicate what it sais (recursive function call), but its kinda strange, I thought it should detect that kind of thing before calling function, not during some "cleanup".
Can you show dialog script causing this (what is "_run_dialog144" by the way)?

AGD2

I have no idea what _run_dialog144 is (I'm guessing it's something hard-coded into AGS?), because I'm simply running the dialogs with the function Dialog.Start(); when the Talk icon is clicked on the character. But the crashes typically don't happen when I first click Talk on a character. I have to navigate back and forth through a few linked Quest for Glory style tree dialogs before it happens. It often seems to occur when I'm reading a child dialog and click "Something else" to return back to the main dialog.

Dialog 144 looks like this:

Option Text
1: Goblins    (Show: checked, Say: unchecked)
2: About something else... (Show: checked, Say: unchecked)

Code: ags
// Dialog script file
@S  // Dialog startup entry point
return
@1
  cShareen.Say( "They were once an intelligent race. Creative. Resourceful. But their once-grand path has since split into tiny tracks. Now they dwell in splintered groups, deprived of their strength, their unity, and their purpose." );
  dShareenGoblins.Start();
stop
@2
  dShareenThirdTrial.Start();
stop


Nothing out of the ordinary. Yet I've noticed that the game seems to crash on the same few dialogs every time, and they all seem to be newly added or recently edited ones (where existing options where shuffled and new ones added).

--EDIT--

Would it help if I sent you the Game.agf file?

Crimson Wizard

#12
I found it is possible to crash 3.2.1 with this if you make, for example, two dialogs, that run each other:

dDialog1:
Code: ags

// Dialog script file
@S  // Dialog startup entry point
return
@1
 dDialog2.Start();
stop
@2
return


dDialog2
Code: ags

// Dialog script file
@S  // Dialog startup entry point
return
@1
 dDialog1.Start();
stop
@2
return


The second options are required to not make first ones start automatically.

If you will continiiously click on first option, game will eventually crash with "stack cleanup error".

If instead you would use "goto-dialog X", that seem to work well.

Code: ags

// Dialog script file
@S  // Dialog startup entry point
return
@1
goto-dialog 1
@2
return

AGD2

I don't think I have any dialogs set up with that exact structure, but I found a way to crash it every time on my side. My dialog structure looks as follows (note: dialog names are changed to the number of each in-game dialog for easier reference):

dDialog144
Code: ags
// Dialog script file
@S  // Dialog startup entry point
return
@1
  cShareen.Say( "Blah" );
  dDialog145.Start();
stop
@2
  dDialog143.Start();
stop


dDialog145
Code: ags
// Dialog script file
@S  // Dialog startup entry point
return
@1
  cShareen.Say( "Blah Blah" );
  dDialog146.Start();
stop
@2
  dDialog144.Start();
stop


-I navigate to dDialog144 and click option 1 to go to dDialog145
-On dDialog145, I click option 2 to return to dDialog144
-Repeat the above process around 20 - 25 times.
-The game will ALWAYS crash on dDialog145 when clicking option2, with the following error:

QuoteError: post_script_cleanup call stack exceeded: possible recursive function call? running _run_dialog144

Changing all the dialog script name references in the game to goto-dialog X instances kind of defeats the purpose of easily being able to refer to them by script name. Plus, it'd be a bit unfeasible to do that with over 335 dialogs in the game.

Does the engine actually need to crash fatally when it encounters this kind of issue? Could it perhaps just write a warning to the log file instead, but keep the dialogs (and game) running?

Crimson Wizard

#14
Quote from: AGD2 on Thu 03/04/2014 12:37:17
I don't think I have any dialogs set up with that exact structure,
I think it's pretty much the same, just have more options.
What you have is a recursion of one dialog being started from another while the prior was not finished; then it repeats again and again, with all previous dialog scripts staying in memory. This causes script's stack overflow.

Quote from: AGD2 on Thu 03/04/2014 12:37:17
Does the engine actually need to crash fatally when it encounters this kind of issue? Could it perhaps just write a warning to the log file instead, but keep the dialogs (and game) running?
It can't continue running, because it has a fixed limit of script data it can keep.
But that is not the "bug" itself, because it protects engine from stacking dialog scripts endlessly.
When the Dialog.Start is called from dialog script it does not end current dialog, but suspends it (at least, as it seems).

I think this is not a "bug" in common sense, but rather design flaw.

Quote from: AGD2 on Thu 03/04/2014 12:37:17
Changing all the dialog script name references in the game to goto-dialog X instances kind of defeats the purpose of easily being able to refer to them by script name.
I found you can actually write "goto-dialog dDialog1".

AGD2

I tested a bit more and it seems that any parent/child dialog combo in the 3.3.0-compiled game (and for any character) crashes the game if jumping back and forth between parent and child dialogs like this.

As an experiment, I just tried this same pattern in our Quest for Glory 2 remake, which has similar dialog tree structures and was compiled with 3.2.1. I couldn't get this crash to occur in that version of the engine. Did there used to be some kind of safeguard or additional checks in 3.2.1?

Crimson Wizard

#16
Quote from: AGD2 on Thu 03/04/2014 12:53:04
I tested a bit more and it seems that any parent/child dialog combo in the 3.3.0-compiled game (and for any character) crashes the game if jumping back and forth between parent and child dialogs like this.

As an experiment, I just tried this same pattern in our Quest for Glory 2 remake, which has similar dialog tree structures and was compiled with 3.2.1. I couldn't get this crash to occur in that version of the engine. Did there used to be some kind of safeguard or additional checks in 3.2.1?

I don't think so. Rather 3.3.0 can have more checks than 3.2.1.
Thing is that I have reproduced this in 3.2.1 as easily as in 3.3.0. Upon examining the code I can see that this problem roots in how dialog scripts are designed. It simply runs other dialog before properly disposing previous one. Basically, if there wasn't a check in the engine, the program would crash anyway, and this time - much harder (program stack overflow).
If there's a case which causes problem in 3.3.0 but not in 3.2.1 - there might be some additional reasons.
I really need to know how to reproduce this.

AGD2

Sorry, scratch that. I actually looked at the Quest for Glory 2 source code, and saw that we had used goto-dialog commands everywhere, which is why it wasn't ever crashing.

Another thing is that goto-dialog won't work in all cases. Take for instance this type of script:

Code: ags
// Dialog script file
@S  // Dialog startup entry point
return
@1
 cEgo.Say( "Blah Blah." );
 if( globalvar_somecondition==1 ) dDialog3.Start();
 else if( globalvar_somecondition==2 ) dDialog4.Start();
@2
 dDialog2.Start();
stop


Random thought: could the Dialog.Start(); function be tweaked to automatically stop, break-out of, and close any active dialog that's already running, prior to starting the new one?


Crimson Wizard

#18
This won't be a simple fix. We will have to rewrite the way dialog script is being run.

AGD2

Ah, right. Would this be something for 3.3.1, then?

Crimson Wizard

#20
Quote from: AGD2 on Sun 06/04/2014 21:15:34
Ah, right. Would this be something for 3.3.1, then?
If someone will make this...
I don't know, at this point this looks like a serious change to engine.

AGD2

I was in the process of changing all my Dialog.Start(); instances over to goto-dialog instances when the editor crashed with the following error:

Spoiler

Application Error
---------------------------
An unexpected error occurred. See below for details.

System.ComponentModel.Win32Exception: Error creating window handle.
   at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
   at System.Windows.Forms.Control.CreateHandle()
   at System.Windows.Forms.ToolStripDropDown.CreateHandle()
   at System.Windows.Forms.Control.get_Handle()
   at System.Windows.Forms.ToolStripManager.ModalMenuFilter.PreFilterMessage(Message& m)
   at System.Windows.Forms.Application.ThreadContext.ProcessFilters(MSG& msg, Boolean& modified)
   at System.Windows.Forms.Application.ThreadContext.PreTranslateMessage(MSG& msg)
   at System.Windows.Forms.Application.ThreadContext.System.Windows.Forms.UnsafeNativeMethods.IMsoComponent.FPreTranslateMessage(MSG& msg)
   at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32 dwComponentID, Int32 reason, Int32 pvLoopData)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
   at System.Windows.Forms.Application.Run(Form mainForm)
   at AGS.Editor.GUIController.StartGUI(String[] commandLineArguments)
   at AGS.Editor.ApplicationController.StartGUI(String[] commandLineArguments)
   at AGS.Editor.Program.RunApplication(String[] args)
[close]

I guess this could be related the the same issues mentioned previously in this thread. I did notice (when I reloaded the game into the editor) that I had accidentally doubled up a dialog with two commands under @2, like this:

DBortInitiation
Code: ags
// Dialog script file
@S  // Dialog startup entry point
return
@1
  cBort.Say("Blah Blah Blah.");
return
@2
goto-dialog dBortMain
 dBortInitiation.Start();


Not sure if that has anything to do with it. Just mentioning it in case it's relevant.

I had saved the game (CTRL+S) but hadn't compiled it when the crash occurred. After saving, I recall trying to double-click several dialog topics, and none of them would open. After a few attempts, I double-clicked another dialog and the editor crashed with the above message.



tzachs

Quote from: AGD2 on Mon 07/04/2014 08:42:06
I was in the process of changing all my Dialog.Start(); instances over to goto-dialog instances when the editor crashed with the following error:
The "Error creating window handle" exception can happen when you go out of resources. This could be a resource leak somewhere in the system, but this could also be due to too many open windows.
Did you have a lot of open windows in AGS?
Did you have a lot of open windows outside of AGS?

AGD2

I didn't have that many windows open in Windows nor many tabs open in AGS at the time. Actually, far less than I typically do, as I had just loaded up the editor not long before.

HandsFree

Don't know if this goes here, but I'm using 3.3.0.1156 and my game exe is deleted everytime I use F5 or ctrl-F5. Is that expected behaviour?
I used the winsetup to specify full screen so ctrl-F5 would give me a full screen. Is there another way to achieve that (ctrl-F5 now gives me a window)?

thanks

edit: oops, this was meant to go in the AGS 3.3.0 thread. Apparently I ended up in the wrong thread...

Crimson Wizard

#25
Quote from: HandsFree on Fri 02/05/2014 14:13:28
Don't know if this goes here, but I'm using 3.3.0.1156 and my game exe is deleted everytime I use F5 or ctrl-F5. Is that expected behaviour?
I think it worked like that since 3.2.1, at least. It may be argued if this is a right thing to do...

Quote from: HandsFree on Fri 02/05/2014 14:13:28
I used the winsetup to specify full screen so ctrl-F5 would give me a full screen. Is there another way to achieve that (ctrl-F5 now gives me a window)?

Go to File -> Preferences. On preferences window set "When running without debugger" to "Use game setup configuration".

HandsFree

Thanks that works.

I used 3.2.1 before this and I'm sure I didn't lose any executables. It looks to me it happens since 3.3.0.

monkey0506

HandsFree, I'm reasonably certain that running with the debugger has deleted the executable from the Compiled folder since 3.0 was first introduced.


SMF spam blocked by CleanTalk