Introducción al Desarrollo de Videojuegos con GameMaker · Module 2: Sprites, Objects, Events, Instances, and Rooms
Core Events: Create, Step, and Destroy
Lesson 8 of 60 · 60 min
Also available in: ES
Introduction: GameMaker's Event-Driven Architecture
In previous lessons, we explored what a sprite is and how to bind it to an object to give it a graphical representation within the game world. However, a static image alone does not make a video game. For an entity to come alive, make decisions, respond to player input, and disappear at the right moment, it requires internal logic organized over time.
GameMaker runs on an event-driven architecture. This means the engine does not execute a single, massive block of sequential code from start to finish. Instead, it breaks down the behavior of each element into specific contexts called "Events." Events are automatic triggers telling the engine: "when this occurs in the virtual world, execute this block of instructions immediately."
Among the wide array of available events, three form the backbone of any entity's lifecycle: Create, Step, and Destroy. Mastering the exact timing and frequency of these three events is the foundation for building solid gameplay mechanics, from player movement to projectile handling and enemy management.
The Instance Lifecycle
When we place an object in a room or spawn it dynamically via code, the engine is not manipulating the abstract object template, but rather a live, unique "instance" of it in RAM. Every instance moves through a predictable lifecycle made up of three distinct stages: its birth into the game world, its active frame-by-frame existence, and finally its removal from the scene.

