Game systems in a management/survival simulation (The Making of KING of TAPES)


In this article I'll show you the game systems we used in our management/survival simulation, KING of TAPES.  We use Unreal Engine 4, but I'll explain how the game works in a way that you don't need to know how UE4 works. 

Warning: Contains details on how the sausage is made!



A quick overview of the systems we'll look at

  • The time of day system
  • Tape management system / random tape title and box art generator
  • Customer management system
  • Survival system (player character statistics like food, drink and urine)
  • Customer AI
  • Player statistics system

Most of these function on their own, but depend on other systems for information or events. For example, the customer spawning system needs information from the tape management system, and the time of day system feeds events into the customer AI.

All of these are "singletons", and they are created automatically when you enter the game, and destroyed when you leave.

Time of day system

Let's start with the simplest system in the game: Time of day. We needed something to control when things happen in the game, and give the player a feeling of progression. This system was the answer.

It's not much more than a fancy clock. It ticks away in the background at pre-set intervals, and when it reaches the time for ending the day, it stops counting and sends out an event. Once the game has done all its end-of-day tasks, it resets the time of day system, which advances to the next day and starts counting again.

The time of day system is controlled by two variables: Duration of a minute of game time, and the duration of a workday. Although our clock counts the time in minutes, you could easily have it count hours, seconds or even smaller units of time if necessary. 

The duration of a minute allowed us to easily configure how quickly time passes, and the duration of the workday controls when the store closes at the end of the day. This was super useful for debugging: We had several bugs relating to when the store closes - it would have had me banging on my keyboard in frustration if we had to always wait a long time for the game day to end!

We wanted to connect this to a dynamic sky and ambient light system, but since you don't go out of the store and wouldn't really see it, we left it out of the gamejam version of the game.

Tape management system

The tape management system's job is keeping track of where all the tapes generated in the game are.

At the start of the game, we randomly generate all the tapes. In the gamejam build of the game, this is 240 unique movie titles and tape box art for them! Each tape is also randomly assigned a box color and a category. Tapes also have a chance to either be on the shelf of the store, or be rented already.

Sometimes random generation guarantees mindblowing results:


Most of the work is done using a custom material, which blends two texture inputs together. I was kind of surprised how well it performs! The textures are from Unsplash, which quite generously has a "do whatever you want" license on their images.


The tape generator is controlled by two variables: Shelf fill percentage and rental chance. Fill percentage controls how many tapes are generated. For example, if a shelf fits 24 tapes and you have two shelves, a 100% fill percentage would generate 48 tapes. Rental chance on the other hand controls if the tape is on the shelf or not. A tape marked as being rented will not appear on the shelf, but can be returned by a customer.

The fill percentage and rental chance allowed us to tune both the look and feel of the store. It could either be filled to the brim with tapes, or have some space in it.

All the information from this generation process is stored into the tape manager, which then keeps track of what happens. For example, when a customer rents a tape, it's then marked as having been rented. Similarly, a returned tape is marked to be available in the store. This information is used by the AI - for example, when the customer AI is choosing which tape it wants to rent, only the tapes which are currently available in the store will be considered.


Customer management system

This system manages when a customer is spawned, but also what task a customer will have when they enter the store.

Customer spawning is effectively a timer. Two variables control the spawning speed: Spawn interval and interval deviation. The deviation adds randomness to the spawn interval - without it, customers would always at exactly the same rate.

When a customer spawns, the system chooses a task for it: In the gamejam build, this is either "rent tape" or "return tape". This logic uses information from the tape manager - when the rent task is selected, the customer is given one of the tapes in the store as its target. Similarly, when a return task is selected, one of the rented tapes is chosen at random and given to the customer to return.

