The Six-Month Report

Six months ago, I left a six-figure job as a Software Development manager at Amazon.com so that I could start my own Video Game Studio, SyncBuildRun. I walked away from an amazingly productive team that I loved working with, a supportive manager, and opportunities for career growth at a top tech firm. I had over $100k in cash and stock saved up, a supportive wife, an ambitious idea, and a plan. Here’s what went right and a little less-than-right over the previous six months.

What went Right?

Mentors – Before I started this adventure, I set up a series of recurring appointments with industry veterans that I respected, who had a history of success. I’ve met with startup founders, technical experts, game designers, public speakers, and more than a few accomplished VP and C-level executives. Keeping these conversations going, getting their opinions, asking the right questions, and keeping abreast of the problems right around the corner has been invaluable in making sure we’re always marching forward. I am deeply in debt to every one of my mentors, and thankful for the time that they spend with me.

Great Hires – Hiring is difficult. It’s easy to hire poor performers, but very difficult to hire solid contributors. I’ve been lucky with the three contractors that I’m working with most closely, in that their contributions have really raised the bar for what this project can be. So far, we have defined the look and posture of the main characters, the overall themes and tone for the soundtrack, the title sequence for each episode, and the setting and story arc for the overall game. I’m happy to work with this great team, and I hope to be able to continue to work with them as the game progresses, but I wouldn’t hesitate to recommend any of these guys for another project.

On Budget – When I started, I estimated that I had about 18 months to 2 years of financial runway. Given the low figure I’m paying myself (enough to cover the mortgage and pay bills), plus other business expenses (paying the team, legal costs, overhead), I’m currently somewhere between 20% and 30% through my overall budget. In other words, I’m right on track for where I thought I’d be at this point in development.

Solid Concept – When I tell people about the game concept and about the Episodic format, the result is always the same: amazement and enthusiasm. The people with whom I speak about this game are excited to see it and play it, and when they ask the hard questions, they’re impressed by the answers. We’ve thought this through, considered the edge cases, and we’re doing something that’s really unique in gaming. I think people are going to love it.

What could have Gone Better?

Overly Optimistic Development Schedule – Like all software developers, I was highly ambitious with what I thought I would be able to accomplish in time. My initial goals were to have three game modes fully prototyped by the end of December. Not only did that missed milestone make a lovely wooshing sound as it flew by, but I decided to add a fourth game mode.  The upside is that I prototyped the most complex, risky, and difficult game modes first, and am currently running pre-alpha tests with a small number of players to get further feedback and refine these risky modes. The remaining modes are known quantities that will be familiar (and fun!) to many players, so I’m less worried about surprises there. Still, I wish I were about one month further along.

Some Hires Taking Too Long – Finding a production artist has been the most difficult challenge, and it’s not for lack of trying. There are lots of talented artists out there, but finding the ones who have art plus 2D animation skills, who are versatile enough, employable in the US, and available has been a challenge. We’ll also need some developers soon, but I’m less worried about that. Still, it would be great if everything regarding team building moved a little faster. I have found that this is true everywhere, so at least I know I’m not alone.

Marketing & Business Surprises – The biggest miss to date was not having a solid Go-To-Market plan, and this includes a strategy around how we announce, whether we do a Kickstarter and how we do it, how we get press coverage, how we determine our customer base, and so on. We’re about to sign a contract with a dedicated PR person, and we’ll have a nice website with plenty of pictures, video, and information on it pretty soon. This area is difficult because there’s no “one right way” of doing PR and becoming a known quantity, but six months of stealth mode seems like an eternity, and it’s time to emerge from the cave and show the world what we can do.

Various Little Problems – Then there are all the little issues. Problems with Code Signing Certs. Problems with various business people who are late, or don’t return phone calls. Problems with contract revisions. Problems with web databases. Problems with code that works in one environment but not another. They’re all solvable, but they become death by a thousand cuts if they’re allowed to pile up. Such is running a business, and honestly, at least here I have control over what to focus on and what problems to swarm on. That beats the seemingly random tossing and turning that can be endemic at larger, more bureaucratic companies.

What’s Next?

We’re weeks away from announcing our game, figuring out a Kickstarter strategy and timeline, doing a Steam Greenlight campaign, and ramping up our team to full production capabilities.  If we’re smart, diligent, and focused, by this time next year we should be about midway through the first season of our first episodic title. We’re super excited to announce and make players happy, and while there will doubtless be more bumps along the way, I think we’re in for a really great adventure.

Strategies for Success

I often wonder if I’m repeating myself with some of the stories I share, since I share them so regularly with different groups of people. However, a former CEO reminded me that it can take up to six times of repeating something for the message to really sink in, so I don’t lose sleep over it as long as I’m not boring my audience.

That said, there are a few key lessons that I learned from various leaders that I would like to share.

Shotgun Your Success Strategies

The first strategy is from a CEO who spoke at the World Business Forum in NYC. Her advice was, when approaching any goal, don’t just try one approach at a time. While it’s the scientific method to alter a single variable through multiple iterative approaches, time is too critical to waste running linearly thorough strategies. Instead, do many many approaches at once, like ten. Shotgun a bunch of methods, so that if seven of the ten fail, at least three will drive you towards success.

Big companies do this all the time with interviewing. When they post a job, they don’t just talk to one person at a time, make a decision, then move on to interview the next person. Often, they’ll interview several people in the same week, perhaps even in the same day, for the same position. Some will inevitably have other offers, will bow out, or won’t make the grade. But of the many people interviewed, one or two will at least be qualified and a good fit, assuming the prescreening process at the company is decent.

At SyncBuildRun, we realized we couldn’t just work on code all the time, we needed to also think about title videos, concept art, music, marketing, financing, etc. About half my time every day is spend writing code, but the other half is spent talking with my contractors, reviewing their work and providing feedback, handling legal and financial issues, speaking with advisors, interviewing potential partners, and doing forward planning. Even if one of these areas falls behind, I know I’m making progress on the rest of them, so overall, we’re okay.

