3 Lessons Learned in Noob Collaborative Game Development

I’m currently working on a 2D RPG Game Engine ( think Zelda or FinalFantasyII/IV ) in AS3. At the start of this project, as typical projects with friends go, it seems like a completely easy task. “Hey you know AS3… can you write us a quick game engine for this idea we have?” Sure… I’ve finished a simple little game before, I can totally do that.

Take 1:

From previous (limited) game dev experience I know I’ll need to set up a heirarchy of classes to handle Player Characters, Enemies, Scenes, Buttons, etc. So, thinking things out logically (read: noobishly (?) ) the first thing the team will want to see is going to be a the big-picture, visual framework. I sit down and start hammering out a SceneManager to handle scene changes easily. I’ve created an IZFScene interface to standardize the methods of all of my Scene objects for the SceneManager to manipulate. I’ve got my placeholder backgrounds that I tossed into the Flash Library from photoshop ( or MSPaint ) and I’m off and running creating smooth fade-in/fade-out transitions between scenes. The engine process looks like:

  • Create a new ZFScene Object ( Preloading scene ) and background/objects & add to a layer
  • Fade In Layer
  • On button press, fade out Layer
  • Figure out which Scene to load next ( game Title Scene )
  • Create a new ZFScene Object ( Title scene ) and background/objects & add to layer
  • Fade In Layer…. etc… etc…

Sweet. Something does something on the screen and everyone can begin to see the outline of an actual game. Enter the “Collaborative” aspect of this game. Artist/PencilSorceress sends me a message after seeing what I’ve got uploaded to my dev server, “Hey so I’ve got a title screen ready for you!” And “dev process fail” #1 shows up.

Dropping my art assets into the Library means that either:

a) Artists, Designers, and all other project members:

  • will need a copy of Flash to make changes
  • will need to know how to use Flash to make changes
  • will need to know not to touch my precious code if they want to live
  • will need to know how to use subversion or some form of version control

b) I’m going to become everyones bitch, stopping my coding process every time a new piece of artwork is ready, or a new character needs to be added, or new content is ready… etc.

So, to get rid of those obstacles, I need to develop the project in such a way so that Non-Flash people don’t need Flash knowledge and Artists can simply upload assets to a specific directory on an ftp site and the game will dynamically load these assets on each browser refresh.

Take 2:

I created an AssetLoader class that will handle loading various asset types ( images, xml, sound files, etc ) and then re-tooled my SceneManager to use this class. It was an insanely tedious process that, if I had built the engine from the start, would’ve made things easier.

The other benefit that I add into this AssetLoader class is that once assets for a scene finish loading, I can begin loading the assets for the next scene. To me, this seems like a genius move that will save some time and make things better. I created an array to hold the names of the scenes that needed to be loaded and in which order so I could step through them and know what needed to be loaded next.

Also, using ObjectOriented Principles, I subclassed my ZFScene class to create separate classes for each “scene type.” So there is now a PreloadScene, TitleScene, IntroScene, PlayScene, and BattleScene. Each scene shares the same interface ( IZFScene ) so I can call them all but using the same methods, yet each can handle UI/button creation and events, sounds, etc all internally

Now my engine flow looks like this:

  • SceneManager creates a new PreloadScene object
    • AssetLoader gets a list of assets needed and loads them
    • onComplete, add to Layer and fade in, begin loading next scene
  • SceneManager creates a new TitleScene object
    • AssetLoader begins loading TitleScene assets and waits until PreloadScene has told us it’s time for the next scene
  • etc…

Up until this point, I feel like I’m doing things in a fairly efficient manner. I’m using OOP, interfaces, managers to handle specific objects, I’m a pretty smart guy.

Lesson I’ve Learned So Far #1:
While coding something new ( a whole game engine ) and with little experience in projects of massive scope, the moment you think you’re coding things in an efficient and intelligent manner, go ahead and prepare your ego because, soon, it’s about to be completely destroyed. And this is how you gain experience and level up in real life.

I loaded through all of the scenes in order up until the game PlayScene. Up until now I’ve had a linear path of scenes to load. Preload->Title->Intro->Play. In-game, if you recall Zelda ( or Hero Arms ) the player can now go in 4 screen directions. Which one do you begin loading in advance? Do you pre-load 4 surrounding scenes on every scene change? That seems to defeat the purpose of preloading and now you’re doing at least 3x the amount of unnecessary, wasted loading, which wastes time. Frustrated and slightly demoralized, you have to go back and do what you did to get you this far.

Having an internet connetion puts you in almost instantaneous access to the largest collection of knowledge and experience ever seen before in the history of man. Thousands of games have been created before me, hundreds of which were RPGS, which means that hundreds of programmers had pulled millions of hairs out long before I loaded up Flash. I spent days digging through resources and sites like GameDev.net, Gamasutra.com, and AIGameDev.com. I also went out and bought a book I should’ve had on my desk long ago, Head First Design Patterns.

