Engines · Design · Business · GameMaker 8 classics · Publishing · News
Inicio › GameMaker 8 Classics › Optimising a classic project: sprites, code and draw order
GameMaker 8 Classics

Optimising a classic project: sprites, code and draw order

Where a classic project loses frames and what to change first.

Optimising a classic project: sprites, code and draw order
Where a classic project loses frames and what to change first.

A classic project rarely slows down for one dramatic reason. It loses frames in small amounts across drawing, collisions and code that runs every step, and the losses only become visible once a room fills up.

Optimising here is a question of order rather than cleverness. Find the expensive habit, change one thing, then look at the frame rate again instead of rewriting the game on a hunch.

Classic game editor with a busy room and sprite resources open
Frame cost is usually the sum of many small per-frame decisions rather than one slow feature.

Where a classic project loses its frames

Drawing is normally the first cost. Every visible instance asks the engine for work each frame, so cost rises with the number of things on screen, not with how interesting they are.

Collisions come second. Checks that run every step against many instances add up quickly, especially when the masks involved are detailed shapes.

Then there is the code that runs constantly. A short routine that executes for hundreds of instances per step is more expensive than a long routine that runs once.

Sprites: frames, cropping and masks

Frame count matters more than most developers expect. Long animations of near-identical drawings cost memory and drawing time while communicating very little to the player.

Crop transparent margins before importing. A sprite with generous empty space carries a larger bounding box, and that box is used for both drawing and collision work.

Choose the simplest collision mask the gameplay allows. A precise outline is accurate and expensive, which is a poor trade when the game only needs to know whether two characters touched.

Draw events and the order of drawing

Anything in a draw event runs once per instance per frame, so it is the worst place for calculations that do not change between frames.

Compute in the step event, store the result, and draw the stored value. The same applies to text: assembling a string every frame costs more than it looks.

Skip work that cannot be seen. An instance outside the visible area does not need to be drawn, and a layer hidden behind another one does not need to be redrawn at all.

Step code and the cost of constant work

The most expensive code is the code that runs when nothing has changed. Auditing for that pattern finds more wasted frames than any micro-optimisation will.

HabitWhat it really costsBetter approach
Rebuilding a list every stepThe same work repeated unchangedRebuild only when the data changes.
Searching every instanceCost grows with room populationKeep a short list of the ones that matter.
Detailed masks everywhereCollision checks get heavierUse simple shapes where gameplay allows.
Text built every frameString work repeated per instanceCache the string and redraw it.
Many near-identical objectsMemory plus drawing overheadMerge into one object with states.

The pattern behind the table is multiplication: cost equals the work per frame times the number of instances doing it. Reducing either factor helps, and reducing both is what produces a visible change.

Work from the top of the list down. The first row usually costs more than all the small adjustments below it combined.

Objects, instances and room population

Object variety is cheap, instance count is not. Ten objects used five hundred times cost far more than fifty objects used once each.

Remove or disable what the player cannot reach. Decorations outside the current room, spent particles and finished projectiles should stop existing rather than keep thinking.

Persistent instances deserve suspicion. Keep the list short and deliberate, because each one works through every step of the game for as long as the session lasts.

Measure before you rewrite anything

Play the game and watch where the frame rate drops. The worst moment tells you which system to examine, and it is frequently not the one you suspected.

Change one variable, then measure again. A notebook entry per change beats a week of guessing and produces a list of decisions you can defend later.

When nothing obvious appears, isolate by removing. Disable a layer, a system or a group of instances and watch the frame rate respond; the answer usually arrives within minutes.

Record the result each time. The same spot in the same room is the only fair comparison, and a number you cannot look up again becomes an argument later.

Optimising a classic project: sprites, code and draw order
GameMaker 8 Classics

Optimising a classic project: sprites, code and draw order

Related guide on this topic.

Winning back the last few frames

The final gains come from discipline rather than tricks: fewer instances, simpler masks, less work in draw events and less repeated calculation.

Test on the weakest machine you can find. A build that holds its frame rate on old hardware will not embarrass you on a new one.

Keep the changes that paid off and revert the ones that did not. Half of optimisation is deciding what to leave alone.

  • Trim sprite frames and crop transparent margins first.
  • Move computation out of draw events and cache the result.
  • Simplify collision masks where precise shapes are not needed.
  • Reduce instance counts before rewriting code that already works.
  • Measure after every change and keep only the wins.

Optimisation in a classic project is mostly subtraction. Each change removes repeated work from the frame, and the sum of those removals is what players feel as smooth movement.

Stop when the frame rate holds on your weakest target machine, not when the code looks tidy.

Read the guideAll classic guides