Aim Higher Than Everyone Else

This one is from film director James Cameron, also at the World Business Forum. Jokes about his supposedly enormous ego aside, Cameron had it right when he was talking about how he approached making truly groundbreaking films. “I aim high, really high, way higher than anyone else. Then, even when I fail at a few things that knock me back, I’m still succeeding at a level well above where everyone else was even aiming.”

Amazing for both it’s hubris and it’s brilliance, this strategy has also served us well. While other game companies are eager to make the next Match-3 or Angry Birds clone, we’re aiming much higher with a long-term customer engagement strategy of multi-episode games that last for months, with content at a continuous weekly cadence. Sure, a one-off game would be easy, but we want to aim big. If we fail, we release a one off game. Going the other way would be nigh impossible. Our goals are actually a lot bigger than that (a lot), but I don’t want to spoil everything here.

Which leads me to my one bit of cautionary advice about this strategy: Aim high internally, but meter your external communication with your customers so that you don’t disappoint them. It’s far better to under-promise and over-deliver than the other way around, and if you’re aiming high internally but being conservative with your promises outside the company, you’ll be set up for success when you ship.

Cross Coverage is Critical

It’s great to have subject matter experts on staff, but it’s better to have folks around who know a bit about each others job, so that they can contribute constructively. Lane was one of the most fun, and most talented guys I ever worked with, and he had the role of “Technical Artist”, which meant that he made content and wrote code, basically did whatever needed to be done, to get some weird cool effect on screen. When we were trying to relaunch the Space Quest franchise at Escape Factory, Lane was tasked with Roger Wilco’s vacuum cleaner “weapon”, which needed an animated cone in front of it to display the area of effect. The cone didn’t track the player correctly, and was animating oddly. Sure, an artist and developer together could have worked this out, but Lane jumped in, fixed the content, and wrote the code to make it work the way the designers wanted.

This isn’t a call to hire people who are jack-of-all-trades. Rather, it’s a statement that your team should know enough about each others job that 1) they can contribute constructively about various topics that come up and not just the easy to discuss topics, and 2) they can cover for tasks outside of their direct area of expertise when someone is inevitably out sick or away on vacation. At AMZN, we had a rotating on-call system, where every dev would be on-call for a week and would have to handle whatever external or customer crisis came up. It always sucked, especially for the new hires who rarely knew what to do. I solved this by starting an on-call wiki for our group, where every time a problem came up that was new, the on-call person was required to document what the problem was and how they fixed it. Then, we would review the documentation as a team, and ensure everyone was on the same page. Stress around on-call immediately dropped, because instead of being a source of tension about the unknown, it was now a learning opportunity and a chance for cross pollination. Junior devs learned from senior devs, and senior devs got to watch junior devs automate away their ten step process with a 20 line Perl script. Everyone learned something.

The final bit about Cross Coverage is that it shouldn’t just apply on your production team. Ensure that you have this on your board, across your advisors, and on your executives. Have multiple people who know finance, not just your CFO and directs. Hire musicians, so that lots of people can discuss the feel, mood, and tempo of your soundtrack in actual musical vernacular, instead of just telling your contract musician “I don’t know, it needs to sound more purple.” Having groups of people who speak the same language is critical for successful and productive communication.

 

Reputation

Perhaps one of the least talked about aspects of building a product, team, or company, is the network of advisory relationships that leaders must build in order to be successful themselves.  These relationships can start before a leader even considers their own project, team, or company, and the personal brand that you’ve built since probably the High School era can come into play with how those relationships play out.

I make no effort in hiding the fact that, in my younger days, I was a jackass online. I got into public arguments over trivial crap, made blatantly inappropriate comments, joked about things that were extremely off-color. I don’t necessarily regret this, but there were certain things I was careful about. When I was snarky or sarcastic, I at least aimed my comments at an audience who would understand my sarcasm (mostly friends). The same with my weird sense of humor. At the time, forums like LiveJournal didn’t have the tight privacy controls that Facebook currently has, so, taken out of context, I’m sure many of my online comments would cast me in a poor light. I’ll own up that.

Still, I was careful to always treat hard working people with respect, whether they were leaders or individual contributors.  Even when I disagreed with peers or leaders, I made sure to note that it was their ideas that I had problems with, not them as people. When I committed to a task, I did my best to always complete that task to the best of my ability, and often this mean stretching my abilities. I didn’t alway succeed, but when I fell short, I owned up to it, and found a path out. When I did succeed, I shared the win with everyone who contributed. I behaved ethically at all times, always looking out for the best interest of my employers and my teams.

These actions have, over nearly two decades, paid dividends. I have advisors who are senior executives at major tech corporations, I have peers and other game leaders who take me seriously and answer my emails/phone calls, I have multiple high net-worth individuals and groups who talk to me about investing in my ventures, and I have a wide swath of people who are eager to work for or with me again. I’ve done pretty well at managing my personal brand, and a great book on this topic is Career Warfare, which I recommend you pick up and read immediately.

I mention this not to brag, but because too often I see many people walking down the wrong path. This can be as simple as constantly posting questions in online forums, questions to which the answers are easily available via Google. This sets up a personal brand associated with laziness at best and opportunism at worst. I have seen people who know they have deficiencies in their writing style or code polish, but instead of acknowledging it and coming up with a plan for improvement, they shrug and say “what can I do?”  You can discuss a path to fixing it, that’s what! I have heard (and luckily not seen firsthand) the tales of embezzlers and frauds who, once discovered, were never able to work in their industry again, nor in their city in any capacity, because of their reputation. All of these are easily prevented.

