Sigmoid Curves are Game Designers’ Friends

Back when the pandemic started, this video by 3Blue1Brown got many people talking about logistic curves in an epidemiology context. It made me think about how frequently game designers also use S-shaped curves, so I decided to write an article about them. Upon doing some research, I found many interesting usage examples of sigmoid curves in game design, and decided to make this compilation, also adding a bit of my own experience. I hope you like it!

What are sigmoid functions?

A sigmoid function is an S-shaped curve whose slope angle starts small, then reaches a max steepness, and then goes back to a smaller growth.

The derivative of sigmoid curves are bell-shaped, which makes them relate closely to probability distributions (don’t worry, I’ll get back to this later!).

The logistic curve

A logistic curve is a specific example of sigmoid in which each of the “halves” behave similarly to an exponential curve. It was invented as a model for populational growth, replacing the exponential model.

Logistic curve

It’s no news that exponential growth is very common in game design — see upgrade costs in incremental games such as Cookie Clicker: the cost is multiplied by 1.15 when you buy each unit of it, and it repeats ad infinitum. But as 3Blue1Brown notes, exponential growth rarely exists in the real world, because in the natural world, growth usually becomes saturated or unsustainable and eventually reaches a limit.

For this reason, when modeling or measuring player behavior, growth that seems to be exponential is usually just the start of a logistic curve. Similarly, a common way to represent a player’s learning curve is as an S-shaped function. As this author describes it, it has three phases: A slow start as the player develops familiarity with the mechanics (I), a roughly linear slope while they have a solid understanding of the game (II), and a part where it gets harder and harder to improve, as players get close to the skill ceiling (III).

Player mastery by time, adapted from JFurness’s post

The formula for logistic functions is

, where x₀ is the x value of the sigmoid’s midpoint, L is the curve’s maximum value, and k is the steepness of the curve.

Usage

Now that we know a little bit about these curves, let’s see what practical uses they have. Here are some situations in which a sigmoid function might be useful compared to a simpler alternative such as a clamped linear function:

1. When your min/max thresholds represent ideal values and you need your curve to tend toward them.

Many F2P designers use logistic curves as a base to pace the interval between each level up. That is because there are two important values for that interval that need to be maintained for a long time:

  • A low interval (that is, high frequency) for introducing new content and get players “hooked” at the start of the game;
  • A maximum interval that is just enough to keep advanced players engaged while also not making it too expensive for developers to create new content.

As you want to keep the player for as long as necessary in the first scenario and, once they are engaged, keep them infinitely at the second scenario, an S-shaped curve with a smooth transition between these 2 moments is perfect for shaping their progression.

This is an approximation I made of the amount of sessions it takes for each level up in Township by Playrix.

Likewise, this example by Daantje shows how a logistic curve can be used to control enemy drops in an MMO. If she had used an exponential function, the rewards curve would have gone through the roof! If you don’t want your curve to overshoot a maximum value, a logistic curve gives you the control you need.

2. When you need a strictly increasing (or decreasing) function

Sometimes a linear curve seems suitable for the job, but you need to restrain the y-axis inside min/max limits while also guaranteeing a strictly increasing function (the corresponding Y value always increases when the X value is increased).

For example, let’s say that in an RPG your character has an “accuracy” stat while the enemy has an “evasion” stat, and the difference between these values determine the chance of a given attack hitting the enemy. We could use a linear function for this, but as you can see, it has some limitations:

Chance of landing an attack depending on the difference between your accuracy and the enemy’s evasion.

If your enemy’s evasion is 5 points below your accuracy, drinking an Accuracy Potion™ to temporarily increase that stat during this battle would have no effect, since your attack’s hit chance already reached its max value. If you want to guarantee that having a bigger accuracy always means a bigger chance of hitting an enemy, a logistic curve is a better option:

Chance of landing an attack depending on the difference between your accuracy and the enemy’s evasion. This example was adapted from this post on Reddit by NathanielA.

3. When you want an accentuated change at a specific part of the curve

Let’s say you are making an action game where players compete for high-scores in each level. Doing certain tasks such as killing monsters increases your score, and at the end of the level, a time bonus is also given, rewarding faster players.

During beta testing, you see that in a given level, the players’ best times are distributed in a bell-shaped curve:

The simple way of balancing the time bonus, of course, would be using a linear curve, with 0 bonus given for players who take too long to complete the level:

However, if your design goal is making most players feel powerful when surpassing other players, you could “skew” the middle of this curve to make the bonus difference bigger where more players are concentrated:

Here, the bonus score has a steeper slope where the most common “best time” results are gathered.

This way you would have a more dynamic, aggressively changing leaderboard as your player base masters how to optimize their times. The amount of rewarded points would also be proportional to the amount of players surpassed (due to the relationship between the logistic function and the bell curve).

As a plus, the fact that it’s strictly decreasing makes the line never touch the x axis, meaning you wouldn’t limit your time bonus to players who make it in less then 8 minutes in this example (as it happens with the linear curve).

Drawbacks

I’ve mostly compared sigmoid functions with linear functions so far, so I think it’s fair to also show some cases in which you’d probably be better off with a linear function.

1. Communication and predictability

If your goal is communicating your game’s rules as clearly as possible to the player, a logistic curve might not be very elegant.

Let’s go back to the same “time bonus” example:

In this scenario, the main path allows the player to score only 100 points by collecting treasure, while the detour yields 300 points but takes 10 more seconds to traverse. How would players figure out the best path to take if they are aiming for a maximum score?

If you are using a linear curve for the time bonus, the answer can be easily found — players will understand that each extra second they take subtracts a constant value from the bonus. On the other hand, if you are using a complex formula such as a logistic function, the rule is not as easily communicable and that might discourage players to fully understand the game’s mechanics.

As a player, Isn’t it much easier to understand a rule such as “1 second means 50 score”?

When you represent all the small decisions the player makes throughout this whole level and the time they take, things get even more unpredictable. If it’s important for competitive players to understand the impact of each individual decision in isolation, a linear curve is more effective.

2. The sweet spot

One could argue that functions that have a very accentuated change in a specific part are also too sensitive — moving the slope a little bit to the right or a little bit to the left will have a drastic affect on your game balancing and could potentially ruin it. If you don’t have enough gameplay data or won’t be able to make post-release adjustments, relying on a perfectly-balanced logistic curve can be risky.

Creating your own function library

If you do a lot of game balancing on Excel or Google Spreadsheets, it’s useful to have your own library of custom functions (on VBA or Go, respectively). Here’s a logistic curve function on Excel VBA:

Function Logistic(x As Double, centerX As Double, height As Double, steepness As Double) As Double
Logistic = height / (1 + E() ^ (-steepness * (x - centerX)))
End Function
Function E() As Double
E = 2.71828
End Function

Other Sigmoids

Sigmoid Freud

I used logistic function in most examples but there are plenty of other kinds of sigmoid functions, with different uses. Here are some cool ones:

  • JFurness made an article about this very beautiful function that starts on 0,0 and whose output is restrained inside [0,1).
  • Another cool sigmoid by Jason Hise where both the input and output is restrained inside [0,1], which makes it great for transforming ranges if you are a programmer!

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store