Tag Archives: Pygame

Building Tools

One of the things that makes coding particularly awesome—especially in the case of Python—is the ability to reuse code. If the programmer writes things in such a way as to make them generic enough, he can then take those generic sections of code and apply them to different situations. As one might expect, reusing code that has already been written speeds up development time considerably by allowing the programmer to automate different chunks of the program. To illustrate, let’s put this in the context of one of my apparently recurring themes, doughnuts.

Say you decide one morning that you’re going to start your own bakery. You get the space, buy the equipment and groceries, and refine your recipes. The problem with your bakery setup, however, is that you’re the only employee, which means you’re responsible for everything from purchasing groceries to preparing pastries to dealing with the customers to cleaning up afterward. If you continue in this fashion for a while, you will get things done. In fact, you might even turn a profit if you’re lucky. Unfortunately, though, your business won’t grow very much until you can get some help, and, quite frankly, you’re getting tired.

To take some of the pressure off of you, you decide to hire and train someone to help out around the place. You hire a new kid, train him to do basic jobs like cleaning the seating area and washing dishes, and as a result, free up more of your time to invent, cook, and socialize with customers. Things are going just fine for a while, but you eventually come to realize that your business could be even more productive if you hired a third person to help you with the morning doughnut frying and filling. Side note: jelly doughnuts, you guys. Seriously. Jelly doughnuts.

Reusing code is a lot like the metaphorical bakery. You find a task you have to accomplish pretty regularly, and you farm the work of that task out to a separate process. Either that, or you take a complicated, time-consuming activity and wrap that up in a function somewhere. Here’s an example in non-bakery terms.

I am currently using Pygame for its ability to process keys. When I want to figure out what keys are being pressed, it can look a little something like this:

  1. for event in pygame.event.get():
  2. if event.type == pygame.KEYDOWN:
  3. if event.key == pygame.K_LEFT:
  4. player.walk(x=-1, y=0)
  5. if event.type == pygame.KEYDOWN:
  6. if event.key == pygame.K_RIGHT:
  7. player.walk(x=1, y=0)
  8. if event.type == pygame.KEYDOWN:
  9. if event.key == pygame.K_UP:
  10. player.walk(x=-0, y=1)
  11. if event.type == pygame.KEYDOWN:
  12. if event.key == pygame.K_DOWN:
  13. player.walk(x=0, y=-1)

If you didn’t bother reading all of that, I don’t blame you. I certainly don’t want to have to write it every time I want to create a game. To solve the problem, I created a code module whose job it is to carry out those basic functions, and all I have to do is give it two pieces of information: which key should call which function, and when the module should check to see what keys have been pressed down. The code for the first part looks like this:

  1. keyboard_handler.register_keydown(‘left’, player.move, x=-1, y=0)
  2. keyboard_handler.register_keydown(‘right’, player.move, x=1, y=0)
  3. keyboard_handler.register_keydown(‘up’, player.move, x=0, y=1)
  4. keyboard_handler.register_keydown(‘down’, player.move, x=0, y=-1)

And when I want to have the program check which keys are down, I just do this:

  1. for event in pygame.event.get():
  2. keyboard_handler.process_key_events(event)

With a single call to process_key_events, I tell the program to go look at my shiny, new keyboard handler and run all that bloated code you saw above. Instead of having to type 13 lines of code, I now only need to type 6, thus slashing my required code by more than half. This makes my programs easier to write because there is less writing to do. At the same time the code is easier to debug because there is less of it to read. Productivity 1, frustration 0.

I’m excited to be finished with the tool-making process—at least for now. I’m equally excited, however, to have designed something that can really speed up coding and simplify development, not just for myself, but for anyone who wants to code in Pygame. Che Martin of Blind Adrenaline Simulations once told me about two weeks he spent building a module to make jaws speak in his games. At the time I couldn’t fathom spending two weeks coding something that wasn’t directly connected to a game. Now that I’ve spent 8 days creating my own tool to build into all of my future projects, though, I understand what he meant, and I appreciate the experience.

Downs and Ups

I looked at the website today as Randi and I were searching for the renewal email, and it occurred to me that I haven’t posted an update in over a month. In fact, it has been closer to two months since I posted anything, and as of my last writing, I was still hard at work on boxing. I think the biggest reason for my absence has been that while a lot has happened, not much has been accomplished. Let me try to explain.

