javascript text game js13kgames tutorial

js13kGames Tutorial – How to Make a Text Game with HTML5

Most games focus on impressing you with beautiful artwork and graphic assets. Computer and GPU performance is pushed further and further in order to render the most elaborated game graphics.

But what if you could make games that leave the rendering and graphic asset creation aspects to the world’s most power GPU: your imagination?

That’s when text games come into play. A text game uses the API of your brain to render it’s contents directly into your visual cortex, saving the developer lots of time, and giving the player the freedom to imagine (or “render”) the game content as they please, same as when reading a book.

This tutorial covers the creation of a text game and it’s inspired by and aimed to help those participating in the js13kGames competition, where the goal is to create a HTML5 game that’s 13kb or less. This event is organised by Andrzej Mazur and it runs every year.

The total size of this game is 7.7kb zipped, so we don’t even have to bother with minification.

The Game

The game we’ll create is inspired in the PC classic Oregon Trail, where the goal was to lead an expedition of settlers to the Far West in 19th century US.

This game will be created using only HTML, CSS and JavaScript. No external libraries will be used.


Whether you are familiar with this game or not, it doesn’t matter. The way our game works is as follows:

  • You command an expedition in which you have a number of people, food, money, oxen (to carry things) and firepower.
  • You have to reach 1000 km to your destination.
  • Food is consumed as you go.
  • You can only carry a certain amount of weight (depending on how many people and oxen you have).
  • If you run out of crew members or food, it’s game over.
  • As you travel, there will be random events and sometimes you have to make decisions.
  • If you find shops, you can buy things.
  • If you are under attack, you can choose to fight or flee.

This is what our final game will look like:

javascript text game js13kgames tutorial

Artwork Licenses

The caravan sprite was created by Andrettin, licenses CC-By-SA 3.0 and GPL 2.0. The rest is all public domain.

Tutorial Source Code

You can download the source code of this tutorial here(just double click on index.html to play, you don’t need a web server for this game).

Don't miss out! Offer ends in
  • Access all 200+ courses
  • New courses added monthly
  • Cancel anytime
  • Certificates of completion

Basic Structure

We’ll start by putting together some of the files we’ll use.

For now we won’t be showing anything to the user. It will all be done via console. Afterwards we’ll take care of displaying everything on the screen. To begin, let’s create a minimal HTML file (we’ll add more stuff to it later). You can create a blank CSS file as well:

Caravan.js will contain our caravan object (OregonH.Caravan) with an init method.

The Caravan object will keep the caravan properties and will take care of things such as weight calculation, distance calculation and food consumption.

In regards to:

This is called a namespace. We are using the OregonH object in all different files so that we don’t pollute the global scope. If this object is not present, it is initialized by an empty object.

Game.js will contain some constants we’ll need in our game (you can tweak these to modify the game). They will be explained as they appear in the tutorial. The “Game” object OregonH.Game will take care of the main game aspects such as game starting, game pausing/resuming, and the simulated time step.

When it comes to game parameters such as these, there is always the question of “how do you come up with them”. The way I usually do it is I try with any number for say “food weight”, then if the game doesn’t feel right I change it. I do that with all parameters until the game feels balanced.

You can type in the console of your browser and it will give you access to the caravan object with the properties we game it.

The Caravan

Let’s implement the full caravan object:

  • Update walked distance
  • Calculate weight
  • Drop items if too much weight


Regarding the distance update in updateDistance, the caravan goes faster or slower depending on the free capacity. If the caravan is running close to full capacity, it goes slower. This distance update method is meant to be called on each “game step”.

When it comes to weight calculation, both people and oxen can carry things (as defined by the corresponding constants).

If there is too much weight, guns are dropped first, if there is still overweight, then food is dropped.

What about this.ui.notify? We still need to create the UI object which will take care of showing things to the user. If you want to have a play in the console with what we have so far you’ll have to replace these by console.log() calls.

Basic Game Step

Now that we have the caravan model in place we can setup the basic game step and initialisation part, including winning the game or game over.

