Gamify JS: resources for easy browser roguelike creation
colin-williams-dev
Posted on December 12, 2022
Maybe you've heard of a roguelike video game before, or maybe you haven't... in this blog I will describe the foundations of what makes a roguelike and how to do it in a couple files of JS, HTML and CSS... and perhaps a little bit of why you should along the way.
What's a Roguelike?
- Role-playing - Each player will traverse the game-world from the perspective of one main-player at a time.
- Randomly Generated Dungeons - Roguelike games revolve around a central idea of randomization. Through this, the environment and its inhabitants (living and inanimate) provide unique experiences to the player through the dynamic interplay of each random component. More below:
- Randomly Generated Items - Not only will the environment be random but everything that populates it will be as well. This can be simple such as the occurrence of beneficial health recovery items or stat-increasing equipment or more complex like non-player-characters that can align with the player or interfere!
- Non-modal Abilities - Unlike a lot of current video games where players will unlock new skills or abilities based on an arbitrary amount of experience they gain in the game, roguelikes start the same way they end in regards to the capabilities of the player avatar. All skills are available to the player the moment they begin the game. Only their aptitude and proficiency of using those skills will improve over the time played.
- Permadeath - A final pillar to the roguelike is that when you die... you're dead. Related to the previously mentioned quality of roguelikes each time a player dies they will begin again as a new character (with the same skills) in a new world and the only remaining meta-artifact is the player's own memory of what they have previously encountered.
You may begin to see why the roguelike has a long history of being computer programmers playgrounds; their mechanics are minimal and consistent, but also revolve around randomness. Or it could also be due to its origin in ASCII... In fact, the genre's name comes from the titular game Rogue from 1980 which was a text-based terminal game. But, the history is for another post...
How to Build a Roguelike
So, the fledgling Javascript adept that I am couldn't wait till after school to try to get my hands dirty in the code involved in making these beloved games. Fortunately for me, there is a thriving community in the JS world for roguelikes. What follows is a cataloguing of useful resources for creating minimalist roguelikes with nothing more than a few hundred lines of JS, CSS, and HTML.
Rot.js
ROguelike Toolkit JavaScript (rot.js) is a JS library which facilitates the development of games upon the roguelike foundations I listed above. Rot.js is opensource, free, and the repo can be cloned here: https://github.com/ondras/rot.js#usage
or you can use it like this:
npm install rot-js
Its library hosts tools which help the developer with:
console-rendering
randomly-generated-numbers
path-finding
field-of-view
map-generation
keyboard-input
tile-maps
event-scheduling
The Rot.js namespace data-structure is invoked with the following commands:
ROT.Scheduler
ROT.EventQueue
ROT.Map
ROT.Display
ROT.Noise
ROT.FOV
ROT.Lighting
ROT.Color
ROT.Path
ROT.Text
ROT.StringGenerator
Kenney.nl
Kenney is a free game assets library for developing minimalist games such as our roguelike project. Above I briefly mentioned tile-maps as a feature of rot.js and https://www.kenney.nl/assets/micro-roguelike is where you would get a PNG to use tile-mapping to import 1x1bit sprites from an image-asset for your environments.
To implement this tile set with rot.js we import the asset and assign it to an element:
const tileSet = document.createElement("img");
tileSet.src = "kenney-micro-rogue.png";
Then we map some characters to the 1x1 sprites of our choosing:
var options = {
layout: "tile",
bg: "transparent",
tileWidth: 40,
tileHeight: 40,
tileSet: tileSet, // micro-rogue asset
tileMap: { // characters mapped
"@": [4, 0], // to [x, y] of grid
".": [4, 4], // -->
"P": [11, 0], // -->
"*": [9, 3], // -->
},
width: 18,
height: 20,
}
Object.keys(options.tileMap).forEach(function(k) {
options.tileMap[k][0] *= options.tileWidth;
options.tileMap[k][1] *= options.tileHeight;
})
*code from Chris McCormick roguelikle-celebration-2021 tutorial repo
annotations by me. Below are the sprites we mapped!
And the rest of the code to create the map and initialize our Game when the map has rendered to the DOM!
this.display = new ROT.Display(options);
var digger = new ROT.Map.Digger(options.width, options.height);
tileSet.onload = function() {
Game.init();
}
SFXR.me
And the last resource for today is an awesome 8/16 bit sound generator App called SFXR. https://sfxr.me/
It's super easy to use and you can easily export the generated sounds into your coding environment by pressing the "serialize" button which will output a JSON object to copy/paste. But, you can also just use the library inside your game code:
npm install jsfxr
<script src="https://sfxr.me/riffwave.js"></script>
<script src="https://sfxr.me/sfxr.js"></script>
As I mentioned above, you can use their webApp to generate sound objects OR use the sfxr.generate(preset);
method passing in one of their pickupCoin, laserShoot, explosion, powerUp, hitHurt, jump, blipSelect, synth, tone, click, random
presets. Using either of these ways to generate a sound object you can then utilize it in your code with .play
or further modulate the sound with .mutate
.
In case those aren't enough reasons to start creating a roguelike with JS, and HTML, what about...
CSS
Video games have a quality called "juice". The "juice" of a game refers to simple visual enhancements that make the game "feel" good. These can be elements such as screenshake, dust clouds, muzzleflash, minor object-physics, projectile tracers, etc. And these can all be created using CSS animations and @keyframes
!
Through @keyframes
a developer can manipulate movement/position, rotation, size, and opacity to list a few!
.grow-and-fade {
animation: grow-and-fade 1s forwards;
}
@keyframes grow-and-fade {
from {
transform: scale(1);
opacity: 1;
}
to {
transform: scale(3);
opacity: 0;
}
}
I hope you all found this a least mildly fun to read! It's super easy to get started and hopefully this can be your jump-off point!
"As the moon burned bright above,
I paid my Bedouin guide,
And wondered how long I'd be below."
(randomly generated intro narration from one of my favorite roguelikes: Spelunky)
WORKS CITED
https://github.com/ondras/rot.js - Ondřej Žárarot - rot.js repo/README
https://github.com/chr15m/roguelike-celebration-2021 - Chris McCormick tutorial repo
https://en.wikipedia.org/wiki/Roguelike#Gameplay_and_design
Posted on December 12, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.