Goodbye my Cintiq

This has got to be the worst timing possible. My Cintiq went to meet its maker in the sky this afternoon. So that means I’m out of a drawing tablet, and even worse, I have no means of replacing it. As I do all of the art for all of my games, I rely on my tablet for just about everything aside from music and programming. This is an absolutely devastating setback,  and due to some crazy unexpected financial burdens,  I actually have very little financially I can put towards game development.

I’ve been on a streak of absolutely nasty events regarding game development lately. They say that the darkest hour is just before the dawn, so let’s hope things can turn around!

BeanBattle Stress Test Results

Bean Battle will have dozens of enemies onscreen simultaneously, probably capping off at around 50 – 70 at once. It goes without saying that such a massive legion of baddies will consume quite a bit of memory and processing power, especially considering each enemy has to detect collisions with the environment, the player, other enemies, projectiles, etc., as well as run through all of their logic every single step. I don’t have any solid enemies implemented yet, but my main concern with memory/cpu usage was actually the amount of processing required for dozens of spine sprites running through their animations at the same time. Of course Spine sprites require a bit more processing power, considering the bones can be rotated and adjusted realtime, and additions that require more processing (such as setting/removing attachments and IK joints) will only bog down the processer even more.

Before I dive into any major project where I expect technical limitations to play a strong influence on the game design approach, I always like to run the engine through a few stress tests to know what sort of performance I’ll be working with. This helps me determine the expected scope of the project as well as how much optimization, if any, must be done.

So, a quick background about our unsuspecting guinea pig for today’s experiment! It’s a bit of a heavy Spine sprite. Here’s the lowdown:

  • 37 joints total
  • 2 IK constraints
  • 17 image attachments
  • of those 17, 5 are mesh deformed images (with each image being deformed by about 4 joints simultaneously)
  • 30 animations (and a whole lotta keyframes!)

As you can see, in terms of processing required, he’s a considerably hefty rig – I’d probably gauge him in the midupper level. I expect an average enemy to have closer to 20 joints, no mesh deformation, most likely 17 attachments, and 2 IK handles. The mesh deformation and realtime IK will definitely add a bit to the processing power required. So all in all, this rig could be considered a bit overpowered for the average test subject, but I like to start big and work my way down!

My test environment was set up in the manner I intend the game to be played at. All tests were performed with a resolution of 1920×1080. I used the GM Debugger to view the amount of memory used, as well as both the GM debugger and Bandicam to get a fairly accurate reading of the FPS. Onto the results!

No sprites – 25044.72 kb memory consumed, running at a solid 60 fps (of course), recording with Bandicam at a solid 60 fps

No sprites – 25044.72 kb memory consumed, running at a solid 60 fps (of course), recording with Bandicam at a solid 60 fps

1 sprite – 25057.71 kb memory consumed, running at a solid 60 fps , recording with Bandicam at a solid 60 fps

30 sprites- 25434.14 kb memory consumed, running at a solid 60 fps , recording with Bandicam at a solid 60 fps

50 sprites – 25694.34 kb memory consumed, running at a solid 60 fps, recording with Bandicam at a solid 60 fps

100 sprites – 26363.63 kb memory consumed, running at a solid 60 fps, recording with Bandicam 59-60 fps

200 sprites – 27642.06 kb memory consumed, running at 60 fps, recording with Bandicam 56-59 fps

300 sprites – 28940.68 kb memory consumed, running at 59-60 fps , recording with Bandicam 47-49 fps

500 sprites – 31537.62 kb memory consumed, running at 57-60 fps, recording with Bandicam 34-41 fps

1000 sprites –  running at 30 fps, recording with Bandicam ~24 fps

 

So analyzing these results, we can see that memory consumption really isn’t a problem in the least bit, but our first hit on processing, albeit incredibly minor, occurs when we have 100 sprites onscreen (still running at 60 fps, but recording with Bandicam at 59 fps). Even at 200 fps, we’re still cranking out a solid 60 fps while playing, but it dips a bit more while recording, though quite small. At 300 sprites is when we begin to see the performance touched by the massive number of baddies onscreen, losing a frame during play. From 500 – 1000, it absolutely falls apart, steadily dropping all the way down to a staggering 30 fps when we finally hit 1,000.