Yes, how you act will follow you around. Yes, the game development community is small and people will know your name. Software development is not quite as small, but word still gets around. There are no quick paths to success, and while brand management can be overdone to the point of appearing fake, keep in mind that what you do and how you act in your early attempts will impact the opportunities that open up to you later. It’s not necessary to win every online argument, nor is being the “hero” for every team win indicative of your personal success; it may come across as hogging the spotlight. Understand how you are perceived by others, demonstrate a consistent value add, show passion and enthusiasm for your work, and soon enough, you will be surprised at the opportunities that present themselves to you.

Don’t close the door on possibility, do things that open doors up ahead of you. It’s best to be able to take your pick of multiple opportunities than to have to follow the only path available.

Animation Subsystem

In this part 2 of 2 posts, I’m going to describe an animation system that I’ve used for quite some time. There are a few tricks that are slightly clever, and the system allows for a lot of complexity with a fairly simple framework. If you haven’t read my previous post about the Display/Logic split, you may want to get through it for a bit of context for this section.

Previously, I discussed how we would handle game logic in one class, and the display of the game state with a separate class. In typical casual games (poker, match-three, and jumping games for example) what I would do is have the logic update the game state all at once, and then have the display “catch up” by playing pretty animations. Of course, we could just have the display instantly match the logic, but that’s not quite as magical for the player.

While there are plenty of tweening and motion animation libraries that are available on the internet, I realized that I needed to solve a different problem: Sequencing. For example, let’s say that we have some Checkers-type game, where the player jumps pieces on a board over other pieces, making the jumped-over pieces vanish for points. There are score multipliers for many jumps in a row, and we want to communicate the score progression and the multipliers to the player.

Given our previous discussion, we may have our Display handle mouse clicks that select a board square with a piece to jump, or with a destination for that piece to jump to. The method in IGameLogic may be something like playerClickedSpot(x,y), where x,y determines the board square that was clicked.  There are many different things that can happen to that board spot. Maybe there’s nothing there and the click causes no action. Maybe a player clicks a game piece they can’t move. Maybe a player clicks a piece they can move, then clicks an invalid jump destination. Maybe they’re rapidly clicking a series of valid locations. We need to handle all of these in a way that makes sense to the player.

As I stated above, we typically have the game logic update the game state instantaneously. This example isn’t for a physics based FPS where we would have the logic track the arc of the jump curve for the piece on a frame-tick counter. It’s fine for the logic to instantly move a piece from origin to destination and tabulate the new score, as well as track any multipliers.  This way, we know if a subsequent input is valid or not, which is important.

So our game logic can respond by respectively calling methods exposed in our IGameDisplay interface such as NoAction(), InvalidPiece(x,y),  PieceSelect(x,y), InvalidDest(x,y), PieceJump(startX, startY, endX, endY, jumpedX, jumpedY, totalScore, multiplier). These are fine methods that the Display can respond to, perhaps by playing a buzzing sound for InvalidPiece or InvalidDest while wiggling the selected piece on the board. For PieceJump, we can kick off the motion of the jumping game piece, and update the numeric score. If multiplier is nonzero, we can show another fancy number floating upwards while playing a great sound.

But how do we know exactly when to do these things on the Display side? And what about that last case, where the player rapidly clicks a series of valid jump destinations in order? If the logic updates instantly, and calls back to display with a new PieceJump call instantly, won’t those motions override each other, confusing the player?  Yes, so we can’t handle the updates instantly on the display side, and we need a way to sequence those animations.

This is where the AnimationSequencer comes in. The AnimationSequencer is a class that handles ordering and playback of animations in our game. Every animation that it handles implements an interface, IAnimation, which exposes the following methods:

  • start()
  • tick(deltaT)
  • finish()
  • isStarted()
  • isComplete()
  • isBlocking()

Let’s focus on that last one, isBlocking(), because that’s the key to a huge amount of power here. Every class that implements IAnimation must set whether or not it is blocking, either as an option in the constructor, or as a default. Blocking is just a flag, true or false, either this animation blocks or it doesn’t.

The rest of the methods are straightforward. Start does setup, and is called on the first frame (if isStarted returns false). Tick is called every frame thereafter, and when the animation realizes it is done, it internally calls finish on itself, which will set the isComplete flag to true.

Here’s an example concrete class for doing linear motion:

package com.syncbuildrun.Engine.Animations
{
	import flash.display.DisplayObject;

	public class LinearMoveAnimation implements IAnimation
	{
		protected var m_started:Boolean;
		protected var m_complete:Boolean;
		protected var m_blocking:Boolean;
	
		private var m_element:DisplayObject;
		private var m_startX:Number;
		private var m_startY:Number;
		private var m_endX:Number;
		private var m_endY:Number;
		private var m_time:Number;
		private var m_totalTime:Number;
		private var m_preDelay:Number;
		
		private var m_deltaX:Number;
		private var m_deltaY:Number;
		
		public function LinearMoveAnimation(element:DisplayObject, startX:Number, startY:Number, endX:Number, endY:Number, time:Number, preDelay:Number,isBlocking:Boolean)
		{
			m_started = false;
			m_complete = false;
			
			m_blocking = isBlocking;
			m_element = element;
			m_startX = startX;
			m_startY = startY;
			m_endX = endX;
			m_endY = endY;
			m_time = time;
			m_totalTime = time;
			m_preDelay = preDelay;
			
			m_deltaX = m_endX - m_startX;
			m_deltaY = m_endY - m_startY;
		}
		
		public function start():void
		{
			m_started = true;
			m_complete = false;
		}
		
		
		public function tick(deltaTime:Number):void
		{
			// empty function
			if(m_preDelay > 0.0)
			{
				m_preDelay -= deltaTime;
				if(m_preDelay <= 0.0)
				{
					m_element.x = m_startX;
					m_element.y = m_startY;
				}
			}
			else
			{
				m_time -= deltaTime;
				
				if(m_time <= 0.0)
				{
					return finish();
				}
				
				var percentage:Number = 1.0 - (m_time/m_totalTime);
				
				m_element.x = m_startX + (m_deltaX * percentage);
				m_element.y = m_startY + (m_deltaY * percentage);
			}
		}
		
		public function finish():void
		{
			m_complete = true;
			
			m_element.x = m_endX;
			m_element.y = m_endY;
		}
		
		public function isComplete():Boolean
		{
			return m_complete;
		}
		
		public function isStarted():Boolean
		{
			return m_started;	
		}
		
		public function isBlocking():Boolean
		{
			return m_blocking;
		}
	}
}

