Let’s write a Chip8 emulator in Kotlin [Part 0: Motivation & Setup]

Disclaimer

This series is a means for me to learn Kotlin. As such i might misuse some features of Kotlin, not follow best practices or simply to silly things. Please always check the comment section for feedback from more knowledgable people. I’ll also have follow up articles where i refactor the code to be more idiomatic. So, make sure to check back.

Why?

I recently started looking into alternative JVM languages. After a short interaction with Scala, i looked into JetBrains’ Kotlin. When learning a new language/platform, i usually write a simple application that allows me to iteratively explore new concepts and features. For my adventure in Kotlin i chose to write a Chip8 emulator.

My goals with this little series are as follows:

  • Learn a bit of Kotlin
  • Document my journey
  • Get feddback from Kotlin users
  • Show how to write a simple emulator

My non-goals are:

  • Teach anyone Kotlin, use the official docs if you want to learn it all
  • Write the most efficient and precise Chip8 emulator

Let’s get going.

Setting up a Kotlin project

As stated earlier, i’m not going to try and teach anyone Kotlin given my knowledge level. Instead i’ll comment on the tooling surrounding Kotlin. What i present may not be best practices but it’s what has worked for me.

The project i’m going to set up has to fulfil these requirements:

  1. Build management and packaging
  2. Dependency management
  3. IDE integration
  4. Version control

Requirements 1 and 2 can be achieved by choosing one or combining multiple of the following tools: Ant, Ivy, Maven, Gradle, SBT and so on. I’m going to use Gradle as there exists a first class Gradle plugin for Kotlin. It’s also quite a bit less verbose than Maven and hence suitable for a textual series like this.

Being a brain-child of JetBrains, Kotlin has first class support in Intellij IDEA, so that’s what i’m going to use. Quite a change for an Eclipse guy like me.

On the version control front i’m going to go with Git, hosting a repository on Github.

Given these choices, i need to install the following:

  • Latest JDK (make sure the bin/ folder is in your PATH)
  • A Git client (TortoiseGit on Windows, on Linux use your package manager, on Mac OS X use homebrew to get the latest and greatest)
  • Intellij IDEA 13 (community edition will do)
  • Gradle (make sure the bin/ folder is in your path)

Project Structure, Build and Dependency Management

Let’s start by setting up a few folders and files for our project. We’ll add a build.gradle file describing our Gradle build first:

The buildscript block is required to pull in the Kotlin Gradle plugin (line 6). Line 10 and 11 specify that this project uses both the Kotlin and Java plugin, allowing us to mix and match the two languages if required. Next we define the repositories from where dependencies are fetched. For now, the only required dependency is the Kotlin standard library (line 18). Finally i added two tasks (run, dist) to run the project and package it into a JAR for distribution. Note line 21 where i define the main class. That class name is used by the run and dist to execute our app and package our app as a runnable JAR respectively.

The wrapper task pulls the Gradle wrapper files into our project structure. This will allow other people to work with the project without installing Gradle themselves.

The last missing bit is a source folder and main entry point. Per convention, the Kotlin source files are placed under src/main/kotlin, Java source files are put into src/main/java. Tests go into src/test/kotlin and src/test/java respectively. I put a very simple Hello-World style Kotlin app in src/main/kotlin/chip8/main.kt:

Where is the Chip8Package class we defined as the main class in the build.gradle file? Turns out that Kotlin will put all top-level functions of a package into a synthetic class called <Packagename>Package. We therefor have to specify that synthetic class for the JVM to run our main function.

Before moving on, we’ll invoke the wrapper task to pull the Gradle wrapper into our project:

The wrapper is composed of two script files (gradlew for *nix and gradlew.bat for Windows) and a folder called gradle/ which contains a tiny JAR and a properties file. From now on, we’ll invoke the script files (gradlew, gradlew.bat) in our project directory.

Running the app on the command line is as simple as calling the run task:

Note that we now use the gradlew script instead of our local Gradle installation. The first time the wrapper is invoked, it downloads the Gradle version we specified in the wrapper task and installs it. This may take some time but won’t be repeated on subsequent invocations.

We can also package our app as a runnable JAR via the dist task and run that JAR:

The project layout now looks like this:

IDE Integration

