A Reward System is a common feature found in most video games, as most games feature some form of rewards. Commonly known as loot tables, these systems are designed to incentivize players to complete various tasks or goals such as defeating enemies, completing quests, or engaging in other activities by offering rewards.
In this article we’re going to explore how to design a robust and dynamic reward system that is flexible enough for most use cases that you’ll come across as a game designer – if designed accordingly, this approach is so adaptable that it can be used for any genre and for way more than just loot or rewards.
Table of Contents
Loot Tables vs Reward Systems
When most designers think of loot tables, they immediately think randomly generated loot in RPGs like Diablo. These loot systems are found traditionally in pen-and-paper RPGs like Dungeons & Dragons, MMORPGs such as World of Warcraft or Guild Wars and ARPGs like Diablo and Path of Exile.
As more modern games employ more RPG progression mechanics, loot systems can also be found in a plethora of other genres: Battle Royale games such as PUBG, Fortnite and Warzone, RPG/first person shooter hybrids such as Fallout, Destiny; Survival games such as The Last of Us or DayZ and even more casual games such as Minecraft or The Legend of Zelda.
This classic definition of loot tables is pretty narrow and loot generation isn’t the only way they can be used. It’s generally understood that they to refer to something like a random distribution system for various types of items – but rewards don’t have to be random per se, nor do these items need to be loot in the traditional sense – rewards can take many forms, such as points, resources, items, upgrades, unlocking new features or content and even generate content themselves – you’d be surprised how flexible a reward system like this can be.
Abstraction is an essential skill in the game designer’s tool belt, so we’re going to abstract loot tables into a fully-fledged reward system. If set up correctly, this method can be a great aid in the way designers approach game balancing if used as the underlying system for any type of game in any situation where you want to give something to your players.
Fixed Loot: The Hardcoded Way
Let’s start with the basics. The act of rewarding players sounds simple enough on paper – the player does an action and gets a reward in return – after all its part of the core compulsion loop for virtually any modern video game.
Think of a game like Dark Souls – there are specific chests in the game that contain exactly one particular piece of loot, at the same position, every time. That’s fixed loot that has been hard-coded.
In this very simple example the player defeats an enemy and gets some fixed reward in return – for example a sword, a potion and some coins:
For a very simple game or an enemy that you only fight once this approach might be good enough, but even if you want to extend this system just slightly, directly assigning rewards to their source isn’t going to cut it in the long run.
What if players should encounter this type of enemy multiple times throughout the game, do you give out the exact same rewards? Maybe you want to give out slightly different rewards each time? What if you want to base loot not around that exact enemy but want to consider the player’s current progression (such as level, difficulty, etc.) or the area the player is currently playing in?
When it comes to rewards, what if you want to give out a random selection of items? Maybe there should only be just a chance of getting a reward? What if some of the possible items should be more scarce than others?
These are common questions every game designer will probably ask themselves at some point and handling all this in a tightly coupled way gets complex fast and will lead to a lot of design debt quickly. That’s where a dynamic reward system comes in.
Of course fixed loot is an important way for designers to create specific rewards at key moments in game – this too can be modeled with this system.
Dynamic Reward System
So how do we solve this tight connection between the source and the reward? The magic word here is decoupling (the programmers among you might guess where this is going), specifically separating the source from the reward, which we’ll aptly call the Dynamic Reward System.
There’s three main aspects to a dynamic reward system:
- Reward Source: Any type of action or mechanism in the game that triggers the generation of items.
- Reward Container: An abstract data structure holding the rewards. Not to be confused with an actual container that could be found in-game.
- Items: The actual rewards the player gets.
To better illustrate the method, it helps splitting this system into it’s compartments in an abstract way:
So a player performs an action and instead of “defeating an enemy” there’s a reward source and instead of loot there’s items.
The important part is that instead of directly giving a reward for a certain action, we interpose an abstract reward container between the two. So for any given reward source you assign a reward container and for each container you determine it’s contents, i.e. the actual rewards.
One beauty of this system is that you can now assign the same reward container (that you set up once) to a lot of different reward sources. This already gives you a lot of flexibility when designing reward systems for your game! But we’re going much deeper.
First of, everything you can imagine as some kind of action in your game can be a reward source. Everything. It helps thinking about sources by defining the specific actions the game or players may take:
- Defeating an enemy
- Opening a treasure chest
- Drawing from a deck of cards
- Playing a fishing minigame and catching a fish
- Gathering plants in the forest biome with your herbalism skill
- and much more…
So a reward source is triggered by some action or mechanism in the game. These can even be “meta” actions such as claiming a reward in a menu, purchasing an offer in a shop or simply a timer that counts down and automatically gives some rewards.
Once you separate the source and action from the rewards, you’ll be able to think about them in a more abstract way. As a little exercise, take your favorite game and think about how you could define reward sources and actions for it – I just thought of Metal Gear Solid 5 and how extracting enemy soldiers themselves via the fulton system are the reward – and action that leads to a reward source.
At the heart of the dynamic reward system is the reward container. These are hooked to reward sources as the intermediate between sources and rewards.
Reward containers have a lot of alternative names: Loot Table, Drop Table, Loot Box, Random Distribution System, Loot Pool, Gacha Box, Prize Box, Random Selection, … the list goes on. These terms often refer to a specific implementation in other games, but all roughly mean the same thing.
Given our simple enemy example above, we could define it’s reward container like so:
For the sake of this article, a reward container is simply an abstract data structure that holds a reward table among some other parameters that we will add later. Within that table we can define reward slots. A reward slot may contain any kind of item you’ve defined for your game – some examples include: currencies, cards, tokens, resources, skins, equipment, weapons, etc. you name it.
To recap, our reward container consists of:
- Reward Table: Also called loot table or drop table. Essentially a list of items found within the reward container.
- Reward Slot: An entry in the reward table. May contain any kind of item you’ve defined for your game, among other parameters we’ll later add.
- Rewards: Also called loot. Term to describe all possible items a player can get from a reward container.
- Selected Reward: Also called the loot drop. The eventual item(s) that are being selected from the reward table and given to the player.
- Item: A specific reference to an object or reward that you want to give out. An Item can be a currency, a card, token, resource, skin, equipment, weapon, unlock, feature, etc.
We’ll also need to define how rewards are selected, specifically how the game rolls onto a given reward container. For this example we’ll define that this reward container gives out every item for every reward slot that we have set. So in the example above, the player gets a sword, a potion and one coin.
Adding Reward Parameters
So far every item is a single thing. It’s pretty likely that you want to give out more than one copy per item for your game – for things like currency (for example gold) or consumables (like potions).
So let’s define a new amount parameter for each reward slot:
Nice! So if we attach this reward container to the enemy, now every time the player defeats said foe, they will get 1 sword, 3 potions and 50 coins.
We could now duplicate this container, change it’s contents and attach it to different enemies. But wait, giving out these exact rewards every time gets boring real fast – what if we want to have a random chance of obtaining one of these rewards?
Weighted Random Selection
Enter the world of statistics and probabilities with a concept called Weighted Random Selection. That’s a mouthful, so lets break it down.
The way this works is that the game randomly selects an element from the reward table, where the chances of each element to be selected are not equal, but rather defined by relative “weights” (or probabilities). For this to work we’ll need to change how the reward container itself selects rewards. Instead of giving out every reward defined for each of its slots, it will now select exactly one reward from the table.
Next we’ll be adding a new parameter called Weight to each reward slot:
Once this reward container is triggered, the game evaluates all it’s reward slots and takes the sum of their weights and then rolls a number between 1 and that sum.
For our example above the table contains 3 individual entries, each slot has a weight of one, so the weighted sum is 3. The game would roll a number between 1 and 3. (possible numbers: 1, 2, 3)
Each item thus has a 33,33% chance to be selected. This is known as a Uniform Distribution. In statistics, uniform distribution refers to a type of probability distribution in which all outcomes are equally likely. Think of a dice with six sides or a coin flip – each side has the same probability to be “selected”.
The Chance value isn’t something that’s input by you – it’s a simple calculation based on weights. A percentage readout that helps designers understand the probability of selecting a particular reward within a container at a glance. It is calculated like so:
SelectionChance = SlotWeight / SumWeight
Of course a good reward system is about controlled randomization and anticipation – designers need to be able to define these probabilities create anticipation. Even if players don’t have a concrete idea on what rewards they’re going to get, they can anticipate they will get some loot. That moment of anticipation is as important as the actual reveal of the item. Not every item in our container has the same value and the sword is probably more desirable than some potions for example.
Let’s model this by tweaking the weights for each of the items to account for player anticipation and item value:
Sweet! Now the sword has less weight than the other items and has thus a lower chance to be selected, making it more rare, better representing it’s value. The weighted sum of this container is now 35 and all calculations above still apply.
So far we’ve defined the following parameters for each reward slot within a reward table:
- Roll: Also called Draw. The generation of a random number in order to determine which item is selected from a give reward table.
- Item: A reference or ID to the item you want to reward.
- Amount: How much you want to give of said item.
- Weight: A numerical (integer) value representing how likely it is to roll on a certain item. Determines the relative “size” of this reward in relation to other rewards in this table. e.g. an item could have a weight of 100. This is not the percentage chance!
- Sum of Weights: The total sum of the weights of all items in a given reward table. This number is used to determine an it’s selection chance.
- Chance: Also called selection chance or drop chance. The percentage chance of selecting a given item from a reward table. The probability is based on a item’s it’s relative weight in relation to sum of weights in the reward table.
This setup already gives you lot of design space to define reward structures for your game – You can create lots of different containers, hook them up to different reward sources, add various reward slots and define their amounts and weights. You can for example make certain rewards much more rare by reducing their relative weight, thus increasing their perceived value.
But there’s one big drawback – we can’t give out guaranteed rewards anymore! That’s because we’ve changed how the game selects rewards earlier above, so let’s fix that now.
It’s likely that you want to guarantee a certain reward every time a reward source is triggered. The simplest way to do this is to define a weight of “-1” for each reward slot that you want to guarantee.
If you’d wanted to give out all rewards, simply change all weights to -1 and you’ll have a “give all” container as in the beginning of this article:
We can then mix and match both weighted random selection and guaranteed rewards like so:
Keep in mind that this changes how the table and its weights are evaluated, as each slot with a weight of -1 is given out in addition to the roll and this entry then needs to be ignored when a number is rolled.
Thus in the example above the game now rolls on only two items, the total weight is now 25 and probabilities have changed even though we haven’t changed the weights for slots A and B. This might be obvious, but if you don’t have a probability readout handy this could be easily missed while punching in the numbers.
So in the example above, each roll would now have one of two outcomes:
- 33% chance of getting 1 sword and 50 coins
- 66% chance of getting 3 potions and 50 coins
Alternative implementations for guaranteed rewards would be:
- Adding a “IsGuaranteed” flag to each reward slot. When ticked, the item is given and the game ignores the weight parameter.
- Having a second reward table called “Guaranteed Rewards” for each container which would give out every item in that defined in that table.
Depending on your preferences and needs, one of these implementations might be a bit cleaner than setting -1 for the weight parameter.
The Power of Nothing
So far for every roll on a reward container there will be always at least one reward given out. We currently can’t control if an item should drop at all and how likely it is once a reward source is triggered.
You might need this functionality for games in which a certain action is performed a lot of times, for example in Action RPGs such as Diablo or Path of Exile. Players will kill hundreds of monsters in short periods of time – giving out an item for every single kill isn’t feasible. So what is the solution?
We could add a check to each action before a roll and only trigger the reward source if the check passes.. but it’s much cleaner and more flexible to add this functionality to our reward system directly.
One way for this to work we will add special type of item to our reward tables which equates to getting nothing, i.e. an “empty” draw. This item is sometimes called “NoDrop” or “NullItem” – if this item is selected, no loot is given out for the roll. We could model it like so:
The beauty of this method is that the null item can be modeled like an actual item in your game, so it doesn’t require you to build special functionality or checks around your reward system – it’s all contained within. Just add the null item to any of your reward tables, determine it’s weight and you can control the probability to get any other item in that table.
How you technically handle the null item in your game is up to you – I’ve worked on games where it’s an invisible resource that is actually collected and accumulated, but has no functionality whatsoever and it is never shown to players, in others it’s literally doing nothing when selected. Whatever you do, make sure it doesn’t lead to issues in the long-term. We don’t want unnecessary design debt, do we?
Nested Reward Containers
There’s another important piece missing for our Dynamic Reward System: Recursion. Once you’ve designed a few reward containers you’ll likely want to link one to another.
For this to work you want to be able to have a given reward slot contain a reference to another reward container like so:
In the example above, slot C now links to a second reward container called “Gold Coins”. If said slot is chosen, the game recursively evaluates that table and chooses on these rewards.
Nested Reward Containers unlock a lot of design space, for example:
- Smaller Tables: Instead of having a few huge reward tables, you can keep them smaller and interlink them. This makes it easier to adjust and balance weights and probabilities.
- Hierarchy: Have reward containers be themed around a particular category of items, for example weapons, consumables, gold, etc.
- Use these themed containers to establish an item hierarchy, such as: Equipment > Weapons > Swords > Two-Handed Sword > Claymore.
- Link Many to One: You can define a few commonly used tables (such as “Trash Loot”) and hook them up to lots of parent reward containers.
- Example: Define various types of containers such as “Tool Cabinet”, “Desk Drawer” and “Filing Cabinet” and have them all link to the “Trash Loot” container.
- If you want to adjust which trash items should drop, you just need to adjust that particular reward table and it’ll automatically update all parent containers.
For the example above slot A could link to a “Weapons Reward Container” instead of giving out a sword directly. Slot B could be a “Consumables Reward Container” instead of giving out 3 potions flat.
One thing to look out for with nested reward containers is to avoid circular references, as these could lead to a circular loop (infinite recursion) and crash or hang your game. In other words, you don’t want to link container A to B and then have B link back to A. You could implement checks so that this isn’t possible (e.g. the game throws an error when a circular reference is found) but I find it best to be intentional when designing my reward systems and just avoid this problem outright at design time.
Putting It All Together
Now, let’s combine all the parameters and features into a single system:
The combination of nested reward containers and null items allows you to exactly control probabilities for each of your items and allows for very deep and nuanced reward structures. Use weights in combination with nested containers decrease, increase or even guarantee that reward hierarchies are evaluated by the game. Go deep in the hierarchy or create re-usable tables to manage complexity and speed up your game development.
In this article we’ve learned how to abstract implementation-specific features into generic systems that we can use as the foundation for reward systems in various types of games. With this system you now have the power to model pretty much every type of reward structure you can think of.
Additionally there’s many ways on how this system can be further expanded:
- Repeated rolls
- Conditional selection (only allow selecting an item if certain external conditions have been met)
- Rolling with and without replacement (removing an item from the reward table once it has been selected)
- Gradually increasing/decreasing weights with subsequent rolls
- Procedurally generating items (item blueprints)
- Modifiers (external factors that influence the reward selection logic)
- and much more.
In a future article I’ll be going into much more detail on these extensions, best practices on using this method, many tips and tricks on how you can manipulate and tailor this system to your specific needs. I’ll be exploring concrete implementations and how you can model reward structures of other games – how you can use this system to solve various other design problems that aren’t immediately obvious.
If that sounds interesting to you, please consider subscribing to the GameDevGems YouTube channel! Did you learn something new today? How would you use this system in your game? Let us know by joining our ever-growing GameDevGems Discord Community!
About the Author
Written by Steve Haßenpflug, a seasoned game designer with a strong product & technical background. His focus is on creating engaging games for companies who want big results. GameDevGems is a passion-project of him.
Steve has developed top-grossing AAA games for IPs beloved by players around the world (Angry Birds, XCOM, Trolls) with international companies (2K Games, NBC Universal, DreamWorks, Rovio) and helped bootstrap gaming startups in the early stages of seeding.
He’s an expert in mobile free-to-play mechanics and is currently focused on bringing web3 game development and blockchain technology together at ChromaWay.