I'm making a game in Game Maker that involves the player leaving a trail of debris behind them. This trail is permanent and has gameplay implications (for which I'm using a fairly coarse grid to store the player's movements), so I need to draw it on the screen. I'm comfortable with GML.

I have a sprite (with subimages) that represents the debris left behind. I'm not sure of the best way to go about it. Surfaces perform well and are straightforward to my mind - I draw the trail to the surface, then the room draws the surface between my objects and the background - but my rooms are more than a screen, and surfaces seem intended more as an image buffer than as a large background. A background resource I edit as I go would probably be better, but this doesn't appear to be an appropriate use of backgrounds.

Is there another approach that would work better? One consideration is that I need to be able to store the trail at checkpoints so that it's not destroyed if the player dies.


Having a surface that draws over your entire level probably wouldn't be a good idea in terms of memory usage, but a background that does the same thing would not be any better, in fact it would be worse. You might not have any problem just having each trail piece as an individual object, but objects are pretty heavy weight and can slow your game down if you have too many. One way that could work is having a single object draw the sprite repeatedly in the correct locations. I recommend storing the trail locations in a ds_grid then in the draw event of your trail drawing object you can have:

for(i = 0; i < ds_grid_width(trailGrid); i+=1)
    draw_sprite(trailSprite, subimage, ds_grid_get(trailGrid, i, 0), ds_grid_get(trailGrid, i, 1))

where the x values are stored in the 0 position in the grid and y is stored in 1. But all those draw calls will quickly get out of hand in terms of speed. Basically you have to choose whether to sacrifice memory or speed, whether you have a surface drawn over the whole level or you make lots of draw calls. But wait! Theres a third option. Deactivating instances.

You could have each trail be an instance and deactivate them when they are out of view, this will cause them not to take up processing time while they can still be reactivated in the game.

instance_activate_region(view_xview[0] - 64, view_yview - 64, view_wview[0] + 64, view_hview + 64, false);

This will deactivate all the trail objects in the room and activate the ones in the view, with a little buffer on the sides. A note of warning from the GM manual: "It is normally not necessary to deactivate instances every step of your game and this can actually cause your game to lag and runs slow. Instead it is recommended that you only run these functions every few steps in an alarm (for example), or if the view has changed position, and it is especially important that you do not use these functions in the draw event as this can lead to serious errors in your game."

This is probably your best bet as it will save you processing speed without killing your memory.

  • \$\begingroup\$ I ended up storing the locations of my sprites and drawing them to a surface the size of the view, with some culling if they were off-screen, but the instance_deactivate and instance_activate are both new. \$\endgroup\$ – Merus Oct 11 '14 at 2:46

Your Answer