The AnimationSequencer operates on the frame tick of our game, so it’s called by the onEnterFrame method of our IDisplayLayer. The Sequencer has two data structures, a queue and a list. The queue is a pending queue; The rest of our code adds animations to be played into this queue. The list is the current playing list; The Sequencer ensures that the animations in this list are playing, or clears them out when they are complete.

Here’s the magic: Every frame, the Sequencer first checks if there are Blocking Animations in the list. If there aren’t, it starts pulling IAnimations from the queue until either the queue is empty, or there’s a blocking animation in the list. Then it stops, and services the IAnimations in the currently playing list by calling tick (or start). It checks every animation that is started to see if isComplete returns true, in which case it pulls that IAnimation from the list and discards it – it’s done. If a Blocking Animation was removed, the next frame we’ll pull more animations from the queue onto the list until the above conditions are met.

AnimationSequencer

This seems incredibly simplistic, but it affords amazing power. Now, by correctly setting queued animations as blocking, we can control the order and pacing of every update from the Game Logic. In our above example, where we get a first call into PieceJump(), we might queue up the following animations:

  • PlaySound(jumpSound)
  • ScoreRollup(newScoreval, duration=1sec)
  • PieceJump(selectedPieceSprite, startX, startY, endX, endY, duration=1sec, BLOCK)
  • PieceRemove(removeX, removeY, BLOCK)

Our Sequencer will start playing a sound, start rolling the score up to the new value from the presently displayed value, and will start the selectedPieceSprite jumping from the board square at StartX, StartY to the square at endX,endY over the duration of 1 second. Because this last animation is blocking, it will wait until that completes before it pulls PieceRemove into the list, which will vanish the just jumped piece at removeX, removeY.

But wait, half a second into this, the player clicked another square for a second valid jump. Now we get a call into PieceJump() while these animations are still playing. But that’s fine! Because now we add the following to the queue:

  • PlaySound(jumpSound)
  • ScoreRollup(newScoreval, duration=1sec)
  • FloatMultiplier(removeX,removeY, MultiplierValue, duration=0.5sec)
  • PieceJump(selectedPieceSprite, startX, startY, endX, endY, duration=1sec, BLOCK)
  • PieceRemove(removeX, removeY, BLOCK)

We added a multipler float up animation, but that won’t start playing until the first PieceRemove from above has finished. All these new animations will sit and wait until the first move completed, and then they will proceed in a normal fashion, which is what the player expects.

Here’s the tick function for our Sequencer:

public function tick(deltaTime:Number):void
{
	var blockerExists:Boolean = false;
	var removeArray:Array = new Array();  // of ints
			
	for(var i:int = 0;i<m_activeList.length;i++) 
	{ 				
		var anim:IAnimation = m_activeList[i];
		if(anim.isStarted() == true) 
		{ 
			anim.tick(deltaTime);
 		} 
		else 	
		{ 
			anim.start(); 
		} 				 
		if(anim.isComplete() == false) 
		{ 	
			blockerExists = blockerExists || anim.isBlocking(); 					
		}
 		else
		{
 			removeArray.push(i); // add index of finished anim 				
		}
 	}
 
	// now walk backwards to remove finished anims from the active array 							
	for(var j:int=(removeArray.length - 1);j >= 0;j--)
	{
		m_activeList.splice(removeArray[j],1);
	}
			
	while(blockerExists == false)
	{
		var newAnim:IAnimation = m_pendingQueue.shift();
		if(newAnim != null)
		{
			blockerExists = blockerExists || newAnim.isBlocking();
					
			m_activeList.push(newAnim);
		}
		else
		{
			blockerExists = true;
		}
	}
}

Two final notes: First, PlaySound is not really an animation, but we can queue anything into the AnimationSequencer that conforms to the IAnimation interface. In fact, I found one of the most useful animation types is the BlockingDelayAnimation. It doesn’t affect a single thing on screen, but it takes up time, and it blocks further animations down the queue. It’s very useful for pacing apart screen events into digestible chunks for the player.

Second, I stated above that an IAnimation will call finish on itself when it reaches the end of it’s runtime inside of the it’s tick method. However, exposing finish via the interface allows us to have a clean way to skip animations while ensuring that everything winds up in the correct final position. If you want to allow players to skip through sequences, or you want to shut down all animations before leaving a display mode, simply call finish() on every animation in the list and then every animation in the queue in order. If the Animation classes correctly put all of their final object positioning/state/whatever code in the finish method, then everything will look exactly as if all the animations had completed normally.

A Framework for Screens & Logic

I’m going to dive into some software architecture for a little bit and describe the system that I’m using for overall interactions and screens in our game. This is the first of two posts on this topic.

In developing many games, one problematic thing I’ve seen is that developers or teams start out by rolling some high performance 3D rendering system, and the first time they run the game, they boot right into some 3D world with a few models to control and drive or shoot or whatever. They pat themselves on the back, and they pull up a clever console so that they can load a different level or model or racetrack, and then cheer because they think they’re 90% of the way done to building a great game.

They’re wrong.

There are so many other things that go into making a game, and certainly into making a game that is user friendly.  These things are often forgotten until near the end of the production cycle, which is why there are countless games with terrible audio, music, menus, transitions and so on. It’s why I chose to solve this problem up front (even though I do have a console) and develop a good system for switching between game modes, as well as segmenting my display and logic functionality.  Here’s what I did.

