Accurately Reproducing Game Audio in the Playback Environment

Original Author: David Thall 

Sound Designers are faced with a difficult proposition. Add sound effects, music and dialogue to a game, set rules that determine how those sounds are panned, attenuated and processed in real-time (both individually and with respect to one another), and then hope that the player will hear the resulting ‘mix’ over a system capable of reproducing the spatial accuracy, dynamic range and frequency response of the original content. It’s a difficult proposition… at best!

During my time on the engine team at Insomniac, I spent a considerable amount of time and effort trying to ‘fix’ the mix. Building an advanced ducking system, improving distance attenuation and panning curves, expanding dynamic range and listener focus using an ‘HDR Audio’ algorithm, introducing near-field rendering techniques to improve presence and envelopment, improving the reverberation and occlusion algorithms to enhance the perception of indirect sound in geometric spaces, and creating a live mixing system to allow sound designers to move continuously between mixer snap-shots based on gameplay context. All of these tools added to the sound designer’s palette, giving them the ability to make the choices they needed to make in order to bring the sound ‘experience’ to the player.

But something critical was still missing…

Sound source post-processing in the game world relies on an accurate mapping to the real-world ‘listening’ space. And simply put… this doesn’t exist for audio in games (at least, not without rendering a binaural mix to headphones). Whereas image content can be mapped to a television screen (with very little loss in the world-space-to-screen-space translation), audio content is ultimately being piped through a set of misplaced, misdirected low-quality loudspeakers.

So, we need some way to guarantee at least some amount of consistency between 2D and 3D sound localization in the game world and 2D and 3D sound rendering in the playback environment, both for sound designers and for players.

We can do this by introducing a loudspeaker analysis and pre-processing step, prior to audio engine initialization, mixing and playback. The idea here is to capture the number, location and radiation pattern of loudspeakers in 3D space (azimuth, elevation, distance and orientation), as well as the dynamic range, frequency/phase/magnitude response, and impulse response of the loudspeakers in the playback environment. Given these parameters (which could be captured in real-time prior to initializing the audio engine, or stored in a user profile and reloaded on-demand), the audio engine can then be fed the appropriate information it needs to properly ‘correct’ (‘skew’) source rendering parameters before mixing the results to the destination loudspeakers.

Without these parameters, the audio engine is forced to render to an abstract, idealized set of perfectly positioned, perfectly responding loudspeakers. Any variation in the real (physical) layout from the idealized layout is unaccounted for. Unfortunately, this is how game audio engine engines work today. This leaves much to be desired, both for the player and the sound designer.

The simplest solution we’ve implemented is to fill out a user-generated profile with the loudspeaker positions, orientations and response patterns provided by a television manufacturer. Our more advanced solution synthesizes an all-pass autocorrelation sequence (a probe signal), plays the probe signal through each loudspeaker in series, and extracts the 3D location and response of each loudspeaker by de-convolving the probe with the room response captured by a microphone. The resulting analysis data includes AOA (angle of incidence) per loudspeaker (translated to azimuth and elevation angles), relative distance (with respect to the other loudspeakers), frequency/phase/magnitude response, impulse response and polarity. Furthermore, we can determine which loudspeakers are full-range, and which loudspeakers are low-frequency emitters (aka subwoofers).

The azimuth angles are used to initialize the panning algorithm in the audio engine. This means that misplaced loudspeakers are actually accounted for when panning to the output. For example, let’s say the front-right loudspeaker is placed +40 degrees to the right. In the idealized layout, the front-right loudspeaker is assumed to be located +30 degrees to the right (a 10 degree difference in physical layout). If the panning algorithm uses the idealized layout, and a sound source is panned to a position that translates to +30 degrees to the right, then the sound will emanate from the single loudspeaker, which is placed at +40 degrees to the right. This is incorrect. If, however, the panning algorithm uses the real (physical) layout, then the sound source will properly sit at +30 degrees, panned 3/4 of the way to the right-front loudspeaker. While a 10 degree difference in position may not seem so significant, the case becomes more apparent when a sound source smoothly pans across the plane in the direction of the loudspeaker. In this case, panning without speaker correction will result in doppler shift for a constant-velocity pan, and a skewed mix of the entire sound scene in the direction of the misplaced loudspeaker. Add to this the misplacement of multiple loudspeakers in a surround setup and you get a completely skewed mix.  Sadly, the idealized layout is the current state-of-the-art in game audio rendering.

The elevation angles are used to correct for loudspeakers which may be placed at unequal heights with respect to the rest of the layout. For example, if the player has a center loudspeaker that is lower or higher in elevation than the left-front and right-front loudspeakers (e.g., the loudspeaker is on the bottom of the television set), the correction system will perform height virtualization to elevate the center loudspeaker signal back to the idealized position. Failing to do this would result in skewed panning. For example, a sound which should pan on the azimuth plane from front-left to front-right would incorrectly elevate toward the center channel (either up or down with respect to the azimuth plane), independent of it’s physical position. With correction, a sound source panned to 0 degrees front-center would seem to emanate from that exact location in space… un-elevated.

The relative speaker distances are used to apply a fixed delay to the output of each loudspeaker channel. These subtle delays correct for asymmetries in speaker distance. In essence, these delays place loudspeakers onto the idealized unit sphere, where each channel is equidistant from the listener.

A related correction is for speaker orientation. Inconsistencies in the rotation of loudspeakers (e.g., speakers placed facing downward in a television enclosure) are corrected so as to conform to a directional, listener-centric phase response.

Relative loudspeaker gains are corrected using simple equalization per output channel. For example, if the front-left and front-right loudspeakers are bigger and louder than the center loudspeaker, then sounds placed in the center channel (e.g., dialogue) will be modified with equal-power gain compensation. These coefficients are also used by the panning algorithm.  So if a sound pans through the quieter, smaller center loudspeaker, the adjacent loudspeakers will help contribute more focused gain to the sound as it moves across the plane.

The frequency response of each loudspeaker can also be corrected with respect to the room response. If, for example, a loudspeaker rings at a certain set of frequencies due to undesirable room modes, we can ‘whiten’ those sub-bands of the response to more closely match the loudspeaker to its natural response in an anechoic chamber (an echo-free room). Note that we’re not attempting the push a loudspeaker beyond it’s natural response; rather, we’re enabling the loudspeaker to output its natural response pattern, given an ideal set of room conditions.

Together, the loudspeaker analyzer and suite of correction routines combine to create a system that ensures accurate audio reproduction in the playback environment, both for sound designers and players. Integrating such a system into a game engine dramatically improves the accuracy of the sound designer’s intent.

The Simulation Dream

Original Author: Tynan Sylvester