Before we can import our project into Intellij IDEA, we need to install the IDEA Gradle plugin. Fire up IDEA, on the welcome screen go to Configure->Plugins, click on Install JetBrains plugin, search for Kotlin and install the plugin.

We can now import the project by clicking on Open Project on the welcome screen, navigating to the project folder and select the build.gradle file. IDEA will ask us some specifics about our Gradle project. Make sure to select Use customizable gradle wrapper, so IDEA uses our wrapper properly.

Once loaded, we can run our main function. The simplest way to do this is to open up the main.kt file in IDEA, right click and select Run 'chip8.Chip8Package':

This will also create a configuration for us which we can use to launch and debug the app later on. Speaking of debugging, it works as you expect. Simply create a breakpoint in a source file in the line number margin on the left and start your app in debug mode:

Version Control

Time to push our master piece to Github. I created a Github repository called chip8 which you can follow along. Since we already have a folder, we can initialize the repository with a few magic incantations on the command line:

We should also create a .gitignore file so we don’t commit the build directory, IDEA project files and so forth:

Let’s add our initial set of files, commit and push them to the remote repository:

Let’s also tag this state:

And we are done!

Up Next

You can now simply clone the repository and follow along the rest of the series, provided you installed all the tools we talked about earlier.

In the next article we’ll write a simple Chip8 ROM disassembler.

Following Along

  1. Install the required tools (JDK, IDEA, IDEA Kotlin plugin, Git)
  2. Clone the repo: git clone https://github.com/badlogic/chip8.git
  3. Checkout the tag for the article you want to work with: git checkout part0
  4. Import the project into IDEA (Open Project, select build.gradle file, select "Use customizable gradle wrapper"

Happy coding!

libGDX 1.4.1 released

Time for a new release, here’s the changelog:

In addition to the changes in the main repository, we have two new extensions (which are maintained outside the libGDX repository).

  • gdx-ai contains all kinds of nice stuff, from state machines to steering behaviours.
  • gdx-pay is our in-app purchase API which is currently a work in progress.

Very Important

We updated to all the latest 3rd party tools we use. This implies that you have to update a few things on your end:

  • Eclipse 4.4.x users MUST update to the latest Gradle Integration (3.6.2+). Update URL: http://dist.springsource.com/release/TOOLS/gradle
  • Eclipse users MUST update to the latest RoboVM Plugin (1.0.0-alpha-04). Update URL: http://download.robovm.org/eclipse/
  • Intellij IDEA users MUST update to 13.1.5+ because older versions don’t support Gradle 2.1, which is required by the Android plugin
  • Update your Android SDK build tools to the latest (20) and for good measure also get the latest Android version (20) via your Android SDK manager
  • You MUST update XCode to the latest version (6.0.1+). Make sure you open it once and agree to the license

In addition to this, you may experience a few minor issues with RoboVM which we hope to resolve in upcoming RoboVM releases:

  • If you want to deploy to a device that has been restarted recently, you MUST deploy a demo app via XCode first. The reason being that the library we use to deploy apps to a device hasn’t been updated for the latest XCode/iOS versions. Simply create a new XCode iOS project and run it once. We hope to resolve this issue soon
  • You can now specify what type of simulator you want to start via the Gradle command line or within the Eclipse Launch Configuration of your iOS project. If your app fails to launch on the simulator, go to the launch configuration and select a different simulator. Old launch configurations can’t be migrated properly.

Let us know if you run into any issues. See this wiki article on how to update your libGDX project to the latest version. The current libGDX version is “1.4.1”, the current nightly version is “1.4.2-SNAPSHOT”, OR you can just check our all new versions page which details all the versions of dependencies as well. Thanks Tomski!

If you migrate an old project and want to support iOS 8, you MUST add new launch images, see the x3.png files here.

Happy coding!

libGDX wins Duke’s Choice Award

Damn right. The Duke’s Choice Award is an anual thing given out by a jury of judges as well as the community to projects from the Java realm based on various criteria. It’s one of the biggest honors you can get in the Java world. Here’s the Java Magazine article on the winners, including my ugly face, Robotality’s Halfway and Interrupt’s Delver (which you should both buy and play the hell out of):

The story behind that photo is actually quite funny. Oracle send a photographer from the Netherlands to my place in Graz, via car. He took about 500 images. I felt very special that day…

Thanks to all the contributors, this award goes out to all of you (you can put it on your resume :D).