My last post was full of optimism about the coming break and the progress I would make on the boxing game. As soon as school finished for the year, however, I managed to contract a really nasty piece of malware, and I found myself having to reformat my computer. As I was upgrading from Windows XP to Windows 7, however, I neglected the fact that the new install didn’t wipe out the old one, but rather installed alongside and throughout it. Thus, I wound up with a tangled amalgamation of two operating systems with a virus lying dormant somewhere in the ruins of the Windows XP side.

No problem, I thought. I’ll just reformat again.

This time, the reformat and reinstall went off without a hitch, and I figured I was Scott free. Side note: I bet there is totally some dude out there named Scott Freeh, and he probably gets a lot of grief from people. Poor guy. Anyhow, I set up Carbonite to start restoring my files, but a mislabeled checkbox caused the program to start dumping the entire backed-up contents of my old format into my pristine new one. This meant that I had directories for Windows 7 that were bare and desolate, and I had jam-packed directories that followed the Windows XP folder structure, all of which were hopelessly entangled once again. Because several gigs had been dumped into my pristine format before I realized the error—that’s what I get for restoring overnight—there was no way to quickly fix the problem.

You can probably guess what I ended up having to do yet again.

Amongst my 3 reformats were all the things that ordinarily occur throughout the holiday season: traveling, dinners, spending time with family, etc. As a result, New Year’s came and went, and I hadn’t written a single line of code. I ended up going back to work on January 2 having accomplished absolutely nothing during the Christmas break.

And then came the coding craziness. I finally realized, after banging my head against the problem for some time, that there was no immediately plausible way to carry out key commands that utilized multiple key presses. For example, holding up arrow and pressing a could not throw a left hook to the head using my current library. So I needed to find a new library—one that would allow me to press multiple keys simultaneously.

First, I tried looking for python-based solutions to the problem. The only solution I could find, however, was the Pygame library. In talking to other audio game developers, I found very little support for Pygame, with criticisms ranging from speed of execution to a lackluster sound library. When I brought up Sound RTS as an example of a great game that just happened to be written in Pygame, it was pointed out to me—accurately, I might add—that even it suffers from very slight execution lag on things like key presses.

So, scared off by the boogie monster of latency, I started looking at BGT, the audio game development toolkit written by Philip Bennefall of Blastbay Studios. Because the core components of BGT are written in C++, execution of almost anything is incredibly speedy. Another feather in its cap is the fact that Philip is an INCREDIBLY NICE GUY! I cannot stress that last point enough.

However, I soon discovered two problems with using BGT, neither of which had anything to do with the language itself. The first of these was the fact that I had already spent a year learning to program in Python, and I was loathe to throw away all of that practice and knowledge in favor of a different language. The second was that I had incredible difficulty switching from a Python mindset to a BGT one, and as almost everyone who has ever rerolled their character and become a newbie again will tell you, starting over sucks.

In order to reconcile the conflict in my head—Python versus anything else, speed of execution versus speed of development—I did what I should have done a long time ago. I signed up for the Pygame mailing list and started asking questions. I received a number of intriguing answers, but probably the best of them went something like this:

You’re so busy spending all of this time worrying about speed and lag and all of these other things that haven’t come up yet that you haven’t even written a single line of code. Many, many people have written great games in Pygame, and they haven’t run up against a speed barrier. So program something—anything—and if you start having problems with speed, there are work-arounds for that.

When I decided to adopt this mindset, it opened up a whole new world of possibility to me. Instead of seeing potential difficulties as obstacles, I started seeing them as barriers to be broken down. Instead of looking at things through a lens of negativity, I started finding more positives. So what if Sound RTS has a tenth-of-a-second lag on key presses. It’s not like that style of game requires lightning reflexes anyhow. And I didn’t even notice the lag until someone pointed out to me, so what did I care? It’s still a great game.

But I didn’t want that lag, because the kind of games I’d like to develop will require lightning reflexes. So I started looking into why it existed in the first place, and almost immediately, I found the answer. It turns out the chief Python critic on the Audyssey list was right, though it chaps my hide to admit it. The sound support for Pygame isn’t the greatest, and when used in a certain way, it can create all sorts of slowdown in programs to the point that, if you make the sound buffer size too large, it can take over a second to modify any currently playing sounds. Huge problem, right?

Well no. If the Pygame sound module slows things down too much, don’t use it. Problem solved! Seriously, it’s that simple!

And just like that, I’m back in business. I’m using the Pygame keyboard module to handle all of my key presses, and I’m stoked about the things it can do:

  • It keeps track of each key press that the user generates, and it gives the program the opportunity to act on these. If, when looking through the key presses, the program finds an “up” in the list, it can run through its analyses and decide to make the player jump.
  • It has a key_pressed function which allows the program to check what keys are held down. If, while walking across a level, the player holds down the control key, the get_pressed function will see this and make the player run.
  • It tracks when players release keys, and it can use this information to call additional events. If, for example, I wanted to program a laser gun that charged itself up as long as the player held down the control key, then fired when the control key was released, I could do that!

