Quick answer: A GMS2 particle system needs three things to emit visibly: a system created on a draw layer, a particle type with non-zero life, and an emitter with a defined region. Use part_system_create_layer, part_type_create, and part_emitter_region. Skip any one and you see nothing.
Here is how to fix GameMaker particle systems that produce no visible output. You wire up a system, type, and emitter in your Create event, call part_emitter_burst on click, and the screen stays empty. No errors. The particle system index is valid. The fix is almost always one of three things: the system has no layer, the type has zero life, or the emitter has no region.
The Symptom
You set up a particle system in Create, call part_emitter_burst(ps, em, pt, 50) in a Step or button-press event, and see nothing. The particle system index is a positive integer (so creation succeeded), but no particles ever appear on screen.
What Causes This
System has no layer. part_system_create in GMS 2.3+ creates a system at depth 0 with no layer assignment. If your room layers do not include depth 0 visibly, the particles draw under everything else. Use part_system_create_layer instead.
Particle type has zero life. If you forget part_type_life, the type defaults to a 0–0 life span. Particles are emitted and immediately destroyed in the same step.
Emitter region is a single point. Without part_emitter_region, particles emit from (0,0) which may be off-screen in your view. Set the emitter region to the position you actually want.
Type or emitter destroyed prematurely. Calling part_type_destroy in the same Create event destroys the type before bursts can use it.
The Fix
Step 1: Create the system on a layer.
// Create event of oVfx
ps = part_system_create_layer("Effects", false);
// Particle type (a small white spark)
pt = part_type_create();
part_type_shape(pt, pt_shape_pixel);
part_type_size(pt, 0.5, 1.5, 0, 0);
part_type_color1(pt, c_white);
part_type_alpha2(pt, 1, 0);
part_type_life(pt, 15, 30); // Critical: non-zero life
part_type_speed(pt, 2, 5, 0, 0);
part_type_direction(pt, 0, 360, 0, 0);
// Emitter
em = part_emitter_create(ps);
part_emitter_region(ps, em, x - 8, x + 8, y - 8, y + 8, ps_shape_ellipse, ps_distr_linear);
Make sure the layer name “Effects” exists in your room. If not, create one or use the room’s default Instances layer.
Step 2: Burst when needed.
// On click or hit event
part_emitter_burst(ps, em, pt, 40);
Step 3: Update the emitter region for moving sources. If your particle system follows a moving object, update the region every step:
// Step event of moving object
part_emitter_region(ps, em,
x - 8, x + 8,
y - 8, y + 8,
ps_shape_ellipse, ps_distr_linear);
Step 4: Free resources on cleanup.
// Clean Up event
part_emitter_destroy(ps, em);
part_type_destroy(pt);
part_system_destroy(ps);
Step 5: Persistence for cross-room effects.
part_system_persistent(ps, true);
persistent = true; // instance variable on the controller object
Both flags are needed: the system itself must be persistent, and the owning instance must survive the room change so the indices remain valid.
Verifying With a Visual Test
Drop a part_emitter_burst directly in your Step event temporarily so it bursts every frame at the player’s position. If you see a constant stream, the system works and your trigger code is the issue. If you see nothing, recheck life span and layer assignment.
Common Off-By-One Mistakes
The argument order for part_emitter_region is (ps, em, xmin, xmax, ymin, ymax, shape, distribution). Putting xmax before xmin produces an invalid region that emits from a single corner. Always order min-then-max, X then Y.
“Layer, life, region. The three things every visible particle system needs. Forget one and you see nothing.”
Related Issues
For other GameMaker rendering issues, see Room Transition Flicker and Layer Depth Draw Order.
Layer for the system. Life for the type. Region for the emitter. Three pieces, one effect.