There’s an old dream in game design. It drives the design of games like SimCityDwarf Fortress, Tropico, The Sims, and Prison Architect. I like to call it the Simulation Dream.

In 1996, Starr Long, the associate producer of Ultima Online, talked about the game before release:

“Nearly everything in the world, from grass to goblins, has a purpose, and not just as cannon fodder either. The ‘virtual ecology’ affects nearly every aspect of the game world, from the very small to the very large. If the rabbit population suddenly drops (because some gung-ho adventurer was trying out his new mace) then wolves may have to find different food sources (e.g., deer). When the deer population drops as a result, the local dragon, unable to find the food he’s accustomed to, may head into a local village and attack. Since all of this happens automatically, it generates numerous adventure possibilities.”

That’s the Simulation Dream – the idea of making a complex simulation of a story world, which creates fascinating emergent stories as powerful as those you might write yourself. The idea bursts with potential. And it appears everywhere. Early in the development of BioShock, that game had an ecology too. There were three parts to it. Splicers would hunt Gatherers, who were in turn guarded by Protectors. The player was supposed to interact with and manipulate this ecology to survive.

But these dreams shattered. After its release, Richard Garriott said of Ultima Online:

“We thought it was fantastic. We’d spent an enormous amount of time and effort on it. But what happened was all the players went in and just killed everything; so fast that the game couldn’t spawn them fast enough to make the simulation even begin. And so, this thing that we’d spent all this time on, literally no-one ever noticed – ever – and we eventually just ripped it out of the game.”

The same happened on BioShock. While BioShock retained some valuable vestiges of its simulation-heavy beginnings, the game as released was really a heavily-scripted authored story. There was no systemic ecology at all. It worked fantastically as a game – but it wasn’t a deep simulation.

The problem is that simulations with a lot of moving parts quickly become complex in the intimidating academic sense. There are so many pieces interacting that the game can easily become too much to understand, predict, or play with. All the interesting stuff in the game ends up lost in the silicon, inaccessible to the human players’ understanding.

And that’s really the key – making complex simulated events accessible to human understanding. Which brings us to a nerdy idea I like to call the Player Model Principle.

The Player Model Principle

The Player Model Principle is this:

The whole value of a game is in the mental model of itself it projects into the player’s mind.

We make a simulation in computer code. That is a computer model of some situation – a dwarven fortress, a prison, and so on. But that is not the only model of that situation designers need to worry about. There is another model of that fortress or prison – the mental model in the player’s mind, which the player constructs while playing the game. Designers create the Game Model out of computer code, while the player creates their own Player Model by observing, experimenting, and inferring during the play.

MentalModelDiagram

In play, the Game Model is irrelevant. Players can’t perceive it directly. They can only perceive the Player Model in their minds. That’s where the stories are told. That’s where dilemmas are resolved. So the Game Model we create is just a pathway through which we create the Player Model in the player’s mind.

The Player Model Principle indicates a source of risk. Namely, anything in the Game Model that doesn’t copy into the Player Model is worthless. That’s what happened with the ecologies in Ultima Online and BioShock. They didn’t enter the Player Model and so degraded into noise. This is a fairly obvious risk and is common in game design – all designers have seen players not understand a piece of their game.

But the Player Model Principle also implies an amazing opportunity. What if we could put something in the Player Model without implementing it in the Game Model? What if we could make the player perceive some event or relationship or meaning that wasn’t even there?

The advantages are obvious. We wouldn’t have to build it or test it. And it wouldn’t add any complexity burden to the game. While this sounds exotic, it actually happens all the time. It’s called apophenia.

Apophenia is seeing meaningful patterns in random or meaningless data. For example, look at this wall socket. What do you see? A face! And not just a face. But a face with a confused, perhaps pained expression. Why do you see that? There is no such personality here. But we perceive it all the same. It’s how we’re wired as human beings.

Outlet

That ability to perceive personality and intent is a deep-seated human ability. It happens below conscious awareness, the same way you can look at a room and understand it as a 3D space without thinking about it. The only knowledge of the room you have is a 2D projection of it on your retinas. But some silent processor in your brain generates the perception of a 3D environment. In the same way, we effortlessly perceive minds and intentions. It’s why ancient peoples perceived spirits in rocks, water, sun and moon.

Apophenia is powerful and varied. Consider these Michotte demonstrations, named after the researcher who explored them in the mid-20th century.

sims1

But none of those emotions are in the game. The Sims 3 has a very simple computer model of social interactions which does not really depict deep human emotions like jealousy and anger. We perceive these things through apophenia – the same way we perceive a small ball fleeing from a large one.

Now the player takes control of the story. He hatches an evil plan involving a cheap stove, poor cooking skills (which cause fires), and wooden chairs.

sims2

And the plan works.

sims3

This story was co-authored between the player and the game. The game simulated some simple event (attraction between redhead and roommate), and the player ascribed meaning to it (jealousy and frustration) the same way he might have for the Michotte balls, even though that emotion was not actually in the simulatiion. The next part of the story was cued by him when he orchestrated the murder. The game simulated the logistics of firey deaths, but the sense of sorrow and revenge was, again, ascribed completely by the player. Most of this story is apophenia – present of the Player Model, absent from the Game Model.

Creating apophenia

It’s hard to see obvious ways to make players imbue meaning into a game that the game doesn’t actually have. But survey the products that do it well and you see patterns.

Borrow archetypes from real life and fiction

Use the archetypical jealousy plot, the evil stepmother, the good king, the classical hero. This saves exposition since the player already knows the stock character or situation you’re hinting at. This makes it easy for players to fill in absent details.

Allow players to project themselves into the game.

When a virtual character has your name pasted on, it is easy to imbue that character with motivations that are relevant to you. The same goes when the player projects in their friends, house, and so on, into the game. The Sims gains massively from this.

Create uncertain situations with human-relevant values in the balance

This is storytelling 101, but it bears mentioning. The simulation has to create situations that are worthy of being called stories. That means something important has to be in the balance, and the outcome has to be uncertain. Human values must be at stake.

Human values are things like life/death, alone/together, wealth/poverty. The game should revolve around things that affect these human-relevant values, and not descend into a dry simulation of traffic networks or production lines. Such simulations may be intellectually interesting, but will not generate effective stories because they are emotionally hollow.

Express or imply simple, pure, primal emotions

Annoyance is less interesting than fury because of the difference in intensity. Melancholic existential hipster sadness is less accessible than grief over a dead child because that grief is simpler, more relatable, and more primal. If the game has no opportunities for characters to feel such emotions, it is unlikely to generate good apophenic stories. Stories are built from primal feelings, so the subject matter of the simulation must create situations where characters would feel primal emotions.

Drowning in Complexity