Now, as helpful as these results are, they’re only an incredibly tiny fragment of the whole entire picture. Remember, these enemies aren’t running through any code whatsoever, other than updating their animation every single frame. No collisions, no logic. There’s also no animation tweening involved, and each sprite is locked into a single 30 frame animation (although the sprite file itself does have the full 30 animations). It’s incredibly difficult to gauge how much the processing will take a hit once we add in all of the game logic and collisions, but it’s a bit comforting to know that we can nearly quadruple the targeted maximum number of sprites (50 to 200) with seeing only a very minor amount of performance loss while recording with screencapture software, and absolutely no performance loss ingame.

My only concern at this moment? My PC is a bit powerful – definitely not a beast by any means, but it’s certainly leaps and bounds above the lower-powered laptops. I’m running an i7-4770 CPU @ 3.4 GHz with 24 GB or RAM. My GeForce GT635 GPU, albeit quite puny by today’s standards, certainly trumps the builtin GPU’s of lowend laptops. My targeted system specs would hopefully allow this game to run on nearly all laptops from within the past couple of years, but I’ll need to do quite a bit of testing.

Once I have a more appropriate experiment whipped up, I’ll be sure to share those newer (more accurate) results!

Reusing assets from old projects

I reuse my code from my own past personal projects quite a bit – it’s a serious timesaver, so I wanted to write an extremely quick note about this handy little approach before I hop off to dreamland.

It’s by no stretch of the imagination to say that I scrap a lot of my personal projects. It’s not necessarily that I lose interest – it’s moreso that another exciting project oozing with potential starts shifting into frame, and I can’t help but give it the TLC it deserves. As a result, I tend to move from project to project very quickly, sometimes in a matter of days. One could easily land at the conclusion that I waste quite a bit of time; I mean, work on a game for a few days, then scrap it and move on? How could that possibly be beneficial to me? Spoiler: It actually is.

I wouldn’t be exaggerating if I said that I’ve learned something from every single project I’ve ever attempted. Sometimes I walk away with just a few bits of new knowledge, and other times I find myself brimming with knowledge of tons of new systems and gameplay mechanics I’ve never attempted before the project. The scope of the project doesn’t matter, I’m always learning. And lucky for a programmer, a lot of this code can easily be adapted and reused in future projects.

A couple years back, I wrote a gamepad input system for Gamemaker Studio that extends the functionality of gamepads with simple commands, allowing you to check things like thrusting on the analogue stick, double tapping,  mapping gamepads to players, etc. With every new project I attempt, I import my lofty stack of gamepad scripts, and each project seems to demand something more of the input, requiring me to add new gamepad scripts ontop of my old ones. Over time, the number of gamepad scripts slowly increases, and now with my current project, I have my whole library of scripts neatly organized allowing me to detect just about anything I’d need from gamepads. I coded it be reusable, so I literally just have to drop it into my project, call an initialization script, and it’s good to go!

But that’s not the extent of code I reuse from old projects – oh no, not by a longshot. Things from mathematical functions (like figuring bezier curves, I mean, who wants to write all that math twice?), my realtime trail generation system,  camera system, even collision code! Over a decade of programming in GMS has allowed me to build a library of my own personal scripts I’ve written, and anytime I need one, I can easily import it and make any necessary changes. It’s an incredible timesaver and allows the prototyping phase to sometimes run at blazing speeds!

It’s more than code though. I often find myself reusing other assets as well, such as sound effects, studying animation from my old characters as a reference for animating my new characters, maybe how I designed the movement of the player or an enemy, artwork, logos, databases, etc. In so many cases, I find myself saying, “Oh wait, I’ve done something similar to this before! Let me refer back to it, it’ll be a good reference instead of trying to figure it out again from square one.”

So all those old projects, that old code, those old sprites, that long list of old sound effects, all those old assets… you know, the ones you spent hours creating but eventually scrapped because the project wasn’t getting anywhere? Take advantage of having created it in the first place and understand that everything you create is practice, a learning experience to improve your skills, so absolutely no project is a waste of time. Reuse, rinse, wash, and repeat!

A quick note though – NEVER reuse code or assets from freelance work or paid projects. You’re usually under a contract and thus legally obligated to hand over ownership of your code to the project/project creator. BUT, this doesn’t mean that you still can’t learn throughout the process! Ciao!