A couple of things:
Code folding is useful if you don't overuse it, as you can use #region and #endregion to hide very lengthy bits of code when you don't need them, and can just comment what the section does.
Finite state machines almost always have a place somewhere in your game, especially with the types of games that are popular with the GameMaker community. They're probably the single most useful code organization concept I've discovered since my early days. I used to spam nested if statements with tons of variables that held conditions. Turns out, it was processing the same logic as a finite state machine, but with half of the efficiency and 1% the elegance.
Use enumerators if you find yourself using multiple if/else statements or a switch statement with a single variable, and you're comparing strings as placeholders, just use an enumerator. They're more efficient, easier to read, global, and they pop up in code completion, so you always have the list of them at your fingertips.
Imagine you have an inventory system, where each position of the inventory has a few properties, such as: item, color, effect, damage, durability, count, etc.
You could set up an enum as such:
Code:
enum inv
{
item,
color,
effect,
damage,
durability,
count
}
Ternary statements can sometimes be much simpler than a bunch of if/else statements, so use them when you can, but only when they make sense. I tend to overuse them, but I feel that it makes my code more concise. For example:
Code:
if ( mouse_over )
{
image_blend = c_gray;
}
else
{
image_blend = c_white;
}
versus:
Code:
image_blend = ( mouse_over ) ? c_gray : c_white;
Some people will disagree with me on this, but
use macros. You can create a script called "macros" and define all of your macros with the #macro tag. I use them as a list of constants, and tend to find them useful as arguments for specific parameters in scripts. For example, I have a clk function that simply counts down to zero and then resets to the start number when it's done, but you can also input the macro "CLK_NO_RESET" as the reset parameter. If the script recognizes that as the argument, then it simply doesn't reset the clock.