Sunday, July 16, 2006

Reusable Code

I think we should all be quicker to criticise our own code.
I've been working on a lot of core code recently, lots of helper functions and multi-project libraries, during which I have aquired a stronger nose for reuse than I previously had, I can smell possible hinderances to modularity a mile off, and can also spot a flourishng bud of future usability currently hidden beneath a swamp of tight coupling.
I know why I've gained this talent: necessity. I work in a relatively small gdev company, and with our current influx of contracts, it's become imperative that we reuse a lot of the code between projects. Normally, we'd tech design a game quite thoroughly and only then start the coding from a baseline of the helper functions already provided by our inhouse engine. Recently, we copied a project, and bent it to match new design requirements and art content. No thought went into the design, we just copied it. That felt wrong.

These games we are working on are all multi-platform, so all in all, I'm currently in charge of 8 different publishable products (on 3 different platforms, with 4 different gameplay codebases), an editor, 2 research and development projects, and all the people (not just the coders) who are working on them. Ok, so I currently command the largest team in our office. It makes sense that we have, overall, the most work to do, but sometimes it feels like there is just too much to do. As a saviour to my own sanity, in stepped my pragmatic gland and I went code weaving (my term for very high level refactoring). We've suddenly increased from each game including one library (the engine), to an average of three libraries (standard helpers, and another semi-specific library on top of the existing engine). We have moved from source safe (ugh) to subversion for our content and source control (which makes my life easier, as I can stop what i'm doing and help out easier due to the amazing branching capabilities). We started ripping up the games we had running, breaking them into component pieces, rebuilding the pieces as reusable libraries, and reinjecting them back into the games. This approach has given us the ability to drop in whole wodges of tested game code (one sony approved TRC compliant module of code is worth ten in the presub) and not worry about backlashes and being dragged kicking and screaming back to months old code that has just shown up a bug that you can't remember how you fixed it for product "3c"... but its imperative that it is fixed for "5b"

So, looking back on how we originally approached this recent spate of tasks, I'd say we were hasty in getting the first one done - which might have been why it took so long to do ;)
We should have built up libraries of reusable code (like the ones we are building now from the remnants of the first two games), and the bugs would have been easier to clear out as they would not have happened twice (bugs fixes from the first game accidentally did not get applied to the second).
So, with my new eye for modularity, reusability, and possibility, I see less and less work for us code guys on the horizon, and more and more work for our artists and designers, which to me means we're finally doing something right. Shouldn't we all be writing tools, algorithms, and architectural code?
We should not, at this stage, still be developing options menus, memory card handling routines, controller handlers and state machines. We should be developing tools for our designers and artists so that have more autonomy.

We optimised our build times from 5 minutes down to 30 seconds recently (a combination of pch and #include "*.cpp" module compile files), so why are we not optimising the turn around for our artists and designers? They need quick feedback too.

Saturday, March 18, 2006

Geko On Rails

Ruby on rails looks like its all framework, macros, and default variables to me. I don't say that in a derogatory manner, oh no. I love the idea of "Web site: just add choices in the right palce". I love it so much that I want to do the same for the games we write.

I see in the near future a complete game created from existing artwork in under a month of real programming, more and more components added will shorten this until the only real programming left will be optimisation and research code.

The future's bright, the futures almost like Ruby.

Game Logic II

Right, mulled over for some time now, just had generally positive feedback from workmates. Yeah the system is okay, probably quite slow in practice compared to hard coded solutions, but it is rather extendable, so may get the vote anyway. I want to submit this to game gems or something in the future, so some comments would be cool. (Game Gems 6 is out very soon, so i guess it'll be at least Game Gems 7 till i get "on paper" ;) )
  • Minimal entities
  • Behaviours as Tags/labels
  • Behaviour containers
  • Messages
  • Conversations
The entities in this logic system are simply an ID (which can be the pointer to the entity if you want), plus the TagList item. This makes "thousands of entities" sound nice and cheap, but the data has got to be stored somewhere, and this is where the behaviours come in. Behaviours are like public inherited base classes, they add functionality, get themselves contructed and destroyed when the entity is constructed and destroyed, but they also handle messages, and just as importantly, they store their data in BehaviourContainers. To get access to the correct behaviour container, you can access the BehaviourContainerRegistry. Seeing as the behaviour containers are registered, they can be linked in as seperate modules, or even loaded at run time through dll's or even scripts such as Lua.
Behaviour containers contain a message handler which takes all the standard arguments, plus the ID of the entity that this behaviour is acting for. If the behaviour requires per entity unique data, the behaviour container will also have a pool of entity states. For memory's sake, only entities that have differences from their creation prototype get their behaviour state instanced.
Obviously, there is also the immediate speed benefit of using pools of entity states too, but that may be counterbalanced by the inherent slowdown of such a dynamic system.
Some behaviours have prerequisites of other behaviours, such as "IsCollidable" requires "HasWorldPresence".

All entities get around their game world via messages, and all messages can be simple, but for complex message sequences, it might be better to "strike up a conversation", when i mentioned this to someone they said that ratchet and clank(tm) used this system, so even though i think i thought of it alone, i can't claim "new idea". The system is straightforward enough, you create a reference counted conversation object, you send it along with your message, elements get filled in, and you get messaged back with "done filling it in" messages which allows you to carry on with the rest of the complex sequence you started.

For the system to be fully dynamic, the tags (after the compiled in ones) are stored in the tag manager, and you can forward and reverse search the tags (tag->string->tag).

So, you have a behaviour container registry that lets you get the correct behaviour container by tag (which you can get by name from the tag manager, or from the entity you are talking about just by getting one of the tags in the member taglist), and the functionality of that behaviour is either uniform across all entities that have that tag, or is unique per entity by getting the behaviour struct contained in the behaviour container. Scripted logical tick functions can be written easily by having the Tick tag call a script once a tick, or alternatively call a standard format tick function in C++.

Why democracy doesn't work

As a lead games programmer, I have to deal with gross ineptitude on a daily basis, and even when I'm not talking to games artists I still have to deal with boss like external entities, and de-clued decision makers.

This is what got me thinking about democracy. I beleive that those who are in the know need to be the ones empowered to make decisions for us. How many times has someone that has been out of the loop so long that they just plain forgot what was important, or worse, was never in the loop, and has read about "The Important Stuff" in a memo, how many times have they been key decision makers? Far too many times in my opinion.

UK MPs are elected to speak up for their community. Our vote goes to chosing someone that has a better clue than us at how to run the country, and hopefully also has an opinion resembling our own. My fear is that modern democracy is not about "who is right for the job", but more about "who looks like they are in charge". This is not really going to help our country.

So, even though i do not personally like what Mr Blair has done with the country overall, I beleive in him or whoever leads the party that i choose to support. I do this because whoever is in charge, was chosen from a selection of people that themselves were chosen by the populous to make their decisions. We empower them, let them get on with it.

Sunday, January 22, 2006

Game Logic

I've been thinking about making a game engine more data driven for some time now, and only recently (while working on this ten weeks of hell project) have i come up with a solcution that i think will truly work.

The idea is simpler than i ever thought it could be. I'll keep on it for a while before i announce anything, just cos i need to run it through the sanity filter known as my workmates.

The development process

I've worked on many developments, long, short, conversion, diversion, pet, work, community. One project stands out from all of them, and its only really just started.

I've always been one for diving in, getting things done, but with plan of action. I'd spend quite a bit of time figuring out how long things take to do, then add them up and report back to whoever wanted to know. Most of the time it fell on deaf ears, when it didn't they weren't pleased with the reports (probably because they sounded so pessimistic). Even when we did get any kind of go ahead, all we did was lookat the schedule and attempt each milsetone in turn, going from definition to final code in one difficult step.

Because this latest project is extremely short original title (10 weeks from start to SONY submission), but reasonably well funded (we can afford four full time coders plus a PS2 graphics programmer for 4 weeks), it made us all panic a bit. Okay, so obviously this isn't the next GTA, but it has to be completed to the point where SONY will accept it, and that means that its gotta be bugless, behave completely as expected, and be reasonably good within the limitations of the timeframe.

So, for the first time ever, we designed the game technically. Now, when a lot of people hear that they might assume that we'd never done a technical design doc before, they'd be wrong. A technical design document for us though had always been a document about what we were going to do, and what technology we were going to use to do it. This has been the kind of document requested from Sony for some time now, and its the limit of what we had previously produced. This time, we didn't stop. We went deeper with the game logic, peeled away when and where the data was used, how the in game entities interract, right down to the actual pseudo code for an entities' reaction to a collision from a player. We then stepped out and had a look around at the code, added more work on the initialisation of levels, and just kept adding.

The design doc is by far the largest one to date, it is the same size as a design doc written for a project of about 5 times the budget, and is still growing. During the work, we found at least 3 bugs, 2 integration issues, figured out that we'd need to ask about 5 different big questions of the publisher, fixed 1 stupid coder error (an optimisation that would not have been optimal), and even figured in the designers considerations for tweakability and ease of level creation without him having finished the game play design document.

So, what do i think of the design first, code later aproach? Unbeatable. And we haven't even dropped a line of code yet.

Followup in roughly ten weeks :D

Tuesday, January 17, 2006

Managing projects that never end

I'm not talking about ongoing projects that have multiple versions (e.g. Photoshop, Windows, GCC), I'm talking about projects that have terribly underfunded development. The projects that i am talking about are the pet projects that are too big, and in house projects that are unsigned by publishers so they only get a few man months per year. You know the thing, a project that would have normally take a reasonable amount of time, but due to unforseen (or possibly forseen but ignored) circumstances, has to be put on hold "for a while". This kind of project can dishearten people more than any other, as code begins to rot before the project has finished, or other people bring out new software that is very similar to what you were going to do, or worse, you lose heart, leave the project so long that you forget all the good ideas you had when you first started the project.
So, how do you stop these long projects from crumbling under the weight of time? How can you set a process by which the project can be dropped and continued? What is the essence of a pausable project?
I've worked on quite a few never ending projects, and of them all, only two have been pausable. Both of these projects are connected to each other, which in some sense makes the number of projects just one, but i think of them as two projects, as one is dependent on the other, but not the other way around.

The differences:
The differences between the pausable pair and all other projects I've worked on seems to boil down to coding style. Not coding style from the point of view of braces and how to name your functions, but more of a "don't hack" attitude. This is an important thing, especially in a project that does not have a design document (another victim of the never ending project's underfunding). I've found that in the pausable projects, there is a distinct truth to most things, there are no lies in function names, classes do what they sound like they do, they all have similar construction, and all have similar style of implementation. There is consistency of implementation, even if there is a shift in thought. There is also a bold line struck between modules of code reducing the coupling to the minimum. This means that the code is easier to search, easier to modify, maintain, and remove if it was never necessary.

So, is the pausable project a better project in general?
Probably not. You pay the price in performance when you make your code extra readable and easily maintainable. You also pay the price in terms of time to develop, as without a thorough design, you may code many more modules than necessary. So, even though the project could be restarted at any point, is easier to maintain, can be reused and can be used to teach good style, the actual code takes more man months to develop, is slower in terms of frame rate or other performance metric, and is probably more bloaty than necessary.

So, if its not better, why do it this way?
Well, not all projects have the benefit of a straight line in development. Not all projects get done at all, and sometimes its better to work on reusable code, just so you can reuse the code on the next endless project. Some projects don't need the performance of a fully designed and tuned project, but do need the maintenance and modifiability of a pausable project (think about converters and editors).

its up to you to decide if your project needs to be pausable, but if it does, keep the following in mind:
  • The maintenance programmer is you, and you will remember none of your tricks until its too late, so document them or don't use them at all. Never do anything unexpected, no hacks, no odd code.
  • Be strict in style, if you change style, then you lose flow. Stick to the style you started with, or change the style of the entire project so it's still consistent.
  • When you make additions and deletions, show your reasoning in comments, otherwise you will forget why you did it, and might change something in error. Also keep the old code (commented out?) so you can see what you deleted and possibly reintroduce it if it was an error to delete it in the first place.

Saturday, January 14, 2006

If you can't who will, and why should they?

In the context of the previous post:

The truth is, for the most part, no-one will do anything unless there is something in it for them. In the business world there's always a cost associated with everything, no matter how small. Because everything has a cost, no-one will do anything unless there's some form of profit. If you have paid upfront, then great, but most people don't work that way in the business place. The only people who will do without being paid upfront, are those that either think that you're worth listening to, or those who have nothing better to do. I've come across some different people while working in the games industry, here's my take on some.

The inferior subordinate: not meant to be insulting in any way, I just refer to the fact that the subordinate in this case believes that you (currently) have a better idea of what you're doing than they do. To get this type of person working on the right thing, you can literally tell them to. They'll go and do it, probably get a bit stuck somewhere, probably make a few mistakes, but that's part of the learning associated with this job. If, on the other hand, you take them in hand, tell them what you want done, tell them why, give them a gist of how to do it, and then come back to them every so often (but not so often that you are interrupting them), you will save them from making mistakes, and at the same time the mentor-student bond builds (great thing for both parties in my opinion). So if you are nice about it, and you really do mentor your subordinates, you not only get better work, but you build a mutually beneficial bond, and your subordinates also learn faster, and therefore become more productive at a greater pace than the subordinate that was "told to do it".

The superior subordinate: this is a particularly difficult situation to fix. The problem is that even though you are in a position of power, you are not normally in a position of respect. This is normally a mentor-student relationship that went bad, and can normally only be fixed by putting the subordinate under a completely different lead. The new lead needs to be careful to not repeat the same mistakes the previous, but this isn't always possible. The best way to re-train the subordinate is to give them a clean slate, and assume good things until proven otherwise.
You can usually expect good things of these people, but you have to be on your toes in case things get out of step.

The inferior boss: this is actually quite a good relationship, as long as you aren't intent on making it obvious that you know more about XYZ than your boss. Sometimes it's a fine line, but most of the time private messages, or just a glance at the right time, can get enough of a message across that you have a differing opinion, and that can lead to the conversation about whatever it was. Although this situation doesn't arrive often, it can lead to a deeper friendship than even the mentor-student friendship, as you generally perceive each other as equals.

The superior boss: This is one of the worst relationships in the world. When your boss thinks that your opinion counts for nothing, or when your boss doesn't give you anything to do because they don't think they've got anything easy enough for you to do, that's when you just can't get anything done. You haven't got any respect, so you can't change anything, and you aren't trusted, so you will get blamed when the workload is killing your boss, because you did so little. It's a hateful situation, get out of it as quick as possible. I can't tell you how, it's never easy.

So, in my opinion, appear to be an inferior boss, and an inferior subordinate, and you'll probably get the most out of everyone you meet. I can't do it myself (I'm too bolshy) and it's caused me grief. 've mellowed with age; I think I'm more humble now, and that's a trait I consider to be an absolutely necessary in a coder.