Understanding this flow prevents the most common beginner pitfalls, such as redeclaring variables inside repeating events or expecting initialization code to run again without respawning the instance.
The Create Event: Birth and Initialization
The Create event fires only once across the entire lifespan of an instance, at the exact moment that instance appears in the game world. This happens in two scenarios: when loading a room if the instance was placed manually in the Room Editor, or dynamically during gameplay via creation functions such as `instance_create_layer()`.
The primary role of the Create event is state initialization: here we declare all variables the instance will need throughout its existence, define baseline values (health, movement speed, state flags, timers), and perform any one-time setup calculations that should not repeat.
💡 Golden Rule: Never reference a variable in a Step or Draw event without initializing it in the Create event first. Attempting to read an unassigned variable causes GameMaker to crash with an unhandled runtime error.
Let us see how to structure the Create event for our main player character in a platformer project. In the Asset Browser, select the `obj_jugador` object, click "Add Event," choose "Create," and select "GML Code" as your scripting method.
// ========================================================
// OBJECT: obj_jugador
// EVENT: Create
// PURPOSE: Declare control and movement variables
// ========================================================
// Speed and movement physics
velocidad_horizontal = 0;
velocidad_vertical = 0;
velocidad_caminar = 4;
gravedad_fuerza = 0.3;
fuerza_salto = -7;
// Character stats and state
puntos_vida = 3;
estado_actual = "quieto";
puede_moverse = true;
// Debug console message confirming instance creation
show_debug_message("obj_jugador instance created successfully.");In this snippet, we establish baseline properties for our player. Variables such as `velocidad_caminar` store values determining movement speed, while `puntos_vida` tracks durability before defeat. Notice that the Create event does not move the player; it simply prepares the internal state so the rest of the engine can operate on valid data.
The Step Event: The Engine's Beating Heart
Unlike the Create event, the Step event executes continuously on every single game frame. If your project's frame rate is set to 60 frames per second (FPS, the default in GameMaker), code inside the Step event runs exactly 60 times each second for as long as the instance exists.
The Step event serves as the primary update loop for the entity. This is where real-time logic belongs: reading keyboard or controller inputs, applying gravity to vertical positions, checking proximity to obstacles, and updating state machines.
Inside GameMaker, the Step event is split into three specific sub-events that execute in a strict sequence during each frame cycle:
| Sub-event | Execution Order | Recommended Use |
|---|---|---|
| Begin Step | 1. Start of the frame | Pre-update tasks, resetting temporary flags, and reading input sensors before main gameplay logic processes. |
| Step (Main) | 2. Middle of the frame | Processing player inputs, computing physics, evaluating AI decisions, and executing core mechanics. |
| End Step | 3. End of the frame | Camera updates to track moving targets, final position corrections, and sprite direction synchronization. |
For the vast majority of your gameplay code as you start out, the standard Step event (the middle one) is the ideal place to implement your control mechanics.
Let us examine a concrete example. In the same `obj_jugador` object, add a standard Step event with the following code. Notice how this script relies directly on the variables initialized in the Create event:
// ========================================================
// OBJECT: obj_jugador
// EVENT: Step
// PURPOSE: Read inputs and update the x/y position
// ========================================================
// Check if the instance is authorized to process movement
if (puede_moverse == true)
{
// Read keyboard inputs (Arrow keys or A/D)
var tecla_derecha = keyboard_check(vk_right) || keyboard_check(ord("D"));
var tecla_izquierda = keyboard_check(vk_left) || keyboard_check(ord("A"));
// Calculate horizontal direction: 1 (right), -1 (left), or 0 (idle)
var direccion_horizontal = tecla_derecha - tecla_izquierda;
// Calculate horizontal speed in pixels for this frame
velocidad_horizontal = direccion_horizontal * velocidad_caminar;
// Apply movement to GameMaker's built-in X coordinate
x = x + velocidad_horizontal;
}
// Health check: if health reaches zero, trigger instance removal
if (puntos_vida <= 0)
{
instance_destroy();
}This code highlights the synergy between Create and Step. In Create, we declared `velocidad_caminar = 4` once. In Step, that value is processed 60 times per second based on the user's inputs, smoothly updating the instance's `x` coordinate.
💡 Performance Warning: Avoid allocating large data structures or hard-coding variable resets inside the Step event unless intentionally recalculating them. Writing "speed = 5;" inside Step overwrites that memory address 60 times a second unnecessarily and prevents other events from modifying that value dynamically.
The Destroy Event: Clean Exits and Memory Order
The Destroy event triggers at the exact moment an instance is removed from the game world by a call to the built-in function `instance_destroy()`. Like Create, it runs exactly once per instance, immediately before GameMaker deallocates the entity from memory.
It is critical to distinguish between two lifecycle end events in GameMaker: "Destroy" and "Clean Up." While Destroy is called specifically when an instance is removed intentionally as part of gameplay rules (such as an enemy dying or a coin being collected), the Clean Up event runs whenever an instance leaves memory for any reason, including closing the game or transitioning between rooms.
The Destroy event is the ideal location to trigger consequences that must happen as a direct result of an entity's removal: spawning an explosion effect, dropping loot when an enemy is defeated, awarding points to the score manager, or playing a shatter sound.
Let us write the complete implementation of this projectile to observe how all three events work together cohesively.
// ========================================================
// OBJECT: obj_disparo
// EVENT: Create
// ========================================================
velocidad_bala = 8;
direccion_x = 1; // 1 = right, -1 = left
tiempo_de_vida = 120; // At 60 FPS, 120 frames equal exactly 2 seconds// ========================================================
// OBJECT: obj_disparo
// EVENT: Step
// ========================================================
// 1. Move the bullet continuously in the set direction
x = x + (velocidad_bala * direccion_x);
// 2. Decrement the lifetime counter by 1 each frame
tiempo_de_vida = tiempo_de_vida - 1;
// 3. Check whether the lifetime has expired
if (tiempo_de_vida <= 0)
{
// Calling this immediately triggers the Destroy event and removes the bullet
instance_destroy();
}// ========================================================
// OBJECT: obj_disparo
// EVENT: Destroy
// ========================================================
// Debug message simulating impact particle creation
show_debug_message("Projectile impacted or expired at X: " + string(x) + ", Y: " + string(y));
// Secondary effects such as impact sounds or smoke sprites would be spawned hereKey Events Comparison
To reinforce when to choose one event over another during object architecture, use this comparison table as a quick reference guide during your development sessions:
| Event | Trigger Frequency | Primary Responsibility | What NEVER to Do Here |
|---|---|---|---|
| Create | Once, at the exact moment the instance is instantiated. | Declaring variables, setting initial parameters, and configuring timers. | Polling keyboard or gamepad inputs (the player cannot press keys in the sub-millisecond of instantiation). |
| Step | Repeated every frame (typically 60 times per second). | Checking inputs, calculating collisions, updating x/y coordinates, and running AI logic. | Declaring new variables meant to accumulate or persist data across frames. |
| Destroy | Once, immediately before being deallocated from memory. | Granting rewards (points, loot), leaving debris, or spawning explosion instances. | Attempting to move the instance or assigning it new continuous movement logic. |
GML Code versus GML Visual Across the Lifecycle
While this course uses GML Code as the industry-standard workflow for speed, clarity, and modularity, GameMaker also offers GML Visual (formerly Drag and Drop). In GML Visual, these three events follow the exact same timing logic. The only difference is visual representation: instead of writing statements like `x = x + velocidad`, the developer drags action blocks such as "Assign Variable" into the event action list.
Events are not tied to a specific syntax; they are the engine's internal mechanism for synchronizing the simulation loop. Mastering the sequence of Create, Step, and Destroy allows you to code comfortably in GML and easily translate logic from visual scripting tutorials across the community.
Hands-On Activities
Complete the following three practical exercises in your GameMaker project to consolidate your understanding of event timing and observe their runtime behavior firsthand.
Summary
- The lifecycle of a GameMaker instance is driven by predefined events responding to key stages of the simulation loop.
- The Create event triggers once upon instance instantiation; its primary role is to initialize variables with safe defaults.
- The Step event executes once per frame (typically at 60 FPS) and hosts movement logic, input polling, and real-time detection.
- The Step event includes complementary phases: Begin Step (early-frame setup) and End Step (post-movement adjustments and camera tracking).
- The Destroy event runs immediately before an instance_destroy() call frees the entity from memory, making it ideal for visual effects, drops, or death audio.
Practise what you learned
Exercise 1 · 1 point
Match each core GameMaker event to its purpose and timing within an instance's lifecycle:
- Create Event
- Step Event
- Destroy Event
Exercise 2 · 1 point
What happens in GameMaker if you try to read or use a variable in the Step event without defining it first in the Create event?
Exercise 3 · 1 point
Complete the statements about GameMaker's core lifecycle: 1. The event acts as the main update loop, executing continuously on every single frame. 2. To remove an entity from the game world and trigger its cleanup event, you call the built-in function ().
Sign in to save your progress — Sign in