This post is part of a series of reviews on the book Head First: Object Oriented Analysis and Design. Check out the Introduction post for a full table of contents along with some initial notes.

Last chapter we worked on the whole baseline for our Game System Framework application by breaking it into a lot of small problems. In this chapter we’ll focus on the best way to get started on those problems and make sure we’re not wasting time on the wrong things.

We’ll start with the concept of architecture, which is defined by the book as an “organizational structure of a system, including its decomposition into parts, their connectivity, interaction mechanisms, and the guiding principles and decisions that you use in the design on a system”, it’s what transforms a bunch of spreaded resources such as the ones gathered last chapter into a well-ordered application.

Moving on from concept to practice, let’s decide a place to start off, which should be the most important features of our application (also named architecturally significant). To figure our what is architecturally significant, we use three questions called ‘the three questions of architecture’:

  1. Is it part of the essence of the system? Can the system survive without this? Is it really core?
  2. What does it mean? If you don’t know what a feature really means then it’s probably important that you pay attention to it so it won’t cause a mess in the future.
  3. How do I do it? Focus on features that you judge to be harder first or completely new to you. This way you avoid, again, causing a mess in the future.

With these we can figure out where to start, so let’s take a look at the feature list again and judge it with the three questions:

  1. Supports different types of terrain.
  2. Supports multiple types of troops or units that are game-specific.
  3. Each game has a board, made up of square tiles, each with a terrain type.
  4. Supports different time periods, including fictional periods like sci-fi and fantasy.
  5. Supports add-on modules for additional campaigns or battle scenarios.
  6. The framework keeps up with whose turn it is
  7. The framework coordinates basic movement

First and most obvious, the core feature is the board, you can’t have a game without a board (at least not one that depends fully on a board). Secondly, the units, without them there won’t be much action, will it? Lastly the basic movement part, it doesn’t sound too clear so we’ll need to spend some time on it. It really doesn’t matter which of these you start with because they’re all key.

Let’s start with the board module. It will basically be a class that will take a width and a height, filling it all up with tiles. Additionally we should have methods to return a tile at a given position, add units to a tile and return all units at a given position:

require 'tile'

class Board

  def initialize(width,height)
    @board = Array.new(width){ Array.new(height).fill(Tile.new) }
  end

  def tile(x,y)
    @board[x][y]
  end

  def add_unit(unit,x,y)
    @board[x][y].add_unit(unit)
  end

  def remove_unit(unit,x,y)
    @board[x][y].remove_unit(unit)
  end

  def remove_units(x,y)
    @board[x][y].remove_units
  end

  def get_units(x,y)
    @board[x][y].units
  end
  
end

Pretty simple, initialize starts by creating a two-dimensional array and filling it with empty tiles. The rest is just plain expressive, but note how we delegate most methods to the Tile class. And here it is:

class Tile

  attr_reader :units

  def initialize
    @units = []
  end

  def add_unit(unit)
    @units << unit
  end

  def remove_unit(unit)
    @units.delete(unit)
  end

  def remove_units
    @units.clear
  end

end

Each tile is supposed to handle units in it, so we start by having an array of them and methods directly related to arrays.

Cool, we got the first key feature done with, let’s move on to the next. Since we already started dealing with units, let’s jump to the ‘game-specific units’ feature. So we go ask the customer for what he meant and he starts pointing things out such as specialized unit properties, such as a tank with specific offense and defence, a space-craft with a certain model type and a special weapon. Sounds complicated when you look at it the way the customer said, but when you stop to think about what’s common between all these things, we’ll figure out that if we deal with ‘game-specific’ units as just units with different properties and types then everything becomes quite simple:

class Unit

  attr_accessor :type, :properties

  def initialize(type, properties)
    @type = type
    @properties = properties
  end

end

The unit type can simply be a string while the properties are a hash, with the key identifying the property name. We could have used inheritance, but then the game designers would have to create a class for each unit, which would lead to chaos in a game with 100 different unit types. This way it doesn’t matter if certain unit has offense or defence, or a specific kind of weapon, it will all be mapped by the properties hash.

Anyway, there’s another key feature dealt with. So we move on to ‘coordinating movement’, which was something we really had no idea of. We then go ask the customer and each ones comes up with things such as a move legality algorithm and factors that affect movement that would be different for every game developed. In this case, we’ve found more things that are different about a feature than things that are the same, so there might not be a good, generic solution for it, so as long as you explain to our customer that anything we build would just bring more difficulty to a game developer and thus generate a bad product, it’s OK to say ‘no’.

As strange as it might look, we’re done for the chapter. But wait, all we have are some key features that we finished and a few incomplete classes! Remember, the customer doesn’t pay us for great code, he pays you for great software, and as long as we’re on the way to delivering a solid project on time, it’s all good. Take a look back at our progress, we went from a bunch of spreaded documentation to a solid application structure that is well on it’s way to being finished, that is what architecture is all about.