Function overrides – what are they, and how do they work?
By using macros, you can make a function call a script instead, thanks to the fact that macros essentially act as a global Find-n’-Replace, effectively Overriding the original Function.
Why might you want to do this? Why not just have a wrapper script and use that instead? That depends. In my case, I’ve used this previously to track the existance of data structures to make sure there weren’t any related memory leaks. While I could’ve made a wrapper function and replaced all occurrences in my code, it was simply easier and more readable to use an override, and I didn’t have to remember to use the new script name. On top of that, for a release build, I could just disable the macro and the script call overhead (even if small) is immediately removed, without having to edit my code again.
Anyway, here’s a quick override example — #macro builtin_function_name script_name
will make any calls to builtin_function_name()
call the script script_name()
instead, and pass all the same arguments.
This means you can change how a function behaves, or grab and store data that is normally passed to it so you can check it again later – or do both!
However, sometimes we still need a way to call the original functions – but how? We can’t call the function name anymore, since that points to a script! And GameMaker doesn’t have a super()
method built-in, given that it doesn’t need one in normal circumstances…
Luckily, you can point back to the original function! How? With another macro, of course! #macro point_back_to_original_function builtin_function_name
allows you to access the built-in function again by calling point_back_to_original_function()
with the same arguments as the original function – Neat! Let’s look at a more practical example – writing out debug messages to a file (this script is called _show_debug_message
in the IDE):
📝 Script: _show_debug_message(string)📋///@func _show_debug_message
///@arg message
///@description Write a debug message to a text file, then output to console
//Define override macros
#macro show_debug_message _show_debug_message
#macro ori_show_debug_message show_debug_message
//Get the argument
var message = argument0;
//Write to the file
var file = file_text_open_append(global.DEBUG_FILE_PATH);
file_text_write_string(file, message);
file_text_close(file);
//Output to the console too
ori_show_debug_message(message);
It’s as easy as that! And you can do far more with it too, if you feel like it! (Also, you can still return the result of the function if you need to, if you’re overriding a function that does return a value)
I like to define the macros inside of the overriding scripts so I can find them easier, but you don’t have to do that.
These override methods can work for regular scripts too, but that’s not usually as useful.
So that’s that! Overriding functions using macros is really quite easy! You do need to be careful in some cases though, so here’s a few of things to watch out for:
- Macros that point to other functions or scripts do not have intellisense
- If 2 scripts attempt to override the same function, a macro error will occur, and the game will not compile, so systems that use macro overrides may not be compatible with each other.
- You can’t override functions that are already being called via a macro – so if someone has a macro like
#macro sdm show_debug_message
so they only have to typesdm()
to put out a debug message, overrides toshow_debug_message()
will not affect the shortsdm()
macro – only direct calls toshow_debug_message()
- Overriding scripts need to either accepts the same number of arguments as the original script or use optional
argument[index]
arguments, or else they’ll cause a crash or prevent compiling.
Happy Coding!
thanks love you bye 💙