Thoughts on Game Architecture

I’ve made a few games in my time. And made various parts of a few other games for other people. Most of the games that I’ve worked on have been pretty simple, but recently I’ve been working on some more complex ones, both in ActionScript and in Objective-C. And one of the things I’ve been struggling with as things get more involved is how to best architect these things.

After giving it a LOT of thought, one bit of insight I had is that we (meaning those of us who have been brought up in the Flash world) have picked up some really bad habits. Maybe we could label it “MovieClip-itis” or something. Its major symptom is making everything a Movie Clip, or in modern terms, making everything a Sprite. It’s ingrained in us. And I’m just starting to realize how bad it is.

Back in the day, we’d draw some graphics, select them, convert them to a symbol, type Movie Clip, select the symbol, open the Actions Panel, and start typing, “onClipEvent…” and put all the object’s behavior in there. Ugh. I know. Or, we’d double click the symbol, and start writing code on its internal timeline. Not much better.

Then we got AS2 and AS3 and we realized how bad that all was. So what did we start doing? We create a symbol, give it a class name, and then create that class, putting all the object’s behavior in the class: “class SpaceShip extends Sprite…” right?

I know there are some of you out there saying, “Not me. I use Flex Builder (or FDT or whatever), not the Flash IDE.” I use straight up code and embed or load in my graphics.” OK, but I bet you are still doing “class SpaceShip extends Sprite” with all the spaceship behavior in that class. Maybe a few of you aren’t, but I bet a whole lot of you are. It’s my first impulse. Pretty much all of my books give those kind of examples.

So why is it bad? Well, I hate to label stuff like that “good” and “bad”, but in a nutshell, you are mixing game behavior and view. A sprite is a view. All it should really know about is display object stuff – its position, rotation, scale, color, alpha, what graphics it should be displaying, etc. It shouldn’t know about its speed, direction, fuel, ammo, shield, etc. Those should be part of a space ship model object. The model object is updated by the game loop or whatever system you have in place, and the sprite would simply read what it needed to from the model to display itself correctly. Or, depending on your architecture, some other type of controller object would read from the model and update the sprite externally. Theoretically, your whole game could run without a view, with you just watching values change in the debugger. This also makes it easy to re-skin a game, since you’re just changing out dumb views.

Again, I don’t want to pass moral judgements on software practices. I’m sure many a fine game has been written with all kinds of game logic in classes extending sprites and movie clips. But as your games get more complex, doing things this way is open to getting very messy. I could go into details, but you’ve probably already experienced this messiness. God knows I have. For me, it’s not so much about this being “bad” but the automatic, knee jerk reaction of creating view objects with game logic in them is DEFINITELY bad. It’s something I’m trying to break in myself. So thought I’d share it in case you are running into similar things.

This entry was posted in ActionScript, Flash, General, iPhone, Objective C. Bookmark the permalink.

