DEV Community

Cover image for How to Build the Hunger Simulator in The Long Dark with Javascript
Nadya Primak
Nadya Primak

Posted on • Originally published at nadyaprimak.com on

How to Build the Hunger Simulator in The Long Dark with Javascript

Before I became a programmer I loved to play games. I played games for many years before I even knew the most basic concepts about coding. However these days I see that people are trying to introduce their kids to programming and looking for ways to make programming concepts more approachable. I think that using existing games people love is a great way to do just that. That is why I focused on how I could learn to code with games when I was starting my career. In this tutorial I will show you how to do that by walking you through the process of extracting a feature from a video game called The Long Dark and recreating it on your own.

If you are reading this you might already have at least some interest in The Long Dark, and may have played it. But I will briefly explain the game just in case. The Long Dark came out on Steam several years ago and had a beta release that was primarily a survival simulator. The game takes place in the Canadian far north where a mysterious phenomenon has caused all of the power to stop working.

In the original simulator, your goal was essentially to survive as long as possible by staying hydrated, nourished, rested, and avoiding freezing to death. You could choose between different environments to try your luck in, some which have a range of man made shelters and some which have nothing but a few caves dotting a barren landscape teeming with aggressive wildlife.

An example of some aggressive wildlife. You can see the health meters at the bottom left

By releasing a minimum playable version of their game early, The Long Dark developers gave players something to continually look forward to and give valuable feedback on as they added more features to create something truly spectacular. Now the game has a fully fleshed out story mode with multiple seasons and difficulties in addition to special challenges. Whether you’re developing a game or an application for a startup, the idea of slowly adding on features and polish over the course of time is the most logical and sustainable way to build a good product. It goes to show that when you learn to code with games like The Long Dark, you might be surprised by how many lessons will transfer over from games to other types of development.

It goes to show that when you learn to code with games like The Long Dark, you might be surprised by how many lessons will transfer over from games to other types of development. Examining games from a developers perspective and extracting a feature to recreate can also help you get into video game coding, so it’s a win win.

While its good to talk about strategy and general practices like building off of something small, I want to get into actual coding in this post. After all you can’t learn to code with games unless you actually write some code! In particular, I want to show you how we can take a feature from a game like The Long Dark and try to replicate it with Javascript code. I suggest starting with something simple, like a hunger meter. We could define a variable like fullness.

let fullness = 100;
Enter fullscreen mode Exit fullscreen mode

Why fullness and not hunger? Certainly nothing is stopping you from calling the variable whatever you want, but in my mind it is easier to call it fullness because then I can set it to 100 and know that means “completely full.” Whereas if I used hunger, I might be confused. Does 100 mean 100 percent hungry? Hunger doesn’t make as much sense to measure by percentage as fullness.

In The Long Dark, you get hungrier the longer you don’t eat. That means we need something to measure time. Since it’s a video game, time also goes by a lot faster than in real life. So let’s say every 30 seconds translate into 1 hour. We could use a Javascript function like setInterval that would get called every time 30 seconds have passed. You can read more about the function and test it out here. Note the double slashes in the code below indicate comments.

let fullness = 100;

setInterval(function(){ 
   fullness = fullness - 5; //subtract fullness by 5 percent
   console.log("logging fullness", fullness);
}, 30000); // 1000 is 1 second (in milliseconds) 
Enter fullscreen mode Exit fullscreen mode

By assigning fullness the value of itself minus 5, I am essentially decreasing fullness by 5 percent. Then I am logging out the new fullness value to the console, so I can confirm that my function is working. Having to wait 30 seconds to confirm my function is working can be a little bit annoying, so you can reduce the number of milliseconds to 1000 temporarily for testing purposes.

If you’re using a coding editor in the browser such as Codepen(I’ll be including a Codepen link a little further down) the console can be opened up by clicking on the “console” button in the bottom left corner of the editor

So now we have a fullness value that decreases over time, but what about eating? In The Long Dark you can eat all sorts of things. If you scavenge you can find canned beans, peaches, even dog food (ew) to eat. Or you can go fishing or hunting. Each type of food has a different number of calories which affect how much your fullness meter gets filled.

For now, let’s just create four foods. A granola bar, some canned beans, a pound of deer flesh, and a rainbow trout. Let’s say 200, 450, 800, and 150 calories respectively.

const trout = 150; //use const to declare a variable when you never change the value of the variable
const deer = 800;
const granola_bar = 200;
const beans = 450;
Enter fullscreen mode Exit fullscreen mode

