For the last two years, I have been working on a very ambitious game. The game is a top down sandbox with multiplayer support. I’m aiming towards a city-based game, where players can wander around a procedurally generated city. One of the main reasons I started creating this game is to learn about multiplayer networking at a low level - client-side prediction, server-side reconcilliation, cheat preventation, and reducing the visual effect of latency.

It’s very hard to debug a crash when no stack traces are printed. It becomes a case of manually trying to find the error.

GET /foo/bar/
Doing something useful
Error: Expected } near ;

ES6 promises doesn’t seem to offer the functionality to change this, and bluebird has on[Possibly]UnhandledRejection, which can only be used if you don’t add a .catch() case to the promise. There is no global callback for a rejection unless it’s unhandled. To workaround this, we’re going to need to override the method which runs the callbacks. This is a little hacky, and relies on the library not changing - but it’s better than swallowing errors.

First, if you haven’t already, install Bluebird.

npm install --save bluebird

Next, make a file somewhere (perhaps called bluebird.js) with this as its contents:

const Promise = require('bluebird')

// Throw errors in promises rather than calling reject()
// Makes debugging A LOT easier
Promise.prototype._rejectCallback_old = Promise.prototype._rejectCallback
Promise.prototype._rejectCallback =
	function(reason, synchronous, ignoreNonErrorWarnings) {
		if (reason.stack) {
			throw reasong
		} else {
			this._rejectCallback_old(reason, synchronous, ignoreNonErrorWarnings)
		}
	}

module.exports = Promise

Alternatively you could just print reason.stack if it exists, however I prefer a full crash whilst debugging. You could also make it possible for promises to declare whether they should throw errors - similar to the throw keyword in Java - and print out the stack rather than crashing in that case.

I created a very short C++ snippet to accumulate a series of Mats into a single Mat strip. It works like acc = acc + m - a new mat is added to the accumulator each time, then stored in the accumulator again.

Example output
Example output
#pragma once
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgcodecs.hpp>
#include <assert.h>

using namespace cv;

class MatStrip
{
public:
	Mat current;
	float scale;

	MatStrip(Mat start, float scale=0.3f):
		scale(scale)
	{
		resize(start, current, Size(start.cols * scale, start.rows * scale), 1.0, 1.0, INTER_CUBIC);
	}

	void add(const Mat &in_o)
	{
		Mat in;
		resize(in_o, in, Size(in_o.cols * scale, in_o.rows * scale), 1.0, 1.0, INTER_CUBIC);

		assert(in.type() == current.type());
		Size sz1 = current.size();
		Size sz2 = in.size();
		Mat im3(sz1.height, sz1.width+sz2.width, current.type());
		Mat left(im3, Rect(0, 0, sz1.width, sz1.height));
		current.copyTo(left);
		Mat right(im3, Rect(sz1.width, 0, sz2.width, sz2.height));
		in.copyTo(right);
		current = im3;
	}
};

Usecase: shells dropping in sync with firing, fake bullets, etc

You must use a particle emitter to create particles, however this doesn’t mean it’s impossible to create single particles on command. You can create a particle emitter which simply adds particles from a queue to the system

#pragma once
#include <SFML/Graphics.hpp>
#include <Thor/Math.hpp>
#include <Thor/Graphics.hpp>
#include <Thor/Particles.hpp>

namespace sfext {

class SingleParticleEmitter
{
	std::vector<thor::Particle> *particles;
public:
	SingleParticleEmitter();
	SingleParticleEmitter(const SingleParticleEmitter& that);
	void operator() (thor::EmissionInterface& system, sf::Time dt);

	void push(thor::Particle particle);
	void push(sf::Vector2f position, sf::Vector2f velocity, float lifetime, float rot=0, float rotsp=0);
};

}; // end namesapce sfext

The above allows you to use the push functions to emit particles. Here is an example of it in use:

SingleParticleEmitter single_emitter;
thor::ParticleSystem particle_system;
particle_system.addEmitter(single_emitter);

// When you need to emit a shell:

single_emitter.push(origin, velocity, 1.0f);
// lifetime of the particle in seconds --^

Here is the cpp file:

#include "singleparticleemitter.hpp"

using namespace sfext;

SingleParticleEmitter::SingleParticleEmitter()
{
	particles = new std::vector<thor::Particle>();
}

SingleParticleEmitter::SingleParticleEmitter(const SingleParticleEmitter& that)
{
	particles = that.particles;
}

void SingleParticleEmitter::operator() (thor::EmissionInterface& system, sf::Time dt)
{
	for (auto particle : *particles) {
		system.emitParticle(particle);
	}
	particles->clear();
}

void SingleParticleEmitter::push(thor::Particle particle)
{
	particles->push_back(particle);
}