I read chapter after chapter of Design Patterns, and each new pattern spawned pages and pages of notes on where I could use each new pattern, where it made sense to use it, how I could restructure my game and my data to accomodate each pattern, etc. Head First Design Patterns became my new bible. Everything could be encapsulated into a pattern and every aspect of my code could be revolutionized by said knowledge. Luckily, I spent some more time googling game design and game development, until I came across this blog post, The Seven Stages of the Programmer, by Mick West. This stage in particular caught my eye, simultaneously making me groan ( italics added by me ):

 

Stage 5 – Methodological

After perhaps years of delusion, some tragedy will befall our programmer. Perhaps he will get a job, and the skills he thought wondrous will prove to be of little worth. Or perhaps some personal project, such as a game engine, will be transformed by much sweat into a blob of worthless code, undeniably incorrect despite his seemingly god-like powers. Faced with this reality, one of three things happens: the programmer may give up in despair, they may lapse back into delusion, or finally they will discover “methodology”, and avidly begin to read books on this, and begin to “program” in UML. This stage is perilous, as the methodological world is similar to the mythological world, replete with Sirens, succubi, heroes and monsters.

 

That’s me. I’m there. Someone writing a blog post years ago just reached into the future and called me out. And I am so thankful that he did. I would’ve re-coded my engine and spent countless days mapping things out, writing everything out, patterns, structures, concepts, ideas, and all of it, while probably beneficial to have it written and thought out, would’ve probably led to more frustration and demoralization than would have been helpful.

 

Lesson I’ve Learned So Far #2:
Design Patterns will not save you. But the concepts and theory gained while learning design patterns will allow you to approach your code from a completely fresh and more efficient manner.

So now what? Jumping in fails. Endlessly planning and structuring and designing will probably just lead to me becoming overwhelmed and giving up. How should I approach this engine development in a more intelligent manner?

I never came across an article nor a blog about how to develop a full game engine; about the mindset and the approach to undertaking this task to succeed. But what I did come across in the countless post-mortems and game development articles found on Gamasutra & Gamedev.net was that almost every developer or designer mentioned an almost universal template that they all roughly seemed to follow across all game genres. The phrases appeared over and over again, “our first task was to make something playable” , “we wanted to begin playtesting mechanics as soon as possible” , “first we needed to get a guy to move around and hack stuff”.

Making a game playable to test game mechanics doesn’t mean loading screens and navigating menus and save game data. What I took from all of the post-mortems and all of the blogs and all of the articles I read has shaped the way I’m approaching this engine now. I’m sure it has a name, maybe this is common knowledge and I just haven’t googled enough to find it. But the concept of creating small, single-task-specific “test” SWFs… for instance, a small MapTest swf to show the different zones, and which screen links to which screen, like this Changing Rooms article by MadSci.

With each class, or similar family of classes ( a Character and descendent PlayerCharacter, EnemyCharacter, AllyCharacter family ) I’ve been setting up test/driver SWFs to specifically test, use and alter only those files. This makes it easy for me to see a number of things. Chief amongst these things for me is Progress.

Making a class useful via a practical visible example from the start has seemed to help manage that overwhelmed feeling I was experiencing before. It also gives me a library of small proof-of-concept type files to show off and say “yes the InitiativeQueue class for the Battle scenes I’m using works, here’s the example” instead of having one large battle scene swf that you may or may not see the specific results or effects of each of the individual classes that make up the battle code. “Yes the random damage result found between damageMin and damageMax for each weapon works… here’s a file showing changing weapons/min/max and the resulting values it generates.” It makes sense. The old adage “Divide and Conquer” definitely makes things manageable. And for me, a project that is manageable is a project that is finishable.

Second, by developing this engine in a specifcally modular way, making test/driver swfs for each set of code, is that once I’ve started putting the pieces together into a cohesive engine, I won’t have to play through the game for an hour just to get to that one Boss Battle to test my Boss code classes.

Third, if you checked out that Changing Rooms article link, creating something like that to test a dungeon or cave, you now have the beginnings of an immdiately testable Tool! Instead of showing which Room Number you’re in, what if it was an Input Box for a Room Name and below were boxes to enter the number and type of enemies found in this room? Export these entries out to an XML file and you’ve now got a basic Dungeon XML File Creator that you could easily read in somewhere else and parse the values into sprites and AI… anything!

Lesson I’ve Learned So Far #3:
Dividing my project into small, specific task testable goals and files has made me more productive, kept me more motivated, and allowed me to “feel more comfortable” with the stability of the code I am writing.

While it might take a little extra time to set up a Test SWF file, being able to modularly test each class or family of classes, there’s just a solid and stable feeling that comes along with that. I dont know about you, but I know for me, unless I can test each function and piece of code to make sure it’s doing exactly what I want, I just never feel confident in the whole project. But by testing each class, I can feel more confident in the robustness of my code when I add them together into a whole cohesive application.

 

FacebookTwitterGoogle+Share

Leave a Comment

Your email address will not be published.

1 Trackback

  1. Zombie Flambe » Blog Archive » AS3 External XML Animation Scripting with TweenMax, Part 1: Why (Pingback)