Hex Game – Randomly Building Game Boards
In the first part of this series, I introduced the rules of the game and discussed some much-needed improvements to make the game more fun. The most pressing issue is the ‘first click lose’ issue and the ‘unwinnable game’ issue. Both of these are sure to ruin the fun. This post discusses methods of generating boards and then shows how I randomly generate the board currently.
Content Generation
Games use random generation and procedural generation all the time. Both techniques are generally used to make the game feel less scripted. In a First-person shooter game, having guards randomly spawn on the level makes the level more fun the second time around. Random and procedural generation are not only used for boards and NPCs, but also for textures, terrain, whole worlds can be created either random or procedural generation. What is best? It depends on what you are using it for.
Procedural generation
Procedural generation is where the code creates content using an algorithm. The algorithm can be completely deterministic or it may include elements of randomness. If it is deterministic, then if you call the functions with the same parameters, you will get the same results every time. In general, it is often desired that this is the case. Functions that repeat the same outcome are easier to debug and easier to maintain. You can still have randomness in the game, simply by passing in randomly generated parameters to the procedural functions.
Random generation
Completely random content generation is not very common in games. This is content that is generated without an algorithm guiding the choices. For instance, in this Hex game, the board is currently randomly generated. Because of this, boards can be 100% bombs or 100% goals. They can be unwinnable. They can be really anything since it is random.
In order to make the game playable, I simply set the chance of each space type to be very low, but it still results in a game that can be no fun at all.
Human generation
Just to finish up the possibilities, when you are making your own games, it is possible to have the boards generated by humans of course. Using a map editor or editing the raw data structures of the game (JSON/Arrays/Etc.) you can hand make levels. This is also a very common technique.
Finally, it is worth mentioning that combining the techniques is also possible. You could procedurally generate boards that meet various requirements (solvable/winnable/etc) but then review them and select by hand. Thus you save tons of time but still ensure that each board meets your standards.
Random Board Generation
The existing app board creation relies on randomness entirely. Lines 11-15 are the key lines in the board generation code below. What this board generator does is loops over every space in the board, and for each space randomly choose to make it a danger (or not.) If the board space is not a danger, then it draws another random number to decide if it is a goal.
public randomlyGenerateBoard(radius) { this.board = new Map<string, GameHex>(); this.goalCount = 0; this.dangerCount = 0; for (let q = -radius; q <= radius; q++) { let r1 = Math.max(-radius, -q - radius); let r2 = Math.min(radius, -q + radius); for (let r = r1; r <= r2; r++) { let isGoal = false; let isDanger = Math.random() < 0.1; if (!isDanger) { isGoal = Math.random() < 0.1; } this.board['' + q + '|' + r + '|' + (-q - r)] = new GameHex(q, r, -q - r, isGoal, isDanger); if (isGoal) this.goalCount++; if (isDanger) this.dangerCount++; } }
This is a very simple board generator. The reason to write something like this is to quickly be able to play the game. You won’t know how much fun a game can be until you can try it. And even with the known limitations of this board creation type, it quickly generates boards that can be played. I was able to use this to add the features that were required for the rest of the game, such as showing how close the bomb and danger are to your current position and keeping track of the score.
On point before, I talk about why random was so bad, I just want to reiterate, why it was so good, and why this is so important during agile development. Building something that allows you to keep going forward, is a huge win. Rather than take ages to build a procedural level maker, or even spend time making 10 boards by hand, using this simple random generator quickly showed me that I was on an okay path, and I can keep going. If the game was boring or had a huge hole in the logic, I would have been able to find it using this generator. I was also able to show this version of the game to friends and get feedback about the gameplay.
Anytime you can quickly build a playable version of the game, you should. You can always come back and improve it later. But, if for some reason you were going down the wrong path, and instead of making a quick version, you built the final version, you can never get that time back.
Random Board Generation Issues
Problem 1: Unwinnable Games
Some games are not winnable because there are not enough goals and the space between them is too far to reach without running out of energy. Even if you clicked on the goal on your first click, you would not have enough points to make it to the next goal.
Problem 2: Instantly Winning
Some games are won as soon as they start because there are no goals. So as soon as the player clicks start, it announces they have won. Not fun.
Problem 3: Can’t lose
Some boards are generated with no danger spots. So users can click anywhere and win.
Hex Game
- Hex Game Part I – Initialization
- Hex Game Part II – Randomly Building Game Boards