New to GML, as a C or C++ programmer , and I have some questions.

Hello , Im new to GMS 2, and the GML language. My previous experience with programming languages is mostly C and a little of C++. I am going to ask a lot of questions about GML ( as I learn it ) , in later future posts, from a C programming point of view because I am transitioning from C to GML. All of my questions are labed like a bullet listing and are in no way in any particular order. Forgive me if I go off tangent.

  • Whats the learning curve from C or C++ to GML?
  • In C programming, there is something called "Undefined Behavior" which is a big issue , in GML it does not exist by that name. I tried to look it up by name in the online manual on GMS website but it does not exist. But does undefined behavior exist as something else in GML ?
  • Do you have streams in GML ? In C , its stdin, stdout, stderr, and FILE* - as far as I know. In C++ its cin, cout, cerr, and FILE *; ?
  • Pointers....Dont you have pointers in GML for address referencing , especially for file streams when your reading or writing data to a hard drive, or using arrays?

In GML if you have the following :
Code:
/// this is GML
var myvalue = my_object_code()
The code above looks similar to C as a pointer being assigned the address of where a function is declared in memory, the example below, you can do this ( although I have never had the need to use it ).

Code:
// this is a program in C
#include <stdio.h> 

void mymsg(void); // just show a message

int main(void)
{
      int *myfunction = mymsg(); // we're assigning the address of mymsg to the pointer 
      mymsg();
      return 0;
}

void mymsg(void)
{
     printf("Hello World.\r\l"); 
}
When ever I see a tutorial on GML on youtube, that someone is demonstrating , that
assignment of a variable to a function reminds me of that assignment of a pointer to a functions address in memory for C or C++.

  • Every statement in C MUST be followed at the end by a semi-colon, unless it its a conditional test like if () { .... }. Why does GML allow statements like the following?

Code:
/// This is GML
var myvalue = my_object_code()
  • There are no preprocessor directives or manifest constants in GML - what do you use instead?

Code:
// This is a program in C

// this is a preprocessor directive 
#include <stdio.h>

// this is a manifest constant 
#define MSG1 "Hello World" 

int main(void)
{ 
    printf("%s\r\l", MSG1);
    return 0; 
}
  • Can you do tail recursion in functions for directory tree searching of a storage medium such as a hard drive or USB flash drives.
  • The rule of thumb when declaring variables in C or C++ is that you have to initialize their values to 0. when you declare a variable, it is assigned to a address in the computer's memory which may contain a garbage value. In some ways the uninitialized variable may have a value that is 0, which I call, "good garbage", which should never be assumed. Is this true for GML or all declared variables before their assigned values initialized to 0 by GML ?
  • In C and C++ , main() can also be declared as
    Code:
     int main (int argv, char *argc[])
    which allows the user to pass in arguments to the program from the OS shell. GML does not have a main() like C or C++, but can this be done some other way?
(off tangent)

