Optimizing Your Game Maker Game
Intro: Since I'm a pretty mediocre programmer, I often go for an easy solution to my coding problems rather than an efficient one. Game Maker is kind of notorious for being slow anyway, so it didn't take long for me to hit its limits. But with a little research, and some good advice from experienced GM users, I started to make some optimizations to my game that significantly increased its speed. And now I pass that knowledge down to you!
Here are some tips, from what I think is the most important, to leaster.
1. Deactivate/Destroy Unused InstancesObject instances slow down Game Maker a LOT. I've heard that ~50 instances is the most that you should have awake at once. And the more work an object is doing each step, the slower it will be, so take care to make sure nothing is awake if it's not needed.
To that effect,
instance_destroy() and
instance_deactivate() are your friends. Try deactivating anything that's outside of the player's view, and destroy anything that's outside of the room.
For example, put this in the Step Event of an invisible object that sits in each level:
instance_deactivate_region(view_xview[0], view_wview[0], view_hview[0], false, true);
instance_activate_region(view_xview[0], view_yview[0], view_wview[0], view_hview[0], true);
Make sure you don't deactivate important objects (like the object calling the code!). If you set the argument "notme" to true, the object will ignore itself in the deactivation.
2. Use Tiles Instead of ObjectsTiles are much, MUCH faster than objects, so you should use them in place of objects whenever you can. You can actually do a lot of things with tiles, like create and destroy them, set their depth, get their position, etc. They're not completely static.
Background details that you don't actually interact with are perfect tile material.
3. Do Fewer Collision ChecksObjects that have collision events are much slower than objects that don't. So place those events in the objects which will have the fewest instances. A good example is the player versus the 100 bullets. You obviously have to do a collision check between the two objects... make sure that event goes in the player object instead of the bullet.
Collision functions (and trig calculations) in general are pretty heavy, so it's a good idea to have as few of them as possible. Make sure you're not doing the same collision check more than once in a single step. If you need to look up the return value of any slow function more than once, consider putting the value of the collision in a variable and check the variable instead.
Whenever possible, turn off "Precise collision checking," which is a per-pixel collision detection method.
4. Optimize Your Use of Step EventsStep Events are, of course, called every step... so the more you do in the Step Event, the slower your game will be. Whenever possible, reduce the size of your Step Events, and also the number. If you don't have to do it every step, then don't!
One alternative is to use Alarms.
5. Do Less DrawingThe less drawing you do, the better. Optimize your drawing routines.
If you have a covering background, make sure you switch off the use of a background color.
Also be careful with the use of many views. For each view the room is redrawn.
6. Sample Down Your Sound/MusicSound can take up a lot of memory and space, especially wavs and mp3s, so sample them down if you can. Ask yourself if the higher bitrate or extra channel is worth the hit!
Keep in mind that Game Maker doesn't support mods or oggs, and it barely supports mp3s, so
consider using a library like supersound.dll for your sound needs.
7. Crop Your SpritesFirst of all, look carefully at the sprites and backgrounds you use. Animated sprites take a lot of memory and drawing lots of sprites takes a lot of time. So make your sprites as small as possible. Remove any invisible area around it (the command crop in the sprite editor does that automatically). The same applies to background images.
--- Newly Added ---8. Turn Off SynchronizationUnder "Global Game Settings -> resolution" there is an option "Use synchronization to avoid tearing"... make sure it is unchecked! Not only does it do very little to help with tearing problems, it can also drastically reduce your game's speed. I had it checked accidentally and it increased my CPU usage about 10-20% (from about 20-30% to 40-50%).
9. Use Smaller Screen Resolutions640x480 is fine for most games. I kind of regret making [Immortal Defense] 1024x768 -- it looks nice, but just the fill rate makes it much slower. Use dedicated resolutions, they work faster than windowed and much, much faster than stretched.
10. Use Bigger Tiles, Rather than More TilesWhile tiles are lighter than objects, having a lot of them will still cause slowdown. If you can use a handful of large tiles rather than a lot of little ones, do so.
11. Draw Primitives to a Surface FirstRegarding functions like
draw_circle,
draw_rectangle, or
draw_line: first draw the primitive to a surface, then draw the surface to the screen. It's much faster that way.
12. Don't Use execute_string()It's really slow.
In conclusion, do more with less and compromise when you can! Thanks to
Melly,
rinkuhero,
ChevyRay, and whoever else for the tips. Please share your own, or let me know if I've made any mistakes.