GameMaker Question on code pre-processing and scripts

F

Finn

Guest
I defined a macro to switch on/off debug mode like this:

Code:
#macro DEBUG_MODE_ENABLED true
Now I want to use GML's pre-processing to handle debug mode so that when the macro is set to false it wont affect performance any longer and remove all the sanity checks and messages that debug mode features.

For instance, I want to surpres text output if the macro is set to false with the following script:

Code:
/// @description sc_show_debug_message
//    Will show debug messages only if debug mode (macro) is set to true
/// @argument string

if (DEBUG_MODE_ENABLED) { show_debug_message(argument[0]); }
which basically just wraps the built-in function show_debug_message().

-> What I could not find out is this: Does the pre-processor deal with these kind of scripts properly?
If the macro is false, will it only set the script to being empty or actually remove the script from the compiled code entirely?
 

Hyomoto

Member
As far as I know there is no pre-processing done of this nature. So you are correct, when this script is called it will simply say if ( false ) { // do }, it won't actually prevent the script from being run. The macro is just a substitution, so the computer sees:
Code:
if ( true ) { // do }
There are a few pre-processor functions in GML, but they are quite limited. The only way I know to 'get at' the game before runtime is through gml_pragma. Now, the way I get around this particular issue is two fold: one, the check like you have since my logging script is a bit more complex so the comparison is cheaper than the final product. Two, I have an object that is created if debugging is enabled, and that object is used to call and inject debug information from objects into the render. So, if I disable debugging the object isn't created and none of the debugging code is run. It looks something like each object inherits a parent with a flag, 'debugMe'. When an object is created, or exists at run time, if the 'debugMe' flag is set (and debugging enabled) it is added to a list managed by the debug object. The debugging object will then call user event 15 on those objects during post processing. I use this as a way to essentially write debugging widgets that are local to the object in question, and as you want, to completely disable the system when I flip debugging off (either globally or just the debugMe flag).

EDIT: Apparently GM can handle removing it. My suggestion still seems relevant but apparently it is possible to define a macro for purposes of removing a block of code at compile time.
 
Last edited:
F

Finn

Guest
Short answer: no, the pre-processor doesn't do anything to that script except replace DEBUG_MODE_ENABLED with whatever you defined it as. There is no simple way to define a block of code that shouldn't exist at runtime as GM will always compile everything in the project, even if it ends up being otherwise unused.
Thanks, As far as I read the pre-processor is smart enough to remove un-used conditional statements where the conditions are macros.

For instance:

Code:
#macro DEBUG_MODE false

if (DEBUG_MODE) { //do }
will actually remove the entire if statement from the compiled code.


My question is what would happen to scripts like desribed in first post above. I dont want empty scripts in my compiled code since they would still consume resources.
 
N

NeZvers

Guest
I hope you understand that writing
DEBUG_MODE_ENABLED means you want value true in that place.
Making
Code:
#macro DEBUG_MODE_ENABLED true

if (DEBUG_MODE_ENABLED) { //code;}
//into
if (true) { //code} //it will do it always
Check command line parameters if you want to debug after compile.
 

sylvain_l

Member
-> What I could not find out is this: Does the pre-processor deal with these kind of scripts properly?
pre processor ?!? no certainly not.(or we have a misunderstand on what call pre processor)
but nearly all half decent compiler are able to optimise and get rid of dead if(false){} branch. So for the GML that should be removed too.

at worst, do the test, run a zillion loop with and without a dead if (of course not in debug mode, as in debug most info is keep and compiler should do 0 optimisation; but release build.)
 
F

Finn

Guest
Thanks, I will come up with a way to test this. With "pre-processor" I mean the step before compiling the code.
I wish there was more documentation on topics like this; it seems one has to come up with tests for GMS2 all the time to find out what it is actually doing and how it is handling things.
 

Hyomoto

Member
Hmm, I haven't heard that GML is smart enough to simply remove if false branches. I wouldn't be surprised if it could, but I'd be interested to hear the results of such a test. If I'm wrong that would be an interesting tool, but as far as I know all code is included.
 
I'm almost certain it has been mentioned by either Russell or Mike that GM will indeed remove code for any condition that always evaluates to false.
 

FrostyCat

Redemption Seeker
NPT has definitive evidence that conditions controlled only by compile-time-resolvable literals are internally optimized.

Anyone seeking to prove or disprove the existence of pre-processing routines must present assembly-level evidence in the debugger, not factually shaky "I don't think YoYo did it" arguments or time-sensitive benchmark measurements.
 
F

Finn

Guest
This GMWolf video is good; should definitely have more attention.

This actually also answers my original question: The answer is the script can be used if combined with forceinline() as intended. It will not affect performance in the compiled code once the debug macro was switched off (or set to lower prio like in the video below).

 
Top