41 Responses to Thoughts on Game Architecture

  1. Eric Smith says:

    I’ve been doing a lot of game architecture research as well, and I know the feeling. Using Box2D for my physics, I was initially surprised that after setting the whole thing up, there was no visual output. Just a bunch of math. However, once I realized that this is how it’s SUPPOSED to be, it started pointing me in the right direction. Separating the model from the view is a bit more blurry in games than applications, and I’m still learning a lot about how it’s supposed to be done.

    If anyone is looking to practice what Keith is talking about, try implementing Box2D. It’ll force you to update your graphics and data separately.

  2. Subb says:

    You should read Game Programming Gems 6, the section about Game Object Component System
    http://www.amazon.com/Game-Programming-Gems-CD-ROM-Development/dp/1584504501

    Good stuff.

  3. will says:

    I couldn’t agree more. Once I got a good understanding of MVC and how it relates to Flash it was very much an eye opener on how ‘bad’ things can be coded in Flash.

    I now try to look at view components purely as an API which is manipulated by the model/controller to get some kind of visual output… that’s it. I am very much a fan of the modular nature of this type of design.

  4. Bjorn Schultheiss says:

    In business applications we’ve been using the Presentation Model Pattern which seems to solve this same issue.

  5. Alan says:

    Would you suggest something like…. (access mutators omited)

    public class Spaceship
    {
    public var art : SpaceshipArt;
    public function attack(enemy:IEnemy) : void{}
    }

    public class Main extends Sprite
    {
    private var spaceship : Spaceship;
    private var enemy : IEnemy;

    public function Main()
    {
    spaceship = new Spaceship();
    addChild(spaceship.art);
    spaceship.attack(enemy);
    }
    }

  6. sascha/hdrs says:

    But still even if you use a MVC like pattern for game objects why not extend view objects from Sprite? Sure, sometimes it’s better (or more lightweight) to extend a Bitmap or even BitmapData but most of the time Sprite provides all the basic stuff that you need for a view object.
    The PixelBlitz engine for example tried the re-invent the wheel by creating it’s own kind of view objects but in the end, and after some speed tests, it turned out that a Sprite would do just as well.

  7. Alan says:

    @sascha/hdrs
    I think Keith is still suggesting that view objects extend Sprite( often they kind of have to ), but rather the logic that controls that object be elsewhere, did you look at my example….

    the key is when he wrote here:

    ‘I bet you are still doing “class SpaceShip extends Sprite” with all the spaceship behavior in that class.’

    The ‘with all the spaceship behavior in that class’ is the part he suggest be put into a controller or model class.

  8. sascha/hdrs says:

    Ok, getting the point now and fully agree. In the end the only thing that could thwart your OOP plans is performance which can be critical in some games.

  9. Totally! But, while it is “bad” for the reasons you stated… it also makes medium to intermediately complex projects way easier to get a mental model on things (I think). One could argue, too, that it makes for easier programming–but I’m not sure that’s as strong as the argument for a good mental model.

  10. Macaca says:

    Seperation of data, logic and view is usefull because then you’re able to only load graphics in memory for objects that are in the current room/level/map, and release the others. Also this makes easier to have compound visuals (single object with multiple sprites on multiple layers).

  11. Martial says:

    Reminds me the architecture of openFrameWorks, which is nice I think. On the main class there’s two methods with constant enterframe : “update()” and “draw()”, espacially made to separate what you said here.
    But I did not see the point in flash, feel like It could be performance killer, but maybe I’m wrong!

  12. Raymond says:

    Box2D is an eye opener , I love the way it does all calculations and make you update the game. If I could implement a whole game like that, swapping the rendering engine/Graphics will be a piece of cake.

  13. 5566 says:

    Most of the time I write classes taking in the Sprite or MovieClip in the constructor. Setting the linkage and extending Sprite/MC makes the 1st frame very big. I know there are ways to work around, but then, it requires extra effort.

  14. sep says:

    I agree, the way i do it is:
    class SpaceShip {
    public function set skin(value:Class) {
    _skin = new getDefinitionByName(value) etc… }
    (space ship logic….)
    }
    I am getting the skin class from a swc, it is only graphic, and if I want a new SpaceShip I create a new instance of the SpaceShip class and pass it a new skin class..
    what do you think of this approach ?

  15. Iain says:

    I really think you’re underestimating your audience Keith – everyone already knows this!

  16. kp says:

    Phillip, yeah, for smaller projects, I agree. It’s also a great way to prototype, I think. But I’ve found over and over when I’ve started out with this kind of model (sprite with logic) that at a certain point things get very messy.

  17. kp says:

    sascha, martial, yeah, performance can be a factor but i think it’s better to start with a good architecture and tune performance later, rather than premature optimizing.

    Iain, no, not “everyone” knows this. I think for people doing business applications or coming from other programming fields, separation of view and logic is more ingrained. But again, I think long time Flashers have picked up some bad habits. I know I have.

  18. Phil Peron says:

    I think this is something that PushButton Engine does quite well. http://pushbuttonengine.com/

    A ship ‘entity’ would have a ‘render’ component that draws the avatar, a ‘spatial’ component that deals with x, y, rotation… and a ‘controller’ component that deals with handling user input and collisions, etc.

    As someone with an application development background, building a game with PBE has been extremely satisfying.

  19. Iain says:

    Hi Keith – no offence meant, I just noticed that nobody was commenting with “Wow, I never realised that!” To rephrase my last comment more constructively: I think there is a big difference between the average Flash programmer (for whom this would be a big revelation), and those who bother to go read blogs about it. I find on my own blog that I get a bigger response when I assume more knowledge on the part of my readers. Remember MVC is a freaking religion for a lot of Flash developers!

  20. Iain says:

    Re. MVC for games, I’m of the opinion that it’s good to break the rules and let each model hold a reference to its view, because often the view includes information you need to perform collision detection – e.g. with getPixel() on a bitmap, hitTest() on a vector, or using the geometry of a 3d object. Otherwise you’re stuck with just rectangle and circle collision detection.

  21. enzuguri says:

    RE:Giving Models reference to the view.
    I recently had a project where we were converting the ‘view’ from 3d to 2d to try different approaches. For collision detection I made an interface ‘ICollidable’ with method ‘collidesWith(object:ICollidable)’and then let 3d and 2d components implement this individually, so sprites were simply hitTestObject, and 3d was a bit more complex.
    This detection is run on update in a Mediator (guess which framework I’m using ;)) which obviously just runs on an array of ICollidable’s it knows nothing of the specific implementation.
    What do you think? is there a case for changing this detection to the model, when you say ‘should run without a view’ in this case I would simply have ‘NullCollider’, so the view would always be present in some form, even if it’s just null/debugging objects.

  22. kp says:

    Iain, no offense taken. I appreciate the dialog. I’m sure this is old hat to many, but I attend user group meetings, and get emails from book readers, and see plenty of other people’s code. And trust me, everyone does not know good architecture! 🙂 Maybe a lot aren’t speaking up saying wow, I didn’t know that. But I’m sure there are more than a few saying, “I do that… what’s wrong with it?” and hopefully it will spark them to look into it a bit more.

    enzuguri. If what you are doing is working for you, I’m not saying you should change it. But if it starts getting messy, separating the view from the logic is a proven strategy for helping to clear things up.

  23. kp says:

    Also, I think this came to light for me more in working with cocos2d for the iPhone. They have a Sprite class which you can extend and add graphics to. And there you are with an empty class, just begging for all kinds of complex logic. I started giving in to its demands and things started getting messy. Now refactoring things so that my sprites are pure views, updating from a model.

  24. Robert says:

    I appreciate this dialog as well. In my opinion, many programmers, not just flashers, have picked up bad habits. It’s part of the learning process. You do something the best way you know how until you know a better way. It takes plenty of experience and a certain amount of humility to realize that there will probably always be a better way, and you need to keep learning.

    At any rate, I’m recently taking on more complex projects as well. I always knew that separating your model and view was important for a number of reasons (scalability, maintainability, etc), but it’s becoming more apparent to me now than ever. I wonder how I got along without it when I was a newbie. I’m now past understanding frameworks into appreciation for them…but I’m sure I still have a way to go.

    Keep the good blog posts coming!

  25. hieronymous says:

    “I could go into details, but you’ve probably already experienced this messiness.”

    Please, do go into details. Those of us who haven’t “experienced this messiness” might not see the disadvantage of combining a a view with behavior. With some concrete evidence, however, we might see this as more than just a philosophical opinion.

  26. ryan miller says:

    checkout the PushButtonEngine, it’s not an engine as much as a framework for making games, and it’s a component system which is all the rage these days in game dev.

    http://www.pushbuttonengine.com

  27. Josh Tynjala says:

    I approached the first few Flash games I built by putting everything into Sprite subclasses. This approach made sense for such simple games. There was no problem navigating my code, and I could get things done faster without proper MVC.

    On the other hand, my next game definitely needs better separation of behavior and visuals. There’s so much going on that some my classes would become a huge mess of event handlers and non-visual logic mixed with drawing code. They’d have a thousand or more lines that are ridiculously difficult to navigate. Since I’m also building a level editor for the game, if only for myself, I’m able to reuse more of the real in-game code now because the view doesn’t have all the gameplay behavior baked in. For this game, MVC is a lifesaver and I absolutely believe it is necessary.

  28. Kevin Newman says:

    I recently did a Tetris game where the entire Tetris “engine” is distinct from the graphics engine (the number representation on the right is a var dump of the field and tetrad mmodels. I then went and over complicated it by adding an event model. 😛 Hey I was experimenting. 🙂 I’ll see if I can’t post some code later, just for fun. 🙂 http://www.unfocus.com/projects/2009/02/19/new-paint-and-tetris/

  29. Erik says:

    Joe Berkovitz has an excellent demonstration of how a simple game can be architected and still benefit from MVC:

    http://joeberkovitz.com/projects/Connect4/beta3/srcview/index.html

    A turn-based game like this is more simple, but these concepts are completely applicable to a game that does require a run loop.

  30. adehaas says:

    I started to dive into the use of Design Patterns, and trying to stick to true object oriented programming principles (I’m being bold here). Therefor having a model class feeding the view with it’s logic is obvious. I learned, that this is in almost every case the way to go, to keep things as flexible as they should be, and it starts already with code for a more or less simple website in my opinion. The difference to what I did before is just amazing (in a very positive way), and I am able to understand whole concepts using these techniques, that I before just used, but didn’t really understand.

  31. mrnah says:

    Been doing midsize flash games for a while, and have been thinking about these issues a bunch… and am curious about the trade offs of using MVC for midsized games. All to say, I very much appreciate the discussion.

    One of the biggest challenges in learning programming is understanding these higher level abstract concepts without making the same mistakes millions of programmers have made before. Talking about the issues / trade offs can help.

  32. joshua says:

    keith-

    thanks for this. perhaps folks like iain were born knowing good code architecture, the rest of us weren’t. i too started coding in flash and as i have branched out have realized the many errors of my ways. not many (i can think of one or two) of my peers ever questioned the movieclip-itis and showed a better way to code. using actual design patterns has almost never been an enforced part of any place i’ve worked. you do have to take the time to educate yourself, but it is also up to folks in the know to spread that knowledge to others.

  33. Drew says:

    This made me think of one of the best emails I got in regard to a physics engine (FOAM) I wrote a couple years ago. “How do I make my MovieClips physics?” Classic.

    I do have one point to make, and that’s that the distinction between view and logic is completely conceptual. The line the developer draws in the sand doesn’t necessarily run neatly down class lines.

  34. Carlos Perea says:

    The Model-View-Controller design pattern was devised with this in mind. It uses a model (logic), a controller (strategy pattern), and the view. The model is completely independent of the other two, the controller in turn updates the model and the view will be an observer listening for any updates in the game logic.
    It is an efficient way to separate logic from the gui, but in some games it is unnecessary to go into these levels of sophistication. Nevertheless, if you are developing a standardized game frame from which to derive all your games then the model-view-controller design pattern is a very sophisticated and expandable approach.

  35. Iain says:

    Sorry to bump an old post, but…

    When you wrote this post I generally agreed with you, apart from that you were stating the obvious, however… I’ve gone the other way on this now. I’ve seen too much over-engineered game code of late by people who don’t really know what they’re doing, (and left with the task of making it work). DisplayObjects (sprite, movieclip) ARE the programming paradigm of Flash. MovieClip IS Flash! If you are using them you are using a way of programming that other Flash developers will understand. Whatever home-brew framework you come up with for organising your view code is going to be unique to you, but MovieClip is understood universally, so you are leaving no technical debt. Besides, it’s not like you have boiler-plate graphics code next to your game logic… all the boiler plate graphics code is handled by the Sprite class – your code just adds some behaviour. If Flash didn’t want you to extend DisplayObject, it wouldn’t let you do it. In the real-world having 2 classes for every game object is going to slow you down and in fact make your code less elegant and harder to follow.

    Obviously on other platforms you have to do things differently, and games that use custom 3d engines or PaperVision etc need to be handled differently… But if it ain’t broke, don’t fix it. Ask yourself why you went 10 years without realising you were doing it wrong: you weren’t 😉

    Iain

  36. kp says:

    Interesting viewpoint. I’ve really been diving into this whole area lately. Trying to sort out the best way of architecting things. It does get very easy to over-engineer. Trying to sort out the actual benefits of keeping the model separate from the view, from the academic, “you’re just supposed to, and that’s that”.

    One really quick example is if you are using a movie clip’s x and y in your physics, it’s always going to be rounded to the nearest twip or .05 pixels. This can give you some nasty side effects in some cases. So you need to keep an internal x and y for accuracy.

  37. Iain says:

    Agreed. You can, for example, have worldX, worldY, and worldZ (or whatever) properties for your game object, which is what you use for movement calculations, and then in your draw() method you just update x and y to match. this way you can even do pseudo 3d transformations etc while still extending movieclip.

    Double agree about the danger of “you’re just supposed to”. People who think like that don’t live in the real world, and are trying to solve problems that aren’t there. In Microsft XNA, and I assume on the iPhone, there is not really any concept of a display object, and you do end up with boilerplate render code in the same file as game logic. that is bad, but again could be solved by creating a display object class and subclassing it. And of course in Unity3D you attach behaviour scripts to objects – ditto Director. In both cases it is best go with the flow and code in the way that the program is designed to handle. For better or worse, in Flash that is extend MovieClip.

  38. kp says:

    We’ll have to have a few talks at FOTB. I’m talking about casual game architecture, and talking about a lot of these issues.

  39. David Komer says:

    Hi Keith, fantastic article!

    I, like you, have gotten into the habit of linking classes from the library. It’s served me beautifully and fits the way I think. It’s simply awesome to be able to click on a visual asset in the library- and immediately have access to most of the code which “runs” it.

    The resulting architecture problems were traditionally resolved by folder layout, class names, variable names, comments, etc. As long as it was organized- I knew exactly what did what, and could knock off Flash games/apps super quick due to the “it’s mostly accessible from the library or a few specific folders” ease-of-use.

    Now I’m swallowing the Adobe kool-aid again, and checking into the approach to do design in Flash Pro while programming in Flash Builder.

    Bottom line- I’m finding this approach *requires* separation of design and logic (makes sense when written out like this- but since both tools can be used for writing in Actionscript, it’s not so obvious in practical use) Nested objects simply break (“no property” errors, etc.) when you try and important a SWC which has precompiled class names and you have those classes in the same project, – or if you completely precompile it, you can’t debug easily, etc..

Leave a Reply