So we’ve covered the benefits of apophenia. But we still haven’t solved the problem that killed the ecologies in Ultima Online and BioShock. How do we handle complexity? For apophenia to work, players have to see and understand interesting things happening. And this can easily prevented if they’re drowning in complexity.

Think of a simple system, like orbiting planets. For the most part, each planet only has a relationship with the sun around which it orbits.

Simple-Orbital

If you want to tell a story about each planet, it’s easy. You just look at its one relationship and talk about that. So the Earth orbited… and it orbited… and it orbited. The problem is that while this story is easy to see and easy to tell (satisfying the Player Model Principle), it is also quite dull. We need more interactions, more variation, more unpredictability. We need more complexity.

Now imagine we’ve made a simulation of a village. Each of the hundred villagers has a relationship with each of the others – father, friend, enemy, lover, or acquaintance. Each can work at the fishing pond, the market, the field, the mill. Each can satisfy their own needs at the tavern, in bed sleeping, at the outhouse. The water can flood the field. The outhouse can spill into the market and contaminate it, causing sickness, overloading the hospital, making the doctor work too hard, leading to divorce. It sounds like the Simulation Dream. But there’s another problem now. The connections multiply until the whole system appears as a gigantic hairball of complexity.

HairComplexity

Such a system could support some very interesting stories. I just told you one of them. The catch is that it will constantly break the Player Model Principle. With so many relationships, it becomes very hard for players to understand cause and effect in the system, so those stories end up buried and unobserved.

What we want to do is create systems that are smaller and simpler than these giant hairballs, yet have more interesting, comprehensible interactions than simple systems like orbiting planets. What we really want is not a system that is complex, but a system that is storyrich. Story-richness is a term I invented for this article, and a concept that I keep in mind while doing simulation design. It has a simple nerdy mathematical definition.

Story-Richness: The percentage of interactions in a game that are interesting to the player.

Consider every interaction in the game – every crop harvested, every path walked, every work spoken by a character. Of all the interactions happening in the game, what percent are part of an emotionally meaningful story? In a successful game, this percentage is high. Much of what you observe will be part of a story. In a poor game, it is quite low.

Interestingly, real life and most fictional worlds are not story-rich! Most days for most people on Earth or in Middle Earth are quite mundane. It’s only very rarely that someone has to drop the Ring into Mount Doom. Follow a random hobbit in Hobbiton, and you’ll be bored soon. It reminds me of an old war simulation MMO, where players sometimes had to drive a truck for hours just to reach the front line. Yes, we know war is 99% boredom interspersed with moments of terror, but a game about it should not be.

This means that a simulation game can’t be a faithful simulation of its subject matter! It has to be a narratively condensed, intensified version of that village, fortress, or prison. And it has to seem true to the source material without being true to that source material. The Simulation Dream just got harder.

Creating Story-Richness

Like apophneia, the sources of story-richness are difficult to see. But there are some patterns. The basic principle is to avoid uninteresting events and create more interesting ones.

Choose the minimum representation that supports the kinds of stories you want to generate

This is a complex piece of advice that I’ll try to unpack by example.

Imagine we’re making a simulation game and trying to decide how to model food in that game. How many classes of food do we put in? We have lots of options

  • All of them! Cheese, venison, beef, chicken, broccoli, barley, corn, beer, water, juice, and so on. Hundreds of options, each acting slightly differently.
  • Categories by type: Meat, vegetables, liquid.
  • Categories by quality: High-quality, medium-quality, low-quality.
  • One: Food is food.
  • Zero: Food is not modelled and nobody eats.

Which do you choose?

Choose the minimum representation that supports the kinds of stories you want to generate.

The above sentence is fairly dense, so I’ll try to unpack it.

Consider the kinds of stories you want to generate in your game. To what degree are they about food? If you’re making a simulation of a New World colony in 1550, food will be important because starvation is a key driver of many stories in such a setting. The threat of hunger is, one way or another, part of most of the stories in such a setting. So you’d probably want a pretty nuanced food model. In such a game, the difference between seal blubber and vegetables could be important, because a diet of only seal blubber leads to scurvy during the winter, which leads to death. Human values are at stake!

However, if your game is a prison sim, you could make a strong case for not simulating food, or for simulating it in the simplest possible way. Because prison stories are not typically about food. Watch Oz or The Shawshank Redemption and few of the plotlines revolve around who is eating tasty bacon and who is eating cheap rice. A complex food simulation in such a game is likely to just add a lot of systems and noise that don’t contribute anything to the stories players care about. This complexity would be better added to the systems for gang membership, shiv combat, or friendship.

In general, lean on the simple side. You don’t have to simulate that much. The game is a co-author, not an author. It just need to hint at what is going on – the player’s apophenia will fill in details.

Use hair complexity for cheap fictional flavor

Hair complexity is my term for pieces of the simulation that don’t affect anything outside themselves.

I call it hair complexity because it sticks off the main ball of relationships without feeding back into it, like the hair on your head. Such hair complexity can be ignored by players who don’t wish to deal with it, while more interested or skilled players can pay attention and get its full flavor. It’s like the flavortext in a card game.

Examples:

  • In Dwarf Fortress, each dwarf has an appearance. These appearances do nothing, but help players form mental images.
  • In Prison Architect, prisoners have criminal histories. They do nothing (so far), but they add flavour if you want to watch a certain prisoner.
  • In The Sims, sims have conversation topics represented by images in speech bubbles. For the most part, these topics don’t matter. They could talk about sailing or sports; it makes no difference. What matters is that they are talking and their relationship score is improving. But players can, if they wish, watch the stream of images and imaging a thread of conversation leading from money to cars to a mutual friend.
  • It was mentioned to me at a conference that hair simulations (e.g. Tomb Raider) are, ironically, hair complexity, since they don’t affect anything else in the game. Har har.

Hair complexity is cheaper to design. And since it doesn’t feed back into the larger game system, it doesn’t add complexity – just a bit of interface burden.

Eclipse Colony design case study: Crop Growth

Let’s put this into practice and look at a small example of a simple system design problem from my game Eclipse Colony. I faced this problem in early May 2013. Get ready for design nerdiness – we’re about to do some heavy analysis on what seems like a simple problem.

Task

Currently, plants just grow on a timer and can be harvested when the timer expires. But it’s odd that plants yield the same regardless of whether they’re exposed to vacuum or not. I’d also like some notion of farmers tending plants to help them grow and yield more. Fix these issues.

In this situation I wrote several candidate designs to choose between before I decided on a path. Here they were:

Option 0 – Skip it

  • Do nothing. Let plants grow the same on the same timer anywhere.