Now you might be thinking we have a problem, and you would be right. If we are counting our fullness as a percentage and our food in calories, how will we add them together? Looks like we will have to make some changes to our existing code, after all. The average man needs to eat about 2,500 calories per day. For the sake of simplicity, let’s say that is the number that constitutes 100% fullness.

const maxCalories = 2500; // maximum calories you can eat
let currentCalories = 2500; //calories you need to eat per day
let fullness = 100; // still keeping percentage for display purposes
const trout = 150;
const deer = 800;
const granola_bar = 200;
const beans = 450;

setInterval(function(){ 
   currentCalories = currentCalories - 60; //subtract fullness by 60 because we burn 60 calories per hour while sitting
   fullness = (currentCalories/maxCalories) * 100 //calculate fullness percentage
   console.log("logging fullness", fullness);
}, 30000); // 1000 is 1 second (in milliseconds) 
Enter fullscreen mode Exit fullscreen mode

Above you can see I’ve added two new variables, maxCalories and currentCalories, which make it very easy to do our math in setInterval to calculate the fullness percentage. Just divide currentCalories by maxCalories and multiply by 100. We also are subtracting 60 calories every 30 seconds because that is how many calories we burn per hour when we are sitting. Now we are ready to add an eatFood function. This one should be very simple. Just updating currentCalories, right?

eatFood(food) {
   currentCalories = currentCalories + food;
}
Enter fullscreen mode Exit fullscreen mode

At first glance this would seem to be enough, but ultimately we will want to display the fullness data and update it every time currentCalories changes. In that case, it makes sense to create a function for updating fullness as well, to avoid rewriting the math multiple times. Let’s take a look at the whole thing again (minus the variables).

setInterval(function(){ 
   currentCalories = currentCalories - 60; //subtract fullness by 60 because we burn 60 calories per hour while sitting
   updateFullness()
}, 30000); // 1000 is 1 second (in milliseconds) 

updateFullness() {
     fullness = (currentCalories/maxCalories) * 100 //calculate fullness percentage
    console.log("logging fullness", fullness);
}

eatFood(food) {
   currentCalories = currentCalories + food;
   updateFullness();
}
Enter fullscreen mode Exit fullscreen mode

I moved the console.log message into the updateFullness function so that you can see what happens to fullness when you eat food. In my Codepen example, I have buttons that the user can click to eat the different kinds of food, but since I am sticking to Javascript for this tutorial there is another way you can call the function in the code for now.

Just like we called updateFullness inside the setInterval and eatFood functions, you can call eatFood by typing eatFood() and just adding whichever food you want to eat inside the parenthesis. That means eatFood(beans) would pass the beans variable into function.

If you throw in a couple of eatFood() functions at the top of your code, you will notice that your log statements will become problematic. This is because we don’t have anything checking for fullness being greater than 100 percent. We can fix this by adding an if statement inside the updateFullness function.

We don’t want this to happen, since you cannot be more than 100% full

updateFullness() {
    if( (currentCalories/maxCalories) * 100 <= 100) {
        fullness = (currentCalories/maxCalories) * 100
    } else {
        fullness = 100;
    }
    console.log("logging fullness", fullness);
}
Enter fullscreen mode Exit fullscreen mode

This if statement will make it so that fullness gets updated to 100 if eating the additional calories would make fullness exceed 100 percent. Otherwise, the same calculation will be performed as usual. In my Codepen example, I also introduced a death state where if your fullness gets to 0 you can no longer eat food and your status displays as dead. The logic for that is very simple, just checking if fullness is 0 and then setting a variable dead to true. Then inside the eatFood function you add another if statement preventing currentCalories being added unless dead is false.

Another thing you will notice in Codepen is additional if statements for judging what to display for the current hunger status as well as for what color the health bar is. I’ve essentially added a simple GUI for users to interact with. If you want to add this functionality, check out these resources for creating a progress bar and buttons . The only additional Javascript that I am using is document.getElementById and changing the style and innerHTML of the selected element. You can read about that here and here.

There is a lot more you can do from here. You could create a hydration meter using some of the same code we already have. You could get closer to replicating the functionality from The Long Dark by adding a general health bar that begins to go down only when your hunger becomes very low. That would be more realistic since you obviously don’t immediately die when you didn’t eat 1 days worth of calories. I encourage you to explore what you can build on top of this code and can’t wait to see what you make! Hopefully this has helped give you some ideas of how you can learn to code with games.

The post Learn to Code with Games: The Long Dark appeared first on www.nadyaprimak.com.

Top comments (0)