Welcome to the GMC! It's always refreshing to see someone new and enthusiastic trying to tackle things step by step instead of diving in head first. You're on the right track already!
I'll be responding to the aspects I believe could use some elaboration or haven't been directly answered yet.
Familiarize yourself with the basic event types you'll likely find yourself using most commonly: Create, Step, Draw, Destroy and Cleanup.
- The Create event runs when an instance of the object is created, and only then.
- You mainly put declarations into this event, or anything else that needs to happen exactly once when an instance is created and never again.
- The Stepevents run every step (also called frame).
- You put your game's ongoing logic into this event - anything that needs to be continuously checked or changing.
- The Begin Step event fulfills the same purpose, but all Begin Step events run before all Step events. All End Step events run after all Step events. The order is: All Begin -> All Step -> All End.
- The Drawevents run every step (unless explicitly disabled or the instance is invisible).
- You put your game's drawing into this event.
- Common pitfall: Merely having a Draw event disables the automatic drawing of the object's instances. This can be re-enabled by calling draw_self or its DnD equivalent Draw Self.
- These are the only events in which drawing functions will show a visible effect by default. Your drawing will be overwritten by the room's background otherwise - unless it doesn't have a background. However, the engine is optimized to handle drawing in the Draw events, so you should avoid drawing outside of them.
- The Draw Begin and Draw End events fulfill the same purpose and are ran in the order of Begin -> Draw -> End, similarly to the Step events.
- The Draw GUI event and its Begin/End variations run after all the other draw events and disregard the location of any cameras and can be scaled and sized separately from all other drawing. This is useful for user interface elements, for example.
- The Destroy event runs when an instance is explicitly destroyed, for example via instance_destroy.
- You can put any code that should run when an instance is destroyed into this event, such as sound effects when an enemy dies.
- There is no guarantee for this event to run over the course of an instance's life span.
- The Cleanup event runs when an instance is removed for any reason, for example when it is destroyed or you leave the room it was in.
- You put deallocations for dynamic resources such as lists, grids or maps (which were declared in the Create event) here.
- There is a guarantee for this event to run over the course of an instance's life span.
- This is the counterpart of the Create event, as it denotes the end of the instance's life span.
Internalize these and you will be able to plan out the life span of your objects' instances clearly.
Declare the variables and resources they will be using in Create.
Control how they behave in Step.
Control how they look in Draw.
Make them go out with a bang in Destroy, if applicable.
Free up memory used by the used resources in Cleanup to avoid memory leaks.
Common function families include the keyboard, mouse, draw, collision and random functions (the manual should yield relevant results for these terms).
Other extremely useful functionality includes things like arrays and the dynamic data structures: Lists, grids, maps, and the somewhat more rarely applicable queues, stacks and priority queues.
In terms of controlling the flow of your code, the available statements can be found on the
Language Features page.
Avoid setting anything as
solid, as you're handing over control over positioning while there is a collision involving a solid instance going on. This is probably the most common cause of beginner frustration.
That aside, avoid relying on events (other than the Step/Draw order I mentioned earlier) executing in a specific order - because they don't. This behavior is subject to change at any point in time. Anything that is critical to execute in a specific order should rely on the Step chain (or depth (1.x) / layers (2.x) for drawing). A classic example of this is "attaching" one instance to another to make them move as if they were one - if you put movement and following of each into the Step event, you have a 50% chance of it working out fine (if the follower's code runs after its target's) and a 50% chance of the follower lagging behind by one frame (if the follower's code runs before its target's). Correct ways to handle these would be to either handle it in a single event (the main body moves, then positions its attachment) or having the follower's code in the End Step event.
The Execute Code action is what lets you use GameMaker's programming language, GML, instead of the visual DnD blocks. GML has everything DnD has (and more). If you wish to use GML, Execute Code is indeed all you need.
Note that in GameMaker Studio 2, you have the option to purely use GML, without the need to put Execute Code blocks everywhere - this interface basically makes object event and script windows look like a text editor and may therefore seem more familiar to you due to having experience with C++.
Reading the
entirety of the manual is not at all required. A lot of manual sections will deal with platform-specific functions you likely will not be using for a long time to come, if ever. The common function families I mentioned earlier are a good starting point to get a good grip of the basic foundation.
Definitely read up about the difference between instances and objects, as this is something that is often mixed up and then becomes the result of frustration. You can think of this as the difference between objects and classes in C++.
How to address variables in other instances is also a good topic to research.
In general, the manual is an extremely valuable resource to just keep open at any point in time so you can look up new or unfamiliar stuff. Note that you can middle-click a function you're unsure how to use to bring up its manual page.