As I've mentioned in the past, I've always enjoyed playing roguelike games such as NetHack, Dungeon Crawl Stone Soup and ADOM. If you've never played these games before I highly encourage you to check them out. The ASCII graphics may not be for everyone but the incredibly deep gameplay more than makes up for it.

I've tinkered on a few home-grown roguelikes in the past and it's always proved to be great fun. Inspired by the most recent 7DRLC, a competition where participants must make a roguelike in 7 days, I went on a search for blog posts regarding developing roguelikes. I found Trystan Spangler's great set of posts on creating a roguelike in Java and then a corresponding set of posts for Clojure by Steve Losh and decided to try my hand at making a set of posts for making one in Javascript. I hope to get through at least a good part of Trystan's series and will try my best to make each post match content-wise.

I will be using rot.js library developed by Ondrej Zara. At the moment of writing, the master branch is ponting to the 81a8eb0d6c commit of the library. If there is any breaking changes in future blog posts, I'll make sure to let you know! The most important file in this project is the rot.min.js file.

Just to make sure everything is up and running, this first post will consist of getting a Hello, World up and running! We will start with a very basic game structure. We'll create an HTML page called index.html and our code will be in a Javascript file under assets/game.js. Note that all the code for this part can be found at the part 1 tag of the jsrogue repository.

Demo Link

The results after this post can be seen here

index.html

This file will be our HTML skeleton and simply includes the rot.min.js from the master branch and the assets/game.js.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<!DOCTYPE html>
<html>
  <head>
    <title>Javascript Roguelike</title>
  </head>
  <body>
    <script src="https://raw.github.com/ondras/rot.js/master/rot.min.js"></script>
    <script src="assets/game.js"></script>
  </body>
</html>

assets/game.js

The first thing we'll want to do is make sure our browser supports the rot.js library. We do this when the page is done loading by using the isSupported function like so:

1
2
3
4
5
6
// Check if rot.js can work on this browser
if (!ROT.isSupported()) {
    alert("The rot.js library isn't supported by your browser.");
} else {
    // Good to go!
}

If our browser has all the necessary functionality for rot.js to function, we're good to go! For this first blog post I just want to get everything set up by getting a canvas up on the screen and using the library to print out Hello, world in a variety of colors. In later posts we will make our game more structured, but for now this will do. All the following code will go in the else branch. We first have to create a display, which will be 80 characters wide and 20 characters tall. Once we've created this display object, we must add it to our HTML page.

1
2
3
4
5
// Create a display 80 characters wide and 20 characters tall
var display = new ROT.Display({width:80, height:20});
var container = display.getContainer();
// Add the container to our HTML page
document.body.appendChild(container);

We've now got our display up and running! We will use the display.drawText function which accepts x and y coordinates as well as a string to print (and an optional width for wrapping). When printing using drawText, we add in color formatting strings to specify the foreground color of the text (using %c{name}%) and background color of the text (using %b{name}%}). In the name of the color we can put any valid CSS color. We will be using the Color library object to convert a color to an RGB specifier via the toRGB function. We're going to print 'Hello, world!' 15 times with the foreground getting lighter while the background gets darker. We put this code right after creating our display:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
var foreground, background, colors;
for (var i = 0; i < 15; i++) {
    // Calculate the foreground color, getting progressively darker
    // and the background color, getting progressively lighter.
    foreground = ROT.Color.toRGB([255 - (i*20),
                                  255 - (i*20),
                                  255 - (i*20)]);
    background = ROT.Color.toRGB([i*20, i*20, i*20]);
    // Create the color format specifier.
    colors = "%c{" + foreground + "}%b{" + background + "}";
    // Draw the text at col 2 and row i
    display.drawText(2, i, colors + "Hello, world!");
}

If worked, you should see the following when you open index.html:

So the final code for game.js is:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
window.onload = function() {
    // Check if rot.js can work on this browser
    if (!ROT.isSupported()) {
        alert("The rot.js library isn't supported by your browser.");
    } else {
        // Create a display 80 characters wide and 20 characters tall
        var display = new ROT.Display({width:80, height:20});
        var container = display.getContainer();
        // Add the container to our HTML page
        document.body.appendChild(container);
        var foreground, background, colors;
        for (var i = 0; i < 15; i++) {
            // Calculate the foreground color, getting progressively darker
            // and the background color, getting progressively lighter.
            foreground = ROT.Color.toRGB([255 - (i*20),
                                          255 - (i*20),
                                          255 - (i*20)]);
            background = ROT.Color.toRGB([i*20, i*20, i*20]);
            // Create the color format specifier.
            colors = "%c{" + foreground + "}%b{" + background + "}";
            // Draw the text two columns in and at the row specified
            // by i
            display.drawText(2, i, colors + "Hello, world!");
        }
    }
}

Conclusion

We've now got a small test application up and running with the rot.js library. All the code for this part can be found at the part 1 tag of the jsrogue repository. I hope you enjoyed this post and that you'll stick around for the next part!

Thanks for reading, Dominic.

Next Part

Part 2 - Screen Management