Creation of a match 3 game like Farm Heroes Saga using any language – step 1

It’s not a secret in a lot of cases games with a simple and immediate gameplay become a blockbuster.

One example of these kind of games is the match 3 game, which generated absolutely top selling games like Bejeweled, Candy Crush Saga and Farm Heroes Saga among the others, although my all-time favourite is Puzzle Quest.

In this tutorial, we’ll learn the basics of these games using some basic concepts and a pseudo-code which will allow you to create your match 3 game on every platform in every language. Then, I’ll show you some examples made with the most important languages and frameworks.

AN ARRAY TO RULE THEM ALL

Believe or not, the whole game is built on an array. There’s no physics, no collisions, no bullets, nothing. It’s just you and an array. Every item in the array has a value which represents the gem (or the fruit, or the animal, or…) placed in the respective position.

The first thing it comes to mind is a 2-dimension array, since the game has rows and columns, but since I want this tutorial to be as much adaptable to any language as I can, we will be using a simple, basic, one dimension array.

Why are we doing this? Because different languages has different way to initialize and handle multi dimensional arrays, while the basics of single dimension arrays are quite the same.

This way, the classic 8×8 match 3 game field can be represented with an array just like this:

In the picture, you can see every cell has an index going from 0 to 63. Array indexes are always zero based, which means the first element starts with an index at zero.

Then, any array element accessible with the above indexes, must have a value. Since we don’t want to fill an array with eggs and apples, we are going to assign each symbol a different number, such as 4 for an apple, 5 for an egg, 1 for the strawberry and so on, as you can see in this picture:

I don’t want symbols to be zero based because some languages working with frames such as AS3 refer to frame 1 as the first frame. Since it’s very likely you’ll want to place each symbol in a different frame, starting with 1 is the best thing to do.

DEFINING CONSTANTS

A good definition of constants involved in the game will make our life easier when it comes the time to make some changes to the game engine. Let’s see the constants we should use in a match 3 game:

TILESIZE: we know each tile is a square, now we should decide how many pixels should be the side of the square.

FIELDSIZE: most match 3 games are built on a 8×8 field, but you can make it bigger of smaller if you want. FIELDSIZE will store the size of the field, in tiles. Remember you don’t have to use all tiles in your field, most Farm Heroes Saga levels only use a small portion of the entire field size, but they all are built on a 8×8 field.

This way, FIELDSIZE*TILESIZE will return game field width and height, in pixels.

TILETYPES: here we will store the amount of tile/fruit/gem types used in the game. If we have 8 different jewels in the game, then this is the number I am talking about. Obviously you haven’t to use all tile types in each level.

OFFSETX and OFFSETY: normally the tiles aren’t placed in the upper left corner of the stage, but in a more convenient position. That’s how OFFSETX and OFFSETY come into play: assuming each tile has its registration point in the upper left corner, they represent the distance between the first tile registration point and the upper left corner of the stage.

SOME BASIC USEFUL FUNCTIONS

This first part will end with some useful functions to make our life easier when coding a match 3 game.

rowNumber(i): given a tile with array index i, will return the number of the row, which is

Once we know a the row, we have to know the column, with

colNumber(i) which basically works in the same way, operating on columns:

isHorizontalMatch(i) will say if a tile with array index i is part of an horizontal match.

Basically an horizontal match can be done from left to right or from right to left, but to simplify the whole process we assume an horizontal match can be only done from right to left.

That is, the first two leftmost tiles of every column can’t be used to determine if they are part of a match, because there aren’t enough tiles on the left. We will start checking from the 3rd tile of each column, so the pseudocode is:

The same concept applies to vertical matches:

isVerticalMatch(i): again, we suppose a match can only be made from bottom to top, so we will exclude the first two topomost rows.

And now we also know if we have horizontal or vertical matches.

That’s all at the moment, next time I’ll show you how to do it in at least a couple of different languages.

  • Graphitt

    Hi, i think it would be best to introduct and use LinkedList for such games. U can write really fast search algorithm.

  • Looking forward for the next step, thanks Emanuele.

  • SadiQ

    Is there a good reason why we should seek for matches from right to left and bottom to top and not left to right and top to bottom?

  • Emanuele Feronato

    @Graphitt: not every language/framework supports Linked lists

    @SadiQ: no, there’s not. Just choose the way you prefer

  • Max

    Dear Emanuele, I have been reading all your bejeweled tutorials for quite some time and as you said in this post, the game designers doesn t always use all the cells for each level, there are generally some holes in the design of the board/levels.
    I was wondering if the programmers use 2 arrays/vectors, 1 binary for the board/level and one containing the tiles numbers.
    Do you see what I mean?

  • Emanuele Feronato

    Sure Max, I see what you mean and I agree. I wouldn’t use a binary because it only allows “on ” or “off” tiles, while in games like Farm Heroes we also have special tiles such as grass tiles.

  • Max

    So you think it is better to use 2 one dimension arrays than 1 2-dimension array?
    I think in term of memory it should be the same at least on the paper, but in practice, in flash for example?

  • Emanuele Feronato

    I wouldn’t mind unless we are talking about *HUGE* arrays

  • Aren’t you thinking about releasing a new book like Flash Game Development by Example (but teaching other games, of course) ?

    Regards.

  • Pingback: Creation of a match 3 game like Farm Heroes Saga using any language – step 2 - Emanuele Feronato()

  • Pingback: Creation of a match 3 game like Farm Heroes Saga using any language – Step 3: adding tiles to stage - Emanuele Feronato()

  • mohit

    hi,
    nice one.. but how to design level one by one. like no of moves, targets, board design so every level should be playable.
    because i check in farm hero they design only board not game element(carrot and apple or sun), so how to decide target
    and move, score.. please help me.

  • Anasmatic

    Thank you Emanuele , this is great.

    there are 2 small corrections have to be made

    rowNumber(i)
    returnfloor(i/TILESIZE) should be returnfloor(i/FIELDSIZE)

    and so
    colNumber(i)
    return i%TILESIZE be return i%FIELDSIZE

    a novice devloper whould be very confused with it

    thanks again

    remove this comment after correcting the functions , the comment will be confusing, it self :)

  • Pavlo

    Thanks for this tutorial! Good job