void SingleParticleEmitter::push(sf::Vector2f position, sf::Vector2f velocity, float lifetime, float rot, float rotsp)
{
	thor::Particle particle(sf::seconds(lifetime));
	particle.position = position;
	particle.velocity = velocity;
	particle.rotation = rot;
	particle.rotationSpeed = rotsp;
	particle.scale = sf::Vector2f(1.f, 1.f);
	particle.color = sf::Color::White;
	particle.textureIndex = 0u;
	push(particle);
}

Now that Github supports unlimited private repos in all plans, you might as well keep things all together (although definitely have backups elsewhere incase Github is DDOS’d again, dies or goes evil). Simply change “rubenwardy” to your username and “XXXX” to a personal access token with “repo” checked. Also make sure you have an SSH key for Github.

# Clone from bitbucket
git clone git@github.com:samkuehn/bitbucket-backup.git
mkdir bk
cd bitbucket-backup
./bitbucket-backup -u rubenwardy --mirror -l ../bk

# Upload to GitHub
cd ../bk
for D in *;
do
	echo $D
	cd $D
	data="{\"name\": \"$D\", \"auto_init\": false, \"private\": true }"
	curl -i -H 'Authorization: token XXXX' -d "$data" https://api.github.com/user/repos
	git push --mirror git@github.com:rubenwardy/$D.git
	cd ../
done
cd ../

I use a dual monitor setup. For each monitor I have a panel, and each panel has a whisker menu. I found that the favourites section of each of these panels is not synchronised. To fix this, I wrote a simple script.

First, you have to decide which whisker config to keep.

$ cd ~/.config/xfce4/panel/
$ ls
whiskermenu-1.rc  whiskermenu-9.rc

The favourites menu is stored at the top of each file, like this:

$ head -n1 whiskermenu-1.rc
favorites=firefox.desktop,google-chrome.desktop,hexchat.desktop,exo-file-manager.desktop,libreoffice-writer.desktop,libreoffice-calc.desktop,exo-terminal-emulator.desktop

Find the one you want to keep. From this point on, replace whiskermenu-1.rc with the config you want to keep and whiskermenu-9.rc with the one you want to ditch.

The script is as simple as this:

#! /bin/bash

rm -f ~/.config/xfce4/panel/whiskermenu-9.rc
cp ~/.config/xfce4/panel/whiskermenu-1.rc ~/.config/xfce4/panel/whiskermenu-9.rc
xfce4-panel -r

If you save that to /usr/local/bin/syncwhisker, then you can use “syncwhisker” in the terminal to keep your menus the same.

I recently wrote and released a python module to allow fetching of profile data. You can install it using pip:

pip install beautifulsoup4 phpbb-parser

Here’s how you import and use a profile:

import phpbb_parser as parser

username = "rubenwardy"
profile = parser.get_profile("https://forum.minetest.net", username)

if profile:
	signature = profile.signature.text
	location = profile.get("location") or "unknown"
	github = profile.get("github") or "none"

	print(username + " from " + location + " has github " + github)
	print("Signatue: " + signature.text)
else:
	print("Could not get profile!")

profile.signature is a beautifulsoup4 object.

Next: Linking a user account to an external phpBB forum.

To get more than 50% on our coursework, you had to submit extensions. Here are some of my favourite ones.

Pong

Screenshot of Pong
Screenshot of Pong.

I created a Pong clone using C and SDL.

Chess AI

Screenshot of Chess
Screenshot of Chess.

I created a Chess game and Chess minimax implementation in C.

Infinite and Generic Game of Life, and more

Screenshot of Game of Life
Screenshot of Game of Life.

Features:

  • Chunk based infinite universe. Automatically expands.
  • Interactive player and universe editor using SDL.
  • Can set the Born/Survive ruleset code (from command line).
  • Can choose the number to steps to take before opening the player or outputting to stdout (from command line).
  • Has tests.

I was contacted by a client to create a system which calculates the workload for employees based on their assignment to tasks and appointments. The system needs to solve two problems: Firstly, different staff members work different numbers of hours, which makes it hard to allocate tasks fairly and proportionally. Secondly, the client wanted to use the system to analyse past workloads and to anticipate future workload, in order to improve her system of work.

Implementation

Screenshot of ETMS
Screenshot of ETMS.

The solution contains an algorithm to suggest new employees to tasks, based on the type of tasks they are currently assigned to, how many hours they should work a week, and how what they are doing at the time.

The solution was written as a web application, using Python, Flask and SQLAlchemy.

ETMS' Graphs
Server side rendered graphs in ETMS.

