Gameplay Balance in Breakout

Mon, Jun 13, 2011

Breakout is a simple game, but you still need to spend some time fine tuning the gameplay balance. Levels need to be created, level difficulty should be identified so that easier levels come early on, the ball speed and accelleration has to be fine tuned, along with the number of lives and scoring strategy.

Creating Levels

In a more complex game, an editor would be built for designing the levels, but for this demonstration I defined the levels in a simple ASCII format in levels.js.

Each level can define its own set of colors, each represented by a single letter, and the bricks are built up of repeating sequences of those letters. 2 bricks of the same color can be placed next to each other by toggling between upper and lower case, e.g:

Breakout.Levels = [

  { colors: {
      y: "#FFF7A5", // yellow
      p: "#FFA5E0", // pink
      b: "#A5B3FF", // blue
      g: "#BFFFA5", // green
      o: "#FFCBA5"  // orange
    },
    bricks: [
      "", "", "", "", "", "",
      "yyyyyYYYYYyyyyyYYYYYyyyyyYYYYY",
      "pppppPPPPPpppppPPPPPpppppPPPPP",
      "bbbbbBBBBBbbbbbBBBBBbbbbbBBBBB",
      "gggggGGGGGgggggGGGGGgggggGGGGG",
      "oooooOOOOOoooooOOOOOoooooOOOOO"
    ]
  },

  // more levels

This gives us a lot of flexibility over the levels.

  • Bricks can be any width we want
  • Each level can have an independent color scheme
  • Bricks dont have to have horizontal alignment

And allows us to build gimick levels, like Mario:

  { colors: {
      r: '#D80000', // red
      b: '#706800', // brown
      o: '#F8AB00', // orange
      f: '#F83800', // fire
      w: '#FFFFFF', // white
      e: '#FFE0A8'  // beige
    },

    bricks: [
      "",
      "    rRrRr                     ",
      "   RrRrRrRrR                  ",
      "   BbBoObo                    ",
      "  boboOoboOo       F    f   f ",
      "  bobBoOoboOo     f e         ",
      "  bBoOoObBbB       F  f     e ",
      "    oOoOoOo        Ff      E  ",
      "   bBrbBb        E  f fF F  f ",
      "  bBbrbBrbBb       FfFfFf  F  ",
      " bBbBrRrRbBbB     fFeFeFfFf   ",
      " oObrorRorboO    FfEeEeEfF    ",
      " oOorRrRrRoOo    FeEeWwEeFf   ",
      " oOrRrRrRrRoO   fFeFwWfEeFf   ",
      "   rRr  RrR     fFeFwWfEeFf   ",
      "  bBb    bBb    fFeEwWeEeFf   ",
      " bBbB    bBbB   fFfEeEeEfF    ",
      "                 FfFfFfFfF    ",
      "                   FfFfF      "
    ]
  },

Balancing Levels

It is important to play test the levels to identify which are easy and which are hard, so that new users get a gentle introduction and enjoy playing the first level but are also presented with harder challenges as they progress.

For this game, we start off with a slow easy level (see left), where each brick is wide and there are not many total bricks, so most players should be able to finish this level and get a sense of achievement.

After that it becomes a matter of tuning the levels to be progressively harder. This can only be done by play testing. It can be hard to predict which levels are going to be challenging.

For example, the following level looks fairly straight forward but turns out to be one of the hardest. We increase the speed of the ball on each brick hit, and in this level the ball can go off on a crazy ping-ping-ping brick hitting spree and suddenly come back towards the paddle much much faster than it left.

  { colors: {
      y: "#FFF7A5", // yellow
      p: "#FFA5E0", // pink
      b: "#A5B3FF", // blue
      g: "#BFFFA5", // green
      o: "#FFCBA5"  // orange
    },
    bricks: [
      "", "",
      "  yyYYyyYYyyYY  YYyyYYyyYYyy  ",
      "  bbBBbbBBbbBB  BBbbBBbbBBbb  ",
      "  ggGGggGGggGG  GGggGGggGGgg  ",
      "  ooOOooOOooOO  OOooOOooOOoo  ",
      "", "",
      "  yyYYyyYYyyYY  YYyyYYyyYYyy  ",
      "  bbBBbbBBbbBB  BBbbBBbbBBbb  ",
      "  ggGGggGGggGG  GGggGGggGGgg  ",
      "  ooOOooOOooOO  OOooOOooOOoo  ",
      "", "",
      "  yyYYyyYYyyYY  YYyyYYyyYYyy  ",
      "  bbBBbbBBbbBB  BBbbBBbbBBbb  ",
      "  ggGGggGGggGG  GGggGGggGGgg  ",
      "  ooOOooOOooOO  OOooOOooOOoo  "
    ]
  },

Balancing Ball Speed

Beyond making harder levels, the primary way to increase the challenge is to increase the ball speed. For this game I decided that the ball would not constantly accelerate (as I did in pong), but instead would increase in speed whenever a brick was hit.

So the more bricks you hit, the higher your score, but the faster the ball.

The challenge became making the ball speed up enough so that the earlier levels, with less bricks, did not feel boring, but the later levels, with more bricks, did not speed up the ball to unplayable speeds.

I did this by ensuring that (a) the ball has a maximum speed and (b) the speed increase is inversely proportional to its current speed. E.g if the ball is going slowly when it hits a brick it gets a large speed increase, but if it is already going fast then it only gets a small speed increase.

You can see this in the hitBrick method:

  hitBrick: function(brick) {
    this.court.remove(brick);
    this.score.increase(brick.score);
    this.ball.speed += 10 * (1 - (this.ball.speed / this.ball.maxspeed)); // decay curve - less accel over time (otherwise game becomes impossible)
    if (this.court.empty())
      this.winLevel();
  },

Once the basic equation is in place, it becomes a question of play testing to find the right constants to plug in to make the game ‘feel’ right.

Continuous Testing

There is certainly more work that can be done to make the current 10 levels more balanced. The current ball speed is probably a little too fast on the later levels where there are lots of bricks, and there probably needs to be a few more ‘easy’ levels early on.

If it were a real game, I would want to spend much more time balancing the game play. Including getting feedback from test users…

… but for now, it is what it is, and thats just breakout!

You can find the game here and the code is here