Preprocessor directives in GMS2 - GMWolf

GMWolf

aka fel666
GM Version: GameMaker:Studio 2.1.4
Target Platform: ALL
Download: N/A
Links: Youtube video
Summary:
After a long hiatus, I'm back with a tutorial describing how to make use of the processor to achieve preprocessor-directive-like constructs.
This allows you to have different sections of code be included, or not, based on macros, or configuration. We also explore how it can be used to improve some function call performance, using debug message logging as an example.

Tutorial:
I hope you find this interesting, if not useful, and I hope to see you guys when i decide to make my next video (evidently 6 months from now :rolleyes:)
 
J

JealousOfCrows

Guest
I'm curious about this, so just by using macros and/or var keywording variables being used multiple times in a script you take advantage of preprocessing?
 

DaveInDev

Member
@GMWolf Sorry to wake up this thread, but I find it very interesting :
I do not want to be impolite (excuse my english), but I just wonder how you can be sure that the preprocessor is really optimising this way ? (but maybe are you part of the dev team ?)
In particular, I'm very curious to know how you are sure that in a "if(true) A else B", the B block is not even compiled ?
I am very interested in this conditional compilation feature, because while developping my game, I am putting a lot of "cheating" codes for purpose testings, and I would like this code to completely disappear from the public compiled version (even in a compiled form).

EDIT: To make a test I tried to compiled a code with a s = @"AABBCC"; statement under condition and look to AABBCC in the compiled EXE with an HEX editor, but I'm afraid that GMS2 is using unicode string, no ? Because I cannot find the string in the EXE, (even with no condition)...
 
Last edited:

GMWolf

aka fel666
but maybe are you part of the dev team ?
Haha no, but I'm flattered.

In particular, I'm very curious to know how you are sure that in a "if(true) A else B", the B block is not even compiled ?
I recall a yoyo employee mentioning this on the forums before.
Also, you can check out the generated c++ code (when using yyc) and it's clear that the c++ optimiser would take care of this.


EDIT: To make a test I tried to compiled a code with a s = @"AABBCC"; statement under condition and look to AABBCC in the compiled EXE with an HEX editor, but I'm afraid that GMS2 is using unicode string, no ? Because I cannot find the string in the EXE, (even with no condition)...
I'm not sure what format string is used but it's entirely possible that its unicode.
Also I'm not sure the strings themselves would be removed depending on how strings are implemented in GML, they may still hand around in static data, but never be referenced in code.

but I just wonder how you can be sure that the preprocessor is really optimising this way ?
I cannot. In fact Iwas wrong about some of the function calls that don't get optimized away (much to my surprise, as with c++ they would handily get inclined and optimized).

But I am rather confident in the case of if statements .
 

DaveInDev

Member
I recall a yoyo employee mentioning this on the forums before.
Also, you can check out the generated c++ code (when using yyc) and it's clear that the c++ optimiser would take care of this.
Oh but you interest me once again ! I did not know that some intermediary C++ code was generated and readable. I looked around but did not find anything in my project dir... Where can I find these files ?
 

GMWolf

aka fel666
Oh but you interest me once again ! I did not know that some intermediary C++ code was generated and readable. I looked around but did not find anything in my project dir... Where can I find these files ?
Only when using YYC.
I'm not sure where to find the cpp files ,YYG switched it up a few times, maybe check your app data files?
 

DaveInDev

Member
Oh yes, I see. Then pointing to MS VC. I'll try this where these cpp files are generated

EDIT: the explanation is here :
 

DaveInDev

Member
For your information, I tested the compilation of this :

GML:
#macro debug true

if(debug)
{
    s = "AABBCC";
}
else
{
    s = "DDEEFF";
}

show_debug_message(s);
and the result is clear :
The if dissapeared and you only see the assignement of the "AABBCC" string, that you can recognize at the beginning.
Even the second string vanished.
That's exactly what I need. Thanks for your help @GMWolf

C++:
#include <YYGML.h>
#include "gmlids.h"
extern YYVAR g_Script_gml_Object_Object1_Create_0;
#ifndef __YYNODEFS
char g_pString1_205D5AB2[] = {
0x41, 0x41, 0x42, 0x42, 0x43, 0x43, 0x00,               // AABBCC.
};
#else
extern char g_pString1_205D5AB2[];
#endif // __YYNODEFS

void gml_Object_Object1_Create_0( CInstance* pSelf, CInstance* pOther );
#ifndef __YYNODEFS
void gml_Object_Object1_Create_0( CInstance* pSelf, CInstance* pOther )
{
YY_STACKTRACE_FUNC_ENTRY( "gml_Object_Object1_Create_0", 0 );
YYGML_array_set_owner( (int64)(intptr_t)pSelf );


YY_STACKTRACE_LINE(4);

YY_STACKTRACE_LINE(5);
YYRValue* sself_s = &((CInstanceBase*)pSelf)->GetYYVarRefL(kVARID_self_s); /* set ContextID to 1 */
(*sself_s)=(const char*)g_pString1_205D5AB2;      // string assignement
;
;

YY_STACKTRACE_LINE(12);
YYGML_show_debug_message((*sself_s));
;
}
#endif
I also tested the result of the YYC compiler in terms of performance, and it's huge !
On my game, I can have heavy rooms with loops containing around 10ms of calculations per loop ; when it's compiled under GCC, it goes down to a steady 2ms !!!!
 
Last edited:

kburkhart84

Firehammer Games
I actually do exactly this for my input system(and will be doing the same for ALL my systems). There is a macro for DEBUG_MODE that goes along with the other macros for the settings. Then I simply have any extra verification(like asserts) be done only in if statements that check the debug mode. I also only output informational debug message inside such if statements. This is basically exactly what you describe in the video. It is 100% a good thing to do, though I think maybe these optimizations could be better documented by Yoyo since most newer coders will never know about it, and the veteran coders really know about it because we come from( or later learned) other languages.
 
Top