MODULE : AGS Breakpoints (a.k.a "DisplayGUI" module)

Started by Monsieur OUXX, Mon 09/10/2017 19:58:14

Previous topic - Next topic

Monsieur OUXX

EDIT: this module was actually heading towards two unrelated directions (on the one hand, experiments on blocking GUIs, and on the other hand the so-called "breakpoints" feature).

Therefore I'd rather start over and split it in two.

- the part concerning the Display-based GUIs : http://www.adventuregamestudio.co.uk/forums/index.php?topic=55331.msg636572545#new
- the part concerning breakpoints : working on it!




Spoiler

Indiana Jones and the seven cities of gold development team proudly presents :


             AGS Breakpoints

                     (a.k.a. "DisplayGUI" module)





Click on image to watch video




What does it do?
In a nutshell :

  • 100% blocking interactive GUI in any script (well, any script where you could normally use function "Display")
  • Easily watch variables' values anywhere in your script, like a real breakpoint (and in future version : edit them)
In detail :

  • Watch the video above (url : www.youtube.com/watch?v=Ww0n18qlsKQ&feature=youtu.be ) or read this :
  • AGS is a very cool engine, but one of its downsides is that it has no real useful breakpoints. Breakpoints can pause the game (hurray!) but you can't watch the variables values, so the Breakpoints are mostly useful to check that your script goes nto a specific code branch (if...then...) but it won't help you debug a complex code with values changing everywhere.
  • Until now, your only solution was to use the "Display" function, but it was really a pain in the neck when you want to display several variables at once (you'd need to write a different "String.Format..." for every occasion). You could use a GUI, but since the whole point of this is to entirely "pause" the game (GUIs included) then the GUIs would be disabled (therefore becoming non-interactive).

    Well now you have a way to entirely pause the game anywhere in the script AND still be able to click around and benefit of useful features. This makes it much closer to a regular "watch" as seen in Visual Studio and others



How to setup:
Basic use setup:
1) import the DisplayGUI module,
2) import the modified Font0 provided in the demo game (you can simply swap the files in your game folder. Fear not! It only modifies the first 20-or-so characters in the font, which should be harmless since they are very rarely used by anyone. If you need those, you can modify the ascii codes in the module and you can quickmy edit the font using Rulaman's "TtfWfnSci" tool (you can find a link here).
3) Import the sprite that represents a small 3x*3px red square, that you may export from the demo game in the "displayGUI" sprites folder
4) Make sure that mouse mode "userMode1" uses this sprite as cursor
5) Before you call any instructions of the module, call "DisplayGUI.Init(myFont)" where myFont is the font that you just swapped

Advanced use setup:
1) Get the original "UltraVariables" module by SSH, or export the one present in the module's Demo Game.
2) Check the DisplayGUI's header to see what custom instructions you need to add to the Ultravariables module. There are only two : One export instruction, and one export instruction.




How to use:
Basic usage:  (no Ultravariables)
1) Don't forget to call DisplayGUI.Init(...) before anything
2) To display a Yes/No popup window, do as follows :
Code: ags

YesNoResult result = DisplayGUI.ShowYesNo("line of text 1", "line of text 2");
if (result==eDisplayGUI_Yes) 
    Display("player clicked YES");
else 
    Display("player clicked NO or exited the popup (by pressing ESCAPE or right-clicking)");

3) To display the Watch interface :
Code: ags

//Obviously, myVariable must exist. Oh, and it does "int" only, sorry!
BREAKPOINT("myVariable name", myVariable); 

//You can watch up to 7 variables, and only 5 can be displayed simultaneously 
//(but you can see the others if you enter their name in the interface)
BREAKPOINT("myVariable1 name", myVariable1, "myVariable2", myVariable2 /*, up to 7 */); 


Advanced usage:  (with Ultravariables)
1) make sure you have followed the setup instructions above
2) Set  and get the value of any variable like this :
Code: ags

SET("myVariable", 7);
int value = GET("myVariable");

3) Display them at will in your Watch interface by typing their name whenever you want.
4) Careful though! These variables are GLOBAL variables by design. In other words : There's only one ultraVariable with the same name in the entire game.


License:
Free to use for any purpose whatsoever, provided you credit us in your game credits (if any ;) ). Don't forget to credit SSH too for his UltraVariables module.


=====================================================================