Analysis: Option 0 should always be there. There are always a lot of things we could work on in a simulation game. We could make a better friendship system. We could add animals or new weapons or wild plants. We could improve world generation. We could differentiate cultures, make a religious belief system, or add more nuances to the combat model. You have to be sure that what you’re doing is actually somewhere near the top of that gigantic priority list, because it’s easy to get tunnel vision. In this case, I decided that crop growth was worth working on because starvation is a big part of life in this fictional space colony. Furthermore, the missing behaviors had been bothering me in a direct and present way during playtests. It was a problem crying for a solution.

Option 1 – The yield variable

  • Each plant has a variable called yield.
  • When the plant is harvested, the amount of food that appears is based on yield.
  • Each time a farmer tends the plant, yield increases. Once tended, plants can’t be tended again until a certain time has passed.
  • Damage to the plants reduces yield.
  • Being left in vacuum reduces yield.

Analysis: I liked this system at first because it seems to reflect the fiction well. But there’s a big caveat: a new variable (yield) is undesirable complexity. Also, how will yield work for wild, unfarmed plants in the future? Will they even have it? How does it interact with more normal damage from fire or explosions? Do plants also have a health variable? The added complexity and edge case ambiguities made this seem a poorer choice.

Option 2 – Use the growth timer

Remember that plants already have a timer that counts down until they’re finished growing.

  • Each tending operation speeds the plants towards finishing growth.
  • Damage to the plants reverses their growth.
  • Being left in vacuum reduces plant growth.

Analysis: The simplicity of this is good because it doesn’t require any new variables. But this doesn’t capture reality – real plants don’t just grow slower when deprived of care or when damaged. They grow poor harvests, but they still flower around the same time. This system could lead to absurd situation like crops being slightly damaged repeatedly and just never becoming harvestable. Or plants being very well-cared for and being harvestable on a weird accelerated schedule.

Option 3 – Re-use the health variable

  • Plants have the standardized health variable.
  • Final harvest output is proportional to the plants’ health.
  • Plant health steadily decreases at all times (due to insects etc.)
  • Plants are damaged by vacuum and normal damage sources like fire.
  • Tending plants is essentially repairing their health.

Analysis: There are no new variables or interfaces, which is good. It captures the essence of the idea well enough. It even expresses the rotting of grown plants, since they lose health over time after they finish growing. This seems like the minimal representation that captures the subject matter and supports the stories I want the game to co-author with the player.

I ultimately decided to re-use the health variable. But even this could still change as the game gets tested more.

The Simulation Dream Reborn

It seems like maybe we killed the Simulation Dream. You can’t just simulate a super-complex world because players won’t understand it. And even if you did, it would be boring, because even Middle Earth isn’t very story rich.

But the Simulation Dream lives on. We just know we have to approach it very carefully. We can’t blindly simulate everything, because most things are boring and people can’t understand over-complex systems anyway. We have to carefully craft a condensed system of simple, understandable hints that cue players’ apophenia to do the heavy lifting of ascribing emotion and meaning. We have to make sure that system projects well into the Player Model. And we have to make sure that much of what happens in it concerns powerful, primal human emotions, not logistical details.

But if we do all that, I think the Simulation Dream is still in our reach.

 

My Twitter: @TynanSylvester

My book:  O’Reilly.

This article was previously posted on Gamasutra where it got some good discussion.

 

Gentle introduction to Google Analytics in Flash

Original Author: Hubert Rutkowski

Introduction

Being able to check out how many players play your game, from what countries, for how long, on which levels they have problems, how much points do they score, even do they ever visit your precious Credits screen or the average FPS number – that sounds incredibly useful, doesn’t it? Fortunately, in web browser games, there’s a way to get such informations. In this post I’m going to describe the process for Flash (ActionScript 3), because I’ve recently implemented it in my released game, and can share some experiences.

Possibilities

And there are even many ways. First, some time ago you could use Playtomic.com – however they had notorious problems with reliability, and are now out of bussiness. Then, the second try could be Google Analytics for Flash project (later shortened to GAF).

That’s true – you can use the well known, very powerful, complex, free, reliable and spied service from Google to process the statistics from your own Flash games. And it’s actually pretty easy to use. Sadly, the documentation is rather cryptic, sparse, ambigous and hard to follow. So, here goes a quick, practical tutorial for you + code samples 🙂

Let’s dive in

First, download the files from their site (latest version haven’t been updated for a long time) and put it in some directory like lib/gaf, alongside other game libraries. Inside your IDE link to the one of the .swc files: analytics.swc (codebased IDE like FlashDevelop) or analytics_flash.swc (component for Flash CS). Code snippet from Ninja Cat:

package
 
  {
 
    import com.google.analytics.AnalyticsTracker;
 
    import com.google.analytics.GATracker;
 
    import flash.display.DisplayObject;
 
   
 
    public class Analytics
 
    {
 
   
 
      public function Analytics()
 
      {
 
      }
 
   
 
      CONFIG::stats
 
      {
 
        private var tracker:AnalyticsTracker;
 
      }
 
   
 
      public function Init( stage : DisplayObject ) : void
 
      {
 
        CONFIG::stats
 
        {
 
          // UA-google-api-code has to be replaced by your ID, taken from GA page
 
          // fourth parameter is visual_debug - its described later in post
 
          tracker = new GATracker( stage, "UA-google-api-code", "AS3", false );
 
          PageView("Home");
 
        }
 
      }
 
   
 
      public function PageView( URL : String ) : void
 
      {
 
        CONFIG::stats
 
        {
 
          // google wants to have slashes before names of pages
 
          tracker.trackPageview( "/" + URL );
 
        }
 
      }
 
   
 
      public function LinkOpen( name : String, URL : String ) : void
 
      {
 
        PageView( name );
 
   
 
        // could also automatically open link
 
        // Link.Open(URL, name, "Links");
 
      }
 
   
 
      public function TrackEvent( category : String, action : String, label : String, value : int = 0 ) : void
 
      {
 
        CONFIG::stats
 
        {
 
          tracker.trackEvent(category, action, label, value );
 
   
 
          trace("GAF event: " + category + " | " + action + " = " + value + " ( " + label + " )" );
 
        }
 
      }
 
    }
 
  }