Because this game is built off of Adobe’s AS3/Flash, I knew I had to handle three very specific events in my top level Game Loop: Frame Enter, Key Up, and Key Down. Everything else we can handle separately. When the game starts up, it sets up listeners for those events at the highest level (the stage) and assigns methods in my base game engine to respond to those events.

Next, we set up an interface: IDisplayLayer. This interface defines a contract of a set of methods for any “mode” of the game, whether it’s a menu, a settings screen, a game mode or a minigame. Every IDisplayLayer exposes the following methods:

  • onKeyDown(keycode)
  • onKeyUp(keycode)
  • onEnterFrame(deltaT)
  • show(previous)
  • hide()
  • load()

There are a few others, but they’re not that important for this discussion.

Any game modes are classes that implement the IDisplayLayer interface. I’ll get into their internal logic below, but from the point of view of the game engine, all it needs to know about is which IDisplayLayer is currently active, which it tracks in the variable m_currentDisplay. Because the base engine is handling keyboard input and frame updates, our handlers for those events simply call m_currentDisplay.onEnterFrame() with the current time difference from the last frame. The same goes for keyboard events.

The great part about this is that when we switch game modes, we automatically pause that mode. An inactive IDisplayLayer no longer receives frame ticks, nor responds to keyboard input, because the engine doesn’t pass those events along. You would not believe the number of poorly written codebases where seemingly random things would happen while typing, all because some invisible screen was still responding to keyboard input. This avoids that entirely.

The other methods, show() and hide(), allow us to do cleanup or setup as we switch between IDisplayLayers.  Flash uses a nested hierarchy of DisplayObjects (or a “scene tree”), where each object is a child of the stage, or another object. If a higher level object is made invisible, or deactivated, all it’s children are also invisible. Thus, for each display layer, the engine creates a parent sprite that the display layer attaches to inside of the load() method. The engine can then hide that display by setting the parent sprite visible property to false, or show it by setting visible to true. When we switch displays, first we call m_currentDisplay.hide(), which gives the display a chance to do any housekeeping for going away, like finishing up an animation (see next week’s post). It also sets the parent sprite visibility for m_currentDisplay to false.  Then the engine calls show() on the new IDisplayLayer that we want to show, which sets the parent sprite visibility to true as well as doing any return housekeeping, and then set m_currentDisplay to be the new display layer.

public function display(newLayer:IDisplayLayer):void
{
    Debug.assert(newLayer != null,"EngineBase:display() - parameter 'newLayer' was null");

    if(m_currentDisplayLayer)
    {
        m_currentDisplayLayer.hide();
    }

    newLayer.show(m_currentDisplayLayer); // Pass in the old layer in case it needs to know
    m_currentDisplayLayer = newLayer;
}

What about setting up those IDisplayLayers internally? We want to separate out the display from the logic for each game mode, because we don’t want the complexity of how the world is displayed to be closely coupled with the underlying data that represents it. We may want to start with numbers or text for a display, and then move to animated shapes, but none of that should affect the underlying data representation.

We also want to ensure that these classes are loosely coupled. If we make changes in any one file, we shouldn’t have to recompile a whole bunch of other files. So we need to minimize the dependencies between classes. Luckily, Interfaces and Factories come to the rescue!

Each display mode gets a concrete implementation class, let’s say GameDisplay, that implements the IDisplayLayer interface so that the game engine can interact and communicate with it. GameDisplay is responsible for all non-keyboard input (mouse interaction), graphics, audio, running animations, etc. but it doesn’t really understand anything about the underlying game mode logic. It has two responsibilities: First, handle input, and second, show pretty things on the screen (as well as play nice sounds).

GameLogic is a separate class that does everything GameDisplay doesn’t do, and nothing that it does. GameLogic tracks the game state, maybe the position of pieces on a board, it understands the logic of valid and invalid moves, scoring, and so on, but it doesn’t care about what these things look like. In fact, one could write several different GameDisplays that interact with the same GameLogic, and these would just be different ways of visualizing the game. Likewise, one could create multiple GameLogics for the same GameDisplay, maybe like different game modes, and they would just run different rules.

So it’s good to separate these two out. And while it’s tempting to simply create a GameLogic right in the constructor for GameDisplay, that’s a path fraught with disaster.

private var m_logic:IGameLogic;

public function GameDisplay()
{
    m_logic = new GameLogic(this); // DON'T DO THIS
}

Why? Well, compiling is still fast, but if you just create the logic directly, every change in GameLogic will force a recompile to GameDisplay. Also, every public function in GameLogic will be exposed to GameDisplay, and you may not want that. GameLogic may need to communicate with other classes via public methods, but some new developer to the project may not know which methods are okay and which are verboten, creating complexity, confusion, and the opportunity for bugs.

So we’re a little clever about this. Some may say too clever. However, we’ll solve all these problems with two more Interfaces, and a Factory Design Pattern. First, we’ll figure out all the methods in GameLogic that GameDisplay needs to call. We’ll put those methods in the IGameLogic Interface. Next we’ll figure out all the methods in GameDisplay that the logic needs to call back into, and we’ll put those into IGameDisplay. GameLogic will implement the IGameLogic interface, and GameDisplay will implement both the IGameDisplay and the IDisplayLayer interfaces.  Now, we can make the constructor to GameLogic take an IGameDisplay as a parameter, and pass in this when we instantiate it in GameDisplay, returning an IGameLogic reference.

public class GameLogic implements IGameLogic
public class GameDisplay implements IGameDisplay, IDisplayLayer

But isn’t that what I stated not to do above? It is, because GameDisplay still needs a reference to GameLogic in order to construct it, when all we want GameDisplay to have is a reference to the interface IGameLogic. Enter the Factory.

public class LogicFactory
{
    public static function BuildLogic(display:IGameDisplay):IGameLogic
    {
        return new ICEHackerGameLogic(display);
    }
}

Now, GameDisplay constructs it’s reference to IGameLogic like this:

private var m_logic:IGameLogic;

public function ICEHackerGameDisplay()
{
    m_logic = LogicFactory.BuildLogic(this,target);
}