This system also triggers the customers to leave at the end of the day (as long as they don't have a task)

Survival system

Since we wanted to simulate the complete retail worker experience, we of course had to add in eating, drinking and going to the toilet... all the while customers are impatiently shouting at you. Just like real world!

This system controls when the player's needs update, and by how much.

It's effectively another timer-based system. Each of the player's needs has a variable controlling its update speed, and how much it goes up at a time. The system also handles eating, drinking and going to the toilet ingame. For example, drinking will immediately increase the player's need to go to the toilet.

If any of the needs goes past its maximum limit... the player dies.

Customer AI

This is one of the most complicated parts, as it's affected by many of the other systems and the player's interactions.

The AI is implemented using Unreal Engine 4's Behavior Tree system. This makes it very simple to build behavior that works in sequence, such as "walk to tape", "pick up tape", "walk to counter". It's similar in concept as finite state machines, but functions slightly differently.

Much of the complexity in the AI is partially invisible to the player, but has a large impact on how the game plays. In a previous version when a customer wanted to rent a tape, they walked directly to the tape. In the current version, the customer doesn't know where the tape is - instead, they look for the category. First they look for a shelf with the same category as the tape. Then, they walk up to it, and look for  the tape on the shelf. The customer goes through the shelves for the correct category, and then looks in other shelves, until it either finds the tape or runs out of patience.

Since the player doesn't really "see" this complex tape searching logic, we could have taken the easy way and just had the customers home directly on the tape they want. But it felt very robotic: How would a customer know exactly where something was? Changing it so that the NPC's actually wander around the store looking for the tape made the store feel much more alive, so it was easily worth it even if the player doesn't necessarily notice the complexity of the system.

This is the full behavior tree of the NPC characters in the game:

It doesn't look very complicated when laid out like this, but each of the small nodes in the graph can perform a more complex task. For example, when an NPC goes to the counter, it executes the following tasks:

  1. Walk to counter
  2. Enter queue
  3. Wait until player is present at the counter
  4. Speak
  5. Wait until player interacts with you
  6. Speak

It looks simple, but the individual tasks in this sequence are much more complex. For example, walking to counter requires the NPC to pathfind to it. Once it enters the queue, it needs to manage its position and walk forwards when customers in front of it move forward. When the player interacts with the customer, the AI logic needs to choose what to do as a result. Etc.

And to add even more complexity to this, most of these tasks can be aborted: If the customer loses patience or the day ends, the customer may need to abort its current task and exit the store.

To accomplish this, the game uses a separate NPC controller to update the behavior tree state. The NPC controller's job is to take care of things like listening to events from the other game systems, or handling more complex tasks such as queuing, or choosing what to do when the player interacts with you. It then updates the information available to the behavior tree for higher level decision making.

In effect, the behavior tree contains the broad strokes that help guide the system on how to achieve its goals, and the NPC controller contains the more complex logic for individual steps.

Player statistics

To be honest this system is simpler than the time of day system... but it's also not very interesting, so I didn't want to start the article with this. All it does is it keeps track of a few values, like how many tapes were rented, and your previous best values. Different parts of the game then update these values when necessary.

This information is then displayed at the end of the game day, giving the player some feedback on what they achieved during the day. We're particularly proud of the calorie counter, as we want our game to promote a healthy lifestyle.


Summing up

Although KING of TAPES is not an incredibly complex game, as you can see there are a number of different systems in play. The sometimes complicated interactions of these systems can make games like this difficult to debug. Race conditions in particular can be a problem: For example, the AI decides to do something, but some system is in the wrong state, and now the AI stops working correctly. Or the AI's task gets aborted at the wrong time, and now it's broken again.

The systems in KING of TAPES are heavily event based - with this approach, we were able to avoid many error conditions that could otherwise easily happen if the game systems just assume everything happens in a specific order. Most systems have flags to tell what state they are in, and an event you can listen for updates. This way when another part needs to do something, it can first check the flag, and if it's in the wrong state, it can wait for an event to execute its own task later.

We also made a lot of use of variables for controlling how different systems work. This was both useful for debugging and tuning the gameplay.


I hope this gives you at least some idea on what goes on behind the scenes in a game like this! Please leave a comment if you'd like us to write more about how any of the specific aspects of the game work.

Get KING of TAPES

Leave a comment

Log in with itch.io to leave a comment.