Introducción al Desarrollo de Videojuegos con GameMaker · Module 2: Sprites, Objects, Events, Instances, and Rooms
Instances in the Room and Hierarchies
Lesson 9 of 60 · 45 min
Also available in: ES
Introduction: The Conceptual Blueprint and the Living Game Entity
One of the most common stumbling blocks when starting out in GameMaker—and in game-oriented programming in general—is confusing the definition of an entity with the active entity existing inside a scene. Developers often use colloquial phrasing like "I placed the player object at coordinate X" or "the coin object disappeared when I touched it." While the intent is clear in casual conversation, these statements are technically inaccurate and can lead to serious programming bugs when writing GameMaker Language (GML) scripts. In previous lessons, you learned how to create sprites, assign them to objects, and program fundamental behaviors across the Create, Step, and Destroy events. However, everything configured in the Asset Browser is merely a template, a theoretical specification, or an architectural blueprint. An object does not inherently exist within the game space: it has no on-screen coordinates, consumes zero draw cycles in the rendering engine, and cannot collide with anything while stored as a project asset. To come to life, that blueprint must materialize inside a level (a Room). That concrete materialization is what we call an instance.

Fundamental Distinction: Object vs. Instance
To internalize this distinction, consider the classic cookie cutter analogy. Imagine a star-shaped metal cookie cutter. The cutter dictates the shape, edges, and ideal dimensions of the star, but the cutter itself is not edible, nor does it occupy space on a baking sheet. The baked dough resulting from pressing that mold into the dough is the actual cookie: you can dust it with sugar, dip it in chocolate, or eat it in one bite without damaging the metal cutter. If you destroy a cookie, the cutter remains untouched in your drawer, ready to stamp out hundreds more. In GameMaker, any asset you create in the Asset Browser with an `obj_` prefix (such as `obj_coin` or `obj_block`) is the cookie cutter or blueprint. It holds the source code determining how entities derived from it should behave, which sprite they render by default, and which events they handle. An instance, by contrast, is each physical, independent copy that you drag into a Room or spawn dynamically via code at runtime. Every instance occupies a specific block of RAM, has an exact position defined by its built-in `x` and `y` variables, and carries a unique numerical identifier called an `id`.
This separation has immediate consequences for your GML code. Imagine you have fifty coins scattered across a level. If you execute a statement referencing the global object asset (`obj_coin`), you might inadvertently modify every single coin at once or arbitrarily read values from just one of them. Conversely, targeting a specific instance reference (its `id`) ensures that your logic operates exclusively on that distinct entity—for example, making only the collected coin burst into particles while the remaining forty-nine continue floating undisturbed.
| Criterion | Object (Asset) | Instance (In-Memory / Room) |
|---|---|---|
| Where does it live? | In the Asset Browser (project files on disk). | In the active Room and in system RAM during runtime. |
| Does it have (x, y) coordinates? | No. It is an abstract asset with no spatial location. | Yes. It has absolute `x` and `y` pixel coordinates. |
| Identifier | Asset index (e.g., `obj_player`). | Unique instance ID (unique reference, e.g., `ref 100024`). |
| Lifecycle | Persists throughout development and project compilation. | Created on Room load or via `instance_create_layer()`; removed via `instance_destroy()`. |
| Variable modifications | Editing defaults in the asset affects future instances. | Modifying instance variables alters only that entity, leaving others intact. |
Placing Instances in a Room: Methods and Layers
A game level or scene in GameMaker is called a **Room**. This is where all visual and functional components come together. However, you cannot drop elements into a scene arbitrarily; GameMaker structures room content through a strict layer hierarchy (**Layers**), visible on the left side of the Room Editor. To place an instance in the scene, the Room must contain at least one **Instance Layer**. By default, when you create a new Room, GameMaker automatically generates an instance layer called `Instances` alongside a `Background` layer. If you try dragging an object from the Asset Browser onto a Background Layer or a Tile Layer, the editor displays a forbidden cursor or rejects the drop, as those layer types lack the underlying infrastructure required to run code or dispatch lifecycle events.
You can place instances onto the canvas using several techniques in the Room Editor: 1. **Standard Drag and Drop:** Click and hold the target object in the Asset Browser (such as `obj_block`) and drag it directly onto the Room canvas, verifying that an `Instance Layer` is currently selected. Releasing the mouse button drops the instance at those coordinates. 2. **Continuous Placement (Alt/Option Shortcut):** Placing individual floor or brick tiles one by one when building a platformer can be tedious. If you select the object in the Asset Browser or layer palette and hold **Alt** (Windows) or **Option** (macOS) while clicking and dragging across the Room canvas, you can paint a continuous stream of instances like a brush. 3. **Quick Deletion:** Holding **Alt + Right-Click** (or boxing entities with a selection marquee and pressing **Delete**) removes instances under the cursor immediately without disturbing surrounding elements.
💡 Grid Snapping: For a 2D platformer, configure the Room grid to match your sprite dimensions (such as 16x16 or 32x32 pixels). You can toggle grid visibility and snapping on or off from the top toolbar of the Room Editor. Precise snapping prevents sub-pixel gaps between solid tiles that could otherwise cause collision detection glitches.
Individual Instance Properties in the Room Editor
Once an instance rests on the Room canvas, it is no longer an immutable clone—it becomes a fully configurable entity. Double-clicking any placed instance, or selecting it with the **Inspector** panel open, reveals its localized, individual properties. GameMaker exposes several built-in variables governing how an instance is displayed and positioned without requiring you to change a single line of code in the underlying object asset:
• **X and Y:** Pixel coordinates in the Room's Cartesian plane. GameMaker positions the origin `(0, 0)` at the top-left corner. Increasing `X` shifts the entity to the right; increasing `Y` shifts it downward. • **Scale (image_xscale and image_yscale):** Geometric scale multipliers. A value of `1.0` renders the sprite at its native resolution. Setting `image_xscale = 2.0` doubles its width. Setting a negative value such as `-1.0` mirrors the sprite horizontally, which is useful for facing enemies or decorations to the left directly in the editor. • **Rotation (image_angle):** Angular tilt expressed in degrees (0° to 360°), rotating counter-clockwise around the origin defined in the Sprite Editor. • **Colour Tint (image_blend):** A color tint applied across the sprite. Defaults to pure white (`c_white` or `#FFFFFF`), which displays original asset colors. Changing this tint to red or purple on an individual `obj_coin` multiplies its color channels, providing visual variation without loading separate graphic assets into memory. • **Alpha (image_alpha):** Opacity level ranging from `1.0` (fully opaque) to `0.0` (completely transparent).
Instance Creation Code and Advanced Customization
While scaling and tinting are useful, the true power of level design lies in customizing **logical behavior** per instance. GameMaker provides two primary approaches: **Variable Definitions** and **Instance Creation Code**. **Instance Creation Code** is a dedicated GML script block executed exclusively for that specific instance. Understanding execution order during room initialization is essential: when a Room loads, GameMaker first runs the object's standard **Create** event. Immediately afterward, if that specific instance has script written in its *Instance Creation Code*, that script runs, cleanly overriding any default values set moments earlier in the Create event.
To open an instance's Creation Code, select the instance in the Room, navigate to the Inspector panel, and click **Creation Code**. This opens an isolated code editor window tied solely to that single placed entity.
// -------------------------------------------------------------------------
// LOCATION: Room Editor -> Click on a specific obj_moving_platform instance
// WINDOW: Instance Creation Code
// PURPOSE: Override patrol variables for this specific platform
// -------------------------------------------------------------------------
// By default, in obj_moving_platform's Create Event we define:
// move_speed = 2;
// travel_distance = 64;
// Here, for this specific platform placed across a wide gap:
move_speed = 3.5;
travel_distance = 256;
horizontal_direction = -1; // Starts moving to the leftThe advantage of this workflow is significant: you do not need ten separate objects in your Asset Browser (`obj_platform_fast`, `obj_platform_slow`, `obj_platform_long`). Instead, you define a single, generic base object (`obj_moving_platform`) and fine-tune its behavior per instance directly within the level.
Hierarchies and Inheritance: The Parent-Child System
As a 2D platformer expands, the number of objects multiplies rapidly. You will soon have stone blocks, breakable bricks, wooden platforms, item boxes, and moving ledges. If your player character needs to stand on all of them, does that mean writing separate collision checks for every block type in the project? Certainly not. Duplicating collision code across dozens of objects violates the foundational software design principle known as DRY (*Don't Repeat Yourself*). If you ever tweak player physics or jump curves down the line, you would have to update dozens of identical events across separate objects, inevitably introducing bugs and making maintenance difficult. To solve this, GameMaker features an inheritance mechanism: **Parenting** (Parent and Child Objects).
Parenting follows a straightforward taxonomic rule: "Every Child is also a member of the Parent family." When you designate an object as a **Child** of another, the child automatically inherits: 1. All events and code logic defined on the Parent object. 2. All variables and default definitions assigned to the Parent. 3. The ability to be recognized in collision functions whenever code checks for the Parent. For example, if you create an empty object with no sprite named `obj_solid_parent`, and then assign it as the Parent for `obj_block`, `obj_stone`, and `obj_wood_platform`, the engine treats all three as instances of `obj_solid_parent` during collision queries.
// -------------------------------------------------------------------------
// LOCATION: obj_player -> Event: Step
// PURPOSE: Unified solid collision check via inheritance
// -------------------------------------------------------------------------
// Instead of checking each type individually with multiple conditions:
// if (place_meeting(x, y + 1, obj_block) || place_meeting(x, y + 1, obj_stone) ...)
// We check only against the solid parent object:
if (place_meeting(x, y + 1, obj_solid_parent))
{
// The player is touching any solid surface in the game,
// whether it is a brick, a stone block, or a floating platform.
is_grounded = true;
}
else
{
is_grounded = false;
}Event Overriding and the event_inherited() Function
A fundamental rule of inheritance is **event overriding**. If a Parent object defines logic in its Create event, and the Child object has no Create event of its own, the child runs the parent's logic automatically. However, the moment you add a Create event to the Child, GameMaker assumes you intend to completely replace the parent's logic with your own. In most scenarios, you do not want to replace the parent behavior entirely—you want to **extend** it. You want the child to execute the shared setup from the parent and then run its own specialized additions. To achieve this without rewriting code, GML provides `event_inherited()`.
// -------------------------------------------------------------------------
// LOCATION: obj_parent_hazard -> Event: Create
// PURPOSE: Initialize universal properties for any hazard in the game
// -------------------------------------------------------------------------
damage_amount = 1;
knockback_force = 4;
is_active = true;Here is how to configure a specialized obstacle, such as poison spikes (`obj_spikes`), which inherits from `obj_parent_hazard` while introducing its own variables:
// -------------------------------------------------------------------------
// LOCATION: obj_spikes (Child of obj_parent_hazard) -> Event: Create
// PURPOSE: Inherit the parent base and add custom properties
// -------------------------------------------------------------------------
// 1. Run the entire Create Event of obj_parent_hazard:
event_inherited();
// 2. Customize or add properties specific to this hazard:
damage_amount = 2; // Spikes deal more damage than standard hazards
poison_duration = 60; // Unique variable that other hazards do not havePractical Case Study: Blocks and Hazards in a Platformer
Let us apply these concepts to structure our retro platformer project cleanly. We will build a baseline hierarchy so our levels feature robust solid surfaces and hazard elements without cluttering our codebase. Follow these steps inside GameMaker: 1. **Create Base Parents:** In the Asset Browser under `Objects`, create an object named `obj_solid_parent`. Leave its sprite empty. Uncheck **Visible** (it acts strictly as a logical container). It needs no events for now. 2. **Create Derived Solid Objects:** Create `obj_block` with the brick sprite `spr_block`, and `obj_stone` with the stone sprite `spr_stone`. In each object, open the **Parent** tab and assign `obj_solid_parent` as the parent. 3. **Create the Hazard Hierarchy:** Create an empty object called `obj_hazard_parent`. In its Create event, initialize `damage_value = 1;` and `can_damage = true;`. 4. **Create Spikes (`obj_spikes`):** Assign it `spr_spikes`. Set its Parent to `obj_hazard_parent`. You do not need any code in its Create event unless you want to override the default damage values.
Practical Exercises
Complete these three hands-on exercises to solidify your understanding of room layouts, instance variables, and inheritance architecture:
Summary
- An Object is an asset blueprint in the Asset Browser; an Instance is an active, tangible entity with coordinates and a unique ID inside a Room.
- Instances must reside on an 'Instance Layer'; dropping them onto background or tile layers is restricted by the engine.
- Holding 'Alt' (or 'Option' on macOS) in the Room Editor enables continuous instance painting, speeding up platform and terrain layout.
- Each placed instance provides editable built-in properties such as x, y, image_xscale, image_yscale, image_angle, image_blend, and image_alpha in the Inspector.
- Instance Creation Code runs immediately after an instance's Create event, allowing you to override variables for that specific entity in that level.
- Parenting allows child objects to inherit logic and be grouped under shared ancestors (like obj_solid_parent), drastically simplifying collision management.
- The event_inherited() function allows a child object to run its parent's event logic before applying unique behaviors or variable overrides.
Practise what you learned
Exercise 1 · 1 point
Within GameMaker's architecture, an serves as the blueprint or conceptual template without coordinates on screen, whereas an is the concrete copy placed in the room that occupies memory, has a position, and possesses a unique identifier.
Exercise 2 · 1 point
What happens if you try to drag an object from the Asset Browser onto a Background Layer or a Tile Layer in the Room Editor?
Exercise 3 · 1 point
Match each built-in instance variable or property to its effect or function in the Room Editor:
- image_xscale set to -1.0
- image_alpha set to 0.0
- image_blend
- id
Sign in to save your progress — Sign in