No GameDisplay is entirely decoupled from the concrete class of GameLogic.

Five Classes - New Page

This seems like a bit of complexity to get some straightforward functionality, but it winds up paying off in testability and maintainability. The first part allows us to quickly spin up new game modes by developing a class that implements the IDisplayLayer interface, and we know our engine can handle switching to and from this screen with ease, and also without breaking any existing screens. Likewise, we can create new game modes that are easily maintainable and decouple logic from display simply and quickly, while defining straightforward methods of communication between those modes.

Next week, I’ll talk about the animation system that we use, and how it solves some clever problems.

Top Games of 2014

As an indie game developer, and also a game afficinado, I thought I’d share my list of the top games of the year. The key for me this year was emotional reactions, as three of my top five games took me down paths of genuine fear, sadness, or anger, more so than any game I’ve played before.

1) Alien: Isolation

SEGA took a big risk creating a game that was part stealth, part AI experiement, and part retro-homage to a classic 1970’s horror sci-fi film. The meticulous recreation of the environments and technology, the pacing, and yes, the terrifying unstoppable alien itself, made for a genuinely scary game where I spent more time looking at the inside of a locker than exploring a space station. Yes, it was too long, and yes, the final levels with the facehuggers and multiple aliens devolved into Dragons Lair style gameplay, but at it’s best, when avoiding the lurking killer that was the solitary Alien itself, this was terrifying genius style gameplay.

2) Watch Dogs

Perhaps my most anticipated game of the year, an excellent single player adventure, great DLC, fun hacking mini-games, and a surprisingly addictive asymmetric multiplayer experience made for a well rounded fun twist on the open-world city-style of games. Ubisoft has a great new IP on their hands, and I’m looking forward to what’s next from the Watch Dogs universe.

3) This War of Mine

Crushingly depressing, this indie game came from out of nowhere to display the terrible cost of war on the civilians caught in the crossfire. With refugee after refugee in my stead, every passing day was a challenge to keep them fed, warm, healthy, and rested. It was a challenge at which I often failed. The glory of this game is not just the setting and interaction, but the despairingly beautiful art direction and the moral choices that the player is forced to make to keep their house of people alive. Every politician should be forced to play this game before taking office.

4) Desert Golfing

The only mobile game (iOS) on my list, Desert Golfing (or “Space Golf” as my wife likes to call it) is freakishly addictive in it’s simplistic simulation. It doesn’t matter that there’s no reset of the score, nor leaderboards, options, or any control other than the swing of the ball. Some of the holes are ridiculously difficult. The game is the mobile equivalent of a long mountain hike: we keep marching on because it’s there.

5) The Walking Dead: Season Two

Although the season officially kicked off in 2013, Episode 3 “In Harms Way” produced perhaps the most fierce emotions I have ever felt for a fictional video game villain. Never before in my life have I so savagely desired to beat someone to death as I did the character of Carver. Overall, the storytelling was decent, and the gameplay not much of a change over Season One, but from a characterization and emotional journey standpoint, The Walking Dead surprised me with how it made me feel, and forced me to reexamine my moral compass.

 

Honorable Mentions:

Kerbal Space Program

Although released well before 2014, the 0.9 Beta released at the end of this year, bringing together many parts that make Kerbal feel really complete. I must have wasted endless days getting my little green men into orbit, on other stellar bodies, and just playing around with orbital dynamics and building stations. Kerbal really feels like a solid game at this point, with a well balanced progression system that’s more than just Science points.

Mini Metro

An indie discovery on Steam, this game is just a relaxing meditation on multitasking. Great stylized graphics that match countless transit maps from around the world, a super simple user interface, and just the right level of challenge, I’m looking forward to the final release of this game in the upcoming year.

 

Everyone’s a CEO

Anyone can be a CEO on paper. All it takes, formally, is a few hundred dollars to file some paperwork, get a business license, be on file with the Secretary of State, State Taxation Department, and IRS, and BOOM, you can list yourself as Chief Executive Officer of a Company of One. It’s not difficult, and an extra $20 in business cards will allow you to pass out little bits of high weight paper that honestly truly represent that you own and run a business.

My business cards read “Founder and CEO”, which technically is true, since I did all of the above, and first and foremost, my primary job is to run a successful company. However, there’s a lot I leave off the table with that description. I don’t just sign contracts, set vision, hire people, and ensure that we have cashflow. I’m actually also the Lead Software Developer, the Lead Game Designer, head of HR and Recruiting, the Lead Concept Artist, the only Production Artist, COO, and head of Marketing. I am, wisely, outsourcing music and audio production, as well as video production, to highly skilled contractors far more talented than myself.

A friend called recently to ask my opinion of an opportunity he was presented with. It only took ten seconds for my alarms to go off, as the company he described was executive heavy and contributor absent; it was literally a company with a CEO and a CFO, neither of whom were well informed about their technology nor product space, but who wanted to hire my friend so that he could then go hire up a full team to do the actual work of making stuff to sell. I’m sure plenty of businesses start that way, but I get shivers just thinking about it, as I’ve seen far too many failures with that formula.

When I was Director of Technology at Novel, we had a team of about 20 people, all of whom were very bright and talented, but few of whom were very experienced. We spent a long time with a large staff focusing on the wrong things, and there was a large overhead at the top (myself included) who spent a lot of time doing things that neither contributed directly to revenue nor to a great product. We did raise some money, which is a measure of some success, but it wasn’t enough. When I left in September of 2011, I predicted the company would run out of money in about eight months. Novel shut down in April of the following year.

About a year ago, I met up with a peer Director from my Novel days, and we discussed where the team went, as well as what we could have done differently. In retrospect, we both agreed, we should have slimmed down the team considerably. Instead of being high level Directors, he and I, we should have focused more on actually creating the product ourselves. We could have been as productive (or more) with an experienced team of about eight, with far less overhead, as we were with a team of twenty mostly green employees.

