Fork Me on GitHub

Scalatron

Learn Scala with a Programming Game

Download the game as a .zip file Download the source code as a .zip file

Design Goals

Scalatron is intended as a fun way to learn Scala, both on your own and together with a group of friends or colleagues. It should be easy to get started, yet provide enough depth to keep players engaged for a while.

This intention leads to the following design goals:

This implies a few secondary design goals:

Some of this is achieved in version 1.0, but many areas that could use some polishing remain.

Architecture Overview

Scalatron is a client-server application. The server, which can be installed centrally or on a player’s own machine, continually runs tournaments between bots, which can be either uploaded through the file system to a shared directory or built from sources on the server through the browser UI.

 -----------------------------------------           -----------------------------
|      Scalatron Server Application       |         |  Scalatron Client (Browser) |
 -----------------------------------------           -----------------------------
|                                         |         |                             |
|  -------------------------------------  |         |  -------------------------  |
| |      Embdedded Web Server           | |         | |    HTML / JavaScript    | |
|  -------------------------------------  |         |  -------------------------  |
| |                                     | |         | |                         | |
| |  ---------------   ---------------  | |         | |   ExtJS: Ajax calls to  | |
| | |  Servelets    | |  Resources    |<--------------|   Scalatron REST API    | |
| | | (static HTML) | | (RESTful API) | | |         | |                         | |
| |  ---------------   ---------------  | |         |  -------------------------  |
| |         |                 |         | |         |                             |
|  -------- | --------------- | --------  |          -----------------------------
|           |                 |           |
|  ---------V-----------------V---------  |
| |    Scalatron Kernel / Scala API     | |
|  -------------------------------------  |
| |         |                 |         | |
| |  -------V-------   -------V-------  | |
| | |    Compile    | |   Tournament  | | |
| | |    Service    | |      Loop     | | |
| |  ---------------   ---------------  | |
| |                           |         | |
| |          -----------------|         | |
| |         |                 |         | |
| |  -------V-------   -------V-------  | |
| | |     Game      | |      Game     | | |
| | |  Simulation   | |    Renderer   | | |
| |  ---------------   ---------------  | |
| |                                     | |
|  -------------------------------------  |
|                                         |
 -----------------------------------------

The Server

The server is a stand-alone application written in Scala. It consists of two primary components, which we will dissect in more detail further down:

The Client

The client is a browser front-end served up by the embedded web server. It consists of a minimal set of static pages (such as the login page), which then use JavaScript to access a RESTful web API exposed by the server.

Server Architecture

Server Components

The Scalatron server, which in compiled form is available in the Java archive /bin/Scalatron.jar, provides a range of services which execute concurrently:

Start-up and Initialization

When the server application is launched, it proceeds to initialize itself as follows in its Main class:

Note that the Scalatron kernel, in addition to the thread pool held by the Akka ActorSystem, creates a second thread pool specifically for the execution of untrusted code. All operations executing within this thread pool are monitored by a custom SecurityManager, which allows the server to isolate plug-in code into sandboxes to prevent it from performing undesirable operations on the server.

The Compile Service

Scalatron allows players using the browser-based user interface (Scalatron IDE) to build bot plug-ins simply by clicking a button. The process that makes this possible is as follows:

The Game Simulation

The game is based on a simulation that consists of an (immutable) game state and dynamics that operate on the game state. The simulation is advanced by applying the dynamics to the state, generating a new state.

The dynamics themselves are nested:

A game round is run by sequentially executing a configurable number of simulation steps (applying Dynamics to the state). After each step (and executing concurrently with the next step) a callback is invoked that receives the updated step. Rendering is performed via this callback mechanism, which means that rendering of the prior state executes concurrently with the computation of a successor state.

Rendering

Rendering of updated game states is triggered by a callback invoked from within the simulation loop. The renderer simply takes the given game state and draws it into a BufferedImage, which is them blitted to the screen into the Graphics2D context of an AWT Frame.

Rendering executes in a multi-stage pipeline whose steps execute concurrently. Each step renders some portion of the user interface (background, entities, scores, etc.) into an image buffer, which is then shifted to the next stage. This multi-stage pipelining lets rendering use multiple CPU cores to accelerate the drawing, at the expense of increased simulation-to-screen latency. Since the screen updates are purely for visual inspection purposes and no human intervention is required (it’s a bot programming game, after all), this latency is not of concern.

The Web Server

While the web server receives a reference to the shared Akka ActorSystem, the current implementation based on Jetty does not use this reference. The intention is to eventually replace Jetty with an Akka/Scala embedded web server, such as Spray.

The web server servers a static entry page, index.html, which then allows the user to log-in as a user or as Administrator, which, after authentication, either leads to an editor page or to an administration page.

The web server also exposes a range of resources that implement the RESTful API sepecification. These resources are accessed via Ajax calls by the JavaScript code running in the browser and by Scala code in the Scalatron Command-Line Interface (CLI).

Client Architecture

The client consists of a collection of web pages, some of which contain fairly complex JavaScript code to implement the user interface. Of particular interest is the page that implements the Scalatron IDE. It combines several panels (Tutorial, Editor, Sandbox, Console) to enable a player to do all bot development in the browser, leveraging server-side services for more complex tasks like compilation and simulation.

The client uses Sencha’s ExtJS to generate the user interface and support the Ajax invocations of the server’s RESTful web API. It also uses the ACE editor component to provide syntax-coloring and (for a browser) fairly sophisticated code editing capabilities.

Contributing

If you are interested in contributing, the best starting point is to fork the project on Github and to look at the list of open issues. Before embarking on something major, you could contact the maintainer and ask for feedback or tips on where to get started.

But of course Scalatron is open source and in the public domain, so you are free to do whatever you want.

Coding Conventions

The Scala parts of Scalatron roughly follow the Scala Style Guide, with the following notable idiosyncrasies, which I’d request you respect, if possible, when sending pull requests:

As a final note, I use Jetbrains’ IntelliJ IDEA for development (Scala and JavaScript). One of its nice features are inspections, which tell you about many things that might be suboptimal in your code, such as discrepancies in using parentheses for arity-0 methods etc. Highly recommended.