Lost in the Underworld – Day 1, js13kgames

Alright, I decided to participate for the first time on js13kgames!

The plan is to create a cavern exploration game with a huge world and multiple paths on it, where the player has to find treasures and powerups. I also hope this series of blog posts is more informative and useful than usual.

The idea is to do terrain generation on the fly using Voronoi diagrams and Cellular Automata, also I won’t use pixel art but instead vector graphics (at least for the terrain).

After checking some of the options in the tools page, I decided to use Florent Cailhol’s JS13k Boilerplate. It is probably the simpler starter project there… it has some game loop logic, seedable RNG and gulp scripts for packing and minifying. It also comes with a sample simple implementation for physics.

I started adding keyboard support so you could jump and move around.

const pressed = {};

module.exports = {
	init: function(){
		window.onkeydown = function(e) {pressed[e.keyCode] = true};
		window.onkeyup = function(e) {pressed[e.keyCode] = false};
	},
	isDown: function(keyCode){
		return pressed[keyCode];
	}
}

Also did some foundations of the “physics” system based on the original, since the terrain will be irregular, what I’m doing for the collisions is checking if the future position of the player will be located inside one of the polygons. I used the “inside” function from James Halliday Point in Polygon repo, an implementation of the PNPOLY algorithm. There’s still a lot of potential optimizations to be done.