When I look at the indie games that I really enjoy, like Braid, FTL, Kerbal Space Program, and even Fez, they were all made by teams of people who dove in and actually made the games, not by executives who outsourced or hired other people to build something as part of some title-inflation driven business plan. That’s the template that I want to follow personally, and it sets the baseline for a good set of questions if you’re evaluating a startup or small company yourself. Sometimes, you have to be like the Bobs from Office Space, and ask people at this prospective employer “just what would you say you do here?” If the company size doesn’t justify high level management, and the answer isn’t “make great games,” then perhaps you should look elsewhere.

Alternately, make your own great product. Then you too can be the CEO, and everything else.

On Other Stuff

A friend once commented that there is no worse situation than a developer working alone in a room. While that is certainly a rough summary of my day-to-day experience, I agree with the sentiment that a singularly focused individual will miss out on many factors that could be critical to a better project, or a larger success.

Every day, there are several blogs and websites that I read over my morning coffee: Gamasutra, the Indie Games weblog, Polygon, GeekWire, and TechCrunch.  Usually there, are only a handful of articles or posts that are interesting to me, but the 30 minutes I spend seeing what’s going on in the world helps me to refocus my efforts on the correct things. I can avoid walking down a poorly received path, or I can redouble my efforts on a track that is taking off in similar work.  A recent post lead me to this page and sample code, which I will probably use to help define the look of a major character in my game. Getting out of the room helps.

I also spent some time at an Indie Dev meetup here in Seattle. It’s good to see what other people are working on, understand their schedules and challenges, gauge how large their teams are, and meet people who could be helpful to us or that we could help out someday. It’s through these types of events that I tend to meet some excellent advisors, judges, testers, and sounding boards.

Again, just today I was turning a particular coding problem over in my mind. I knew I could brute force a solution with a series of conditionals, but it felt like there was a more efficient solution using a bitmask of some kind. I typed off a message to a friend proposing a solution, and just the act of explaining it lead me down to path of validating that yes, the solution would work, here’s how it would work exactly, and it would be more efficient.

Whatever you’re doing, get out of The Room. Right now, as we push into the final weeks of the Holiday Season, we have the opportunity to be surrounded by intelligent, driven people looking to contribute and help. There are great and powerful stories being told every day, but they won’t be found just behind a screen.  Experience the world. Interact. Learn something new. It will almost certainly change you for the better.

An Agile Process that Worked Well

My wife and I recently had a discussion about the Agile Methodology, and how I ran it for my teams.  She also manages large technical projects, but wasn’t familiar with Agile/Scrum/Sprints, so I spent a little time going over it with her. After thinking about it for a while, I figured this was as good a time as any to get my thoughts on Agile out there.  I feel like this is a post I’ve written already, somewhere, so if I’m repeating (or contradicting!) myself, I apologize for that.

Also, an upfront warning, I’m going to swear a lot in this blog post. I tend to swear when I have strong emotions about things that are broken, and I desperately want to fix them. I believe lots of things with software development processes are broken, so this will creep in. If this bothers you, you probably won’t be very comfortable in the software industry, and you certainly should not apply for a job at SyncBuildRun. There, you’ve been warned.

There are several good posts on how Agile has failed, and I certainly have my own thoughts. If one looks at the original manifesto, there are great intentions there. However, Agile either gets a bad rep, or it has become a strict ritualized process where any deviation from what was taught in a Scrum Master Certification Course is cursed as being “Not True Agile!”

So Agile can clearly be a religion, by which I mean that there are many people practicing it many different ways, some of them certain that their way is the right way, but with no clear scientific ability to demonstrate that any one way is better than any other. If there were a “right way” to do Agile, everyone would be doing it that way. Thus, it’s important to distil what matters about Agile, and why one should follow a Scrum or Kanban process, and furthermore which parts of the process to follow.

These are my tips and tricks. They may not work for you. They worked well for my teams. This discussion presumes some knowledge of Agile, but I’ll try to define things as I go if I guess that they’re not common terminology.

The goal of Agile is to deliver working software to the customer, as frequently as possible, and have it be the software that the customer actually needs (or says they need) even if requirements change along the way. That’s the crux of it.  The two most critical bits of process around this are 1) Communication, and 2) Iteration. Everything else is just details.

The typical Agile “work segment” is the Sprint, which is amusingly named, since software is often a marathon, and one does not typically complete a marathon well by running multiple short segments of it as quickly as possible. The Sprint is, typically, a two-to-four week period of work, during which a team signs up for a number of tasks, and then commits to complete those tasks by the end of that time period. At the beginning of the Sprint is a planning phase, and at the end there is a review phase (intended to be with the customer, be they internal or external, but rarely done so in practice) and a retrospective phase. Then the process starts over with a new Sprint.  Tasks are selected from the Backlog by the team based on an overall goal (or goals) for the Sprint, the tasks are “Story Pointed”, there may be a round of “Planning Poker”, then there are daily Stand Up meetings…  Oy, what the fuck are we even talking about anymore? This already sounds like a crazy cult activity.

Okay, so here’s what worked for my teams, and made them productive and happy. This is the result of running this process with four teams at Amazon and one team at Novel. I’ll almost certainly kick off the same process once we scale up at SyncBuildRun, but it will ultimately be up to the team to decide how to run their processes.

We keep a Backlog. This is just a list of all the things we believe we need to do. We know this won’t be complete, probably ever.  That’s fine, it’s a list, and we add or remove things from the list as necessary. We try not to spend a lot of time doing “backlog grooming” because most people would rather eat a bullet than sit through a grooming session. Maybe once a quarter we do a sanity check and blaze through the items looking for duplicates or bullshit tasks that have become meaningless in light of new discoveries.

