Video Game Design with Rx Programming

In this workshop, you are going to implement a barebones game based on Atari’s Centipede almost from scratch using RxProgramming and ClojureScript.

Motivation

Creating a game from scratch is a hard task. However, with modern tools, it’s a lot more easy than when games like centipede where released. Also, working on different problems related with game engines can teach a lot about the internals of modern video games and consoles.

In particular, the events and message system can be hard to master even with modern engines like Unity3D or Unreal Engine. More often than not we find ourselves implementing collisions or events that involve more than two objects and its action might cancel each other. Think on a mutual desctruction when a missile hits an enemy, which one sends the destroy message to the other one?, which object updates the score? Do the message bubbles up or is lost when one object is gone?, Are they on different threads?, Do they have to sync with shared memory?, etc. All this questions can be modeled using RxProgramming with ease without much thinking on concurrency.

While there are implementation of RxProgramming libraries for multiple languages, Clojure (and ClojureScript) Async is an interesting option. While not promoted as RxProgramming, the streams of clojure async allow for simple handling of concurrency and event composing thanks to channels and transducers. Also, you can find that learning Clojure might be a fun task if you come from a background of classic imperative programming like Python or C/C++.

The tools

We will be using ClojureScript and pixi.js. For that we need to have intalled the following:

  • A Java JDK
  • Node.js

Also, while not required, I recommend to install the following:

  • Visual Studio Code with:
    • Calva
    • Rainbow Brackets
  • Yarn
  • Git

You can download all source code at [http://github.com/juancgalan/RxPixiTutorial]

Java Installation

Our first requirement is the JVM. Because ClojureScript uses google closure for transpiling into Javascript, we need to install a JDK. All examples must work fine with either JDK8 or JDK11. I recommend to install OpenJDK when possible using a package manager.

Nodejs

As second requirement, we need nodejs for running our examples.

All examples where compiled and run using the last nodejs version 11.10.1, I’m not aware if the LST version can run them, so please install the latest version.

Yarn

I like to use yarn for managing node packages, you can install it using the suggested package managers or go to the yarn’s site. However, all examples must work using npm.

The Editor

While all ClojureScript editors should work, I designed all examples using VsCode with the following plugins: + Calva + Rainbow Brackets

I also recommend installing Google Chrome Canary with the Devtools Plugin for extra development tools. However, Canary is not required for running the examples.

Base Project

All source code is available at the github repo. Inside you can find the base folder that contains a barebone project with the required config files. All steps of the workshop are tagged as following:

Each tag contains the answer for each step of the workshop, I strongly recommend to first try to follow along before jumping into each commit. I also recommend to review the commit history at each tag for checking all source code edits in detail.

To start with the workshop, please download the master branch and copy the base folder. After the copy is done, move into the new folder and run the following command if you have yarn installed

yarn install

Or with npm

npm install

This will intall all JavaScript dependencies. Later on the workshop, you will need to install the ClojureScript dependencies, for that you have two options: From the command line run

yarn watch

This command will run a daemon that will update ClojureScript dependencies, compile and hot reload new source code. It will also run a local server at [http://localhost:8000] where you can see the generated code.

If you are using Visual Studio Code you can run a task using Ctrl+Shift+P and choosing run task from the command palette. Then choose to run the watch task without output scanning and you are free to go. Additionally, if you installed the Calva Plugin, you can run Calva Reconnect from the command palette also. When the Calva plugin connects, it will enable intellisense for ClojureScript and start two terminal instances for interacting with live code using the Clojure REPL and the ClojureScript REPL.

Agenda

  1. Introduction​
  2. Video Game Engine Design​
  3. Reactive Programming​
  4. ClojureScript for Rx​
  5. Setting Up The Environment
  6. ClojureScript Hello World
  7. Pixi Tutorial
    1. Hello pixi tag pixi0.0
    2. New pixi stage tag pixi0.2
    3. Load resources tag pixi0.3
    4. Moving sprites tag pixi0.4
    5. Refactoring tag pixi0.5
    6. Edge detection and bouncing tag pixi0.6
  8. Events Implementation
    1. Clopi migration tag clopi0.1
    2. Creating an niteractive development environment tag clopi0.2
    3. JavaScript events tag clopi0.3
    4. A-D Keyboard events tag clopi0.4
    5. Introduction to RxProgramming tag clopi0.5
    6. Clopi Streams tag clopi0.6
  9. Full Game Implementation
    1. Step tag rx0.1
    2. Step tag rx0.2
    3. Step tag rx0.2.1
    4. Step tag rx0.2.2
    5. Step tag rx0.2.3
    6. Step tag rx0.3
    7. Step tag rx0.4
    8. Step tag rx0.5
    9. Step tag rx0.6
    10. Step tag rx0.7
    11. Step tag rx0.8