stones.forEach(function(s){
  if (e.dx != 0){
    if (e.dx > 0){
      if (inside([tx+e.w,ty+e.h/2], s.vs)){
        hCollision = true;
      }
    } else if (e.dx > 0){
      if (inside([tx,ty+e.h/2], s.vs)){
        hCollision = true;
      }
    }
  }
  if (inside([tx+e.w/2,ty+e.h], s.vs)){
    vCollision = true;
  }
}

Had to add a special case for high acceleration caused by gravity, which would make the player go though thing barriers because the updated position would just go through it. For this one I’m checking if the line traced from the current position to the future position intersects the polygon, based on a stack overflow response by Dan Fox.

if (e.dy > 100){
  //Prevent falling through thin borders at high acc
  if (polygonIntersects({
    a: {x: e.x+e.w/2, y: e.y+e.h},
    b: {x: tx+e.w/2, y: ty+e.h}},
    s.vs
  )){
   vCollision = true;
  }
}

Added simple camera support, centered on the player, for this I have a camera object whose position I affect along with the player’s. Then I substract that position from the world position of all objects when it’s time to draw them, to translate them to viewport coordinates.

js13k-2

Then I added super simple Voronoi map gen using Raymond Hill’s JavaScript Voronoi, it adds quite a bit of weight to the package but works pretty nice. I may have to slim it down for the final dist.

js13k-3.1

For now, I’m just randomly picking Voronoi cells, next up will use CA for the caverns to look less random.

var voronoi = new Voronoi();
var bbox = {xl: -300, xr: 1450, yt: 0, yb: 3550};
var sites = [];
for (var i = 0; i < 450; i++){
  sites.push({
    x: rand.range(bbox.xl, bbox.xr),
    y: rand.range(bbox.yt, bbox.yb)
  })
}
var diagram = voronoi.compute(sites, bbox);
const stones = [];
diagram.cells.forEach(function(cell){
  if (rand.bool())
    return;
  let vs = [];
  cell.halfedges.forEach(function (halfedge){
    vs.push([halfedge.getStartpoint().x, halfedge.getStartpoint().y]);
  });
  stones.push({vs: vs});
});

Navigating around the map made evident that my physics system still needs a lot of work. I will post it here once it’s more polished so it can be useful for someone.

I found out the core of the RNG module of the boilerplate isn’t working, so made it use Math.random instead for now. It also seems the current gulp tasks don’t work well with some ES6 syntax, I’ll take care of that later.

Current package size is: 7.13 KB

Static HTML generation for slashie.net website using MustacheJS

I did some back-end changes for the slashie.net website, with the idea of making it easier to include new projects and update their status. About one year ago I went for a single page layout, but was doing maintenance over the HTML file… which was a bit frustrating. With the new approach I can easily manipulate how the list of projects is shown. You can see the current results at slashie.net

I looked around a bit for a static site generator, but in the end decided to roll my own since what I was going for was extremely simple and didn’t want to meddle with the setup of any of these.

What I needed was generating a single HTML file based on a JSON file with the information of all my projects. I decided to go for nodejs using mustachejs for the template; the script is dead simple… I thought I’d share what I did, in case someone needs something similar. This approach gives you a lot of flexibility, as long as you don’t need to maintain a lot of different pages.

Mustache

First, the data, it’s basically a structured list of all my projects

{	
	"sections": [
		{
			"name": "Games",
			"id": "games",
			"items": [
				{
					"title": "Ananias",
					"image": "img/buttons/ananias.png",
					"text": "Dive to the bottom of the Tomb of Ananias using your smartphone or computer. Take adventure with you everywhere!.",
					"status": "published",
					"buttons": [
						{
							"title": "Play Online",
							"url": "http://ananiasgame.com/"
						},
						{
							"title": "Android Version",
							"url": "https://play.google.com/store/apps/details?id=co.slashland.ananias"
						},
						{
							"title": "Desktop Version",
							"url": "http://slash.itch.io/ananias"
						}
					],
					"tags": ["turn-based", "stable", "denzi", "roguelike", "pixel-art", "javascript", "android"]
				},
				{
					"title": "Rodney",
					"image": "img/buttons/rodney.png",
					"text": "Slash your way to the bottom of the Dungeons of Doom, learn new skills and use tactics to survive.",
					"status": "published",
					"buttons": [
						{
							"title": "Play Online",
							"url": "http://games.slashware.net/rodney"
						}
					],
					"tags": ["turn-based", "stable", "oryx", "roguelike", "pixel-art", "javascript"]
				}
			]
		}
	]
}

Now, the generator itself, it basically reads the data and the template, parses the JSON and then renders it using MustacheJS

function generateFile(){
	var file = fs.readFileSync('data.json').toString();
	var template = fs.readFileSync('template.html').toString();
	var data = JSON.parse(file);
	groupByStatus(data); // Groups by status and sorts items
	calculateNewRows(data); // Adds the newRow and endRow attributes
	var output = Mustache.render(template, data);
	fs.writeFile('index.html', output);
}

Now, I had to add the groupByStatus and calculateNewRows functions in order to do some processing over the raw project data (namely grouping the projects by status and grouping them by 3); Mustache declares itself as a logic-less template system, which means it lacks if/else statements or loops. All it does is replacing stuff. You may have to do something similar, depending on how complex you need your page to be.

Finally, this is my Mustache template, as you can see, it’s pretty simple

<!DOCTYPE html>
<html lang="en">
<head>
	<title>Slashie.net</title>
	<link rel="icon" type="image/png" href="img/icon.png">
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
	<link href="lib/bs3/css/bootstrap.css" rel="stylesheet">
	<link href="css/slashland.css" rel="stylesheet">
	<!--[if lt IE 9]>
		<script src="lib/bs3/js/html5shiv.js"></script>
		<script src="lib/bs3/js/respond.min.js"></script>
	<![endif]-->
	<script type="text/javascript" src="lib/jquery-1.10.2.min.js"></script>
	<script type="text/javascript" src="lib/bs3/js/bootstrap.js"></script>
</head>
<body>
<section class = "container">
	<section class = "page-header">
		<div class = "row">
			<div class="col-md-2">
				<div id="logoImage"></div>
			</div>
			<div class="col-md-5">
				<h3>Welcome...</h3>
				<p>I'm Slash. This is my collection of game projects, I hope you like them!.</p>
				<p>You might also want to check <a href = "http://slashwareint.com">Slashware Interactive</a>, which is my brand for finished products.</p>
				<ul class="nav nav-pills">
					<li><a href = "http://blog.slashie.net" target = "_blank">Blog</a></li>
					<li><a href = "https://twitter.com/slashie_" target = "_blank">Twitter</a></li>
				</ul>
			</div>
		</div>
	</section>
</section>
{{#sections}}
<section id = "{{id}}">
	<div class = "container">
		<h1>{{name}}</h1>
		{{#count}}<h2>{{count}} projects</h2>{{/count}}
		<p>{{text}}</p>
		<div class = "container">
			{{#items}}
			{{#newRow}}
			<div class = "row">
			{{/newRow}}
				<div class="col-md-4">
					<div class="thumbnail">
						{{#image}}
						<img src = "{{image}}"/>
						{{/image}}
						<div class="caption">
							<h3>{{title}}</h3>
							<p>
								{{#tags}}
								<span class = "label label-success">{{.}}</span>
								{{/tags}}
							</p>
							<p>{{{text}}}</p>
							{{#buttons}}
							<a href = "{{url}}" target = "_blank" class = "btn btn-primary" role = "button">{{title}}</a>
							{{/buttons}}
						</div>
					</div>
				</div>
			{{#endRow}}
			</div>
			{{/endRow}}
			{{/items}}
		</div>
	</div>
</section>
{{/sections}}

<div id = "footer" class = "text-right">
	<p>Copyright (c) 2004 - 2016 Santiago Zapata</p>
	<p>Generated using <a href = "https://github.com/janl/mustache.js/" target = "_blank">mustachejs</a></p>
</div>
</body>
</html>

You can find the mustache tags in the “sections” section, as you can see mustache interprets each attribute contextually from the source object.

The # mustache tags (for example {{#sections}}) represent a repeating block; the contents inside will be replicated for each one of the objects if the attribute is a list, or once if the attribute exists. (this is used for example on the {{#image}} block, to only show the image tag if the project has an image)

The double and triple mustache tags {{}} and {{{}}} are replaced with the value of the attribute of the given name on the context object. The triple mustache leaves HTML content unscaped, which may be useful if you want to include HTML content directly.

Finally, the {{.}} tag is used to include the value of an object directly, it’s useful for example to include the content of arrays of strings.

And that’s about it! now I can easily add new projects without having the worry about the page layout! My program sorts the projects in alphabetical order and groups them by type and status. What’s also important for me is it takes care of the grouping by 3 items which is required by the way I’m using bootstrap.

And of course, the main point of this is decoupling the data from the view, which in turns takes me to the following point: I may in the future work a bit in the frontend side, to maybe get rid of bootstrap and include some filters…

I hope this is useful for someone to create a simple portfolio or similar page.

Tutorial: Multiplayer Strategy game in Javascript, Part 1

This is part 1 of a tutorial on making a multiplayer strategy game in JavaScript; this part is the result of an one hour live coding session (video here, in Spanish, with lots of background noise and fuzzy code). You can download the source code or play the game online.

What is this about?

We are going to build a multiplayer game players can connect via their browsers; it will be a semi real time strategy game where players struggle to control the territory on the map. This is what it’s going to look like when you finish this tutorial:

First version of Kingdom of Elias

Check out the tutorial here!