Game Development Tips from the Trenches of PopCap
Well, this is a post that’s a bit overdue, but, thanks to a well timed bank holiday, I finally had the opportunity to sit down and type up what I’ve been meaning to for some time now…
Before digging straight into the game a team and I have been assigned to build at my new job with PopCap, the powers that be thought it best I first have a sit down with other Flash developers in the company and learn from their suggestions, experiences, mistakes, and successes. So, after surviving the 20 some hour journey from the Dublin office to PopCap HQ in Seattle, Washington, I had the pleasure to sit down with the likes of Max Anderson (I mention his name as he spoke at AdobeMAX in 2010 and a few of you may be familiar with him) and the creators / maintainers of the fantastic PopCap online games Bejeweled Blitz, Zuma Blitz, and Pig Up!
Although much of what was discussed was company specific, what follows is a few of the juicier and more generic (so generic, in fact, they can really apply to any development environment, not just Flash) words of wisdom I picked up during my week long visit to Seattle. Many are really just common sense programming advice, but perhaps some out there (myself certainly included) may find it useful to hear it all again as a bit of a reminder.
When games are initially released, they tend to get a large group of users up front. If there is nothing to maintain that user interest, that group of users will quickly dwindle away. For that reason it is best to let your release ‘trickle’ out into the public. If possible, throttle the number of users at first, then slowly open it up. Limit the number of features in a first release, but make it clear that more are to follow. In general it’s better to release a game of limited features but with a well advertised list of things to come to keep people coming back, than to release a more feature rich game and have the user number spike then fall off.
Treat .swf’s as Asset Packs
While in Seattle I was ‘treated’ to a look at a Flash game which consisted of over 30 odd .swf files. Because each .swf had different dependencies on other .swf’s in the bunch, they had to be compiled in just the right magical order for the whole thing to work at all. Needless to say, this had become a maintenance nightmare of fairly epic proportion. The lesson learned here: if you rely on additional .swf files (and this alone is a debatable practice), those additional .swf’s should simply be storehouses of goods (sounds, images, fonts, etc.) – they should not be ‘modules’ containing chunks of code that your main .swf relies on to operate. Ideally they should contain no (or very very little) code at all. In more concrete gaming terms, you should not have a game .swf that loads in a ui .swf which loads in a leaderboard .swf and in app store .swf, etc, etc. That way lies the road to heartbreak and misery.
Utilize Global Error Handling
Since Flash Player 10.1, it has been possible to catch any ‘uncaught’ errors encountered by the player. While in a perfect world you would always catch errors as they happen and deal with them at that moment, it’s still a good idea to make use of this still relatively new UncaughtErrorEvent just to prepare for the unexpected. Since you can never be sure what exactly happened during this event handler, it’s best just to just handle it as gracefully as possible – even if that means showing alert that tells the user, “hey, something just happened. why not refresh this page or whatever just to be on the safe side.” It may cause some annoyance for a small minority, but it’s much better than a game simply crashing, or worse yet, just silently failing.
Publish a Stand Alone Version
While your final game may be dependent on databases for high scores or Facebook calls for friends etc, it’s always a good thing to have the ability to publish a quick stand alone version. Whether those external dependencies are simply ignored or mimicked with some fake bindings makes no difference but should fit nicely into the development flow. In any case, a stand alone version will make it much more hassle free for both yourself as well as designers, artists, producers, et al. to have a go at the game without having to push a version to a live server or testing environment.
Separate Game Logic from Presentation Layer
This really kind of goes without saying. It’s basically just a matter of utilizing the time tested Model-View-Controller pattern. These days though it’s more important than ever to keep logic separated from presentation. This will make it much easier to get your game quickly running on different devices with differing screen sizes or even ported from one environment to another all together.
Prevent Failure Rather Than Explain It
One of the horror stories I heard during my time in Seattle was about a game that contained an in-app store which would update a player’s inventory without first waiting for confirmation from the purchasing system. So a player might spend some ‘hard-earned’ credits on a shiny new boost and receive visual indication that they do indeed have it (maybe even be allowed to brag about it to their friends), but if there was any glitch during the purchase, they may return to the game to find they really don’t have what they thought they did. That’s really not something you can easily explain away to a disgruntled player. Moral of the story: never allow the client to make any assumptions; keep it as dumb as possible. It’s better a player stare at a spinning wheel a few moments and wait for a purchase system to report success than to just charge ahead not really knowing what has taken place. And speaking of preventing failures, look back to tip 3 and make use of the Flash Player’s UncaughtErrorEvent. Again, it’s better the user is presented with a generic error message than a locked up game, or worse, a game that appears to be functioning normally, but really isn’t.
Keep Class Files Manageable
As a general rule of thumb, class files should really not exceed 300 lines or so. Of course this isn’t a hard fast rule that says classes should just be chopped up willy nilly when they get to line 301. But if you find a particular class file that seems to keep creeping in size, it’s time to have a good hard look at it. Odds are, it’s taking on too much responsibility. One strategy for maintaining manageable classes is to favor a component based architecture. For anyone unfamiliar with the idea, check out the Actionscript PushButton Game Engine – it does a great job of both presenting and using the concept. When in doubt, just repeat to yourself the old programmer’s addage: “Always code as if the person who ends up maintaining your code is a violent psychopath who knows where you live.”
Know the Vision of the Game
As a coder, it’s very easy to get caught up in day to day activities and very specific problems to the point where you lose track of the bigger picture. You can’t really see the game through the ones and zeroes, so to speak. It’s good, though, to always have it somewhere in the back of your mind. So, the next time you’re up against a tough algorithm or some stupid bug seems to creep in out of nowhere, take a breather and have a look through the design docs or go over and have a chat with the game designer (assuming it isn’t you). It does the mind a bit of good to remind yourself that what you’re working on isn’t simply lines and lines of code, but (hopefully) an enjoyable game that will (again hopefully) be played by lots and lots of people.
Maintain Well Defined Interfaces with Little Changes
This is another of those “goes without saying” general OO principles. Implementation in games tends to change often and regularly. If you begin the coding process with a well thought out clean and preservable interface, you’ll save countless hours of head and heartache down the road.
Use a Fixed Rate Timestep
All PopCap games are, at the very least roughly, based on the original PopCap C++ game framework “SexyApp.” If you do a bit of googling, you can find a copy of the framework for download (I don’t want to supply any links as I’m not sure it’s official and I’m definitely sure it’s not supported as it’s a few years out of date now). Of course at the heart of every game framework is the game loop, and the SexyApp loop basically boils down to this: perform 100 fixed game updates every second and draw the screen as often as you can (100 times a second would be great, 60 times is pretty sweet, and below that is acceptable so long as the animation remains relatively smooth). Using this fixed update loop is perfect for keeping physics engines and game logic running smoothly and, more importantly, predictably. For a great introduction to fixed timesteps in general, check out this article from Glenn Fiedler. To get an idea of how to accomplish this in Actionscript, check out Max Anderson’s talk at AdobeMax where he explains his arduous process of porting the classic “Plants Vs Zombies” to Flash.
All business aside, I have to say, I had a pretty fun trip to Seattle. It was the first time I’ve been back in the States for several years and the first time I’ve ever been in Seattle. Climate wise, it’s really not so different from Dublin – I’d wear sunglasses on the way into work and carry an umbrella on the way home. It’s a nice small clean bustling city. All things considered, I suppose if I was forced to return back to the US there are much worse places to live than Seattle *cough*Flint*cough*…