We Story Point our tasks, usually at the beginning of a Sprint. Actually, we do two rounds of Story Pointing (which is atypical), and I’ll get to that in a second, but first I want to talk about what Story Points are. For a long time before Amazon, I was convinced that Story Points should reflect the amount of time required to complete a task. Even at Amazon, I had multiple discussions with TPMs (Technical Program Managers, a thankless job of coordinating people, requirements, and schedules that often resulted in someone quitting because management did not want to hear how an insisted-upon timeline was impossible no matter how the numbers were massaged, but I digress) about what Story Points meant, and it took almost a year to arrive at my own clear conclusion.

Story Points are numbers assigned to the larger “tasks”, called Stories because they are usually a story about a user, as in “as a user, I want to be able to load a document”. Story Points are a number from the Fibonacci Sequence (1, 2, 3, 5, 8, 13, 21…), and they are chosen from this set because Story Points are a combined metric of time and uncertainty. Read that sentence again; Story Points do not simply measure the time it will take to complete the functionality for a Story, they also measure how much “unknown” there is about getting it working correctly. Thus, a 1 point task may take a day or less to complete, and it is absolutely obvious to the developer what code they have to write (“I need a class that stores two floats and a string, and it needs these four simple mathematical methods plus one getter for the name. 4 hours with unit tests.”). An 8 point task, on the other hand, may involve two or three weeks of work, and there is a large amount of uncertainty about how to do this work. (“Hmm, I know I need to do some network calls, but I don’t know if I need UDP or TCP. I may need some cryptographic functions too, but I’ll have to research what libraries are available…”).  A 21 point task is a multi-month research effort, and anything larger than 21 points should be broken down into multiple Stories of 21 points or less.

The goal, of course, is to break up Stories into a bunch of 5s or less; reasonable time periods of effort, manageable uncertainty. By manageable we mean, if the task slips, it only slips by two days, max. Typically a team will estimate Story Points on a per-story basis, and they may use special Playing Cards or index cards or hand signals… Don’t waste your time with this. If you have a good, solid team, with trust and good leadership, just have people call out their estimates. The manager or team lead should ensure that once in a while he asks the quiet guy or the new woman on the team what they think, so that it’s not just one superstar calling all the shots and being either aggressively optimistic or sandbagging everything. As your team builds up trust, your estimates will get better. Call out outliers, and if you don’t agree, ask some detailed questions. “Why do you think it will take that long? Is it really that easy? What are you uncertain about? Did you think about…” A good team can blaze through over a story a minute if they’re on the ball and they understand the stories well.  Again, the goal here is to wind up with a bunch of Stories for a Sprint that are mostly 5 points or less. A few 8s are okay. Anything higher should be broken apart into smaller Stories.

Okay, so that’s Story Points. If you can wrap your head around the purpose and usefulness that bit of bullshit terminology, everything else will be easy.

Now for the process. When I ran Sprints, I ran them in three-week cycles. However, we didn’t do Story Work for the full three-weeks. Those three weeks were broken up like this:

  • Monday Morning, Week 1 – Do Sprint Planning. Look at the backlog, see what we think we can pull into the Sprint, Story Point it and assign out tasks as a team. Spend no more than two or three hours kicking this off.
  • Monday Afternoon through Wednesday Morning – Prototype, Research, Investigate, Design, and talk to other teams. There will be unknowns and might be cross-collaboration required with other teams. This is an opportunity to reduce uncertainty, and ensure there isn’t anything that was forgotten. Do not write production code during this time.
  • Wednesday, 11Am – Sprint Planning, Round 2. Update the Story Pointing now that we have some solid data, pull stories from the Sprint if they’re the wrong stories or they can’t be completed, add new discoveries that fit into the Sprint, or put them in the backlog.
  • Wednesday Noon, Week 1 to Wednesday Noon, Week 3 – Work on those Stories, doing daily standups to track status on the Scrum Board, talk about issues publicly, commit to the deliverables for the next day, etc. Main thing is, for two weeks straight, the team does work.
  • Wednesday Afternoon, Week 3 – Pencils down, start testing and integrating. Any new check-ins from here on that are not bug fixes or integration fixes are a breach of trust.
  • Friday Noon, Week 3 – Sprint Review and Retrospective. If everything works, is integrated, “shippable”, and there are no bugs, great, we party or go home early. If not, keep working and maybe I’ll see you on Saturday. Success is a working, shippable build that is tested and integrated, not simply checked in code that kinda does what the customer wanted.

“But that’s not Scrum, that’s Scrumerfall!” some might say. These people should go work someplace else. Agile is not about always writing code all the time. It’s about delivering something solid to the customer. The up-front planning time is there to enhance communication, specifically between different teams, and reduce uncertainty. It is difficult to do this doing the work periods, but it is easy to do during collaborative periods and planning times. By allocating a full two days to this design and collaboration work, we increase the opportunity for understanding the potential complexity and interaction issues across teams and functional areas.

Likewise, the two days at the end reduce “Big Bang Integration”, and give the team an opportunity to test their code. Far too often, a developer has slipped in some large codebase literally in the last minutes of the Sprint, only for the rest of the team to discover that it changed APIs and broke contracts, requiring lots of extra integration work. The smug developer usually stands up proudly and says “well, I got my work done!” and then leaves others to clean up the integration mess he left. This is the kind of Difficult Genius behavior that we don’t tolerate at SyncBuildRun, and this process of baking in testing and integration time helps to eliminate and flush out these problems.

Why does this work? Solid teams who embrace this pattern know that every three weekends they can potentially go home early, and not have to worry about anything breaking. They start again the following Monday without a scramble to speed ahead as fast as possible, but to plan thoughtfully, and then to build on something that they know was solid from the week before.  They still get all the benefits of selecting their work, scoping the effort, adjusting to changing requirements on a three-week basis, and finishing with something solid, but they reduce uncertainty and increase stability. It’s a process for happy developers, and five teams of implementation has resulted in five happy, productive teams. It may not be the right Agile Process for your team, but there’s solid data that it’s a process that has worked for some very good teams of mine.