Good news everyone! I’m back from my holidays, which I’ll persist in calling “holidays” despite there being nothing holy about them out of a sort of misguided nationalistic pride for a country I’m not even from.
Anyway, today I wanted to talk about why back-story is important if you want people to understand how to play your game…
For those wondering what what this job of mine is, that chews up all my (previously) free time: I get paid nothing-an-hour to tinker around with a Kinect IR camera using Libfreenect, OpenNI (with Sensor and NITE), and uinput. Can you guess what I’m building?
What’s interesting is the stark contrast between the two. Where Rules of Play begins by bemoaning the lack of novelty in the game’s industry:
For a while it seemed that every other title was a fresh attempt to answer the question “What can you do with a computer?” Compare that with the current crop of computer games, the majority of which seem to be addressing the question “What can you do while controlling an avatar that is moving through a simulated three-dimensional space?”
Game Engine Architecture jumps right into defining the various canonical “genres” and their specific technical requirements, as though these are the only kinds of games that ever have and ever will exist. I also noted that, whereas a good third of the book is concerned primarily with 3D graphics programming, a single short paragraph is dedicated to “High-level Game flow”. All it really says is:
For this reason I suppose it’s not a particularly ambitious or creative book. It doesn’t rock the boat, it doesn’t rattle the cage, and the author has a bad habit of name-dropping and using non-words like “authored” and “architected” (shudder). That said it’s sober and lucid and very instructive. I’d recommend it to any and all game-programmers, even those who have no interest at all in 3D graphics programming (though you will be losing that third of the book).
Rules of Play, meanwhile, has scores of introductions and forewords to chew through before you get to the actual point, as though the authors are desperate to justify themselves. This self-conciousness continues throughout the body of the text: it is written in a very vague manner whereby the same word can be defined, say, both as the means to an end and as the end itself:
This is an interesting tactic that drives people in science nuts: in science, definitions are fundamental tools for building theories and making explanations. To a scientist, it appears that the authors want it both ways: the apparent rigor of a definitional approach, but without the commitment. – Amazon Review
That said I still think it’s well worth a look, and for the remainder of this post I’ll try to explain why…
What’s an “ideas man”? Good question:
I’ve always fancied myself as a game-designer, or rather always wanted to be one (when I grow up). Course, I’ve also always heard that the industry has no place for specialised “ideas men” (at least not straight out of university) so opted for a more versatile Informatics degree instead. It was only at the IGDA in Verona (January 2011) that I started to wonder whether there was more to design than I’d been doing for my previous projects: Federico Fasce, now the elected head of Italy’s IGDA chapter, gave an interesting talk about his process. This got me wondering, but it wasn’t until the recent Art Game Weekend in Paris that this line of thought finally came to a head. I was able to have a long discussion Brice Roy, game design lecturer and game-designer for One Life Remains: a loose collective of six indie game developers. The first question all this brought to mind was:
Does being a decent game-programmer make you a better game-designer? Does it make you worse?
As I’ve become a more and more proficient programmer my ideas have become increasingly less “pie-in-the-sky”, to the point of even being a little conservative. This is because every time I come up with some crazy idea the logical side of me censors it before it has time to flourish. Perhaps a person free of such technological concerns would make a better game-designer? A complete ignoramus would tend to propose impossible concepts but, whether they’ll admit it or not, there’s nothing engineers love more than impossible problems.
Furthermore most of my past ideas would have fit quite comfortably into the conventional set of game genres: apparently I’m not nearly as original as I’d previously thought! So:
Should I give up on my dreams of being a game “ideas man” and instead go full-throttle into development instead?
Nope. I don’t think it would ever fully satisfy me, pleasant though it is to have someone us telling you what to do all the time. But if I want to be a designer I clearly need to up my game (teehee), and to do this I may need to find some way of divorcing myself from the technology a tad. For this there’s no better book than Rules of Play, which talks a lot about ideas but never really concerns itself with their implementation. Several reviewers complained that it’s somewhat out-of-touch with reality, but this is actually its great strength: rigour and best-practices can become handicaps when it comes to thinking outside the box. Emily Levine would talk about the importance of “holding your ideas lightly”:
This all feeds back into the with FOSS games’ problems discussion: nobody is more concious of the technology they’re working on the hackers, crackers, trolls, moles and code-monkeys that make up the Free (as in “Freedom“) -Software movement. And as we’ve discussed previously, this may be its great weakness: there just isn’t enough ignorance to go around! Speaking of Free Software: I recently lost some (more) work so have decided to (finally) start putting all my code and assets online, simply because I’d rather see them stolen than destroyed by accident. When I get round to it…
Back to the point: when Free Gamer picked up the above I desperately tried to cover my rear by doing a post about games and originality in general. The overarching idea here was that there’s nothing new under the sun: innovation can be reduced an extension, recombination and/or reversal (contradiction) of one or more existing ideas. But there’s actually a fourth process at work here, perhaps more important that the other three combined: analysis. Analysis allows us to take an existing idea and to break it down to an atomic level. This dissecting of existing ideas allows us to extract the elements of particular interest, elements which can then be combined, extended or reversed. The more effectively we can identify, isolate and -above all- understand these game-design building-blocks, the more effectively we can put them back together in new and different ways.
This is the main reason why Rules of Play is a useful book to read. It is essentially a collection of all the game-design elements the authors have been able to discover over the years. If you can get through the stylistic fluff this makes it something an invaluable resource because, as with programming, the lower the level you start from the more unique the result!
That said if you wanted to buy just one book on game development it probably shouldn’t be either Rules of Play or Game Engine Architecture: I’d recommend Game Design: Theory and Practice for a fairly broad overview of game development, from concept to implementation. But if you can get hold of all three: knock yourselves out
So, did you managed to guess what my project is? That’s right! We’re controlling the cursor with gestures, “Minority Report” style! My boss wanted it working for Windows though and Windows, as you may or may not be aware, is rather unpleasant System to work with: egsnay on controlling the cursor system-wide. Not without some special API at any rate…
Recently I’ve been trying out a bunch of “Free and Open-Source” (FOSS) games. Or rather, I’ve been trying to try out a bunch of FOSS games. But let’s not get ahead of ourselves: unlike those that are (eventually) ported to Linux, FOSS games are quite often made by Linux users for Linux users. As such they are something we can be proud of, which is a change from having to be meekly grateful to the one guy in a hundred who actually bothered to do things by the book and make his code platform-independent (the book in question is called: “How not to be Microsoft’s gimp”).
Previously I did a short series of posts about good FOSS games for Linux – check them out if you haven’t already:
I’ve actually played a few more since then (I’ll post another lot of suggestions at some stage): the point being that there’s no shortage of such games. But I get the feeling sometimes that the crème-de-la-crème of Windows gaming, even free gaming, is “better” than the best Linux has to offer. So what’s the problem with FOSS gaming?
I – Technical issues
I don’t know how many times I’ve naively clicked on a binary and had it do nothing at all. Windows tends to come up with a big fat error-message, but unless you run the program in the terminal, Linux software generally won’t give you the slightest idea what went wrong.
To get “Frogatto” working I had to chase up a bunch of packages that weren’t in the repositories. To its credit the game was more than worth the effort
Most often, when it comes to games, the issue turns out to be a missing library, but solving this can often be easier said than done. If you don’t have the library you may find it on Synaptic or Aptitude if you’re lucky. But the program may be looking for an out-of-date library, so if you have a newer version you’ll sometimes need to use a filthy hack to get it working (eg – spoof the old version by creating a symbolic link to the new one). Alternatively the program may want a newer version of the library than the one in the repositories, in which case you need to find the package yourself on-line and manually chase down all the dependencies. That is, if you’re lucky enough to even find a pre-packaged DEB-file (or similar): you may well end up installing everything by hand as well, which takes a long time and is prone to human-error. Granted there’s probably a better way of doing these things, but I’m not exactly a brand-new Linux-user so there are going to be people are lot more ignorant than I am.
Windows games generally “ship” (I’m talking about indie games here, so by “ship” I mean, “zip”) with all the necessary DLLs. It may be an insult to one’s intelligence that you’re seen as incapable of finding them yourself, and it certainly makes the downloads a lot larger, but at the end of the day you’ve got a program that will work out of the box, full-fricking-stop. On a side note in the future I may start including shared-object files with my games, just to make sure that everything works (previously I’ve blindly obeyed the conventions and only included the necessary libraries for the Windows versions).
Lately the only FOSS game that’s worked first try was “Buggy Race“. It came with a functional installer and ran just fine, but the sound won’t work for some reason…
All this without even talking about bugs. Before Pulseaudio all was well for Ubuntu gamers, but now many games will either run in deathly silence, deafen you with static or crash out-right!
II – Lack of originality
One of the most active/promising/exciting FOSS games right now is probably “0 A.D.“, but when you think about it it’s nothing all that new or different: it’s an “Age of Empires“ clone. Let’s be honest with ourselves: aside from a few examples we are not a really centre for gaming innovation here at Linux-HQ. The rest of the indie crowd are racing forward breaking land-speed records but Free (as in Freedom) gaming is miles behind still trying to reinvent the wheel. Over and over again. It’s a sad truth that many FOSS projects are clones that diverge very little from the source material. The line of thinking goes something like this:
“I loved to play X when I was young but it doesn’t run natively on Linux; let’s do a remake!”
Or, if you’re very lucky:
“X was good but had a few problems; let’s try to improve it, and port it to Linux while we’re at it!”
I’m actually pretty psyched about “FLARE“, but if I was a Windows user I’d probably be thinking “why not just reinstall “Diablo“?
This is all very well, but it does mean that this sub-group of the independent developers gets little or no attention from the rest, who only see inferior copies of something that’s probably Abandonware by now anyway. Just look at the list of articles with a “Linux” tag on TIGsource: almost all of them are commercial products that happen to have been ported to Linux, and only one is also tagged “Open Source“. Same story over at indiegames.com/blog. This is a crying shame in my opinion!
I’ve developed this vague impression that most artists use Mac, most programmers use Linux and almost everyone else uses Windows. We have this incredible technical proficiency in our camp, but I think we have a serious lack of right-brained people: the creative sort with a humanistic education, who don’t even know their arrays from their pointers (tee-hee). In other words: we need “Game Designers”. I’ll admit that I’ve often been sneered things like “design is the programmer’s job”, but in truth when I put down my notebooks and put on my programmer’s thinking-cap, I tend to find reverse-engineering an existing system to be a lot more palatable than building an entirely new one.
Don’t get me wrong: I’m not saying that Alien Arena isn’t awesome, but is *is* clone…
Simply put, programmers like making clones because we know where we’re going and when we’ll have arrived. We want to get into the nitty-gritty of programming without having to think about design, and stealing someone else’s design is the quickest way of doing so! This is why we programmers should probably not be in charge, even if we tend to think we should For the record I’m not entirely sure what I am these day: I plan, I code and I draw, all… “passably” I suppose. So I think I’ve chosen to be mediocre across the board rather than specialising in any one field. But this is probably not the way to go guys
“In any given Internet popularity contest, StarCraft would win hands down. But a full year before StarCraft, the first “modern” RTS was unleashed to the world, and it was years ahead of its time.”
TA was a bit of an obscure cult-hit, adored by its fans and by reviewers but mostly ignored by everyone else. It may be a infinitely deeper, more complicated game, but it never caught on in the way that Starcraft did, because of one serious issue. Years later Chris Taylor‘s Gas Powered Games released a spiritual successor, “Supreme Commander“, which while impressive failed to correct the flaw that had so plagued the original (more importantly even today it won’t run on anything short of a super-computer). And as I mentioned previously, TA now lives on through the FOSS“Spring Project”, which has likewise inherited the thorn in its grand-father’s side.
I’ve talked about “The Cursed“: finally I’ve got a video to show you
“What thorn?” I hear you ask. Why, a complete lack of personality! Just look at the two games’ boxes (wikipedia links above): would you rather pick the one with the blocky robots or the one with the three faces staring at you? We Human-beings have evolved to love eyes and voices, but TA and its offspring have you spend your whole time moving faceless, soulless tanks and robots around and listening to them go “click clunk“.Compare that to any of the -craft games’ units, which are cute, full of character and brilliantly -and often hilariously- voice-acted (“rape the waiting lunch-orders”). Starcraft even had animated face-portraits!
There was also an interesting story with characters you could actually care about in Starcraft, while on the other hand Taylor admits that TA‘s story added as an after-thought. Things weren’t really improved with Supreme Commander (despite a clear effort): the plot of which was pretty irrelevant (it was too cut-off from the gameplay). Worse still, the Springproject‘s are collectively non-existent, which is really not good for a RTS game: generally a campaign-mode is a must to ease the player into competitive online-play, especially if your game has literally hundreds of different unit types.
It seems that many FOSS games, while deep and technically impressive, lack polish and personality. There something called “juiciness” in Game Design, but I’d humbly propose that a game needs “cuteness” too. And I don’t just mean big-eyes and squeaking as in “Lemmings” or “World of Goo“ (though it certainly helps), I mean some kind of human contact. If Blizzard were once the king of RTS gaming it’s because they used caricature, exaggerating proportions and pumping up the charm rather than letting the units become irrelevant canon-fodder stick-figures.
Some ease-of-entry would be nice too…
IV – Design by comity committee
Roger Ebert suggested that games were not and could not be art because they have no author. While I disagree with him for a number of reasons he might well have a point when it comes to projects with a lack of strict hierarchy and hundreds of contributors coming and going over the years. It works great for “boring” software (think of GIMP or Firefox), but games are entertainment. They need some kind of authorial artistic vision or they’ll come across as unfocused. This is not to say that it’s impossible to make games using this development paradigm, but I do think that one needs to be extra-careful!
Keith Fulton on “being extra-careful”.
This is another problem with design by comity committee. The Japanese say “your garden is not finished until there is nothing else you can remove”. I think this applies to Game Design too, but with everyone and his mother adding features it’s very difficult to keep the game lean and mean. FOSS games are vulnerable to feature-creep and in many cases just don’t feel “finished” because they never really are. There will always be new stuff you can add to a game but that’s not to say you should. This is what I learnt from Supersoldat: it may be more fun to add new features than it is to polish those you already have, but polish is far more important if you want your game to be any good.
Probably the best piece of game-design advice I’ve ever read comes from Derek Yu: “finish your damn game!”
Now if you’ll excuse me, I have to get back to my Cyberdogs/Doom clone
Hi all. Again, because of my course-work it’s hard to justify working on “Bugger!” at the moment. That said I’ve taken a few baby steps: work has begun on special effects, another important entity that needs to fit into the hierarchy somewhere (they’re visible and updateable but not collideable). I’ve also added (blob) shadows and a nice big cross-hair, but nothing impressive enough to make a video about. I’ll keep you posted.
In the meantime, here’s a nice little Game Design rant for your delight and delectation!
If it’s broken, don’t fix it
Batman is broken!
Once upon a time…
“I tried out the Batman demo for a while at a local game store, and their fighting system is totally broken. If you keep pressing the ‘counter’ button with one hand and read a book with the other, you will win all of the fights without getting hit.”
Okay, let’s back up a minute. The game in question is “Batman: Arkham Asylum”, and this discussion took place some time before its release. Now that it’s been on the shelves and in the press for some times, I think we can all agree that it’s probably, at very least, the first comic-book-super-hero-based-game not to be shit since “Spiderman 2″ was released in 2004. This is worthy of merit in itself, and quite surprising. But the game was more than just surprisingly un-shit. Aside from the usual console-port issues (poor optimisation and keyboard controls) it trounced all educated expectations one might have had of it, which is more than can be said for a lot of carpet-marketed commercial releases. Whatever you might think of it the fact remains that it impressed critics and gamers alike. It was, all told, a surprisingly good game.
But I’m not here to write a review, especially not of a commercial release. The thing I wanted to talk about is the fact that, despite Arkham Asylum being a surprisingly good game, the combat is indeed “totally broken”. Oh yes, it’s possible to “cheat” your way through almost every fight in the game simply spamming the ‘counter’ button. And then there’s the ‘dodge‘ and ‘stun‘ moves that effectively render you invulnerable. The question is: how can these combat mechanics have garnered so much praise despite their clear flaws?
Lugaru is broken too!
Okay, I’ll stop teasing. The above quote is actually from David Rosen, the child-prodigy behind “Black-Shades“ and “Lugaru”. Lugaru‘s design stinks of teenaged rebellion (it was made during High-School lunch-breaks), giving fighting-game conventions the finger (most notably button-combinations and -mashing) instead opting for a set of interesting and very challenging mechanics that have earned it a cult following (as you’ve probably guessed, I’m a part of it). But while a lot of typical cheap-tricks were prevented, there are still of few ways to beat the system. For instance, Jumping up and down next to cliff will cause the enemy to leap off and kill themselves, while spamming the attack button while armed or fighting armed opponents will make the character to block and dodge anything that would otherwise hit them. And, of course, there are other tactics of varying “cheapness” that are often used to beat the game’s most difficult levels.
That said, the discovery of these techniques has done nothing to shake the game’s cult status. How can this possibly be!?
What I’m trying to get at here is that practically any game, no matter how well-made, will probably have a few flaws (most often AI flaws) that the player can take advantage of. Such flaws are generally referred to as “Exploits”. Now, before anyone pipes up about it, I know Quake is a bit of a special case, since the exploit in question led to what is called “Emergeant Gameplay”. But Emergeant Gameplay probably deserves its own post, so we’ll talk about that in detail some other time: for now let’s focus on the exploits that are simply exploits and nothing else.
I said “onus” – not “anus”!
Let’s get to the point. Your game has a few flaws your players can take advantage of: what of it? Some players will take great pride in finding these exploits, and will enjoy feeling that they’ve somehow beaten the system: great! A small and minority will get very annoyed about them: who cares. But the rest will probably play by the rules, whether they find the exploits or not: why? To find out, let’s take a closer look at our two main examples:
In Lugaru, there are probably two reasons why people generally don’t use cheap tricks too often. The first and most obvious is that spamming a button isn’t much fun, and hurts after a while. But the second is that it seems somehow “dishonourable”, doesn’t make you feel like a badass, and all told it’s simply not very much fun.
The same is true of Arkham Asylum, but there’s something else at work too. See, in Lugaru you either win or you die: there’s no middle ground. Meanwhile Batman shifts the onus from simply surviving a confrontation to doing so while maintaining an uninterrupted flow for a long as possible. Needless to say, the exploits mentioned above instantly break the flow.
The advantages of shifting the onus from winning to winning-with-style are many and varied. Most obviously, you can make simply winning a lot easier, without making the game feel “too easy”. More skilful players are welcome to (and most often will) impose additional challenges on themselves, especially if rewarded for doing so. I’m not a fan of achievements in general, but adding a system of rankings like the one in“Hitman 2″(“Silent Assassin”) is a very good idea. You are rewarded for perfection but you’re also at liberty to just do things the easy way, and either way you get to play the next level:
All told making your game easier, without “lowering the bar” per se, is good if you want more people to be able to play it, and unless you’re catering exclusively to your own super-hardcore tastes, this is generally a good thing (personally I’d rather make something I can show to non-gamer friends without making them cry, although now that I’ve -finally- gotten into Dwarf Fortress I’m quite a big fan). Not forcing the player to restart so often (or at all) is also good for avoiding the frustrations of “hostage content”.
Nota Bene: less forced restarts does not necessarily mean the game is easier! In “Abe’s Oddysee”you’re not forced to retry whenever a Mudoken gets killed, but hardcore players will want to because they’re not just playing to finish the game: they’re aiming for perfection. And perfection in that game is exceedingly difficult! This is also a good example of how “broken” gameplay fosters replayability: the Oddworld games are more or less designed to be played twice, if not thrice: the first time simply to escape, the second to rescue enough Mudokons to get the “good” ending, and a third time to rescue them all and get the “perfect” ending (though of course tricking the player like that can’t be good karma).
It is impossible to lose in“Murder Man”, yet thus far I’ve had no complaints about how “broken” it is. This should raise eyebrows in itself: the idea of making the player restart when they “fail” is, like the now vic-to-vanished system of limited “lives”, inherited from the arcades. And, if not to the same degree as “lives”, it is fairly obsolete nowadays, when you think about it. When not just let the player play? Why force them to retry again and again until they’re good enough. Why fix what is broken?
In case this is the first you’ve heard of Lugaru, here’s something funny to check out, and in case you don’t like mysterious links: David’s left-hand man is shaving his beard for charity.
Except that by “charity” I mean Youtube subscribers
EDIT — I’ve added clean up and added a little bit more about UML, since I can’t very well be defending it without properly explaining how and why I find it useful.
Sweet, I’m finished!
But I do think the AI has now gotten to a stage where it both runs fairly efficiently and rarely (if ever) gets stuck. For those interested in the technical side of things, I ended up using “a priori” checking for walls and “a posteriori” checking for Instances.
The former means checking the position that the current Instance is going to move to, next time they are updated, as well as other potential positions to move to them instead. This means quite a few checks but that’s fine now that we’re using a pathing matrix for walls. This kind of collision checking was used for “Supersoldat” and “Abomination” as well: it works fine for walls, but mobile objects always have a chance of both moving into the same -unoccupied- location at the same time.
Because of this, and because checking for Instances takes a lot more calculations than checking for walls, I’m using a posteriori checking for anything mobile. When a collision is detected we can move the two Instances apart based on the ray between them, and their respective direction rays. This is how collisions were treated in “Zombie Run”: if you’re in doubt about how this works, take some Physics classes (you bumpkin).
To celebrate this success with the AI, I’ve given our protagonist some little animated skirikens to throw at his pursuers:
Unfortunately the shirikens brought a problem to my attention. Not a bug, but a serious misconception, committed back when I was designing the game’s object hierarchy. So before we talk about the problem itself, let’s talk “UML”!
In defence of UML
Building a game engine without any design work is like building… well, anything at all without any design work. But lot of us amateur programmers don’t like the “Unified Modelling Language”. Wesee conception as too much like work, and prefer to dive straight in to the nitty-gritty. And things generally go pretty smoothly at first, so we wonder why we’ve been force-fed all these conventions and all this modelling bollocks. Then progress starts to slow down, as our code becomes punctuation with hacks and kludges. In the end touching anything causes the whole lot to come tumbling down, at which point the project stops being fun to work on, and we give up…
Of course, I’m not saying you have to use UML – there are plenty of alternatives (like Merise), or you can use a modelling language of your own invention (I often break the rules to make specific diagrams quicker to make and easier to read). What’s important is that you, and everyone else working on the project, has some idea of its architecture from the get-go so things don’t get bogged down later. Using your objects wisely can also make your code a lot more scalable: say, if your player character is an Object then more players can be added without too much hassle.
So, what does “Bugger!” look like under the hood?
I generally only use two kinds of UML diagram. “Class diagrams” and “Sequence diagrams”.The former can be see above: it’s one of the first thing I do when I’m thinking about a new project. Class Diagrams are used mostly for deciding on a list of necessary objects, and figuring out whether to represent these as Classes in themselves or attributes. For example, the “Level” class contains multiple “Instances”, so one of its attributes needs to be some sort of expanding Instance container. “Sound” meanwhile, since it only needs to be accessed by “World”, probably doesn’t need its own Class. Class Diagrams can also help you to visualise hierarchies and, most importantly, navigability. Does the Instance class need to know information about the Level that contains it? Yes: it need to be able to retrieve the pathing map and list of other Instances to perform collision checks. So the Instance class needs a static reference pointing to the Level that contains it.
This doesn’t mean that everything should be able to navigate everywhere though: keeping navigability to a minimum will allow you to simply structures by turning them into simple attributes, and it will also save you from Linker hell…
Dealing with Instances
I’ve already explained what the “Instance” class is: effectively anything that appears in the level is an Instance. Using a Level class with an Instance container, rather than just a vector of Instances in some block of code also helps to hide some of the wires: adding and removing Instances can be done with a simple function (or rather “method”) call, as can loading and saving the Level (we can even use the ‘<</>>’ stream operators for extra credit). This is important because once we’ve implemented these functions we can forget about what they’re actually doing, and concentrate on the higher logic. The aforementioned Sequence Diagrams come in handy when dealing with complicated, under-the-hood Class interactions:
We can also have methods for updating and drawing everything. Separating the two means that we use the same class for the editor mode: we simply draw the Level’s contents without updating anything. Part of the collision code is dealt with here too: I can check a point or a whole area for collisions with a certain type of Instance, and the Level will return the address of anything it finds. Likewise created an Instance returns a pointer that can be used to manipulate it later on. But we’re getting too technically – moving on…
An Instance generally has a set of images it needs to draw. Thing is, what with images being rather large, it would better if everyone just had a reference or a pointer directing them to the same image, loaded only once into memory. If you’re familiar with Java or C# you’re probably thinking “easy: I’ll just use static attributes for each class” but in C++ it’s not that simple. The only kind of constant that kind be defined for a class, in it’s header file, is an integer. So Egsnay on the static image pointers: we’ll need to find another way.
“When in doubt, reverse-engineer” is an unspoken motto of mine (though not any more). You’ve probably noticed that many older games are separated into “worlds” or “chapters”, each with their own set of resources. This is so that you don’t need all your big sound and image in memory at once. So all we need to do is create “World” class and hash all our various resources based on integer constants defined in the Instances (or, even better, using the preprocessor). In other words, all the Instances will need is a single reference pointing towards the World and a list of resource names. Afterwards they’ll be able retrieve the appropriate resources as needed, without us needing to worry about manually allocating static variables for each type of Instance. This also means that all resources will be usable by all Instances.
As a further added bonus, we can give the same Instance a different look depending on the World. Remember how the buildings in “Warcraft 2″would have snow on them in the winter maps?
Long story short, when we want to load a new world we simple delete the old one: all the previous resources are freed by the destructor, and all the new ones are loaded by the constructor. This is what I mean by “hiding the wires”.
Sprites and Animations
You may be wondering what the difference between a “Sprite”, an “Image” and an “Animation” is. The first two are defined in the SFML library, but it’s the same story just about everywhere (OpenGL, DirectX, etc).
An Image is a image-file, uncompressed and loaded into memory. It takes up a lot of space to store bitmaps so it’s best to only load each image once and, as I explained in the previous section, only keep in memory those images that are currently being used. Also, because of the way that images are compressed, it’s better to use a small number of large images than a large number of small ones, especially where images use similar colours: most compression algorithms use a variable-length code based on the frequency of various colours, so a “cypher” must be included at the start of the file. This means the more files, the more headers, the more cyphers and the more space is required. This is why many games use “sprite-sheets”.
Sprites, unlike Images, take up very little space. This is because they simply contain a reference to the Image that needs to be draw, and a few other parameters like size and rotation. More importantly, you can define the area of an Image to be drawn, so we can cut the individual sub-images our of sprite-sheet Image. This is where the Animation class comes in:
When an Instance wants a specific sub-image, it simply asks its Animation to find the appropriate area of the Image. The Animation is able to do so simply by knowing the size and number of frames that the sheet is supposed to represent: a little multiplication and we can find the area of interest very easily. Each animation uses a single line of a sheet, meaning that a single Image can be used for as many Animations as it has lines.
Using hierarchies, like using functions, greatly reduces the amount of code. For Supersoldat I had many agents with very similar AI and physics properties, but I copy-pasted the shared code because I didn’t know any better. Murder Man on the other hand featured a very complex object hierarchy: adding new resources, like guns or enemies, is as simple as drawing up all the required animation and specifying them in the header. The shared code does all the rest! Needless to say, I really like hierarchies. The only down-side is that, like functions, following reference is slower than executing local code.
The “Mobile” essentially means that some code specific to mobile Instances can be migrated into another file, and make the make Instance class a lot more readable. For example: methods to deduce horizontal and vertical movement based on a direction and an absolute speed, or to deduce angle and speed based on horizontal and vertical movement. It also means that stationary Instances don’t have a whole bunch of speed and direction attributes they don’t need.
Trouble arises though when we create a new Instance, say one of our “Projectile” objects, and then try to set its speed and direction. We can’t do so, because what is being returned is an Instance reference and not a Mobile reference! I had similar problems trying to read the target location variables of the “Agent” class I was colliding with: again, such attributes don’t belong to Instance.
The obvious solution would be to remove the “Mobile” class altogether, but I’m trying to come up with a more elegant fix, because if I do this each time there’s a problem I’ll end up putting all my attributes and methods in Instance! And on that bombshell…
Yeah, I’m afraid that’s all for now: I need to go back to my sequence diagrams and see if I can come up with an elegant solution. Any question or piece of advice is more than welcome (especially the latter): I’m sharing with you the lessons I’ve learnt so far, but I don’t pretend to have all the answers…
EDIT — It may be possible to use a generic address return value (void*). It’s dangerous, but if I verify the type (all Instances have one) before trying to access attributes which may not exist, it may just work. But then I’m not sure if the GCC will permit that kind of irresponsible coding :p
Another option would be to finally learn how to use Templates…
Sorry for the lack of posts of late. As I mentioned earlier, I’m moving out of my flat and out of the country, so I’ve rather a lot of things to sort out. Lately I’ve been playing around with SFML and building a game engine, so I thought I’d talk about that…
If making a game is like building a house, then there are many resources out there explaining how to make windows and doors, or how to plaster the walls. And there are many blog posts from developers explaining what wallpaper or carpets they’ve chosen and why. But there’s little literature around that talks about how to assemble the structure, in other words the game engine itself (as opposed to higher game logic or programming basics).
In this series I want to take a stab at explaining the architecture of a simple game engine. If you use a tool like “Gamemaker” then this part of the job is already done for you, but it may still be interesting, indeed useful, to know more or less what’s happening behind the scenes. If you’re wondering why you’d go to the trouble of building your own engine, I can only say that it provides a degree of efficiency and above all freedom that you won’t find elsewhere, because it is made specifically for your game rather than as a generalised piece of software.
Before we begin I’m going to be making the following assumptions:
That you’re using C++ or a similar imperative language with object-oriented elements, as opposed to C# or Java which are pure object-oriented, or C which is pure imperative.
That you’re a fairly competent programmer, with an understanding of object-oriented design. Please don’t come to me because you can’t work out how to compile your program: as I just mentioned there are plenty of resources to that end online.
That you’re working in 2D. If you’ve already scratch built a 2D engine then you won’t need my suggestions, and if you haven’t then I’d strongly advise against going straight to 3D. It’s a whole other ball-game.
That you understand what a media library is, and why you’ll need one. Whether you use SDL, SFML, OpenGL or DirectX shouldn’t make a difference, as I’ll be speaking in fairly general terms. Please don’t come to me because you can’t get your library of choice working: again there are plenty of helpful tutorials available.
I’d also like to point out that my way of doing things may not be, indeed probably isn’t, the best way of doing things. The important thing is that it’s a way of doing things, and that in itself my be interesting, if only to hold up in contrast to what you’re used to.
Making a game might seem like a daunting task: where to start? Probably best to start at the beginning, in other words the “main”. When you’re out of ideas, you can always do a bit reverse engineering, so think of a few games you’ve played recently. Most of the time when you launch the program you’re greeted with a “main menu”, from which you can choose to start playing proper, change the options or exit, among other things. After changing the configuration or playing you’ll generally be returned to this main menu and given the same choice again. “Play” and “options” are thus clearly sub-routines of the main.
The “options” sub-routine, has a similar diagram to the “main” itself: you load the necessary resources (the background image, music, menu buttons, etc) and then keep checking for input, clearing and redrawing the screen until a variable, “running” in this case, is set to false. In a game like “Sokoban” where you only need to update the level when the player makes a move, this same diagram applies more or less to the Play function too. If you want something a bit more advanced though, with multiple objects that need to be updated constantly whether or not the player has pressed a key, things become a little more complicated:
Previously we could just wait for the player to press a key, but now the show must go on even if the player is idle. This means setting a maximum number of frames per second. There are two reasons for doing this. First, you want the game to run at the same speed no matter how powerful a computer you run it on. Second, you don’t want the program to be taking up 100% of your CPU cycles, because you may well want iTunes or some other program running in the background, not to mention the various process most OSs like to run. As such we’ll calculate a set number of frames and then wait for a split second, which in computer terms means working on some other process. Regulating the frame-rate is pretty trivial to do if you know how: look it up on Google and you should find plenty of useful information, no matter what library you’re using.
The “level” is an object that can be created and exported to a file using a separate level-editor program or sub-routine that we’ll need to write. It can then be imported back into the game to be played. The level file itself need only contain the coordinates and the type of each “instance”, the various objects of interest in the game: walls, power-ups, projectiles, enemies, and so on. When it is loaded from a file it creates all of these “instances” as specified, and adds their addresses (pointers) to a list.
When the level is told to update its content it simply spools through the collection of “instance” pointers and calls the update method of each one. What this method does exactly depends on the instance: I’ll explain how this works in the next post. Similarly the level can call the draw method of each one of the instances it contains. This is done separately from the update in case any lag occurs during the latter, as this would result in flickers of a half-draw screen. Also the draw order may be different from the order in which the instances were added to the level (the update order), and is likely to be constantly changing as instances move in front and behind each-other. For the same reason that in most board-games all the players take their turn in a specific order which doesn’t change, we want to keep the update order the same, but need to be able to modify the draw order on a whim.
Next time we’ll be looking more closely at objects and hierarchies. I’m not sure when next time will be I’m afraid, but I’ll do my best. Wish me luck in Italy!
Generally when I press ‘publish’ I assume my post will actually be published. Sorry this is a day late – should have double-checked that it actually went through :-S
“Non-linear” is one of those buzzwords Game Designers like to throw around all the time. Others include “Parkour” and “Dynamic”. This post emerged from a very fruitful discussion with the kind folks over at the Wolfire forums.
What does it all mean?
Before I start swinging, it’d probably a good idea for me to give a few definitions (even if they’re wrong) so that we’re all on the same page (even if it’s the wrong page).
A “linear” work is one whose content is experienced in a specific order and its entirety. Literature is a good example of this: generally it’s assumed that you’ll read every word on a page before turning to the next one. We often refer to Literature as a”narrative” medium, because it tells a story.
Meanwhile a “non-linear” experience doesn’t impose any order at all on its audience. Take Painting for example: the artist might guide your eyes a certain way, but you’re free to take in as many or as few of the details as you please and in any order. Because of this freedom to explore content we call Painting a medium for “exposition”.
I’m taking extreme examples here: as with all things in life there’s no sharp line dividing “linear” from “non-linear”, and often you’ll find works that combine elements of both. Comic-books and detective-novels for example.
Where does that leave Games?
Games are actually a “non-linear” medium by default: in Chess there’s no pre-defined chronology, and the player may not even use all the pieces. They won’t come close to experiencing all that game has to offer until they’ve played it a great many times. But if Games as a medium are a naturally non-linear, why do “non-linear games” get so much attention from the press?
Well, let us imagine a game almost identical to Chess, which is played at first with only pawns but then, after a few wins, knights are added. Then bishops, and so on. As you can see the experience of playing this new game has a distinct order to it. This is what has happened to our games over the years: they have had linear elements added to them, and as such are no longer truly non-linear.
Why has this happened? Well, there are a few reasons. The first is that beginning with a simple solution space and building upwards helps ease new players into the game. I discussed this technique in a previous post (Freedom, Challenge and Progression). Then we have designers trying to insert linear narratives into their games for whatever reason. One of the biggest reasons though is that deferring access to content is a great way of keeping players hooked: many times I’ve kept playing a game long after it stopped being fun, just so I could get the satisfaction of having completed it. These last two points were discussed in more detail previously (Games, Narrative and “Hostage Content”).
Multi-Linearity: a dangerous dead-end
So this generation of games are mostly linear, and designers want to return them to their non-linear roots, right? Wrong. When a designers says “non-linear” they really mean “multi-linear”, like a choose-your-own-adventure book. All the big “non-linear” titles such as “Heavy Rain” and “Mass Effect 2″ use a finite number of decision nodes to shape the progression of the game. The illusion of freedom may be very convincing, but as explained previous (Decisions and Interactivity) there’s no real future for this way of doing things, because scripting the consequence of ever possible decision means an exponential rise in the amount of content required.
Hang on, “there’s no real future” for games like Heavy Rain? Yes, you heard correctly: it’s a brilliantly executed dead-end: the most dangerous kind of dead-end. What, then, is the alternative?
Games as Exposition
Believe it or not, I think Valve has the right idea. Their games (the singleplayer ones at least) tend to be perfectly linear, and yet the company seems to have realised something that other game developers have yet to grasp: that games are far more effective when it comes to exposition than narrative.
The opening of “Half Life 2″ presents you with a fascist state, complete with enforcers who’ll push you away, beat you, bully you and humiliate you. It may only be 5 minutes at the start of an otherwise text-book FPS, but it shows that you can create a scene and make a powerful statement without so much of the predefined “what will happen where when” that a linear narrative requires.
“Left 4 Dead” takes this a step further, by eliminating scripted dialogue almost completely: we learn everything there is to know about the world and its characters by exploring: by looking and listening. Like a painting the game never force-feeds its audience content, but rather leaves it lying around for curious players to find.
I think this concept needs to be taken further: start thinking of games as painting a picture, only this picture is one the player can interact with and leave their own mark on. Game Designers shouldn’t be thinking about what will happen in their games, but rather what could happen: I predict the future of Game Design will be one of designing AI parameters, not directly scripting decisions and consequences.
So for your own good, don’t look to games like Heavy Rain for inspiration.
I should probably point out that I haven’t played Heavy Rain, though I have read enough to understand how it works. If anyone reading this has played the game, please feel free to share your thoughts, and even if you haven’t – more opions are always useful!