Version 1.1 :
Added simple graphic theme (because prettier things are more attractive)
              Pro : prettier
              Con : makes the popup blink because AGS function "DisplayTopBar" doesn't behave the same way as "Display". I would suggest: use the theme for Yes/No popup, but not for the Watch interface.






>> DOWNLOAD <<

[close]

 

Dave Gilbert

This looks kind of amazing. I'm going to play with it later today!

Khris

Quote from: Monsieur OUXX on Mon 09/10/2017 19:58:14
  • Until now, your only solution was to use the "Display" function, but it was really a pain in the neck when you want to display several variables at once (you'd need to write a different "String.Format..." for every occasion). Well now you have a more powerful way, much closer to a regular "watch" as seen in Visual Studio and others
I always put my watch variables on a GUI label, and I use a single String.Format() for all of them. That way I don't even have to interrupt the game, unless I want to (using built-in break points).

I watched the video but I'm still not sure why one would need this (unless one thought the only way to debug is Display())

Monsieur OUXX

#3
Quote from: Khris on Tue 10/10/2017 14:04:15
I always put my watch variables on a GUI label3 I'm still not sure why one would need this.

Spoiler

anything you change in a GUI or basic graphical element is not visible on-screen before the end of the game loop.
But what if you want to check variable values within a loop without messing with the chronolgy of AGS scripts executions? What if you want to see the real current value of every variable, including built-in AGS variables?
if you try to display values in a regular GUI, then the changes will not be seen until you do a Wait(1). Which in turn forces the engine to perform the updates it would normally perform at the of the game loop. Therefore it can mess with what you're trying to observe or is even sometimes forbidden (in blocking functions).
[close]


EDIT 2 :
    So I tried to display a variable value in a GUI and indeed it turns out that Label.Text=... or ListBox.Add..
    are immediately reflected to the screen, even within a blocking script with the game fully paused. Not the
    same behaviour as "in-game" elements such as the player, for example.

    Does that make my module useless? Not in the slightest bit. The idea is still to entirely BLOCK the game, anywhere
    within a complex script, and still being able, during that "brutal" pause, to see the value of anything... but in a
    comfortable and interactive way.

    the only way I know to entirely pause the game in a sort-of "meta" way (not only the in-game elements like Character,
    etc.) is to call Display (correct me if I'm wrong?). But then the game is entirely paused and you can't click anywhere
    in GUIs. On top fo that, mouse movements can be seen on screen (because they're handled at "system" level) but
    mouse.x is not updated and can't be watched.

    Therefore, with Khris' idea in mind, I'll use the GUIs capabilities to make the visual aspect of my module more
    appealing, BUT it's still extremely helpful to force a blocked GUI to stay interactive.

    This will allow me to continue with my plan :
    - enabling AUTOCOMPLETE in the symbols suggestions,
    - allowing the user to EDIT a variable value while code is paused
    - adding CONDITIONAL breakpoints, for them to fire up only when the critical time to debug has come.

 

Monsieur OUXX

Could the admins please delete this entire thread?
I'm currently splitting this in two :
1) the GUIs relying on the "display" function (which is a curiosity not necessarily interesting everyone)
2) the advanced "breakpoints" capabilities, that I'm currently refactoring to rely on a regular GUI.

Also I forgot to post it into the Modules subforum instead of here, so it's a good occasion to start over properly
 

Snarky

There's technical information here that could be useful to someone. Why don't you just link to your new threads and we can lock this one?

Monsieur OUXX

#6
Quote from: Snarky on Fri 13/10/2017 19:34:18
There's technical information here that could be useful to someone. Why don't you just link to your new threads and we can lock this one?

Everything that is in here will be present in the next threads. I don't really mind I justs didn't want to pollute the forum.
 

Monsieur OUXX

Quote from: Khris on Tue 10/10/2017 14:04:15
I always put my watch variables on a GUI label

Sorry for digging up, but that fits into this conversation: This solution would work only for labels, but not buttons, because buttons get "grayed out" (actually, the gray grid pattern if they have an image, or a light gray color if they have text). Which leaves the need for a pleasant user interface when freezing the game intact.
 

Snarky

That's a game setting, M. Ouxx: "Visual | When player interface is disabled, GUIs should"... If you set it to "Display normally" they will, well...

SMF spam blocked by CleanTalk