Introducción al Desarrollo de Videojuegos con GameMaker · Module 9: Music, Sound Effects, and Particles
Introduction to the Particle System
Lesson 43 of 60 · 60 min
Also available in: ES
What Is a Particle System and Why Use It?
In 2D game development, visual feedback is essential for delivering punchy, dynamic gameplay. Effects such as sparks flying from a sword clash, smoke plumes rising from a torch, dust kicked up after a landing, or bursts when defeating an enemy greatly enhance the player experience. In previous modules, we created interactive game objects like the player (obj_player), patrolling enemies (obj_enemy), and collectible coins (obj_coin). A common temptation for beginners is to instantiate dozens of standard objects with animated sprites whenever an explosion occurs. However, this approach is extremely inefficient.
Every object instance in GameMaker carries significant technical overhead: it stores dozens of built-in internal variables (x, y, hspeed, vspeed, mask_index, depth, solid, etc.), processes its own events (Create, Step, Draw), and participates in the engine's collision tree. If an explosion spawns 150 shrapnel pieces at once and several explosions occur in quick succession, your frame rate (FPS) will quickly plummet. Particles solve this problem: they are lightweight graphic entities without complex individual event lifecycles, mathematically optimized at a low level to render in bulk through a single unified draw pass.
Particle System Architecture in GameMaker
GameMaker's particle subsystem operates under a hierarchical model composed of three core elements: the Particle System, the Particle Type, and the Particle Emitter. Understanding how these three pieces interact is essential for writing clean, modular code free from performance bottlenecks.

