Today I'll be talking about an interesting trick involving Game Maker's constants.
Constants are basically just like variables, only you can't change them at runtime; you can only change them using the constants form when developing the game. Having grown up with 16-bit video game consoles, I always visualise constants as being in ROM while variables are in RAM - this is purely an analogy, though, as it hardly describes what's really going on in a modern computer.
The cool thing about Game Maker's constants form is that it is more powerful than it really lets on. The documentation is fairly vague; it says "A value of a constant should be a constant expression. That is, it is either a constant number or a string (with quotes around it) or it is an expression." This hints at, but does not make explicit (especially for beginners), the fact that you can use functions for the value of your constants. Or more accurately, the return values of functions.
There are limitations, of course. You can only use Game Maker's built-in functions, and not your own scripts. But you can do stuff like the following example:
The constant DISPLAY_WIDTH will equal the result of the display_get_width() function (the width in pixels of the user's display at its current setting). Now, I must make it exceedingly clear, because this can confuse beginners (as once it did me), but the constant will be, well, constant. Using DISPLAY_WIDTH in your code will not call display_get_width() and give you a new result each time. Constants are evaluated at the very beginning of the game when it runs, so the only time display_get_width() gets called is then; the return value (and only the return value) is stored in DISPLAY_WIDTH.
(Of course display_get_width() is only used as an example, because it's a simple function to understand. In practice you may never use it, because the user (or the game itself) might change the display settings at some point.)
You can go even further, nesting functions like so:
So this is much like what you might do in code or a script, e.g.
Which begs the question... why bother using a constant at all? Why not just use variables like so?:
There are two advantages to constants in my opinion. First, they are colour coded in Game Maker's code editor, and are also part of the auto-complete feature. This is very helpful when coding. And second, it's often cleaner to put them into the constants form that is already provided rather than writing a script full of globalvar and then calling it somewhere in your code.
So now that the basics of using functions for constants are established, I want to get to the "trick" that is the point of this post. Because Game Maker's data structures are created by calling a function, you can make constant data_structures, like so:
To be fair, the functions that create data structures return a reference, or "handle", for the newly created data structure, to be used with other data structure functions. The constants will only be the handle; the data structure itself can still be manipulated. However, because of the two advantages to constants mentioned above, this might still be something you want to do if you have a data structure which will exist for the entire duration of your game.
If this was all you did, then it would still be up to code or scripts to define the contents of the constant data structures. But you can fill in those constants using the constants form, as well. Observe:
Using a second constant, the ds_list_add() function is called, adding a value to the list pointed to by CONSTANT_LIST. The second constant is named using three underscores; it could be anything, but since we don't care to ever use it (it will only contain the return value of ds_list_add(), which is unimportant) the name should be something that won't cause conflicts.
It so happens that it's not possible to perform multiple functions per constant, e.g. separated by semicolons. You won't get an error if you try, but only the first function will be evaluated. But you can just use multiple constants to do as many functions as you want. And, because constants can be multiply defined, only one name need be used, like so:
Of course this might get rather silly after a while, filling your whole constant form with functions to fill a list. However, the data structure functions for reading and writing to strings will work just fine. So the following has the identical effect as the example above that added three values using separate function calls:
Maybe this trick will come in useful someday for you Code Ninjas. If not I hope it was interesting to those who are as fascinated by Game Maker exploits as I am.
Until next time, happy coding!