designates my notes. / designates important. / designates very important.
Some of the information here seems so basic to me. Not that it shouldn’t be in the book. The authors state up front that they want the book to be deep and definitive. Still, it is interesting to me that someone who plays games (assuming you play games before designing games) wouldn’t understand things like resource economies.
Maybe it is only me, but these days (and for decades really) I see the cogs of board and video games almost right off the bat. To me, a great game uses some other (story) elements to distract me from seeing the gears turning in the background.
They define inflation, per Merriam-Webster, as “a continual increase in the price of goods or services”. Then they go on to talk about gold farmers and players killing monster and gaining loot/gold faster than they spend it. I find it amusing and sad how far the destruction of language has come. Inflation is an increase in the monetary supply. With more units of currency, prices rise to reflect the new levels of (less) scarcity and thus require more units of currency for the same goods/services.
A few pages later he correctly identifies inflation as more gold entering the economy than leaving it, thus pushing prices up. I still don’t think they express clearly that prices going up is an effect of increasing the monetary (gold) supply.
Anchor around one number to balance from.
Part 1 - Game Balance
Part 2 - The Mathematics of Balance
Target audience: … Targeting for one demographic means you’re ultimately making the level of conflict/play pressure in the game not suitable for another demographic. That doesn’t mean it’s unbalanced though. We’d say that is “as designed.” Family games are designed to be approachable for a wide range of groups. Games designed for hardcore players like Super Hexagon or even the speed-tuned Starcraft one sees in Korea are nearly unapproachable for the non-hardcore.
Designer’s intent: Once the core demographic is decided, how hard does the designer want to make the game for her desired demographic? Masocore games are designed to be deliberately difficult for even skilled players. Meditative games are designed to produce a continuous series of activities where there’s very little pressure at all.
Transitive relationships … Said another way, if A is better than B, and B is better than C, then A is always better than C.
Intransitive relationships … Said another way, just because A is better than B and B is better than C does not necessarily mean that A is better than C.
The term difficulty curve is sometimes used synonymously with learning curve, but can be referencing many other things (the monster’s strength relative to the player, the change in competitive level between two PvP arenas, and so on).
A synonym for a game curve is a function. In mathematics, a function provides a mapping from one set of numbers to another (for example, if you give a particular function a character’s level, it returns the number of experience points required to reach the next level). For this reason, game designers may more precisely refer to a curve by two names, those of the two numbers that are being mapped. In this case, one might call it the “level/XP curve” rather than the “level curve”; the only reason the latter is commonly used is that enough games have one of these that the “XP” part is implied and understood.
if one wanted to speak of the combat system in a game and how it affects the player’s health, one is referring to a player’s health and all things that affect that health either positively or negatively. So, in this analysis, we could say that the player is taking too much damage or not getting enough health packs or isn’t killing enemies fast enough or has weapons that are too weak or isn’t gaining levels quickly enough. It could be any one or more of these things that’s the issue. In this example, there are many ways to solve the symptom of the player taking too much damage.
Resource flow diagram for [[Ori and the Blind Forest]]:
Character progression: the character in the game grows in some way through player action.
Player’s skill progression: the player’s skills in the game grow through repeated practice.
Narrative progression: the in-game story progresses through character action or time.
Mechanical progression: the more the player plays, the more mechanics get added, making the game deeper, more complex, and more challenging.
Rule of 2: Designers often use the Rule of 2 (credited to game designer Sid Meier): if you need to change a number and don’t know how much to change it by, double it or cut it in half. By doing this, you get a good sense of that value’s effect on the game. It proves much more effective than cutting by 10% and then 10% again (and again). This may seem counterintuitive, since doubling or halving is drastic, and you won’t think that your numbers are off by all that much. Give it a try, though. You may be surprised at how well it works.
Triangular curves
An anchor is a resource that can be related directly to every other resource.
Most games have an anchor, and it’s usually the very stat that is the win or loss condition. HP is a common anchor in RPGs, for example, while victory points are a common anchor in board games.
How are these relationships—weapons, creatures, characters, loot drops, etc.—made meaningful to one another? We can see the relationship using cost curves and the intersections between them.
To do so, it is first necessary to state both the costs and benefits of any object in terms of numbers. Game designers typically start with a single object that they declare to be balanced. Now, in reality, it’s only balanced because the designer says it is. However, if we shape all other things to it, in fact, we will have achieved a first pass at a balanced game, since these items are about equal in power level relative to each other.
Optimal (or “min-maxed”): these characters contain the best performance that one can mathematically squeeze out of the game’s systems. A player who has created an optimal character has probably spent a fair amount of time reverse-engineering the game’s systems, comparing numbers, finding ways to stack bonuses or identify broken skill combos… or they’ve found an online guide from someone else who has.
Viable: these characters may not be mathematically perfect, but they provide a playable experience throughout the game. A typical player should be able to beat the game at the default difficulty level without major problems, if they’re playing a viable character.
Marginally viable: these characters are suboptimal, but can still potentially be used to conquer the game’s content in the hands of a skilled player. Such a build would be nonviable for most players, but expert players might create such a build on purpose as a personal challenge.
Nonviable: a nonviable character is completely hopeless and could not be salvaged, even in the hands of an expert.
There are a few potential solutions to this, depending on the game. If your game is very clearly made and marketed for a more casual, less experienced audience (or conversely, if you’re catering to the hardcore powergamer crowd), you can balance toward one extreme or the other. More commonly, to support all player skill levels, games ship with multiple difficulty levels: an easy mode that’s tuned to provide very little resistance for players who want to focus on the story, a normal mode that’s tuned for most typical builds, a hard mode that’s challenging for a typical build, and a hardest mode tuned to be a challenge even to optimal builds, for example.
Another method that can help is to reduce the power differential between viable and optimal builds, by making most of the character’s power come from things the player doesn’t choose (such as the base damage of weapons that they find in the game) with their attributes and skills providing minor bonuses. If a player in a particular zone is given a weapon that does 80–100 damage and their attribute scores and passive skills can potentially raise that up to the 100–130 range, that is still a noticeable improvement that min-maxers will appreciate, but not such a huge difference that it will invalidate any balance choices you made about how powerful enemies are. If, on the other hand, the player does a base damage of 80–100, a typical player will be at 85–110, and a min-max player can pump it to 300–600, there will be some people complaining about the balance of your game.
Combat is first and foremost a drama, and it’s a drama choreographed with math
If you ask a group of gamers, or game designers for that matter, to describe the best combat they remember, notice the words they use. The collection below comes from a conversation held with six graduate students • Unforgettable • Hope • Shock • Panic • Closure • Movements • Theatrical • Celebration • Lost • Win • Tension • Funny • Chaos • Anticipation • Memorable • Struggle • Prayer/ritual (“Hail Mary” moves) • Unexpected • Drama • Closeness of shared experience (in a multiplayer game) • Realization of mastery/learning
Like design pillars, combat pillars are words that people might use to describe combat in your game. The pillars of combat are • Genre • Time • Pacing • Feel • Participants • Progression • Volume
These seven core pillars, when evaluated and decided upon, result in the definition of your combat. For instance, in Brenda’s game Empire of Sin, the combat could be described as • Genre: Strategy/Empire Building • Time: turn-based • Pacing: methodical and calculated • Feel: visceral, gritty, tactical • Participants: single-player, squad-based • Progression type: player and character progression • Volume: one-third, with empire and crew management being the other two-thirds.
Time in an encounter is as important as the time outside of the encounter in two separate ways, all of which, if implemented improperly, can cause players to accuse a game of being unbalanced. The two purposes of out-of-combat time are anticipation (building up to the next combat) and recovery (release after the previous combat).
In a discussion of time and space, designers are often focused on filling and then leaving empty both time and space. This empty space is the key to building anticipation for a player. No game does this better than Resident Evil, and outside of games, no genre does this better than horror. Empty space—where something could happen—gives the player the necessary time to build up tension for the delivery.
Does the difficulty increase over time at a good rate, or does it get harder too quickly or too slowly, leading to frustration or boredom (the difficulty curve)?
Does the player’s power in the game increase at a good rate relative to the increase in enemy power—or, does the player gain power too quickly, making the rest of the game trivial after finding some all-powerful weapon… or does the player gain power too slowly, requiring a lot of tedious grinding to compensate (the power curve)?
Is the overall difficulty level appropriate for the audience (is the game too hard or too easy)
The friction in this case is never particularly high, because the process of finding a locked door and searching for the corresponding key isn’t typically a great challenge. The Discovery phase is short: it doesn’t take long for a player encountering a lock to realize they must search for the key. The Mastery phase is also short: once the player has the key, all that remains is to return to the lock and use the key on it. The Learning phase is longer and consists mostly of exploring the area and searching for the key. Note also that the Fluency phase has no friction; once the player owns that key, they can typi- cally bypass all matching locks without taking any further effort.
By contrast, consider the resistance to mastering an entirely new skill, such as learning to use a specialized unit in an RTS game:
By putting more of the challenge in the Discovery and Mastery phases and shortening the Learning phase, this effect can be reduced somewhat. For challenges that allow it, visually showing the player an accurate indicator (such as a progress bar) can also help.
These four elements that affect perceived difficulty are2 as follows:
Player skill: the level of the player’s actual skill at the game (the player’s ability to make optimal decisions). The more skilled the player is at the game, the easier the challenges seem, other things being equal.
Virtual skill: the player’s power level in the game (sometimes referred to as virtual skill). Even if the player isn’t very skilled at the game, doubling their health or the amount of damage that they do on a successful attack improves their ability to win.
Virtual challenge: there is the virtual difficulty of the game, based purely on power level of enemies or challenges in the game: increasing the health or attack or speed of enemies in the game (or just adding more enemies in an area), without making the enemies any more skilled, still increases the challenge of the game, because the player must execute their strategy for a longer period or at a higher rate of precision.
Skill challenge: lastly, there is the level of skill-based friction that the game subjects the player to, where the player is not only executing the same tactics and strategies better, but where the player must develop new and novel ways to play in order to succeed. Examples of this type of resistance might be enemies that have more sophisticated AI that make them more challenging to defeat, introducing new types of challenges, or deep puzzles that require multiple skills used together.
This graph would represent a game that requires a constant (and low) level of skill throughout, but increases its power over time, such as a simple idle game. The player may increase slowly in skill (for example, getting better at clicking the mouse quickly in Cookie Clicker), but mostly the player is gaining power through raw stat increases, and the game’s difficulty curve also involves a linear increase in stat-based challenges.
If the level of challenge remains constant (not getting harder or easier), and the player’s power is also constant (player does not gain or lose power over time), the perceived challenge still decreases over time, simply because the player is improving in their ability:
The player’s view of the present and future interaction loops in some game might be summarized as (1) Do Something; (2)???; (3) Profit! The first step here is the current loop. The second (unknown) step represents the future (as yet unknown) loops. The third step is the anchoring long-term goal.
In Metroidvania and Adventure games, the player is motivated by a desire to gain access to new areas and new skills and abilities, which leads to a desire to master the most recently acquired skill or explore the most recently discovered area. This loop is repeated with each successive skill and area throughout the game. The player may not immediately know where all future areas are, but they may see some places they can’t get to right away (giving them some idea of where to return to later), or some objects in the game that they can’t interact with yet (but they know that there will be some future skill or ability that allows them to).
In a game with progressive resource management mechanics (this would include idle games like AdVenture Capitalist, deck-building tabletop games like Dominion, and even real-time strategy games like StarCraft), the player has a motivation to acquire more options for resource acquisition, which grants the ability to create an efficient economic engine—in essence, the core game loop in these games is about modifying the core game loop, and player satisfaction comes from meta-progress. In the case of competitive (PvP) games with a clear end condition, this continues until one player’s engine ultimately allows them to dominate the game and triumph over their opponents for the win. For games with no defined endpoint and only a transition to some sort of elder game, this resource loop continues until the player chooses to exit the loop, either out of boredom with the mechanics or frustration with sufficiently diminishing returns for their effort.
In narrative-driven games (such as Her Story or Life Is Strange), the player is motivated by seeing the story develop and resolve. On successive iterations of the narrative progression loop, the player gains a greater understanding of the plot and world and backstory, and relatedness to the characters.
• Agency: control over one’s environment and one’s own fate. Motivates player to seek improved character stats or abilities, which give increased virtual skill as the reward.
• Mastery: greater understanding over how to manipulate a system. Motivates player to increase the difficulty or complexity of the game, which results in increased player skill at the game as a natural reward.
• Curiosity: finding out what happens next. Motivates player to enter a discovery arc, which when completed grants additional knowledge of the game to the player.
• Closure: finishing what one started. Motivates player to enter an accomplishment arc, which ultimately satisfies the player’s completionist desires when the arc finishes.
• Expression: a show of one’s individuality and uniqueness. Motivates player to collect cosmetic content or make character-defining choices in the game, which allows the player to use the game as a form of self-expression. Depending on the context, the player might be putting themselves in the game or else creating a fictional character of their own devising.
• Connection: relatedness to and fellowship with other humans. Motivates a player to enter guilds, which provide the player with a feeling of social inclusion.
• Superiority: showing domination of one’s peers. Motivates a player to climb leaderboards and other ranking systems, which rewards the player with the thrill and recognition of competing and winning.
• Community: showing value to one’s fellow players, be they opponents, allies, or guildmates. Motivates a player to enter an influence loop, performing behaviors that win friends and provide recognition of the player’s value.
Curiosity → Discovery Arc → Player Knowledge
There are two main types of discovery arcs: exploration of virtual spaces and advancing the narrative.
Progression through level transitions (that is, when the player enters a new level or area) is a special kind of reward, because it shows at a visceral level that the player is moving ahead. The speed at which players move to new spaces should be chosen carefully. Too many transitions in a short period of time is disorienting, but too few makes the whole game feel like one giant series of identical levels with no progression. A common model (not the only one) is to have relatively short levels at the start of the game and have each successive level take slightly longer to traverse than the previous one, on average (with some variation to keep things from getting too predictable). This lets the player feel like interesting things are happening at the start of the game when they aren’t yet emotionally invested in the outcome; a player can tolerate longer stretches near the end of the game, especially when leading up to a major plot event.
• The active progression loops are constantly open and ongoing. Any loop that a player is currently advancing is not yet complete, but as soon as it is completed, it immediately opens up the next iteration of that same loop. In this way, each of the progression systems in the game (technology, exploration, military, economic, and so on) remains open indefinitely.
• The progression loops overlap. Because the game has so many distinct progression loops active at once, and they are staggered, the player is never more than a turn or two away from completing one or more goals.
Progression is strongly related to what is sometimes referred to as the reward schedule or risk/reward cycle. You don’t just want the player to progress automatically. Rather, you want the player to feel like they earned their progression and that they are being rewarded for playing well.
Another thing we know from psychology is that a random or intermittent reward schedule has more impact than a fixed schedule.
dynamic difficulty adjustment (DDA), a special type of negative feedback loop where the game tries to figure out how the player is doing and then adjusts the difficulty level during play based on how the player is doing.
I like this idea, but I also like:
In both Bastian and Transistor, difficulty isn’t a game option, but rather a game mechanic. In both games, the player is given the opportunity to increase the difficulty in specific ways (such as taking more damage from enemies, or making enemies tougher, or having enemies explode or come back from the dead when killed), and each individual challenge can be turned on or off in between levels.
Monster Train has a similar way of taking power ups that increases the difficulty.
In fact, real-life stock car racing also has a negative feedback loop, because the driver in the lead is running into a lot of air resistance, so they are burning extra fuel to maintain their high speed. This means they need more pit stops to refuel, which cost precious seconds and allow others to overtake them a great deal. Meanwhile, the drivers who are drafting behind the leader are much more fuel-efficient and can take over the lead later. This negative feedback isn’t arbitrary, like the weapon pickups in a kart-racing video game; it’s a law of physics that affects all drivers equally, and it’s up to each driver how much of a risk they want to take by breaking away from the rest of the pack.
Interesting comparison of Mario-Kart like games and negative feedback (rubber-banding) to real-life racing.
This braiding power struggles is also good. It is basically the same as positive-sum/negative feedback , but it pulls the power level to a constant instead of letting each player get more powerful.
However, if the negative feedback loop is too strong, this also makes it hard for any player to actually win! The game can easily end in a stalemate where neither player can ever amass enough power to claim a decisive victory, since the further they are in the lead, the more pressure the game puts on them to relinquish that lead. A game like this might have an end condition based on time or number of turns, and whoever happens to be in the lead at a certain point of time is declared the winner.
Zero-Sum, Positive, and Negative Feedback
Early in the game, the negative feedback dominates, making it difficult for any player to get solidly in the lead and end the game too quickly. Later in the game, the negative feedback system plays less of a role, and the positive feedback dominates.
There’s an old joke that “alpha” is Ancient Greek for “software is broken” and “beta” is Ancient Greek for “software is still broken.”
As with alpha, there’s no single industry-accepted metric for when a game goes to beta, but generally at beta, we are what we call content complete as well as feature complete. That is, the entire game can be played end-to-end in its entirety.
• Try degenerate strategies. This is where the player latches onto one overpowered thing and just does that thing over and over whenever they have the option. If this is a TCG and there are no deck construction limits, take one overpowered card and put 100 copies of it in your deck. If it’s a fighting game, spam one move over and over. If it’s a tower defense game, build one kind of tower and ignore the others. Playing this way tends to be boring for the player and (if the strategy works) intensely frustrating for their opponents, so this is the kind of situation you want to avoid, where players are optimizing the fun out of the game.
• Be a total jerk. Stab other players in the back. Make moves that are totally unfair. Refuse to collaborate with anyone, unless doing so gives you a sufficient material advantage. Do everything you can short of cheating to gain even a small advantage, no matter how much fun it sucks out of the room. Ignore all normal rules of decency, and see if you can use this to your advantage. If a player can be rewarded in the game for being mean, they will, so you want to test for this to make sure that players are not incentivized to treat others poorly.
• If you’d like additional strategies on how to play ruthlessly, there’s a wonderful book by designer David Sirlin on the subject that you can read online for free, called Playing to Win (see the “Additional Resources” section). It is, essentially, a retelling of Sun Tzu’s Art of War in the context of competitive games/esports, and shows in depth the competitive mindset.
Additional Resources • Jaime Griesemer, Changing the Time Between Shots for the Sniper Rifle from 0.5 to 0.7 Seconds for Halo 3, GDC 2010, viewable at https://www.youtube.com/watch?v=8YJ53skc-k4.
• Anthony Giovannetti, Slay the Spire: Metrics Driven Design and Balance, GDC 2019, viewable at https://www.gdcvault.com/browse/gdc-19/play/1025731.
• David Sirlin, Playing to Win, available at http://www.sirlin.net/ptw.
Here is an example from the dice game Farkle. In this game, a player starts their turn by rolling 6d6. If they’re lucky enough to roll one of each result (1-2-3-4-5-6), they get a huge score bonus. What is the probability this happens on the initial roll? As with all probability problems, we answer this by computing the number of ways we can roll one of each result and then divide by the total number of rolls. But there are a lot of ways to roll one of each number; how do we count them?
Here is one way to look at this:
One (and only one) of the dice must be showing 1. How many ways are there to do that? Six, because there are six dice, and any of them can be showing the 1.
One of the remaining five dice must be showing 2. There are five ways to do this.
Continuing in this way, one of the remaining four dice must show 3, and there are four ways to do that.
There are three ways on the remaining dice for one die to show 4
There are two ways for the two remaining dice to show 5
There is only one die remaining, so it must show 6
How many possible results are there from a roll of 6d6, regardless of what they roll? Each die can show six sides, so we multiply: 6 * 6 * 6 * 6 * 6 * 6 = 46,656, a pretty large number of possible rolls. How many ways can we roll 1-2-3-4-5-6 on 6d6? In the same way, we multiply, but our numbers are different since we’re restricted in which dice can roll what numbers: 6 * 5 * 4 * 3 * 2 * 1 = 720. Divide the number of successes by the size of the possibility space to get our probability: 720/46,656, or about 1.5%.
In his GenCon 2102 lecture Volatility in Game Design, game designer James Ernest constructed a simple game, Kill the Elf (see the “Additional Resources” section at the end of this chapter), to show some principles of probability. In the game, two players are competing to be the first to deal six damage to the titular third-party Elf, though it could just as easily be damaging each other, or even being the first to win a foot race. The warrior is steady and true, doing 1 damage per turn on every turn. The wizard is powerful but chaotic, rolling 1d6, doing no damage on 1–5, but six damage on a roll of 6. Who should win?
The expected value of both characters is the same: 1 damage per turn. One would expect this to mean that both characters have an equal chance to win, but in fact, they do not, because of what we have been discussing about the differences between shortand long-term rolls. Think of it this way: to win, the wizard must roll at least one 6 in its first five rolls and can tie by rolling a 6 on its sixth roll even if the first five rolls fail. We can easily compute the chance of failing to roll 6 in the first five turns (about 40.1%), meaning that the wizard wins almost 60% of the time. Of the times when the wizard does not just win outright, there is still a probability of 1/6 that the game is a draw, so the warrior only wins slightly more than a third of all games. Even though the expected value of damage is the same between the warrior and the wizard, the game is unbalanced in favor of the wizard.
How do you balance this to make it more fair? One way is to make it a race to do 4 damage instead of 6. Then, the wizard only gets three rolls to win and then one opportunity to tie. The game is even closer to fair if players are racing to 10 damage and extremely close to a 50/50 probability of winning if players are trying to reach 1,000,000 damage. The greater the amount of damage required, the more that the wizard tends toward its expected value.
$${n\choose k} = \frac{n!}{k!(n-k)!}$$
$$ \frac{52!}{5!(52-5)!} = \frac{52 * 51 * 50 *\dots * 3 * 2 * 1}{(5 * 4 * 3 * 2 * 1)(47 * 46 * \dots * 2 * 1)} = \frac{52 * 51 * 50 * 49 * 48}{5 * 4 * 3 * 2 * 1} $$
$$ = 2,598,960 $$
$$ P(n,k) = \frac{n!}{(n-k)!} $$
$$ \frac{8!}{(8-3)!} = \frac{8 * 7 * 6 * 5 * 4 * 3 * 2 * 1}{5 * 4 * 3 * 2 * 1} = 8 * 7 * 6 = 336 $$
$$ 13 * 12 * {4\choose3}*{4\choose2} = 13 * 12 * 4 * 6 = 3744 $$
In this state machine, we start in State 1, the initial state. Every turn that it’s in State 1, it transitions to State 2. Once in State 2, it has a 50% probability of going to either of the other states (1 or 3). If it makes it to State 3, it has a 1/3 probability of going to any of the three states, including remaining in State 3. So, it continues to bounce around between these three states indefinitely.
We can model this as a matrix of possibilities, where each column is the state that it’s currently in, and each row is the state it might transition to at the next state change. Each item in the matrix is the probability of transitioning from the current state (column) to the new state (row):
$$\begin{bmatrix} 0 & \frac{1}{2} & \frac{1}{3} \ 1 & 0 & \frac{1}{3} \ 0 & \frac{1}{2} & \frac{1}{3} \end{bmatrix}$$
In the leftmost column (current State 1), there is a probability of zero of transitioning to States 1 or 3 and a probability of 1 of transitioning to State 2 (because when in State 1, it always goes to State 2 next). In the center column (currently in State 2), there is a 1/2 (50%) probability of going to State 1 or 3, and a probability of 0 of remaining in State 2. In the third column (current State 3), there is a 1/3 probability of going to any of the three states.
Notice that if you add up each column, all of the numbers sum to 1. This makes sense: in a state machine, you are always in exactly one state at a time, so there should always be a 200% probability of being in exactly one state after any transition.
In this example state machine and matrix, you might wonder: where do we most likely end up? Yes, the nature of this particular state machine is that we continue bouncing around between states, but suppose we let this thing go for a really long time such that our position is relatively randomized, and then at some random point, we peeked at the current state. What is the probability that it’s in each of the three states? How much of its total time does it spend in each state, proportionally?
$$ \begin{bmatrix} 0 & \frac{1}{2} & \frac{1}{3} \\ 1 & 0 & \frac{1}{3} \\ 0 & \frac{1}{2} & \frac{1}{3} \end{bmatrix} \begin{bmatrix} 1 \\ 0 \\ 0 \end{bmatrix} $$
$$ \begin{bmatrix} 0 & \frac{1}{2} & \frac{1}{3} \\ 1 & 0 & \frac{1}{3} \\ 0 & \frac{1}{2} & \frac{1}{3} \end{bmatrix} \begin{bmatrix} 1 \\ 0 \\ 0 \end{bmatrix} = \begin{bmatrix} 0 \\ 1 \\ 0 \end{bmatrix} $$
$$ \begin{bmatrix} 0 & \frac{1}{2} & \frac{1}{3} \\ 1 & 0 & \frac{1}{3} \\ 0 & \frac{1}{2} & \frac{1}{3} \end{bmatrix} \begin{bmatrix} 0 \\ 1 \\ 0 \end{bmatrix} = \begin{bmatrix} \frac{1}{2} \\ 0 \\ \frac{1}{2} \end{bmatrix} $$
$$ \begin{bmatrix} 0 & \frac{1}{2} & \frac{1}{3} \\ 1 & 0 & \frac{1}{3} \\ 0 & \frac{1}{2} & \frac{1}{3} \end{bmatrix} \begin{bmatrix} \frac{1}{2} \\ 0 \\ \frac{1}{2} \end{bmatrix} = \begin{bmatrix} \frac{1}{6} \\ \frac{4}{6} \\ \frac{1}{6} \end{bmatrix} $$
Essentially, we are weighting it by taking the probability of transitions from State 1 multiplied by 1/2 (the probability that we are in that state) and the probability of transitions from State 3 also multiplied by 1/2, and add those non-overlapping probabilities together. So there is half of a 1/3 probability (which is 1/6) that we can end up anywhere if we started in State 3, or half of a 200% probability of ending in State 2, if we started in State 1.
We can continue doing this indefinitely, multiplying one transition’s state probability column vector by the transition matrix to get the next state, then multiply that by the transition matrix to get the state after that, and so on for as long as we care to. Multiplying current probabilities by the same thing to get future probabilities is known as a Markov chain, named after the mathematician who invented the technique.
It turns out that if you keep doing this enough times, after about 13 iterations you get the column vector $[0.3\space 0.4\space 0.3]$, and if you multiply that by the transition matrix, you get the exact same column vector as the result:
$$ \begin{bmatrix} 0 & \frac{1}{2} & \frac{1}{3} \\ 1 & 0 & \frac{1}{3} \\ 0 & \frac{1}{2} & \frac{1}{3} \end{bmatrix} \begin{bmatrix} \frac{3}{20} \\ \frac{4}{20} \\ \frac{3}{20} \end{bmatrix} = \begin{bmatrix} \frac{3}{20} \\ \frac{4}{20} \\ \frac{3}{20} \end{bmatrix} $$
In this chapter, we learned a powerful trick for being able to evaluate intransitive mechanics using linear algebra. This is about as complicated as it gets, bringing together elements of cost curves, probability, and statistics, which is why this chapter appears at the end of this book and not at the beginning. The process is the same:
First, make a payoff table.
Then, eliminate all dominated choices from both players. Compare all pairs of rows to see if any pair contains one row where each entry is strictly better to or equal than the other. Do the same for the columns. Continue doing this until all remaining choices are viable.
Find all intransitive “loops” by finding the best opposing response to each player’s initial choice. Eliminate rows or columns that do not contain any elements of any loop.
After the elimination steps, all remaining rows and columns are viable choices. Using only those, construct a payoff matrix for each player:
• Add one additional equation: if each player must choose exactly one action, then the probabilities of all choices sum to 1. In an asymmetric game, the probabilities of each individual player’s choices sum to 1, so this may be several similar equations in that case.
• Using algebraic substitution, triangular-form matrices, spreadsheets, or any other means you have at your disposal, solve for as many unknowns as you can. If you manage to learn the value of X (the payoff for one player), it tells you the expected gain or loss for that player. Summing all players’ X values tells you if the game is zero sum (if they all add to zero), positive sum (if they add to a number greater than zero), or negative sum (if they add to a number less than zero), and by how much overall… if you didn’t know that information from the start.
• If you can find a unique value for each probability that is between 0 and 1, those are the optimal probabilities with which you should choose each throw. For asymmetric games, the optimal solution may be different for each individual player. This is your solution.
• For games with more than two players, choose one player’s payoffs as the point of reference and treat all other players as a single combined “opponent.” The math gets much harder for each player you add over two: a three-player game gives you a system of quadratic equations, a four-player game provides a set of cubic equations, a five-player game gives quartic equations, and so on.
What if you want to generate a number within a range that isn’t 0 to 1? RAND() can be multiplied and/or added to in order to get any range. For example, if you want a number between 150 and 250, that would be =RAND()*200+150. Multiplying 200 by a number between 0 and 1 gives a number between 0*200 and 1*200, so the range is now 0 to 200. Adding 150 to that number increases the range from 0+150 to 200+150, or between 150 and 250.
For 1d6, the, you would use =FLOOR(RAND()*6+1,1). Likewise, there is a function CEILING() that rounds up to the next higher number, and MROUND() that rounds up or down, whichever is closest.
=RANDBETWEEN(1,6) is 1d6, and =RANDBETWEEN(0,1) is a “coin flip” that gives either 0 or 1.
What if you want to roll 2d6? You might be tempted to do =RANDBETWEEN(1,6)*2, but that would not roll 2d6, it would roll 1d6 and multiply the result by 2 (you cannot get a result of 7 this way, for example). Instead, you call the function twice: =RANDBETWEEN(1,6)+RANDB ETWEEN(1,6). Alternatively, put =RANDBETWEEN(1,6) in two separate cells and then add them together in a third cell. (The latter might be easier if you’re rolling a lot of dice: for 200d6, use =RANDBETWEEN(1,6) in one cell, Fill Down for a total of 200 rows, and then SUM() them
=COUNTIF(A:A,5) looks at the entire column A and counts the number of cells with the exact numeric value of 5.
=COUNTIF(A:A,B2) looks at column A and counts the number of cells that match the value of B2.
=COUNTIF(B3:D5,”x”) examines the nine cells B3, B4, B5, C3, C4, C5, D3, D4, and D5 and counts the number of them that have exactly “x” as text.
=COUNTIF(C:C,”>=14”) counts the number of cells in column C that have a value greater than or equal to 14.
When order does matter, that is called a permutation, and the corresponding spreadsheet function is called PERMUT(). If you want the number of ways to select the top ten players out of a thousand (where the ordering within the top ten matters), you would use =PERMUT(2000,20). These are handy functions when you don’t want to take the time to remember the mathematical formulas.
-Aside from that, there are a few functions which are useful in simulating a random shuffle. We’ve already encountered RAND() which produces a pseudorandom number from 0 to 1. Additionally, there is a function called RANK() which takes two parameters: first, a value; and second, a range of cells. RANK() looks up the value within the range and tells you what position it is in, numerically: 1 if it is the highest number in the list, 2 if it’s the second highest, 3 if it’s the third highest, and so on.
That’s fine if you have a deck of cards numbered 1 through 52, but what if you have a standard deck of cards instead? It would be nice to create some kind of lookup table that converts the numbers 1 through 52 into a set of actual cards. There is a function that does this, called VLOOKUP(). This function is a bit finicky; what it’s meant to do is take a table (for spreadsheet purposes, a rectangular block of rows and columns), find a value in the leftmost column, and return the corresponding value in one of the other columns. It takes three parameters: first, a value (“key”) to look up; second, the range of cells that comprises the table; and third, which column to return a value from once it finds the key in the first column. This third parameter is a number, where 1 means the leftmost column, 2 means the column just to the right of the leftmost, 3 is two columns to the right of the leftmost, and so on. But it always looks up the key in the leftmost column, so you cannot use VLOOKUP() with data sorted any which way; the data being matched must be on the left.
To illustrate, let’s extend our card shuffler above that currently just randomizes the numbers 1 through 52. In cells A1:A52, write the numbers 1 through 52 in order. In cells B1:B52, write the names of the 52 cards in a standard deck (you may wish to abbreviate a single number or letter for the rank and suit, e.g., “AS” for Ace of Spades, “TC” for Ten of Clubs, and “5D” for Five of Diamonds).2 This gives you an unshuffled “deck” of cards in column B.
If typing 52 cards manually seems tedious to you, there is an easier way. Off to the side in cells J1:J13, write the ranks of the cards: A, 2, 3, 4, 5, 6, 7, 8, 9, T, J, Q, K (or however you prefer). Copy and paste that a few times so that you have four sets of ranks from J1:J52. Then, put a suit (C, D, H, or S) in K1 and Fill Down to K13, and repeat the process with the other three suits down to K52. Now, reading columns J and K together, you have a suit and rank. Next, in cell B1, instead of writing the name of the card, combine J1 and K1 as follows: =CONCAT(J1,K1) and then Fill Down. This function takes any number of parameters that are cells, ranges of cells, or data, treats each one as a string (that is, a series of characters) and sticks them together in order as its own string. If you wanted to get fancy, you could write the ranks and suits out as complete words (Queen and Hearts, for example) and then use =CONCAT(J1,” of ”, K1) to have the card show as “Queen of Hearts.”
Now, in cell E1, write the following: =VLOOKUP(D1,$A$1:$B$52,2) and then fill down to E52. This takes the value in D1 (one of the randomized numbers from 1 to 52), finds the corresponding sorted number in column A, and then finds the card name right next to that number in column B (the third parameter is 2, meaning look at the second column in the data range, which in this case is column B). Column E now has a shuffled deck of cards!
If it bugs you that VLOOKUP() requires your keys to all be on the left, there is an alternative, using a pair of other functions. MATCH() is a function that looks up the position of a key within a range of cells that is either a single column or row. Its first parameter is the key that you want to look up, and the second parameter is the cell range. If it finds the key in the topmost or leftmost position, it gives a value of 1; if it’s the one just below or to the right of that, it gives a value of 2; and so on. There is an optional third parameter, which determines what to do if the key is not found. The third parameter can be 1 (the default if it’s omitted), which assumes the list is sorted in ascending order and returns the closest position without going over if the key is not found; or it can be −1 if the list is in descending order and you want the opposite; or it can be 0 if the list is unsorted and you’re looking for an exact match only. Usually, you’ll want to use 0. MATCH() is helpful in looking up a key in an arbitrary position (as opposed to the leftmost position).
The other function that goes with MATCH() is the INDEX() function, which takes three parameters. First is a range of cells. The second parameter is 1 for the topmost row, 2 for the next to top row, and so on. The third parameter is 1 for the leftmost column, 2 for the column just to the right of that one, and so on. For example, INDEX(A1:D4,2,3) gives the contents in cell C2, because that is the second row from the top and third column from the left in that cell range. INDEX(E3:G5,3,1) gives the contents in cell E5, because that is the third row from the top and the column on the left within the block of E3:G5.
INDIRECT(). This function takes a single parameter, a string, and it takes that string and interprets it as if it were a cell reference instead. For example, =INDIRECT(“B3”) is the same as simply writing =B3. In this case, how- ever, we can build our own custom string in order to select one of a random range of cells.
Try this: create a table of six different pieces of loot, in cells A1:A6. These can be anything you want: 2000 Gold, the Artifact of Untold Awesomeness, a coupon for 20% off at the general store, whatever. Now, in cell B1, we’re going to select one of these items at random. Enter this formula: =INDIRECT(“A”&RANDBETWEEN(1,6)).
The ampersand (&) in this formula takes two strings and sticks them together (this is called concatenation
=INDIRECT("A"&RANDBETWEEN(1,6))&INDIRECT("B"&RANDBETWEEN(1,6)) &INDIRECT("C"&RANDBETWEEN(1,6))
In order to choose a rarity from this weighted table, use the following formula: =VLOOKUP(RAND(), A1:B5,2)
This generates a number between 0 and 1 and looks it up in the A column, by default choosing the highest number without going over. It then returns the corresponding item in column B.
proper formatting of spreadsheets may serve a similar purpose to using a consistent coding style
Spreadsheets aren’t just about storing data and calculating formulas; they’re about communicating the results of those calculations back to you (or others on your team)
For input cells in particular, it can sometimes be useful to limit the values to something reasonable. One way to do this is through data validation. Select a cell or block of cells, then click the Data menu, and select Data Validation.
Data validation can also be used to create a dropdown list of values within a cell, useful for input cells where you only have a few options and want to make sure the user doesn’t type the wrong thing. To do this, use “List of Items” as the criteria.
Additionally, you can turn on Word Wrap, which forces the column height to be tall enough to support all of the text. To do this, select the relevant cell or cells and then click on the Format menu, and then choose Text Wrapping > Wrap
Another thing you can do to make your formulas more meaningful is to give them a name. After all, which of these is easier to understand at first glance, for a formula that’s calculating damage: =BaseDamage*Multiplier-TargetArmor or =$D$7*$C$1-$F$7? Well, actually, that depends. The former is certainly more meaningful, but the latter tells you where the data being referenced actually resides, so it is a matter of taste. But you can give names to individual cells, or even entire ranges of cells, and use those names in your formulas. To do this, click the Data menu and select Named Ranges:
In Libreoffice => Iterations are enabled with a step of
1 (Tools->Options->Libreoffice Calc->Calculate)
This functionality can be useful for simulating turn-based or time-based effects in a single playthrough. For example, you can have the “turn” or “time” increment itself by 1 on each iteration and have other variables increment based on the game state (in other cells), also on each iteration. Imagine, for example, making an idle game where each iteration represents 1 second of game time, and the player’s currency increments by their currency-per-second. This could also be used to model player vs. player (PvP) games, such as fighting games, brawling games, MMOs, or MOBAs, to track things like character health and/or growth over time, especially when dealing with attacks that are timed or that have cooldowns. Consider having a global “timer” cell that tracks time elapsed and increments itself by one unit of time (in however much granularity is meaningful in the game). For example, an attack with a cooldown might be implemented as follows:
Cell A1 represents a powerful attack that should always be spammed as soon as it’s out of cooldown, marked with “X” if it is the next action and blank otherwise: =IF(B1>0,” ”,”X”).
Cell B1 represents the amount of time left on cooldown, set to 20 when the attack is performed and decremented by 1 for every second elapsed: =IF(B1>0,B1-1,IF(ISBLANK(A1),0,20)).
If you had multiple attacks with cooldowns, you could have Cell A1 compute some kind of priority for this attack based on its utility, but only if it’s not
under cooldown (and a priority of zero if it is under cooldown, meaning it can’t be selected in that case). Then, in a separate column, each cell would check to see if its own priority was equal to the MAX() of all priorities, and if so, it would trigger (and enter cooldown). You could also keep a global timer that just increments itself by 1 each iteration and then a move history where it would keep track of whichever move was chosen on the current time:
Cell J1 as the global timer: =J1+1
Cell K1 is a formula that contains whatever move is being performed this turn
Cells L1:L20 contain the numbers 1 through 20
Cell M1: =IF($J$1=L1,$K$1,M1) and then fill down to M20.