As for the sound library, I just switched back to using sound_lib, the library that’s served me well through both Block Party and boxing. It has all of the functionality I need to program with none of the lag, and if I need it to do more, I can tweak the programming myself.

With all of this in place, I have one last hurdle to overcome, and that’s learning to write comfortably in Pygame. I’ve made a car engine that revs up and fades as you press the up and down arrow keys and steers from side to side as you press left and right. I’m in the process of making a character that walks from left to right and back when you press the left and right arrows. These things still don’t feel fluid to me, though, and only time and experience will change that.

What does this mean in terms of game development? Sadly, it means it’s going to take a little while to get things back off the ground and headed in the right direction. More importantly, however, it means that game development is still progressing. Those of you following the twitter feed will note that activity has started to pick back up as I run Pygame through its paces. Things will get moving again, but they may take a bit longer than any of us would like. I’m not out of the race, though. I can promise you that.

Pouring

                I guess I always knew somewhere deep down that there were going to be down sides to programming, but of late they’ve been cropping up in some very unexpected places. I expected to have to face some of the legendary heckling and complaining that almost all developers have encountered, but the community has been blessedly understanding and kind about the whole thing.

                Perhaps I’d better back up a bit here. A few weeks ago I received an email on the Audyssey list from a user who told me that Block Party wouldn’t run on his system and that he was getting error X. Having no idea what error X involved, I put out feelers, and I was told to put a specific line of code into the main module that would fix everything. I placed the line of code where I was told and uploaded the new executable to the site.

                I then went back to work on the boxing game, building in support for multiple punch types and perfecting existing sounds, only to discover that my current keyboard code didn’t support things like holding down keys. If I wanted to press up and A at the same time to throw a left hook, I could, but I couldn’t hold up and tap A at some future point and achieve the same result. Some people might argue that it makes no difference, but for some reason, the lack of being able to hold keys feels awkward to me, and I’d like to be able to fix it.

                So I started working on a solution. I went out and started researching Pygame, a Python library specifically designed for game development. (Some of you may recognize Pygame as the library used to code Sound RTS.) I figured if I imported the Pygame keyboard module, I could build in support for a lot of the keyboard-based stuff I really wanted. There’s also the added bonus that Pygame supports mice and joysticks as well. But just as I started my research, life started happening.

                First came the emails from the Audyssey list telling me that the new version of Block Party wouldn’t run on 64-bit Windows 7. I have to pause here to point out that the emails I have received thus far have been extremely cordial, and I cannot stress enough how much I appreciate that. After the emails, though, came a mountain of work at my job, and after that came some previously-made engagements which have taken up a significant chunk of my time.

                Today I finally had time to sit down and research the problem, and I came to the conclusion that I needed to roll back to the previous version and find another solution to the problem, only to receive more kind emails from people telling me that They—the emails’ authors—could now happily run Block Party’s latest version on their computers. Argh! Now I have to trouble-shoot Windows 7 64-bit!

                The most interesting and awesome thing about this whole ordeal is the response I have received from the blind gaming community. As I wrote earlier, I have received no negative emails about Block Party’s refusal to play nice with everyone’s computers. Especially given some of the epic flare-ups which have previously occurred on the Audyssey list, I was expecting to have to dawn my ceramic suit and dive for cover to escape the flaming. Instead, everyone has been very understanding and patient with me as I research and learn in an attempt to solve the problem.

                Which is probably why I feel so bad.

                You all have been waiting for months for the boxing game—almost as long as I have. I have been giving out teasers and snippets from time to time and writing about my progress in various forums, but real, tangible results of this project have not been forthcoming. I know deep down that there will be setbacks; I’ve written about them in a previous post or two, but I hate that they’re occurring at all. More than anything I want to finish this game and release it to the general public, but for some reason things just keep coming up. Maybe this is all a bit melodramatic, and maybe I’m just on edge after the whole Qwitter thing, but I keep feeling like there’s a clock hanging over my head, and when it strikes, there goes my credibility. The funny thing is: it’s not you; it’s me.

                Holy crap. I have to stop writing now before something even more cheesy comes out of my keyboard: “maybe we should just be friends.”

                Anyhow, thanks for letting me get that off my chest, and thanks for being so awesome about the whole thing. I promise I’ll make the end result worth it, and we’ll all have a lot of fun.