The Particle System serves as the global manager or rendering canvas. It determines which layer or visual depth particles appear on, updates the position of all active particles each game step, and manages the internal memory allocated to them. The Particle Type acts as a blueprint or template defining how an individual particle looks and behaves: its base shape or sprite, start and end sizes, color transitions, speed, movement angle, acceleration, and lifespan in frames. Finally, the Particle Emitter is an optional utility used to designate a specific geometric area in the room (a rectangle, ellipse, diamond, or line) to spawn particles continuously or in periodic bursts.
Lifecycle and Dynamic Memory Management
Unlike standard numeric variables or sprites automatically managed by GameMaker's garbage collector, particle systems, types, and emitters reside in dynamic system memory (pointers or data structure indices). If you create a particle system inside an object's Create event and the room restarts without freeing those resources, that allocated memory remains locked in RAM. This critical bug is known as a memory leak and will eventually cause the game to crash. Therefore, every particle resource created in code must be explicitly destroyed when its managing object ends its lifecycle.
| GML Function | Purpose | Recommended Usage |
|---|---|---|
| part_system_create() | Initializes a new particle system manager in memory. | Controller object Create event. |
| part_system_create_layer() | Creates a system bound directly to a specific room layer. | Create event when strict draw order is required. |
| part_type_create() | Allocates memory to define a new particle graphical blueprint. | Create event, after initializing the system. |
| part_particles_create() | Spawns particles of a specific type at an exact (x, y) coordinate. | Step event or collision events for immediate impacts. |
| part_type_destroy(type) | Frees a particle type definition from RAM. | Controller object Clean Up event. |
| part_system_destroy(system) | Removes the container system and destroys all its active particles. | Controller object Clean Up event. |
Step-by-Step: Creating an Impact Spark Effect
For our retro 2D platformer project, we will build a centralized visual effects manager object named obj_fx_manager. This object will initialize the particle systems and types used across the game—such as when the player collects coins, hits walls, or strikes enemies. We will begin by implementing a classic glowing spark effect that radiates outward and fades away smoothly.
Open your project, create a new object in the Asset Browser named obj_fx_manager, and add a Create event. In this event, define the system and the spark type's properties:
// --- OBJ_FX_MANAGER: CREATE EVENT ---
// 1. Create global particle system
sys_efectos = part_system_create();
// Assign visual depth so it renders in front of tiles and characters
part_system_depth(sys_efectos, -100);
// 2. Create and define particle type for sparks
part_chispa = part_type_create();
// Built-in engine shape (use pt_shape_spark for a bright retro look)
part_type_shape(part_chispa, pt_shape_spark);
// Size: initial scale between 0.1 and 0.2, decreasing by -0.005 each frame
part_type_size(part_chispa, 0.1, 0.2, -0.005, 0);
// Color: transition from bright yellow to orange-red
part_type_color2(part_chispa, c_yellow, c_red);
// Transparency (Alpha): starts fully opaque (1.0) and fades to transparent (0.0)
part_type_alpha2(part_chispa, 1.0, 0.0);
// Speed: between 2 and 5 pixels per frame, with slight deceleration (-0.1)
part_type_speed(part_chispa, 2.0, 5.0, -0.1, 0);
// Direction: omnidirectional 360-degree spread without forced rotation
part_type_direction(part_chispa, 0, 360, 0, 0);
// Subtle gravity: 0.15 pixels per frame pointing downward (270 degrees)
part_type_gravity(part_chispa, 0.15, 270);
// Lifespan: particle exists between 15 and 30 frames
part_type_life(part_chispa, 15, 30);
// Additive blending to simulate incandescent glow
part_type_blend(part_chispa, true);💡 GameMaker includes several built-in shapes accessible via constants: pt_shape_pixel, pt_shape_disk, pt_shape_square, pt_shape_line, pt_shape_star, pt_shape_circle, pt_shape_ring, pt_shape_sphere, pt_shape_flare, pt_shape_spark, pt_shape_explosion, pt_shape_cloud, pt_shape_smoke, and pt_shape_snow. These constants let you prototype quickly without importing custom sprite assets.
Now that the particle type is configured, we need a way to spawn it at the exact moment and location an in-game action occurs. For one-shot effects, an emitter is not necessary; the part_particles_create() function allows you to spawn a set number of particles at a precise (x, y) coordinate immediately.
For instance, inside obj_player's collision event with obj_coin, or within obj_coin's Destroy event when collected, we can call the manager's particle system to trigger a burst of golden sparks:
// --- OBJ_COIN: DESTROY EVENT (or collision event with obj_player) ---
// Check that the particle manager exists before emitting
if (instance_exists(obj_fx_manager)) {
// Spawn 12 sparks centered exactly on the collected coin
part_particles_create(obj_fx_manager.sys_efectos, x, y, obj_fx_manager.part_chispa, 12);
}To prevent memory leaks, you must implement the Clean Up event in obj_fx_manager. Unlike the Destroy event (which only fires when an instance is explicitly removed via instance_destroy()), the Clean Up event always runs: when leaving a room, transitioning levels, restarting the game, or closing the window.
// --- OBJ_FX_MANAGER: CLEAN UP EVENT ---
// Destroy associated particle types first
if (part_type_exists(part_chispa)) {
part_type_destroy(part_chispa);
}
// Destroy the main system last
if (part_system_exists(sys_efectos)) {
part_system_destroy(sys_efectos);
}Particle Emitters: Continuous Streams and Ambient Zones
While part_particles_create() is ideal for discrete one-shot events (hits, footsteps, collecting items), particle emitters (part_emitter) are designed to define a spatial region and continuously spawn particles over time or fire bursts across large areas. This makes them well-suited for weather effects like rain and snow, floating cave dust, or sustained vents of steam and lava.
// --- OBJ_FX_MANAGER: CREATE EVENT EXTENSION ---
// 1. Particle type for ash
part_ceniza = part_type_create();
part_type_shape(part_ceniza, pt_shape_pixel);
part_type_size(part_ceniza, 0.5, 1.2, 0, 0);
part_type_color3(part_ceniza, c_orange, c_red, c_dkgray);
part_type_alpha3(part_ceniza, 0.0, 0.8, 0.0); // Fades in smoothly, glows, and fades out
part_type_speed(part_ceniza, 0.3, 1.0, 0, 0);
part_type_direction(part_ceniza, 80, 100, 0, 2); // Upward drifting motion
part_type_life(part_ceniza, 120, 240); // Long lifespan (2 to 4 seconds at 60 FPS)
// 2. Create environmental emitter
emisor_ambiente = part_emitter_create(sys_efectos);
// Define region: spans the full room width along the bottom edge
// Parameters: emitter, xmin, xmax, ymin, ymax, region shape, distribution
part_emitter_region(
sys_efectos,
emisor_ambiente,
0,
room_width,
room_height - 32,
room_height,
ps_shape_rectangle,
ps_distr_linear
);
// 3. Start continuous stream: emits 2 particles every frame
part_emitter_stream(sys_efectos, emisor_ambiente, part_ceniza, 2);When working with emitters, keep in mind that they also consume system memory. While part_system_destroy() automatically frees all emitters bound to that system, it is good engineering practice to destroy emitters manually using part_emitter_destroy() whenever you recreate or reconfigure them dynamically at runtime.
Technical Comparison: Direct Spawning vs. Continuous Emitters
| Criterion | part_particles_create() | part_emitter_stream() / burst() |
|---|---|---|
| Resource Overhead | Minimal (no intermediary emitter structure required). | Slightly higher (stores boundary coordinates and rate data). |
| Ideal Use Case | One-shot effects (sparks, footsteps, impacts, item pickups). | Continuous weather or volumetric effects (rain, constant smoke). |
| Spatial Control | Exact (x, y) coordinates of an object or contact point. | Bounded within a geometric region (rectangle, ellipse, diamond). |
| Execution Model | Spawns once per code invocation. | Emits continuously every frame until explicitly stopped. |
Equivalence in GML Visual
For learners building projects with GML Visual action blocks, the underlying logic is identical. In the Particles section of the visual toolbox, you will find blocks such as 'Create Particle System', 'Create Particle Type', 'Set Particle Shape', 'Set Particle Size', and 'Emit Particles'. Under the hood, each block executes the exact GML functions discussed here. However, in production-grade and intermediate projects, writing this configuration in GML Code within the Create event is significantly faster to balance, track with version control, and maintain.
Practical Exercises
Summary
- Particles are lightweight graphical entities handled internally by the engine, designed to avoid the computational overhead of standard game instances.
- A complete particle setup consists of: a System (manages layers, lifecycle, and rendering), a Type (defines appearance, motion, and lifespan), and optionally an Emitter (defines spawn regions and continuous streams).
- Particle systems and types live in dynamic memory: they must always be freed in the Clean Up event using part_type_destroy() and part_system_destroy() to prevent critical memory leaks.
- Use part_particles_create() for discrete, instantaneous effects (coins, sparks, hit impacts), and reserve part_emitter_stream() for continuous ambient and weather phenomena.
Practise what you learned
Exercise 1 · 1 point
Match each component of GameMaker's particle subsystem architecture with its technical role:
- Particle System
- Particle Type
- Particle Emitter
Exercise 2 · 1 point
Why is it essential to free particle systems and types in the Clean Up event rather than the Destroy event in GameMaker?
Exercise 3 · 2 points
Inside the Clean Up event of obj_fx_manager, release the dynamic memory by first destroying the particle type 'part_chispa' and then the container system 'sys_efectos'.
Your code is not executed: specific requirements are checked on the text.
Sign in to save your progress — Sign in