Optimizing Carpoon in Game Maker Studio 2 AKA How I made my game less slow


Whenever I work on Carpoon, it’s on my i7 desktop, but whenever I show the game it’s generally on my not so speedy i5 Surface 3. As Carpoon ran fairly slowly on my notebook the last three times while trying to play the games with friends, I’ve put some focus into speeding up the game. Quite frankly what people were playing on the notebook vs the desktop were a night and day difference, but for the longest time I didn’t worry about optimization because it wasn’t needed.

Also, full disclosure: There might be better ways but this is just what worked for me so far!

1. Setting the Frame Rate

After playing Carpoon vs Ash at E3, and having another subpar framerate performance, I recalled the next morning in an “Aha” moment that GameMaker 1.4 had an option for the game’s sleep margin that sometimes needed to be tweaked for the notebook. Perhaps GameMaker Studio 2 which I ported Carpoon over to this year had a similar new setting?


Looking into it, I found there was a setting for frames per second in the project. Previously set at 60, I increased the count to 120 as perhaps an easy solution to the problem. For the most part, it helped! The harpoons operate with a physics boost each step and they shoot further now as an added bonus. But there was still work to do.

One of the key ways to go about that was a framerate counter that can be toggled with the ‘F’ key:


This way, I could at least keep track when changes I was making were improving the frame rate or not at all because I couldn’t visibly discern them on the speedier i7 at frame rates like 940 FPS.

2. Less calculations each step

One of the handier things about game development these days is the gajillion resources online of developers who posted solutions to problems. This post on GameMaker optimization I found was old, but considering it was by Derrick Yu, the creator of Spleunky, I thought it was a great starting point: https://forums.tigsource.com/index.php?topic=3747.0

The post reminded me that not everything had to update each step event, and I learnt that objects could “deactivate” and reactivate later in GameMaker. I knew that one of the slow things I was doing was a lot of sin and cos calculations each step, and that this might add up when every car was doing them multiple times a step with 30+ cars onscreen.

 This is just a few of them:


To optimize this, I created a list of sin and cos values at the start of the game. This is an idea I remembered from a looong time ago in a Flash game design book:

Then during the game, I used a script to find the sin value for the rotation needed. Along the way, I found out I didn’t need to convert to radians :/




Updating these didn’t give a huge boost in frame rate performance but helped spur making other optimizations.

3. Splitting the game room up to have less objects

Originally, I was having troubles setting up players in a separate room and moving them to the next room. To get around this at the time, I put the player select area in the level room itself. This wasn’t ideal though because I would have to copy the player select area for every room and it left unnecessary objects around during a game:


While I had persistent enabled for the player’s truck, the same had to be done for the player’s harpoon, tow arm and mouse cursor because they’re separate objects:


When I finally had the player select room and level room separated, I noticed that truck was sticking to walls on collisions. After toggling draw_physics_debug(), I saw this was happening: 


The rounded physics fixtures I was adding to the player weren’t transferring through to the next room! I learned from this that fixtures are like their own objects that have to be deleted when they are done with. A catch was that I couldn’t instantly destroy and create the fixtures in the same step moving to the next room, as if going to the next room doesn’t happen at that exact line of code but waits until the step for the entire game is done.

When I started on creating a new room for a different level, I noticed the objects used as player start points weren’t being used by the game. This related back to the room not instantly switching over mid-step but also persisted during a match when respawning. To get around this, I moved the spawn point X and Y to match the new level.

4. Less Physics AKA Physics on Exhaust is Bad!

Somewhat hilariously, one of the biggest drags on performance was using physics for the exhaust. When I originally did this, it created a cool effect where the exhaust hit cars being dragged and went around them.


Turning this off resulted in a big performance boost. Instead of having the exhaust collide with the dragged car, I decreased its z-depth over time to rise above dragged cars and it worked out well enough.

5. Not drawing offscreen cars

Going back to the deactivate/activate advice from the old Derrick Yu post, I gave it a shot for the enemy cars. Once I figured out the proper screen coordinates for instance_deactivate_region(), I found out that didn’t work so well with my NPC car AI. Even when testing for different instances every 14 frames, it was slow - although I could have gone through different cars at different frames it didn’t look promising

Here’s an example of hiding cars with a boundary smaller than the screen size:


For a simpler solution, I created a “drawMe” variable and checked that every few frames to go through the NPC’s draw event or not. Only drawing what was needed helped speed up the game more.

And that’s about it for what I did to speed up Carpoon. I have added a couple features recently so if you want to give twin stick tow truck recycling action a go, it’s in downloads!

Thanks,

Tom

Files

Carpoon-7b-v - Optimization, Stunning Opponents & Parked Cars 21 MB
Jul 06, 2019

Get Carpoon [Early Access]

Buy Now$4.99 USD or more

Leave a comment

Log in with itch.io to leave a comment.