Wednesday, April 06, 2011

Code ownership

When working in object oriented games, a developer often has to think about what object owns some data, this is because we tend to write code that implements data as being managed by objects, handled by them, processed by them, and contained by them. Sometimes it can seem pretty obvious what should own the data, such as when you realise that you need a new member in all your entities to say whether or not it is active. The obvious answer is that the entity owns that data. It's wrong, but we'll get back to that later. Other times it can be a difficult question to answer, like where to store the pathing information for an ad-hoc group of AIs, should they determine a leader and store the pathing in the leader? Should their be a pathing manager that they can all subscribe to? Should it be part of the road / map manager seeing as the A* is running on that data more than anything else?

This is one of those things that keeps coming back to bite us when we try to solve real world problems following real world patterns in a computer simulation written in a computer language. The dysfunction there is that we're trying to solve a real world problem when in fact we should never submit that we're solving a real world problem at all. We're solving the wrong problem. We should never try to solve a real world problem in code. That's usually impossible.

What we do is simulate. We should first appreciate that no matter how much our codebase contains nice identifiers like Ally, or emotive words like Aggressive, or real world nouns like Car, or state adjectives like Dead, what we're actually doing, always, is processing data.

The idea of code owning data seems to have survived in spite of many reasons to not trust it. I've seen rooms owning their portals, even though they obviously share the portal with another room. I've seen player structures own their position data, even if there is not a world for that position to exist in (think about the last time you moved a player to a safehouse somewhere just so they wouldn't be rendered in a cutscene.) I've seen players own their guns (so they become tiresome to drop), and because of limitations, bullets are owned by the world (and then become tiresome to fire from the gun)

Code doesn't need to own data; it needs to process it into more data.

So, going back, your entity needs a new state for when it's active. Who owns this state data? No-one owns it. Ownership is for people or corporations. You can simulate ownership in your game, but code cannot own data. Got it yet? No? Object oriented approaches might pretend that this is possible, but it's not. Data is just data. You can lock yourself away from being able to transform it in simple and direct ways by hiding the data, but no code can actually own the data. Instead of focusing on who owns the data, focus on what needs it and how it's used to make the game run. In this case, rather than adding a new bool to a possibly overcrowded and messy class, don't add it at all. Add accessors for your crackpot brethren who think it should be inside the class, but instead of accessing a member variable, redirect to existence in a set.

That's right: the active state may as well be a list of entities that are active. If you want to only do something if an entity is active, by moving to a list of active entities you no longer have to check to see if the entity is active before doing that thing. Instead, you just commit that transform for all the entities in the list.

Pathing, equally as silly. No, pathing data does not belong to anyone. It is requested by whatever event caused the AIs to start pathing, it is used by the AIs, and it goes away once the path is no longer required (probably cleared up by the terminate of the state the AIs are currently in).

Initially there is a transform to generate the path that converts the world data, the AI position and ergonomics and goal position into a set of pathing instructions (waypoints for example, easy to follow breadcrumbs), then there is the next transform that converts the current AI and the pathing information into an entry on the IsFollowingPath list. Entries might take the form of a pair of pair AIPathFollowing andAIEntity. Then there is a per tick transform that transforms the AIEntity.Movement and AIPathFollowingelements based on timestep and current value for AIEntity.Position. Sometimes this transform would notify that the AIPathFollowing element needs to be deleted, and the pair should be removed from the IsFollowingPath list. Finally, there could be a per tick check to see if the IsFollowingPath list reaches zero, at which point, the path is deleted.

Data is just a source or a destination, not something to be owned. Code can transform data from source to destination, but should not be considered as owning data. Let's stop turning computer problems into a computer language descriptions of a real world problems. Let's admit that we're programming computers, not reality.

If you love it.

If you love it or like it, you have chosen it.
If you've chosen it, you've preferred it to something else.
If you do it, or have done it, you have not done something else in turn.

If you don't do something or haven't done something, you've chosen not to do it.
If you've chosen not to do something, you've preferred something else to it.
If you've preferred something else, then no matter how much you say you like it, or want to do it, you don't.

I would like to say that I love making computer games, and to some extent that is true. I think that most games developers, even if it's not true, at least want to say that they love making computer games. But, the people that actually love making computer games just make them. I do a day job that let's me do something that I enjoy, that is, write code that makes computer games go. I am part of a development team that makes games. I am a games developer, but do I love making computer games?

Going by the statements at the top, I would have said that a few years ago I wouldn't count as someone that loves to make games. Then, late in 2009 I started making games again, not for sale, not for work, just because. I used it as a means to the end of learning about STL and C#. To this end I would say that I was making a game because I wanted something other than a game at the end of it. So, even at this time I wouldn't quite say I loved to make games.

Things changed when I moved to my latest games company, mostly because my family was put in an extremely stressful situation; I am working in London, while my family is living 250 miles away in Wales. I stopped making the game for the sake of learning and instead started writing a non-fiction book on programming. So it turns out that at the time I was more interested in games programming than I was in making games.

But, after a few months of doing the weekend run to Wales, only spending a little time with my kids, I decided I'd try to do something creative with them. The obvious choice for me was to start up a kid safe Dungeons and Dragons campaign. I diluted the rules, made them overpowered, then sent them on mostly story driven hack-em-up missions. This worked out really well, and eventually it reminded me of why I wanted to make games in the first place. I wanted to DM to a much larger audience. I wanted to make games so I could DM without the hassle of the dice and paper. I never really loved making games, I loved games programming and loved seeing people play games.

So, I started making games again, first a 2D minecraft game (using python and pygame) which grew and grew until it stood up as a game that my wife would play for hours, making castles and other pretty things (as people are known to do in pure sandbox games). I then realised that I was already not sure where to go with this game, as it was starting to feel like work, so dropped it and began working on a isometric version of the minecraft game. My kids enjoyed it, but it was severely limited as I couldn't think of a simple and robust way of adding digging without causing all sorts of horrible rendering bugs, so it became boring to do again. So, that's when I decided to to move on again and wrote a very simple platformer. All this time, the kids have been playing the games and telling me about ideas of what to do next or given me level designs to put into the games.

And that is what I started making games for. The feedback from my audience (my family) has so far been the most rewarding experience I've ever had in my 11 years of making games. I don't love making games.

I love people experiencing what I've created, and I create games.

Now think. What do you love?