Quick answer: A particle system draws at its own depth. Set it with part_system_depth, or set part_system_automatic_draw(sys, false) and draw it yourself with part_system_drawit in a Draw event.
Smoke particles always render in front of the player, or always behind — they ignore the entities’ depth sorting entirely.
Particle Systems Have Their Own Depth
A particle system isn’t an instance; it’s drawn automatically at the depth set on the system. By default that depth may not interleave with your instance depths.
Set the System Depth
sys = part_system_create();
part_system_depth(sys, 100); // lower = drawn in front
Pick a depth that sits where you want particles relative to your sorted instances (e.g. for top-down y-sorting, match the emitter’s -y).
Or Draw It Manually
// Create event
part_system_automatic_draw(sys, false);
// Draw event of the emitting instance
part_system_drawit(sys);
With automatic draw off, the system renders exactly when (and at whatever depth) you call part_system_drawit — full control, interleaves perfectly with instance draws.
Per-Emitter Depth
If different particle effects need different depths (smoke behind, sparks in front), use separate systems with separate depths — one system has one depth.
Verifying
Smoke from a chimney draws behind the player when the player is in front, and in front when behind. Sparks layer correctly. No always-on-top artifacts.
“Particle systems draw at the system’s depth. Set it, or take manual control with part_system_drawit.”
For y-sorted top-down games, manual draw in the emitter’s Draw event is cleanest — particles inherit the emitter’s sort position automatically.