Before anything: what is CONFIG::stats? It’s a way of conditionally including code in AS3 (a kind of #ifdef macrodefinitions for you C++ buffs). It’s very useful – by toggling one variable in IDE, you can build a significantly different version of game. So, if CONFIG::stats is not defined, all that is between braces will be ignored. In this case, it might be useful to disable statistics ie. for local testing. Here you can read more about this technique.

So, what I’ve done here, is estabilished interface for using GAF in my game. Create the object of type Analytics somwhere near the start of your game, call the Init method, and you’re ready to go. Then the question arises: how to use it?

GAF gives you two ways of tracking user behaviour: page views and events. Simply speaking, page views are like in the web browser – navigation between different URL locations. User views your /blog subpage, your /about, your /games etc. Events are for user interactions with elements of the page, which don’t result in changing of the page – so for www that would be ie. movie controls, downloading files, clicking on polls etc. With events you can log more informations; pages only log the name of the visited pages.

Note: Google Analytics doesn’t process everything instantly. For more detailed data you will at least need to wait till the next day. There’s a Real time mode which shows pages and events that happend within last 30 minuts, altough it’s with limited functionality. For example, one thing which it doesn’t show is the values of events.

In case of games, you’d want to use this duo like that: pages are for game states and menu screens (MainMenu, Options, Credits, Level1, StatsScreen), while events are used for detailed statistics (I’ll get to that later on). From the code above you can also see that I decided to have LinkOpen be treated as page views, altough it could also work as an event.

Basic Results

So, when you add this kind of code to your game, add the function calls in appropriate places (ie. analytics.PageView(“MainMenu”); ), and turn debug mode on (fourth parameter to GATracker is true), you’ll see some debugging info appear:

gaf-debug

With this you can quickly confirm that things work as expected. Having this, you can go to your Google Analytics dashboard and start peeking at the statistics. Here’s how GA looks with the data from Ninja Cat and Zombie Dinosaurs (I cut out only the interesting bits):

gaf-stats1

What is interesting here, is the incredibly small Bounce rate of 0.03% – it means that 99,97% of users who load the game and see menu, continue to start the first level. Compare that to Bounce rate of anywhere between 40-70% for normal websites. Huge win for me.

right_now_21

Google Analytics has this nice feature of showing some stats in a realtime preview. And so at that thursday afternoon over 20 actual people were playing my game, and from the map below I saw that they were from all around the world. For the creator it’s humbling 🙂

gaf-stats3

Last of screenshots shows the details on which “pages” were viewed the most. We can see ie. that players are not interested in me (Credits) or sponsors (links), and they even very rarely visit Options. Hmmm. When I play new games, first thing I do is look into options and credits. Oh well.

According to Mochimedia, my game so far (beginning of june) had around 28k displays of ads – which is almost the same amount as /Main views in Google. So both systems confirm each others reliablity (or both are wrong ;). As for an online flash game, almost 30k plays (and 1-2k per day) is very small number. I think after maybe 2 months I’m going to write a separate post about how Ninja Cat succeeded in the “internets”.

Apart from the dashboard, you can find useful data a bit burried in Content -> Site content -> Content drilldown and Content -> Events -> Overview. I would really recommend to spend few hours reading Google Analytics help, to get a good understanding of the platform (goal completions, funnels, conversions, intelligence events, how to filter, learning UI) – there’s lots of stuff.

Here I’ll briefly mention three features:

    1. Traffic sources – where you can see the URLs that people are playing your game on… at least theoretically, because I don’t see the URLS of most sites, just some part of it. What works much better for me is the Ads section in developer dashboard on MochiMedia.
    2. Intelligence events – starts working if you have more data, for at least few weeks. Then GA will analyse it and point out for any unusual events ie. sudden increase or decrease of people coming from a certain country, or decrease of avg play time. It’s mostly targeted at website owners, who can then make some adjustments to their site.
    3. Goal completions – on commercial websites they’re used to track how far the user is along the path to goal, which is typically buying something. Landing page -> catalog -> add to cart -> checkout -> payment – you get the idea. In our case, they could be used to track how much has user progressed in game: level 1 -> level 2 -> …, and the goal would be last level of game. In this way GA will show you how many people have finished your game. How cool is that? 🙂 In order to have it, you’ll need to specify a funnel – sequence of page views, which lead to your goal. More on that in GA documentation.

 

Logging detailed statistics

Coming back to the beginning of post – how about original requirement? My game (which is typing game inspired by Typing of the Dead) collects detailed statistics about player progress – they are displayed after finishing a level. Those are things like number of points, enemies killed, katana kills, how much time (in seconds) did it take to finish it, accuracy, number of keystrokes etc. Those are natural things to log. Here’s the code of function in some StatsScreen class that I used:

public function LevelEnd(
 
          level_index : int, level_time : int,
 
          enemies_killed : int, katana_kills : int, score_points : int,
 
          total_keystrokes : int, accuracy : int,
 
          avg_kill_time : int, avg_kill_score : int,
 
          collected_powerups : int, stars : int, health_loss : int,
 
          player_name : String,
 
          _result : int // 1 for died, 2 for won
 
      ) : void
 
  {
 
      CONFIG::stats
 
      {
 
          var cat : String = "Level_" + level_index; // cat is for category
 
   
 
          analytics.TrackEvent(cat, "time", null, level_time ); // I won't shorten analytics though
 
   
 
          analytics.TrackEvent(cat, "enemies_killed", player_name, enemies_killed );
 
          analytics.TrackEvent(cat, "katana_kills", player_name, katana_kills );
 
          analytics.TrackEvent(cat, "score", player_name, score_points );
 
   
 
          analytics.TrackEvent(cat, "keystrokes", player_name, total_keystrokes );
 
          analytics.TrackEvent(cat, "accuracy", player_name, accuracy );
 
   
 
          analytics.TrackEvent(cat, "avg_kill_time", player_name, avg_kill_time );
 
          analytics.TrackEvent(cat, "avg_kill_score", player_name, avg_kill_score );
 
   
 
          analytics.TrackEvent(cat, "powerups", player_name, collected_powerups );
 
          analytics.TrackEvent(cat, "stars", player_name, stars );
 
          analytics.TrackEvent(cat, "health_loss", player_name, FlxU.abs(health_loss) );
 
   
 
          analytics.TrackEvent(cat, "player_name", player_name );
 
   
 
          analytics.TrackEvent(cat, "music_volume", player_name, int(FlxG.music.volume * 100) );
 
          analytics.TrackEvent(cat, "sound_volume", player_name, int(FlxG.volume * 100) );
 
   
 
          var result : String =(_result == StatsScreen.FINISHED_LEVEL ? "win" : "lost");
 
   
 
          analytics.TrackEvent(cat, "difficulty", result, Game.difficulty );
 
      }
 
  }

As you can see, there’s also music and sound volume – who knows, maybe I’ll see some interesting trend here, ie. most players disable music? I also collect FPS informations (min, max, avg) and player name, because I am curious what players will write there 🙂 You can also log capabilities of players system, just like Valve is doing with steam – I log only flash player version.

The reason behind passing player_name as label values is that then you should be able to drill down and view statistics coupled with specific players. Of course 90% of players won’t change the default “Ninja Cat”, but it will work for those who do. However, I’m not entirely sure whether my category/action/label naming convention is any good, and would seriously advise to read few about the topic.

If you’d like to see the values of those events, here’s the breadcrumb path in GA dashboard jungle: Content -> Events -> Top events, then in the list of categories you choose which level you want, just by clicking the name. On the new screen, under graph click Event action as the Primary dimension. Then you’ll see the detailed stats.

gaf-stats4

The Avg. Value column holds the date we’re interested in. The Event Value will contain sum of all the values… not really useful, unless you want to know how many dinosaurs have killed all your players on level 1. Hmmm, that sounds like a great marketing information, “Ninja Cat and Zombie Dinosaurs players so far have killed one million and 200 thousand zombie dinosaurs… wanna help getting rid of the plague?“.

Warning: For a long time I had this problem of not being able to see the values of events in GA reports. I looked everywhere there, I checked code – GIFs were sent, other things worked. I asked on internet but no one answered. I thought maybe it’s just one thing you can’t do from Flash code, and so I released game without this working. Later, when preparing this article, I wanted to try it one more time, so I made a simple test application and started experimenting. To my positive surprise, it worked!

The thing that was blocking it, was the lack of label value sent in event. Though the documentation says label is optional, appareantly if you want to see the actual values, it’s not optional. Also worth mentioning is that the value (last parameter) has to be positive integer. Because of that, all percents should be multiplied by 100, miliseconds by 1000 etc. It would even be sensible to use proper hungarian notation and postfix the units in action names.

 

Conclusion

So, there you have it: a way to track player behaviour, and to look into some interesting facts about usage of your game. A natural question arises: could it be done with other technologies on other platform, specifically: C++ on desktop games?

Technically yes, and that’s even possible in many ways. First, as writing your own analytics service.

But even if you had that magic tool, you’d steel need to ask user for permision – offline applications are not expected to freely contact internet services. Web games have it easier here – user is obviously connected and in his browser when he’s playing, so there’s little difference to tracking user behaviour in game embedded on page, versus tracking user behaviour on page. The latter is usually taken for granted, since most websites collect statistics, and Google Analytics is one example of such a system. So web games should also be accepted.

If you still have technical questions regarding usage of Google Analytics in Flash/AS3, you may read a similiar, but more thorough (and more oriented towards Flash CS users) tutorial over here, ask question in comment below, or do a search in your favourite search engine 🙂

Data-driven design with Unity 3d, Part 1 – Brainstorms, Initial Requirements

Original Author: Mike Wuetherick

This is a slightly-edited re-post of a series that I’ve been writing in quiet isolation (which you get used to doing indie development) on my blog.  Currently up to part 4 of the series, they have been received somewhat well by my small subset of beta testers, so might as well throw them out to the world at large ;}