Originally I created the graphs using a HTML5 canvas. However, during the first client feedback sesson, I found out they used Internet Explorer with JavaScript disabled. This meant that I needed to move all of the graph rendering to the server. I used the Python Imaging Library (PIL) to do this.

One of the areas in computer science that interests me is artificial intelligence. I’ve done some projects experimenting in this area:

ESME, a pattern matching AI similar to Eliza

ESME is a very old project which uses simple pattern matching to do things like “my name is foo bar” → “Hello foo bar”.

Chess AI

As one of my computer science projects, I created an implementation of the minimax algorithm. Unfortunately, due to time restraints, I was unable to implement optimisations such as composition tables and position hashing. This caused the Chess AI to be limited to only looked 5/6 moves ahead, any more caused minutes worth of processing time. This lack of depth caused it to make bad choices.

Here is a shell script specific for GNU/Linux based operating systems to use. On different operating systems the convert commands will be the same, but the for loop will be different due to a different batch file syntax.

rm /tmp/imageex -r
mkdir /tmp/imageex
for filename in *.png; do
	echo "Processing $filename"
	convert $filename -background White \
		label:$filename -gravity Center \
		 -append -pointsize 14 \
		/tmp/imageex/$filename.png
done
echo "Exporting to PDF..."
convert /tmp/imageex/*.png output.pdf
echo "Done."

Today I’ve been doing some work on a flying simulator I’m calling “Flying Pro II”.

Five or six years ago, I created my first ever 3D video game. It was called “Flying Pro”, and it was part of a set of simple 3D video games I called “Pro Series”, for some reason. The games were made using a demo version of a propietary 3D game engine.

Flying Pro II
Early progress on "Flying Pro II".

Hello 2015! Recently I have created an implementation of the 3D projection algorithm. It is just wireframe models. It works pretty well, except it doesn’t do frustum culling. You still see things that are behind you, but upside down.

The source code of this implementation is available under the WTFPL or CC0 licenses - you can choose which one you want to use. Use WASD to move, arrow keys to rotate, space to ascend and shift to descend.

Hi all! I’m back again for another post. This time I am going to show off a project I have had for quite a while - it is a cellular automaton which simulates the Lotka Volterra equations.

Orange for foxes, brown for rabbits.

The Lotka Volterra equations, also known as the predator prey equations, are used to model the populations of two species over time - a predator and a prey.

Graph of my result (left) next to the graph of the expected result (right).
Cropped. I prefer to use the dark theme with Lichess. There is a 3D mode available.

Lichess is an online chess game and community. It is free and open source, ad-free and subscription-free. You can play against your friends, random strangers and the computer. You can create teams to compete in tournaments. There are tournaments going on all the time.

There are different game modes available, but I don’t really touch these. Chess960, King of the Hill, Three-check, From position. You can request that your game is analysed by a chess engine, it gives you suggestions on what you should have done. I like how it shows a graph of how much of an advantage one player has over one another.

Lichess is also good for becoming better at chess. Chess puzzles are available in the training section, where you have to choose the best move in a given situation, and follow it through to checkmate. Players can create their own puzzles.

It is truly better than the alternatives. Chess.com is cluttered with ads and has an uglier design - minimalism is the way forward. Lichess is free and open source, and always will be.

Recently I have been looking at languages and compilation: VMs, parse trees, lexers, and interpreters. Nand to tetris is a pretty awesome guide to how the CPU executes programs - from logic gates to high level languages.

Assembler and Bytecode VM

I created an assembler and Virtual Machine to run assembly style instructions. I haven’t released it as it isn’t as complete as I want it yet.

Parse Trees and Reverse Polish Notation (RPN)

Turns a string such as “( 0 - (6) + ( 6 ^ 2 - 4 * 1 * 5 ) ^ (1 / 2) ) / ( 2 * 1)” into a binary syntax tree, and then into Reverse Polish Notation, and then executes it.

Lexical Analyser

I have also experimented with a simple Lexical Analysisor, however it’s not at a state that I’d like to release.

Rufunge

Befunge is an esoteric programming language - a language which isn’t meant for pratical use, but rather to test programming use. The language consists of a two dimensional grid of characters. Each character is an individual instruction. I was disappointed that the authors didn’t take it seriously enough, and didn’t add input and output to it. So, I created my own! I called it ‘Rufunge’. It’s not finished yet, but can currently run most Befunge programs.

Mesecode

Mesecode is a language which compiles to Lua. It’s purpose it to make definitions in Minetest easier to read.

Instead of:

minetest.register_node("default:stone", {
    description = "Stone",
    tiles = {"default_stone.png"},
    is_ground_content = true,
    groups = {cracky=3, stone=1},
    drop = 'default:cobble'
})

You can write:

mod default

node Stone
    is ground, cracky=3, stone
    drops Cobble