Optimizing OpenGL performance with apitrace

Posted on Thu 22 March 2018 in Gamedev

Today's post is for the programmers: it's a bit technical. I finally solved a long-standing performance issue  in Happy Usagi, and I thought I'd share my notes.

The issue

This was the problem: Happy Usagi was sometimes a bit jittery or choppy. The graphics weren't entirely smooth, there was a little interruption every second or so. On newer computers it was barely noticeable, but on some older models it was a real issue. And the graphics aren't complicated, so there really was no excuse.

Allegro and OpenGL

Usagi uses the Allegro game programming library. Allegro bundles a whole bunch of libraries for various aspects of games: sound, physics, joystick input, etc. For graphics, it depends on OpenGL (it can optionally use DirectX instead but that's not relevant for this story).

Allegro wraps around OpenGL, and in effect hides its complexity. This is a double-edged sword. As long as everything goes smoothly Allegro makes things easy for the programmer.  But when there is a bug, Allegro hides what is really going on. So you need a way to look under the hood.

Enter apitrace

Apitrace is an open source tool for tracking all the OpenGL calls done by your program. Installing apitrace on linux is as easy as:

sudo apt install apitrace apitrace-gui

To start recoding a trace:

apitrace trace --api gl build/debug/usagi

This generates a file named usagi.trace (or usagi.1.trace, usagi.2.trace etc.). You can view this file with

qapitrace usagi.trace

Which results in a screen like this:

Each frame (drawing cycle), apitrace records all OpenGL calls. In the screenshot above, you see that nearly all frames consist of 757 calls. It makes sense that this number is constant from one frame to the next, because each frame, the game builds up the scene in exactly the same way: draw the background, draw the bunnies, draw the interface buttons. Most OpenGL functions perform communication with the graphics hardware, which is slow, so it's important to keep this number as low as possible. 757 is probably a bit higher than I would like. Allegro adds a few extraneous calls that aren't strictly necessary, but this is part of the trade-off between the ease of use of Allegro and the raw power of OpenGL.

What's noticeable though, is that there are a few frames with crazy high numbers of OpenGL calls. 19286 calls in one frame? Now that would certainly cause a jitter! Apitrace lets you examine these calls in detail, as in the screenshot below.

Looking through the calls in this bad frame, I notice a few that don't occur in the good frames. For example, there are calls to glPixelStorei(). Although I don't know exactly what it does, that doesn't matter right  now: the fact that it only occurs in  the bad frame and not in the good frames makes it a suitable starting point for further investigation.

Zooming in further

So I open Usagi in the GNU debugger (gdb) and start tracking back from glPixelStorei

gdb build/debug/usagi
# Set a breakpoint on the glPixelStorei function
(gdb) b glPixelStorei
# Start the program
(gdb) r
starting program build/debug/usagi
Thread 1 "usagi" hit Breakpoint 1 in glPixelStorei ()
         from /usr/lib/x86_64-linux-gnu/mesa/libGL.so.1

Ah great, it worked! I caught the program red-handed exactly in the middle of a bad frame. Now I just have to trace back to the origin of the problem, literally, using the "backtrace" command:

(gdb) bt
 #0 0x00007ffff4307980 in glPixelStorei ()
....
 #12 0x00007ffff67b3475 in al_draw_bitmap_region
 #13 0x00000000004518b6 in blitRow
 #14 0x0000000000451d3c in Bitmap::TiledBlit
 #15 0x0000000000469979 in Button::doDraw
 #16 0x0000000000467277 in Widget::updateBuffer
 #17 0x0000000000467092 in Widget::draw
 #18 0x0000000000460546 in Container::draw

Here you see the chain of function calls that led to glPixelStorei. You have to know the code to be able to interpret this, but I can see right away that the call to Button::doDraw was completely unexpected and unnecessary. Buttons are drawn on a back buffer that is only redrawn whenever the button changes state. In the game, buttons may be enabled or disabled depending on how much money you have. For example, the "buy a block" button becomes available when you have earned enough money to buy that block. And money changes every second or so. Suddenly all the pieces fall into place: due to a mistake the game was redrawing all the buttons, every time your money counter changes, which is complete overkill.

There is more. Why does the redraw of a button cause such a crazy high number of OpenGL calls? It turns out that the button was copied from System memory to Video memory, a big performance no-no.

It's funny how a really difficult bug becomes really easy to solve with the right toolset. I've known about the jitteriness for a long time, but couldn't figure out what to do about it. Until I started using apitrace. Once you know exactly where the problem is, the solution is trivial. In the end it took about four lines of code to fix the main performance issues.

New Release of Happy Usagi

These fixes are important enough to immediately released them. Version 0.3 of Happy Usagi can be download here.


Tips for beginning speedhackers

Posted on Mon 25 September 2017 in Gamedev

This is the second part of my series about Speedhacking. Last week I looked at the reasons why you should participate, now I'm going to give some tips for beginners.

Are you going to join a speedhack, or other type of game jam, for the first time? Here are some tips!

How to limit your scope

In my previous post, I wrote about how important it is to limit your scope. But how exactly do you do that?

If you're really a beginner, keep it very simple. If you think an idea might be just doable, cut it in half. Make your own variant of Snake. Pacman. Tetris. These are the type of games that are feasible in a weekend.

Don't invent everything new, but remake a game you already know. Is it bad to make a clone? Of course not,  remaking famous old games is excellent practice. You won't expect a beginning chef to create delicious new recipes - first they have to master the classic ones.  Start with a remake, and if you find some extra time, you can always add your own flavour and twists to it.

It's best to choose from the genres of arcade games or puzzle games. Arcade games are focused on reaction speed, and usually have just a single screen or a single mechanic that is repeated over and over again,  with increasing difficulty. This provides an interesting challenge without requiring you to design lots of extra "content".

By "content" in mean levels, graphics, storylines. Any genre that requires a lot of that is really tough to pull off in just 72 hours. Examples of these are platformers or RPGs. You may think that it should be possible to program a character like Super Mario in just a weekend. And you would be correct. The problem is that what makes Super Mario fun, are the levels. Designing levels takes time. And the amount of time you spend designing is directly proportional to how fun your entry will be. There is no way to speed up the process. And it eats away from your polishing time.

Schedule polishing time

It's possible (although not very healthy) to spend a good 40 hours out of those 72 hours making games - that's an entire work week compressed in 3 days!  But working to the limit is a sign that you set the bar to high. With a lower bar and fewer hours of work, you can actually achieve better results.

I've seen it happen that participants could only work on their entry for one day instead of the weekend, for reasons (work, life, illness, whatever). And still ended up with a high-ranking little arcade game.

It's usually not the case that you need a fantastic new idea to make a game work. Instead, what makes a game work is a decent idea with a lot of polish. Making a game fun means polishing it. The amount of time you set aside for polish determines the success.

What is meant by polish? Playtesting. Balancing the game.  Take some time to actually play the game yourself. Let somebody else try it. Is it too difficult? Is it too hard? Is the goal of the game intuitive? Add finishing touches. Sound effects and music usually come in last but add a lot to the fun factor.

So instead of planning a game that takes 40 hours to implement, plan for a game that takes 20 hours to implement, then spend any remaining time adding as much polish as you can. The good thing is that usually, this is the most fun aspect of game development. In this phase, every tweak, every added line of code immediately improves your game in a visible way.

How to use the rules to your advantage

It's easy to see the random rules as annoying barriers that stand in the way of  the game you really wanted to make. For example, maybe you have decided that you wanted to remake Sim City. Then the rules are announced, and maybe one of the rules is that the theme must be "Gravity". What do I do with gravity? How on earth do I combine Sim City with gravity? The trick is not to get too hung up on a single plan. Be opportunistic, not dogmatic. Keep your options open. Be willing to make any of a range of games - arcade games, puzzle games, etc. So maybe you can't make Sim City. Is that really the only possible game you could ever make?

Another way to look at it is this: Don't see the rules as limitations, but as stepping stones for your imagination. This is an opportunity to think out of the box. It would be so cool to play Sim City on the flying rocks of Pandoran!

I can't do art

Worried you can't do good art? Again, what may appear as a limitation is really a stepping stone for your imagination. Focus on what you do know. Make a game that is focused around patterns of geometric shapes - like for example Circles. Even better, just use only text. There are some really cool games made with just text, like Dwarf Fortress and Nethack.

Make a word puzzle game, or  a text adventure. Focus on procedurally generated art. Or use a super-low resolution (but scale  it up for modern screens). It's much easier to generate a lot of art if sprites are only 8x8 pixels.

I'm not a good programmer

Worried that you're not a good enough programmer? Well, the bad news is, you do need to know some basic programming. Actually, you need a combination of skills to make a good Speedhack game, but programming stands at the basis.

But then again, it's just a matter of matching the scope with your skills. As long as you're willing to learn, you can start really small. Can you write "Simon Says"? Can you write "Hang man"? Can you write "Higher, Lower"? These games can be programmed in Scratch! (Unfortunately I haven't seen Allegro bindings for scratch yet, so that would make them inadmissible to TINS. But you get the point). Combined with the right art, design and sound, you can still make something cool. Perhaps you're not going to win the competition with these games, but the challenge is purely your own: can you become a better programmer?

Teaming up

Another way around a skill gap is to team up with somebody else. Some competitions, including TINS, allow this. Is it really possible to let teams compete against individuals? How can that be a fair competition? Certainly I've seen some very good TINS entries in the past that were made by teams. But don't underestimate the extra difficulties involved in teaming up. There won't be enough time to do all the meetings and huddles that usually involve joint programming efforts. You need to be able to rely on each other, and find ways to remove interdependencies so that you're not constantly waiting on each other.

I'm not saying you shouldn't join a team. Just be aware of the complications. Teaming up may help you to work around a skills you lack, but requires all of you to have communication skills in abundance.

Here's that promo bit again

So, did I convince you that it's feasible? Do you think you can do it?

Why not give it a try? The next TINS competition will be held from October 20 to 23. Head over to tins.amarillion.org, register and sign up!


The Many Benefits of Speedhacking

Posted on Sun 17 September 2017 in Gamedev • Tagged with Speedhack

Speedhacks (a.k.a Game jams), are competitions where you design and implement a complete game, from scratch, in an extremely short time limit (typically one weekend, or 72 hours). I'm a frequent participant and organizer of these events for the Allegro community (including the upcoming TINS competition, more on that below). I found them to be incredibly educational and fulfilling, and they've allowed me to grow as a developer. Here is why you too should participate in one.

Getting things done

Making a whole game in 72 hours, how crazy is that? For those who ever tried, the prospect seems daunting.

Starting from early high school days, I've always wanted to make my own games. I was endlessly doodling level designs, and I had reams of elaborate technical notes. It was disheartening to look back at all those plans and aspirations, and see how little came of them.

That feeling changed after my first Speedhack. For the first time I realized that, yes, I actually can make all these ideas come to life. Of course there are limits to what you can do in a weekend, but actually making something playable, as opposed to lots of half-hearted attempts and interminable projects, is extremely gratifying and a very powerful motivator.

The problem is that you can't really show off a stack of design notes. Maybe you get some props if you have some cool drawings, but more likely your peers will recognize it for what it is: vaporware. A short playable arcade game is a lot cooler than the epic game that merely exists on paper.

So how do you pull this off? You need developer skills, to be sure, but perhaps less than you think. What you need first and foremost, is to learn to limit your scope.

Limit your Scope

In Extra Credits, game designer James Portnow talks about scope as being one of the six skills that game designers should learn.

Every budding game developer is really a gamer who thinks: it would be so cool to play a game that is a role playing game combined with real-time strategy, with lots of mini-games and cowboys in space.  And it should have dragons and magic and tons of weapons to choose from. You know what, I'm going to make that game myself! It's so easy to fall into this trap. You design something grand and majestic that completely fails to see the light of day.

Where does it go wrong?

Know your limits. Even if you had all the skills required to pull off a grand project like that, it's just so hard to stay focused on a single project for years on end. Work or school or other real-life obligations intervene. Instead, plan for just the amount of time that you can completely oversee. Speedhacks teach you to work with a short time horizon. You can shield yourself from distractions for 72 hours.

Constraints make the creative juices flow

Would you like to make games, but can't come up with ideas? Are all the cool game mechanics already taken? There is nothing like an imminent deadline to get the creative juices flowing. In the words of Calvin: you can't turn on creativity like a faucet. You have to be in the right mood. That mood being: last-minute panic.

At the start of Speedhack, random rules are drawn from a predetermined set. Your game has to adhere to these rules to be a valid entry. For example, a  rule may say that it has to be a puzzle game. Or that it has to have snow in it. Or that you can only use hand-drawn assets. Theoretically, the rules are there to prevent false starts. The idea is that you can't start on your game before the rules are known, so nobody can take an unfair advantage by starting early. But really, the rules just add to the fun.

Rules force you to come up with crazy ideas. For past Speedhacks, I've come up with a platform game set inside a laundry machine, a space shooter where you have to defend Mars against the attacking Earthlings, a puzzle game where you have to choose a matching outfit from a perilous walk-in closet, or a two-player co-op battle game inside a space cheese. Coming up with ideas is not a talent that you're born with or not. Its a skill, that you can practice. And Speedhacks are a great way to practice.

Community

If Speedhacking is so great, why don't you do it all the time? If you can make a game in a weekend, why don't you make a new game every weekend?

You can't without motivation. Here is where the community comes in. Locking yourself away for a weekend may not seem like a very social activity, but it is. During a competition you interact with fellow Speedhackers. Reading the progress reports from others is fun while you take a break from an intense hacking session, and creates a shared experience. The fact that others will be waiting after the deadline to play and review your game, motivates you to not let them down.

The community is your carrot and your stick. Failing to finish feels a bit like breaking a promise.

Oh, the things you will learn!

Speedhacks give you a chance to learn new algorithms, experiment with new techniques, or try out ideas with a prototype.

Have you never applied the A* algorithm? Here is your chance to try it out! Always done hand-pixeled art and want to try your hand at some vector graphics? Now you have the perfect opportunity to do so.  Do a Speedhack every so often to broaden your skillset.

Even if the game you make never ends up being more than a prototype, more often than not you'll find ways to apply the things you learn later on during your working life.  I first used A* for a train routing game I did for speedhack, but later found a use for this technique in a project for work.

So where do I sign up?

Nowadays, there are plenty of Speedhacks and Game jams being organized all over the Internet. Some focus on particular retro systems or screen modes. Some are face-to-face. One of the oldest and most famous ones is Ludum Dare, and it attracts tons of participants every time.

Invitation to TINS

As mentioned before, I organize a Speedhack semi-anually, called TINS.  It is going to be held again over the weekend from October 20 to 23. One thing you should know is that it's organized by the allegro community, and therefore using allegro is a requirement. Allegro is one of the most widely portable libraries, ranging from android to Windows to Mac.  Head over and sign up!

In case you're wondering, TINS stands for "TINS is not Speedhack",  and references the original allegro Speedhack.

See also part 2 of this series with tips for beginning speedhackers


Implicit Tutorials (Notes from Indie Game Show & Tell)

Posted on Tue 20 June 2017 in Gamedev

When I discussed educational games, I omitted one very common type:  games that teach you how to play the game itself.

Last week I participated in the Indie Game Show & Tell in Amsterdam. And there I learned about self-explanatory games, and also the fact that Happy Usagi currently sucks at this.

The idea is also called "Implicit tutorials", and is an important concept in game design. There should be no need for a manual (nobody reads it anyway). The less explanation, the better.  By gradually introducing game elements in a clever way, the game should just explain itself . Super Mario World 1-1 is a very famous example of this.

The first demo of the evening was by Jeroen Wimmers about the game "Circles" (See the screenshot above). It really drove home the point of implicit tutorials. Circles is what you may call an example of "Constraint-based game design", the constraint being that everything, every single thing, is a circle. Start of the level: a circle. Goal of the level: a circle. Level select menu - a bunch of circles.  In a relentless drive to eliminate shapes with corners, explanatory text has no place. How does the player know that you're not supposed to touch certain circles? Jeroen showed how he went through dozens of iterations, trying different visual cues (trembling, disappearing, expanding),  keeping this and reverting that, until the game was crystal clear. Circles is out on steam if you want to give it a try. (There is a free demo).

Another talk on a very similar topic was about Reggie, by Degoma games. Reggie is a tomato with the ability to reverse gravity, in a cool little platformer. This game similarly went through several design iterations, incorporating feedback from players at conventions, until finally the mechanics were universally understood. You can watch the entire talk on Youtube:

But there is a downside to implicit tutorials. A tutorial can slow down the pace and make players give up before they get to the good parts. I can think of a few recent games that suffer from this.

I myself was there to present Happy Usagi. There is no recording of the talk. But I showed this movie which is also on Youtube:

While showing this video I explained that the game has an "altitude-bonus" mechanic. It works as follows. When your bunnies are happy and well-fed, they jump more. For each jump, you get points. The points are multiplied by how high the bunny is. For a jump at floor level, you get 10 points. A jump on a stack of four blocks tall rewards you with 40 points. This mechanic encourages you to build. By building higher, you make each jump worth more.

The audience asked me this insightful question: "How does the player find out about this mechanic?" After all, how can a reward incentivise players to do something, if they don't know that there is a reward? The truth is that this is an area where the game can be much improved. I did add a small hint: When a bunny jumps, a number appears at that spot to indicate that points were scored. But it's very easy to miss the connection between score and altitude. To a casual observer, it seems the score is calculated pretty much at random. Here the player needs explicit explanation.

So that is some very useful feedback. And that's what made this event so great - not only to have the chance to present our work, but also to get feedback from fellow game designers, and to learn more about game design.