I am so used to working OS shell environments like MS-DOS and linux bash shell. Ive learned that long ago, that in order to do anything GUI, with either Gnome ( for linux ) or Windows in Visual Studio for C++ by Microsoft, you have to learn how to use the OS to talk to the machine through the platform specific langauge that is included with C++ . The learning curve for Linux is steep, but very rewarding once you know X11 ( or what ever the standard is now for X-windows ) which I never got to, because the books on the subject come in the form, like a encyclopedia. Its like learning the programming language called ADA ( and I don't plan to ever work for the department of defense, in the USA ).

( back to the original train of thought )

So far....

I suppose there are easier ways in GML to do this , than what I can think of in C that do the same things that I have shown as examples. Again, GML is new to me, but not programming. So thats just some questions and a sample of my background in programming. My big problem is that C has put my mind into a box, because I've spent so much time programming in C. I hope I can adapt to this style of programming in GML. At least GML doesn't give me that feeling like I am going to be sticking my hand into a nest of ants, like when I was trying to learn x86 asm ( which is unforgiving with little or no margin for errors when something goes unexpectedly wrong in the code ).

Thank you in advance.
 

Niels

Member
I have no C experience, so can't help you on that part. But wouldn't unreal be a more natural fit for you? It uses C++ as scripting language.
On the other hand, I bet you are up to speed in no time in GML if you can already program in C
 

sv3nxd

Member
I would say GML should always be an easy transition, given you know a programming-language already.

I can only speak for GM 1.4, but GM 2 shouldn't be much different.

You will encounter that the compiler isn't too harsh on you like say C. You may add semicolons only in specific cases if you'd like.
(But you can put them as you would normally do, would look weird otherwise)

You have a huge variety of gamedev-specific functions that may help you creating a game.


I think the biggest thing to learn is the inbuild functions and when to use them if necessary, given that your understanding of the fundamentals like loops, arrays and etc exists already.

But even that should be an easy task, as there is a manual-description to every function and preset variable. Just press the middle-mousebutton on the word you'd like to know about.
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
Whats the learning curve from C or C++ to GML?
GML's syntax noticeably borrows from C/C++ but is structured in a way scripting languages are. In other words, it shouldn't take much

In C programming, there is something called "Undefined Behavior" which is a big issue , in GML it does not exist by that name. I tried to look it up by name in the online manual on GMS website but it does not exist. But does undefined behavior exist as something else in GML ?
GML is a generally deterministic language - even if you do something strange (like attempting to sort a list with arrays in it), functions act predictably (in that case, sorting based on address).
Issues related to initialized memory do not exist in such form, as runtime keeps track of what's been already assigned and what wasn't, and anything that wasn't is considered to be a special error-value - if we were to talk on C++ terms, a variable value is a small struct containing an index for it's type and a union containing the actual value (for int32/int64/bool/etc.) or a pointer to it (for strings, arrays, etc.).

Do you have streams in GML ? In C , its stdin, stdout, stderr, and FILE* - as far as I know. In C++ its cin, cout, cerr, and FILE *; ?
Buffer functions take place of streams and are essentially wrappers around read/write pointer manipulation on a raw data block.

Pointers....Dont you have pointers in GML for address referencing , especially for file streams when your reading or writing data to a hard drive, or using arrays?
Being largely a scripting language, GML uses references rather than raw pointers. So if you do
Code:
var a = [1, 2, 3];
var b = a;
a[1] = 4;
show_debug_message(b);
You'd get { 1, 4, 3 } because B is a reference to A and also the internal structure had those few extra bytes of information to let the runtime know that the target is an array.
Also arrays are reference-counted, being destroyed when there's no longer anything holding references to them.
The downside of all this is that you can't take a reference to a variable itself, though that can be workarounded similar to other languages.

  • Every statement in C MUST be followed at the end by a semi-colon, unless it its a conditional test like if () { .... }. Why does GML allow statements like the following?
GML syntax happens to be relatively clearly defined (e.g. a statement can't just be "variablename;") so the compiler is able to figure out where one statement ends and a new one begins save for a few odd situations (where you get a warning).

There are no preprocessor directives or manifest constants in GML - what do you use instead?
The compiler processes any conditions evaluating to a constant value during early compilation phases, so if you have
Code:
#macro DEVMODE 1
and then
Code:
if (DEVMODE) {
    show_debug_message("Development mode!");
} else {
    show_debug_message("Release mode!");
}
it would be compiled as if the code was just
Code:
show_debug_message("Development mode!");
- the implementation for functions called in second branch could be missing entirely, and the compiler wouldn't bat an eye - so long as it doesn't make it to the final executable.

Can you do tail recursion in functions for directory tree searching of a storage medium such as a hard drive or USB flash drives.
Directory search functions in particular use global state so you'd do the search first, store file paths in a temporary array, and then pick through it, either applying actions or launching the next iteration recursively. Mind that the default file system functions are sandboxed though.

The rule of thumb when declaring variables in C or C++ is that you have to initialize their values to 0. when you declare a variable, it is assigned to a address in the computer's memory which may contain a garbage value. In some ways the uninitialized variable may have a value that is 0, which I call, "good garbage", which should never be assumed. Is this true for GML or all declared variables before their assigned values initialized to 0 by GML ?
(explained earlier - variables are either initialized to default values or aren't even allocated before need for them)

which allows the user to pass in arguments to the program from the OS shell. GML does not have a main() like C or C++, but can this be done some other way?
There's parameter_string and parameter_count for that.
 

dphsw

Member
Pointers....Dont you have pointers in GML for address referencing , especially for file streams when your reading or writing data to a hard drive, or using arrays
You can get a pointer to a buffer, but as far as I know the only use for this is if you want to send that pointer as an argument to a function in an extension you've written in C. There's certainly no pointers for the arrays - the 'arrays' in GameMaker aren't really arrays as far as I can tell, since their size isn't fixed, and they can hold multiple data types - I'm not sure how they work under the hood, but what GameMaker calls a buffer is what's really a genuine array as any C-style language would call it, a contiguous block of memory of fixed size. (And even then there's an option to make the buffer NOT a fixed size - I don't know what that does, in terms of memory management.)
 
GML's syntax noticeably borrows from C/C++ but is structured in a way scripting languages are. In other words, it shouldn't take much


GML is a generally deterministic language - even if you do something strange (like attempting to sort a list with arrays in it), functions act predictably (in that case, sorting based on address).
Issues related to initialized memory do not exist in such form, as runtime keeps track of what's been already assigned and what wasn't, and anything that wasn't is considered to be a special error-value - if we were to talk on C++ terms, a variable value is a small struct containing an index for it's type and a union containing the actual value (for int32/int64/bool/etc.) or a pointer to it (for strings, arrays, etc.).
  • Does GML have a feature for user defined structs and unions, like the following..

Code:
// this is a program in C
#include <stdio.h>
#include <string.h>

#define MYSIZE 81
....
 struct myjunk {
    short int number1;
    char mystring[MYSIZE];// in C use the null character to tell the compiler where the end if the array is
};

int main(void)
{
    struct myjunk mybox;// this is an instantiation of struct myjunk
   
    // assign values to the struct members
    mybox.number1 = 23500;
    strcpy(mybox.mystring, "hello world\0");

    // show the values
    printf("%d%s\r\l",mybox.number1, mybox.mystring);

    /* the output should show in the shell:

    23500hello world    
   
    */
 
    return 0;
}
This would look the same for a union, except only 1 value can be stored in a instantiation of a union.

Now I have questions about GML, from what I am reading on the manual

I am using GMS 2 using the HTML5 license version, on my Windows 7 Professional installation. The online GMS manual where it talks about the file system, specifically the platform specific saving/loading section says :

  • Windows and Windows UWP- Windows has all files in the %localappdata%\<Game Name> directory (on Windows 7 this is the /Users/<User Name>/AppData/Local/<Game Name> directory).
These are two different file paths. Does this mean that my game has to test for what platform of windows I am using in order for it to find where the directory ( and sub-directory trees ) are, where my files are stored that my game uses or on a user's computer?

And since I have the HTML5 license, it mentions ( same location in the manual ) :

  • HTML5 - Everything is done through the local storage
......
......

It is worth noting that the HTML5 target modules have a limit on local storage (which can be between 1MB and 5MB depending on the browser) meaning that you will not be permitted to save large sprites, screenshots etc...
Im confused what it means by local storage, I am assuming it means storage of the server where the game would be. But when it states the limit of the local storage* depends on the browser, you dont know what browser someone is going to use. I use firefox/mozilla, other people use IE , Chrome, Opera, or whatever - which changes that limit without notice.

*Now the definition of what GMS calls local storage confuses me because I am not counting on the client, I am counting on the server for storage space. I hope this is not referring to the web browsers cache / temp hold directory on the client side. I dont know if there is a way to determine this memory limit from the client side in Windows. Other factors outside the browser can change how the browser behaves for its memory allocation, like another program that has a higher priority running in the background on the OS platform ( especially in Windows ). Again, I am confused as to what the manual means by local storage on that web page ( I thought it meant the server side when I first read the bullet statement ).

I want to design a game that uses sprites or background pictures of smaller sizes, that are used the in space of 1200 x 600 pixels window for the Windows OS. So if were to design the same game for HTML5 I would have to change that resolution size. But to what resolution size? I dont know, because the manual does not have any other information telling me, on how I can find what my sprite resolution limit is in GMS for HTML5 in this context dealing with local storage.
 

GMWolf

aka fel666
The compiler processes any conditions evaluating to a constant value during early compilation phases, so if you have
Code:
#macro DEVMODE 1
and then
Code:
if (DEVMODE) {
show_debug_message("Development mode!");
} else {
show_debug_message("Release mode!");
}
it would be compiled as if the code was just
Code:
show_debug_message("Development mode!");
- the implementation for functions called in second branch could be missing entirely, and the compiler wouldn't bat an eye - so long as it doesn't make it to the final executable.
Wow neat! I had never thought of that! I have to steal this for a tutorial! (Please)

Does GML have a feature for user defined structs and unions
Unfortunately no. But they say it's coming! (Hopefully).
For now, you can follow this conveniently helpful video :;

Im confused what it means by local storage, I am assuming it means storage of the server where the game would be. But when it states the limit of the local storage* depends on the browser, you dont know what browser someone is going to use. I use firefox/mozilla, other people use IE , Chrome, Opera, or whatever - which changes that limit without notice.
The game runs on the client side (the application host is the client. The server only serves the code) So local storare would refer to the memory on the client.

I want to design a game that uses sprites or background pictures of smaller sizes, that are used the in space of 1200 x 600 pixels window for the Windows OS. So if were to design the same game for HTML5 I would have to change that resolution size. But to what resolution size? I dont know, because the manual does not have any other information telling me, on how I can find what my sprite resolution limit is in GMS for HTML5 in this
I think that's a general HTML5 thing.
https://www.html5rocks.com/en/tutorials/offline/quota-research/
 

YellowAfterlife

ᴏɴʟɪɴᴇ ᴍᴜʟᴛɪᴘʟᴀʏᴇʀ
Forum Staff
Moderator
These are two different file paths. Does this mean that my game has to test for what platform of windows I am using in order for it to find where the directory ( and sub-directory trees ) are, where my files are stored that my game uses or on a user's computer?
If you use relative paths (e.g. "some.txt" instead of "C:\Game\some.txt"), the game would write to the appropriate location; reads prefer the same location and also check in game's directory if nothing's there.

Im confused what it means by local storage,
It's a specifically named thing (type) which allows to store key-value pairs in the browser. So when you write "hello!" to "some.txt", it adds a pair of kind"gamemaker.<game id>.<path>" => "<file content>" to LS.
 
If you use relative paths (e.g. "some.txt" instead of "C:\Game\some.txt"), the game would write to the appropriate location; reads prefer the same location and also check in game's directory if nothing's there.


It's a specifically named thing (type) which allows to store key-value pairs in the browser. So when you write "hello!" to "some.txt", it adds a pair of kind"gamemaker.<game id>.<path>" => "<file content>" to LS.
Do you know if the game id is changed every time the game runs or changes every time you compile the program, with a new value?
 

GMWolf

aka fel666
Do you know if the game id is changed every time the game runs or changes every time you compile the program, with a new value?
unless things changes since GMS1, it stays the same. Its actually really quite usefull when dealing with files, or with online services to differentiate the different products you make.
for instance, you may build multiple games that use the same web service, you can use the game ID to tell what game (as in what product) is accessing the service.

The way it works (or at least, worked, but i dont see why it would have changed), is that the Game ID is generated when you first create the project. (GMS1 offered a way to change it.)
 
Top