Well, here goes.  The story starts back in March.  For the year previous, I had been working at DeNA Canada, helping them startup their first Canadian studio (I was employee #2), recruiting, getting coffee makers and all that fun.  Somewhere along the way I was immersed in the concept of ‘server-driven’ game development – a concept that I had experimented with in passing on a few titles, but nowhere to the extent that we did at DeNA.  Note that I started before Rage of Bahamut had hit the charts – even at DeNA, no one really believed that it would be popular, except for the fact that the Japanese market had/has an insatiable appetite for card battles, and the belief was that similar styles of games could translate across the water.  Well, the rest is history, I spent a year at DeNA, learned a huge amount and – most importantly to this series – spent 9 months building server-based games with Unity and discovering the huge potential and power of this kind of game architecture.   If you want to know the secret sauce of how DeNA and other top-grossing mobile titles generate so much revenue from their titles on an ongoing basis?  The answer is Server-driven game architectures.

Anyways, that’s where the story begins.

With my new-found freedom comes responsibilities.  The first is looking for a new job and/or deciding what I want to be when I grow up.  The second is, of course, starting to work on a new game of my own.  I’ve never been one to sit around and wait for an opportunity to come my way, and might as well continue to push my own personal limits while I work through where I end up after this brief intermission.

After a bit of soul-searching about what kind of title I want to create, there is a definite foundation layer of technology and design that I want to get implemented.  These are core building blocks that will be required irregardless of the specific game that gets built, and as such, are something that I can begin to design immediately, ie before I lock down a design.


But first, before I go into detail about these pieces, let’s look at the basic assumptions that I’m going into this new project with.

  1. Mobile (android only for the moment due to lack of hardware)
  2. free 2 play (IAP)
  3. Unity-basedphp server / back-end

I’ve spoken to quite a few people lately about servers / back-end technology, and there seems to be 2 core camps at the moment:

  • Java
  • Ruby and/or node.js or some other esoteric framework that very few people know and understand

I don’t want to go into too much detail about either of these, and when it comes down to it, the simple fact is that I don’t know enough about either to dive into anything with any kind of comfort.  The big thing to remember when starting out any technology project is that you want a solution that is not only something you will be able to build and do what you want, but also something that it is easy to find developers to bring on board and grow the team in the future.  The further from the ‘norm’ your technology solution is, the more difficult it will be to find programmers familiar with the tech and more difficult it will be to get them productive once you bring them on board.

With a solution like Java at least you are safe in the knowledge that there is a lot of support in both industry and educational worlds to help train your future employees / team members.  Node.js / ruby etc?  Not so much.  Python? Maybe, but it’s also a ‘very object oriented’ system that has it’s own complications.

My personal coding style is very bare bones – for a couple of reasons.  I am often jumping between numerous languages on a regular basis, so memorizing the language specific nuances of a particular system isn’t particularly of interest to me, and secondly, I find that the most useful and understandable code (and most easily debugged) is code that doesn’t hide behind alot of abstraction layers / templates / language-specific features.  But that’s just me.  Maybe I suck as a programmer (and that’s definitely arguable), but looking through code trees of programmers that most definitely do NOT suck, I can feel confident that this is at least a reasonable way of looking at things.

Anyways, I digress – let’s get back to the situation at hand.


To PHP or not to PHP

So having said all of the above, the only server language that I know and trust is PHP.  It hasn’t done me wrong in the past, is nicely scaleable and a ‘known quantity’ with regards to finding developers comfortable using it.  As well, I can get up and running with php instantly and know that I will make progress very quickly.

So, let’s discuss the above requirements, specifically looking at the re-usable server framework that the projects require.

Server-side data-driven development

When it comes down to it, from a game design standpoint, separating your game’s data into the ‘cloud’ as it were is the best thing since sliced bread.

Always-on architectures get a lot of bad press (see the recent simcity debacle).  I understand the concerns about DRM / etc, but when it comes down to it, from a game design standpoint, separating your game’s data into the ‘cloud’ as it were is the best thing since sliced bread.

This doesn’t have anything to do with ‘milking your customers’ or invading privacy in the slightest.  The basic fact is for a game designer, being able to push out updates (either new content or simply tweaking the balance of a few items or missions), simply by adjusting some parameters on the server in today’s rapidly evolving market is absolutely necessary for a title to succeed.

Also note that I’m not making any grandious claims (ala Maxis) that I’m going to be utilizing the ‘cloud’ to process the individual AI ticks of the minions in the game or any other such garbage – however, there are some pretty significant ‘must have’ features that any game in the year 2013 should consider ‘must have’  in my opinion. Let’s go through some of them:

Advantages / ‘Must-Have’ features of a server-side / always-0n design

  1. persistent / cloud player state saving – move from device to device, no more unlocking / restarting a game from scratch
  2. server-side data allows you to adjust the balance / tweak your game after launch.
  3. if designed properly, server-side data should also allow you to push out content updates without requiring a new client push.  This is particularly important on iOS, when a simple adjustment of the game would previously require a 2 week turn around waiting for the latest build of your game to get pushed through to your customers.
  4. integration with a larger user login / registration system, and possibly a 3rd party payment / virtual currency platform to reduce / eliminate the friction for your users to start playing your game, and (dog forbid) start spending money on your title.

Server Design – 4 Elements

What the above means, from a server design standpoint, is that we have basically 2 key elements to our server, and quite possibly 3 or even 4 (depending upon what platform you will target).

The first 2 elements to our server design can be broken nicely into:

  1. Static Content (Metadata)
  2. Dynamic Content (Player data)

Metadata

You can consider metadata to be anything static in your game that doesn’t change from player to player.  This could be an inventory of all of the weapons in your game, or a list of all of the level names, all of the dialog text in the game, and so on.  I would highly recommend that you store all of this static information server-side so that it is easy modified and updated after launch. Yes all of it.  I’m not kidding in the slightest.  Every weapon, every item in your massive RPG, every character’s details, the whole story of your game.  Store all of it on the server and query it dynamically (well, mostly dynamically, we’ll go through how we can cache this and allow offline play etc later on).  Yes I did say ‘offline play’ – almost nothing about what I’m proposing here would necessarily prevent offline play, but that’s up to you to decide for your particular title.

Player Data

The dynamic content in your game is the player-specific user data that gets stored as they start the game and progress through the adventure.  This could include their progression through the tech tree in your game, their inventory, unlocked levels, etc.  It could also include a more complex savegame system that stores micr0-states of individual objects in a scene if you like.   All of this information gets pushed to the server and pulled down dynamically when the player first launches the game / effectively ‘syncing’ their game state.  Every MMO that you have played does this kind of thing, and probably a number of other games that you have played in the past 3-5 years as well.  Unfortunately not nearly enough do this kind of cloud-saving (in my opinion).

The 3rd Element of our server design is related to #1:

Content Delivery 

As games get larger and more complicated, the more likely that you will want to be able to push new content or updates to your users dynamically.  Building a system that provides this kind of mechanism out of the box will save you a ton of pain trying to deliver patches / updates to your customers.  This could be as simple as downloading the texture used by a particular NPC to an entire new level or zone for a game.  A tool like Unity provides a powerful http class for handling downloading of content and also provides AssetBundles, which allow you to very easily pack up just about any content in your game and stream it to the user on demand.  You could do this truly on demand (only streaming content as it’s needed), or via an ‘auto updater’ setup (run at game launch or otherwise).  Either way can work, depending on the platform(s) you decide to support.

The 4th element is more crucial for mobile, but applies equally to normal PC development as well:

3rd Party Integration

One of the most popular 3rd party integrations today is facebook.  A major consideration that you need to factor in is whether you want to build your own user registration / login system or use a 3rd party integration.  Facebook is one, others on the market include ScoreLoop, Playtomic, and there are a number of other options.  One that I’m looking at that seems pretty polished is called PlayPhone, but haven’t decided 100%.  I’ll do another post dedicated to the 3rd party integrations because there are a number of factors involved with this decision and more than I want to get into today.


So with the above elements in mind, next time I’ll go into some specifics about how I’m approaching Element #1 and #2. #3 is fairly straightforward and won’t be a huge issue at the start, but I’ll describe how I plan to handle this. #4, as I mentioned above, will be covered separately, although whether I have made a decision on what system I’m going to go with by then remains to be seen.

Until then, have fun experimenting!

Understanding “It’s not what you know, it’s who you know.”

Original Author: Forrest Smith

It is regularly said that “It’s not what you know, it’s who you know.” This is a common phrase that may be even more popular these days due to economic hardships.

While the statement is undoubtedly true it also misrepresents how things work in the real world. After seeing things from both sides it’s not what you might be led to believe.

Entering the Workplace

The first step of a successful career is often the hardest one. Getting your foot in the door is a daunting and often frustrating task. As a graduate you have no professional experience and no real network. Sure you have a lot of friends from school, but they’re all just as desperate for a job as you are!

When I was finishing school I distinctly recall thinking how unfair it was that it’s “who you know” world when I was a student who didn’t know anyone. It’s easy to imagine people with strong connections as greedy one percenters who were born with a silver spoon and haven’t worked a day in their lives. Suffice to say that isn’t how things work.

Company Growth

I work at a video game company, Uber Entertainment. Uber started with a handful of people in a two bedroom apartment and grew slowly [1]. I was hired near the end of year two and distinctly recall a point where 13 of 16 employees had previously worked at Gas Powered Games [2].

Today we’re at 23 full-time employees and only slightly more diverse – 15 of 23 are from GPG. Of the remaining 8 only one or two are “off the street” so to speak. Everyone else had either been worked with directly or came with strong recommendation from trusted peers.

This hiring practice could be viewed as unfair nepotism. The reality of the situation is far less nefarious and much more boring – it’s common sense. If you have a job opening and know someone who is willing and able to fill the role then you bring them on boardHiring through an open call is a last resort after you’ve fully exhausted your company’s extended network.

Many teams, particularly small teams and start-ups, are able to fully staff based purely on hiring previous colleagues or exclusively via recommendation. This hiring strategy works exceptionally well.

Your Network is Your Friends

How do you build a strong professional network? I think it’s elegantly simple.

  1. Be good at what you do.
  2. Make friends.
  3. Meet friends of your friends.

That’s it. I roll my eyes every time I read an article about someone “hacking” the system and securing a lunch meeting with an executive big shot. That’s a black swan event and may not even be as useful as you’d think.

Your network is your friends. It’s not a guy you talked to for two minutes at an industry party. It’s not someone you met briefly and handed a business card. It’s friends you’ve built a real a connection with over time. Friends you know and trust.

It is also important to actually be good at what you do. Someone making a recommendation is putting their reputation on the line. It’s not something that can be done without careful consideration.

Be good at what you do, build real friendships, and everything else follows naturally.

Footnotes

  1. Uber’s Hail Mary: The Long Road of Monday Night Combat (Polygon)
  2. These hires were one-by-one rather than from a large exodus event.

A project management view on IT vs. games

Original Author: Timo Heinapurola

I come from a background of IT development, where I worked in multiple roles from programmer to system architect. During that time I saw many different project management techniques ranging from the overly heavy and bureaucratic ones to the very light and agile ones. It might actually come as a surprise to some of you that working on graphics heavy AAA games has not felt all that different from working on the kind of software projects I had been part of before. This is partly because I have a very strong background in developing games and related technology as a hobby but also because there are just so many similarities between the two.

I’m writing this blog post because over the years I’ve been hearing many of my colleagues in the games and IT industry expressing their doubts about using processes found perfectly suitable in the other. Personally I feel that it’s important to study different industries to find the best ways to operate. In this post will be writing about my experiences on project management in the IT industry and comparing them to what I’ve been seeing in the world of AAA game development. I will start off by talking about different types of projects and the processes used to manage them. Further down I will talk about managing teams and end the discussion with thoughts on how art is viewed in the respective industries.

The post is mostly targeted toward people who only have experience in one or the other industry, but dual-wielders like me might also find it interesting to read about the experiences of other people with the same fate. I also wanted this to be an introduction to the topic for possible future posts, which is why I did not try to be overly comprehensive in my covering of the topic. So if you have ideas related to this post that you would like me to post about in the future, just leave a comment.

What kinds of projects are we talking about?

The types of projects we were working on in my IT days were mostly custom systems that customers ordered from us. In some cases we went directly to the customer with a plan to sell them an idea. The range of projects varied quite a lot. There were projects that simply gathered information through a given workflow and systems that the companies used to manage their payroll or even their portfolio of products with.

Compare this to say the racing games that we have been making here at Bugbear. Instead of collecting information to compute a person’s payroll you choose a region to drive in, select a car and punch through every wall you can find!

The difference here is the entertainment value. While the first is purely a functional system the later is only about entertainment. Personally I think it’s interesting how the borders between gaming and serious applications are becoming somewhat blurry. We’re currently looking for new types of applications to games as the larger world starts taking note of what you can achieve with interactivity. This has gradually paved the road for serious games. Also different methods discovered in the field of computer gaming are rippling into other areas of computing as well. A notable example of such development is the birth of general purpose computing using graphics processors.

What about the processes?

In my world of IT, when we started working on one of our projects, we typically interviewed the customer about what the basic requirements were and gathered a requirements analysis document that was to form the basis of the system’s initial technical design. The customer had an idea and it was up to us to define how that idea could be implemented. This initial technical design was usually the basis for selling the actual implementation and the design was sometimes made as a separate project altogether.

During the project we would constantly check with the customer whether the requirements were still valid and that we were actually moving in the right direction. We tended to have the system architect and project manager visit the customer on a regular basis with a demo of the system to show. These visits often resulted in drastic changes to the design.

The reason why we received so much change requests was that we had not asked all the right questions, neither was the customer able to answer them accurately enough. If you ask me, there is nothing odd about this. We as humans are limited by how much we can visualize before actually having something to play with. This is the same reason why chess is much simpler when you only have to think about the next move than having to build whole a set of winning moves the moment you first touch a pawn.

There you have it, iteration is the key to successfully finishing an IT project. Personally I think that most of my colleagues understood that but often it was the customer who wanted us to make a full design with all the details and commit to it in price and schedule. There might also have been some lack of trust in agility in the sales department that prevented them from really pushing the idea to the customer. I’ve been hearing that change is taking place there, however, so kudos to that.

In game development iteration is even more important. You can always design a game from start to finish, looking at all the details, designing all the interfaces and game modes from start to finish and even fill in the credits page! The fact remains, however, that you will not get it right. Something in the design just will not fit and has to be cut. You will also come up with new ideas once you get a working version of the game. This is why we need to constantly monitor the progress of the project so we can make adjustments and plan where to move the knight on our next turn.

Small agile teams

Scrum and Kanban are a really good basis for creating your own personalized project management strategy. There’s a saying that if you are not exactly following Scrum you’re not following it at all. Personally I feel a bit differently about this topic and see communication as the biggest takeaway in any process. Both in games and in IT, I’ve noticed that a lack of communication has been the reason for most of the significant nose dives.

Another thing to keep in mind is team size. Communication happens best when you are working with smaller teams. Quoting J. Richard Hackman, the writer of the book “Leading Teams: Setting the Stage for Great Performances.”, “My rule of thumb is that no work team should have membership in the double digits, and my preferred size is six.” The design has to be broken down into smaller features that the teams can then start working on separately. My personal experience in working with teams has shown that they should also be given autonomy on how to exactly implement the feature. This empowers them to actually make their own choices on the implementation details while still retaining control over the overall implementation. No autonomy, on the other hand, has lead to team members just waiting for new tasks without thinking themselves about how to proceed.

I also feel that hierarchy is important to some extent. People have to be empowered and be given the choice to do things in a certain way but hierarchy can make sure that the process continues smoothly with someone having the last say. As a person in a leading role it’s important to guide people in a certain direction and listen to them instead of just bossing around. People tend to lose their creativity around people with a “my way or the highway” attitude.

Team sizes have been more of an issue in game development than in IT projects. Those projects have usually required smaller teams with a few exceptions. But if you are working on a large software project where team sizes grow you will still be faced with the same issues as in game development and I would argue that the same solutions will work, in most cases at least.

What about art?

You might have noticed that I have not spoken much about art yet. This is where the IT projects I have been working on and the games I now make differ the most. At Bugbear we have a legion of artists and level designers that create the actual content for our games. In addition to game designers, this group of people comes up with a large portion of our functional requirements.

Many of the software projects I was developing actually had a heavy focus on content as well. It was not sound and visual arts like here at Bugbear but it was content created by the customers to make the software functional. Starting to use a certain system usually meant giving our customer the necessary tools to populate the new system with information. This meant that project management would have to shift a bit at the late stages of the project to facilitate those needs.

To some extent you can think of the content teams as internal customers with programmers building the tools for them to build the game content you see on the screen and hear through your speakers. Their requirements play a big role in how we design our features and how they are prioritized.

Conclusions

I hope this discussion goes to show that there are many similarities in the types of projects I have worked on in the IT industry and the projects I currently work on. This basically comes from the fact that in both industries we are working on a system that has a user interface, is interactive and has some kind of content. This is why I encourage you to keep your eyes open for ideas that come from other industries and think about how they could be applicable in your field of interest.