Stage 0 - Introduction
What's different about this tutorial?
- You already have all the software you need: a web browser, a text editor, and an image editor.
- The result will be easily shareable and require no downloads to play
- We'll make all the assets from scratch: code, images, and sound
- No dependencies. No frameworks. No libraries.
- We're aiming for a game that is at least somewhat compelling
In many tutorials, you have to download a bunch of software, fight with versioning problems, write code where a library does all the heavy lifting so you're left with no understanding of how it does it, and glue together premade assets you never figure out how to make yourself. The end result is often a clone or shallow toy that no one would actually want to play anyway.
Features the finished game will have:
- a small map with easily modifiable grid size
- multiple levels
- 5 unique monsters
- collectible treasure
- high scores, preserved across browser launches
- animation and screen shake
We're going to do all that in less than 850 lines of code.
A warning up front: I'm not
going to focus on best practices here. I'm shooting for the shortest and simplest code. For example, I plan to use tons of global variables (generally a terrible idea, but they make things easier on smaller projects). I trust that you can learn the best practices later.
What the hell is a broughlike and why do I care?
is a game designer most well known for a series of cleverly crafted roguelike games, known as "broughlikes", with the following features:
- Tiny grids
- Low randomness
- High replability despite simple rules
The beauty of broughlikes lie in their simplicity. 868-HACK is played on a 6x6 grid and features only 4 types of monsters. So it may appear that this kind of game is easy to produce. Yes and no. Their simplicity belies the excruciating attention to detail and design work that goes into each one. Go read Brough's blog
if you don't believe me.
So these games are very easy to program, but hard to design. A perfect fit if you suspect you might be a talented designer, but a novice programmer. Also great for game jams; 868-HACK started out in the Seven Day Roguelike Challenge of 2013!
I was inspired to create this tutorial after struggling with and failing to complete the Unity 2D roguelike tutorial
. This was embarrassing because I've been programming for over a decade and have made a bunch of roguelikes and even sold one
, but that Unity tutorial was simply too much. The steps required constant cross referencing with a Unity 4 to 5 upgrade guide, they contained random gotchas that broke everything, and there was a bunch of completely unnecessary junk thrown on like box colliders and rigid body physics.
- It's accessible. You can start tinkering with JS in this very tab. You have a fully featured debugger too.
- No compile times. Refresh and see changes immediately. This is HUGE for learning and sustained motivation
While on this page, open the Console in your browser dev tools and follow along. Open the tools with either: Ctrl+Shift+I or
right click and "Inspect" or
from your browser menu). Type commands into the Console
, press enter, and see what you get.
Variables are used to store data and use it later. This is how we declare variables and assign them an initial value in one shot.
Type any previously defined variable like
into the console to see its value.
Declares a global variable (assuming
is not already declared). Global variables will be accessible everywhere.
You don't have to specify a variable's type, though each will still have a type under the hood.
The important thing to know is what types you have available: strings
). There's also objects, arrays, and functions, all of which we'll cover in a moment.
Results in the string "99problems".
Common arithmetical operators are available:
Results in 1.6666666666666667
Results in 2. This is the "modulus" operator; it basically does remainders.
We'll also use comparison operators like:
For anything else, there's the built-in
statement evaluates some expression and runs the inner block if the expression was true. Otherwise the
block is executed.
If you were to run this several times, you would see that the first block is entered only about 25% of the time.
We'll also use two other conditionals: an inline version of
with no braces and the ternary operator
This does the exact same thing as the above code:
Functions are little blocks of code that we can pass data to and from. They help us reuse, document, and organize our code.
. You can assign functions to variables and pass or return functions to other functions. That gives us a ton of flexibility.
You should also be aware there are a few other ways to represent functions such as "fat arrow" syntax, which does pretty much the same thing:
loop evaluates some expression and repeatedly runs the inner block as long as it's true. You can end the loop early with a
loop repeatedly runs the inner block. How many times? That's determined by the expressions in parentheses. Here we're starting at 1, going up by 1 each time, and iterating as long as we're less or equal to 10. The variable
we declare will be useful for accessing array elements...
When you need multiple instances of the same thing (think bullets, tiles, monsters, etc.), arrays are what you need.
Making a new array is dirt simple. You can even prepopulate them.
You access array elements by passing their index (starting from 0) in brackets.
gives you 200.
Here we're creating an array, adding an element with push, iterating over the array, and uppercasing each element.
that we'll be using throughout the tutorial.
Objects also store elements, but with string indexes (keys), instead of numerical ones.
The syntax uses a different kind of bracket and requires keys to come before elements, but is otherwise similar to arrays. You can access properties of an object through either dot or bracket notation.
You don't have to use classes if you don't want to. But I think they're decent for representing certain things in our game.
If this is a little overwhelming, don't worry! Important takeaways are below
- You can make a specialized version of another class with
Later we'll make a Monster class and extend it to make our specific monster type
- You make a new instance of a class with the
operator, which calls the constructor method.
keyword is a reference to the current instance.
OK, let's get started then. In the next section
, we'll figure out how to draw to the screen in just 6 lines of code.