Let’s start by creating the UI object in UI.js. Add this file to index.html. Also add an Event.js file that we’ll use later:

Event.js skeleton. This will be used later to represent the logic behind random event generation:

UI.js for now:

The “type” refers to whether it’s a positive, neutral or negative message (like you got killed for instance). When we add the UI this will be represented by a different color.

Game.js with the basic step and flow setup:

If you load this up with the console open, you’ll be able to see how over time distance is covered and food is consumed. If food runs out it’s game over, if you have zero people it’s game over, if you reach the distance defined in the constant OregonH.FINAL_DISTANCE you win the game.

The step method gets called the first time from within startJourney. That first time we capture the current timestamp and save it as a “previous time”. At the end of step, we call requestAnimationFrame with the same step method.

When step is called again, we will still need to access the Game object with “this”, so we use bind for that. To learn more about bind go to this Mozilla Foundation tutorial.

The game is only running if this.gameActive is true, so we can use that to stop the game both for pausing (and switch back for resuming) and for game over / winning.

Visual Stats and Progress Tracking

Let’s add some HTML and CSS so that we can see what’s going on and get a visual progress tracker. We’ll also use this occasion to add containers and style for the shop and battle panels.

Important: Since I’m trying to stick to the 13kb limit, I’ll be doing all DOM accessing and manipulation with raw JavaScript. If you are not under this limit I’d strongly recommend using a framework like Angular (that’s what I would use) instead. There are also microframeworks that can be very lightweight if you don’t mind the learning curve.

Index.html will look like so:

And style.css:

We can now add proper DOM manipulation in UI.js and keep track of the progress of the caravan, so that when it indicates how close you are to the goal:

This is what the UI should look like:

basic ui text game

Random Events

How often a random event will occur is defined by the constant OregonH.EVENT_PROBABILITY. I’ve set a value of 0.15 which means on each step there is a 15% chance that there will be a random event.

We’ll have 3 types of random events, but it should be pretty straight forward to add more types, and more variations of these 3 types:

  • Caravan stat change: any stat of the caravan can increase or decrease in value. For example you can find wild berries and increase your food, or there can be a flu event and some of your crew can perish.
  • Shop: a place where you can buy things.
  • Attacks: you are under attack, you can either fight or flee.

We’ll trigger random events in the updateGame of our Game object. Add the following by the end of that method (after we check for winning the game):

Let’s begin implementing “Caravan stat change” events first. The generateEvent mentioned there will randomly pick and event from a list and will “execute it”.

Event.js will have the following code:

Event.eventTypes will have all possible events. Properties:

  • type: refers to what type of event this is. See how they are all of type “STAT-CHANGE” for now.
  • notification: positive, neutral or negative
  • stat: which property of the caravan we are changing
  • value: how much are we changing this property by (it can be positive or negative)
  • text: what we show to the user in the message log

For stat change events we have the stateChangeEvent method which carries out the increment (checking of course that we don’t have negative properties).

random event


Roads can be pretty dangerous and in this game you will be attacked often. When you are attacked you can either flight or flee. It all depends on your firepower, crew members and risk profile. If you do engage in battle and win you’ll get money from the loot.

Event.js with battles:

The firepower and money of the enemies gets randomly modified. showAttack goes in our UI.js file and it shows an attack screen where you can make your choice.

As I mentioned before, if it wasn’t for the 13kb limit I would prefer to use Angular. Feel free to explore microframeworks for some lightweight DOM manipulation libraries.

Basically if you choose to run away, it won’t matter how much firepower you have, but if you fight, you can have a chance at winning the battle and getting some extra cash.


Shops will appear on your journey in the same way as the other random events. The contents of a shop will be random, based in what the initial shop items:

When it comes to show displaying, Angular would have made this very clean but constraints are contraints!

In UI.js

html5 game shop

Game Finished!

You’ve completed a basic text game with HTML5, all of it in under 13kb!

battles text game html5

Leave a Comment!

Got some questions? feedback? what other topics would you like me to write about?