Warning: the following was written for GM version 5.3 in about 2005. The principles still hold true but the details may have altered since.
GM cycle execution sequence:
The precise sequence of the first two event types is probably unimportant
Note that Alarm events are processed before keyboard and mouse events. If an alarm event sets it's alarm to 1 it will cause the event to run every cycle. This has changed in Studio as alarms now count down to -1. I do not know what problem this change was meant to fix. One-tick alarms allow the programmer to create an extra step event that can be switched on and off.
There follows the user input events
It is fairly common practice to put AI code in the normal step event. With care this can make it relatively simple to derive player controlled and non player versions of the same object.
It is useful to note that the normal step event always occurs after keyboard and mouse events. As such it can be used as a "clean up" event for a player controlled object.
It is also worth noting that if you want to have doubled up controls, such as cursor keys AND WASD, then it may be easier to test the keys in "step" and NOT use the built-in key events.
Standard advice is to keep code out of step events as it runs for every instance. If there is only one "Player" object then the "cost" of having a step event in player is usually insignificant.
Note that there is little control over the order that collision events are calculated in. It may be possible to engineer the sequence of instance ids to get collisions evaluated in a specific order, but such editing is almost certainly impractical.
Collisions with solid objects are handled a special way, which appears to mean that if and only if there is an event handler for the collision in at least one of the colliding objects then the position of the object is put back to where it is before the move. Strictly speaking it is put to the position (xprevious,yprevious). Advanced programmers may exploit this by modifying xprevious and yprevious. Alternatively if an event may be triggered by both solid and non solid objects it may use the values of xprevious and yprevious in the event, so ensuring consistent results for both object types.
There are two odd special cases:
In a collision between a solid and non-solid object both objects will have their positions reset. Normally the solid object will be a stationary "wall" block and will be unaffected but this behaviour can cause side effects when a solid object moves, such as a moving platform.
If neither object has an appropriate collision event the collision is completely ignored.
It seems likely that if the object was "Free" beforehand the first collision with solid would put it back to a free position so only one collision with solid will be executed regardless of how many solid objects were hit. This is as yet unproven.
End step is a surprisingly useful "slot" for code. Friction, gravity and collisions have already taken place. You can put code to "tidy up" the object's position here. An example would be code to ensure that a platform game character is standing on ground.
Generally you should be wary of large changes to an object's position at this point as if the object is moved to touch another object the resulting collision will not be detected until the next cycle.
Draw events should only contain drawing code. If views are used the draw event will be executed repeatedly once per view. Also note that objects are free to draw anywhere, this means the draw event is executed for off-screen and off-view objects.
If an object's draw code is complex and there are many instances of the object and multiple views you might want to add a condition to the draw event to suppress drawing when your object is off-screen. The draw code will be called once for each view even if the object is outside the view.
Draw GUI is a special draw step that IGNORES VIEWS and overlays all other drawing regardless of depth. This is intended to be where you put your code to draw score, health and lives. As it is separate from the regular draw event it means the normal sprite draw will still take place. This means it is possible for a player object to draw its own score.
If you add your own draw event then the instance is free to draw wherever it likes regardless of bounding boxes, so although the sprite may be out of view the draw code might still draw within the view. An example of this would be a game's "score" control object. This also means that if you are performing elaborate slow draw functions you may need to test to see if the drawing is out of view and skip operations that will not be seen.