Kha Tutorial: Part 1

Kha Overview

Kha is a Zlib-licensed set of modern low-level APIs written in Haxe. When you compile your Kha project, the Haxe compiler generates code for your chosen platform, and Kha generates/builds your program using the appropriate backend. For example, if you build your project for Windows, then the Kha compiler would use a DirectX backend for its graphics APIs.

API Organization/Structure

Kha organizes its APIs based on their type. For example:

  • The "Graphics1" API is an extremely basic one that offers only one operation: setPixel
  • The "Graphics2" API is more advanced, and offers operations like drawImage, drawRect, and even has support for drawing text using truetype fonts. If you've ever used SDL's 2D drawing API, this is similar.
  • The "Graphics3" API is modeled after the old fixed-function OpenGL and DirectX APIs
  • The "Graphics4" API is modeled after modern OpenGL, DirectX, etc with shaders.
  • The "Graphics5" API is modeled after Vulkan, Metal, DirectX12, etc. These are the latest and greatest in the world of graphics APIs, and if you want to be on the cutting edge, this is the one to use.

The cool thing is that Kha is smart enough to use its own APIs to implement itself where possible. So, for example, if you're on a modern system that supports OpenGL, then the Graphics2 API functions would actually be using the same backend for Graphics4. Likewise, you can use the Graphics5 backend for Graphics4.

So let's say you want to make a 2D game using the Graphics2 API, and build it for HTML5 so you can put it on your website. Kha will first try to render the game using WebGL (Graphics4) for hardware acceleration, but if that doesn't work then it will fall back to Canvas (Graphics2). All of this happens automatically without you having to modify your game's code!

Building A Program By Hand

So enough about APIs, let's make a sample program! There are already a couple of tutorials out there that walk you through using Kha with KodeStudio, which is a distribution of VisualStudio Code that comes bundled with Kha's build system. That's by far the easiest way to get started, because it requires no setup.

But instead of that, I'll go through the process of setting up and running a Kha project using nothing more than GNU Make. If you're on Windows, then you can use nmake which is bundled with Visual Studio, install MinGW/Cygwin/etc, or write the commands manually in Powershell or cmd.exe as they're not complicated at all.

Required Software

You first need to install this software if you don't already have it:

  • Haxe
  • Git
  • NodeJS. This is only required for Kha's custom build system

That's it. Just follow standard installation procedures for all of them. In the case of Node, I'm pretty sure it works with either version.

Setup Development Environment

You must first clone the Kha repository, as well as another one called Krom. Krom is a special native runtime for Kha designed to make the iteration process as fast as possible. You don't have to use this, but I'll show you how since most people will likely want it.

Clone Kha

1
2
3
4
$ cd ~/repos #make sure you clone it somewhere sane. It's a large repo
$ git clone https://github.com/Kode/Kha.git
$ cd Kha
$ git submodule update --init --recursive #clone submodules, which includes the various backends

This should take a while depending on your internet speed, as there is a lot of stuff to download.

Clone Krom

There is an official repo that contains precompiled binaries of Krom, since the build process appears to not be finalized yet. The original code repo can be found here

1
2
$ cd ~/repos #again, go somewhere sane
$ git clone https://github.com/Kode/Krom_bin.git #NOTE: this contains precompiled binaries of Krom

Project Directory Structure

A Kha project is actually very simple, and doesn't have many specific structural requirements. All you need is:

  • khafile.js, which tells the Kha build system how your project is laid out, dependencies, etc
  • build folder, which is automatically generated when you build your project, but I'm not sure if/how you can rename it.

So for the sake of this tutorial, I'll just copy the structure that KodeStudio uses by default:

1
2
3
4
5
6
7
MyProject/
  -> Sources/
      -> Main.hx
      -> Project.hx
  -> Assets/
      -> images, audio, fonts, etc
  -> khafile.js

khafile.js

1
2
3
4
let project = new Project('My Kha Project');
project.addAssets('Assets/**');
project.addSources('Sources');
resolve(project);

Sources/Main.hx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
import kha.System;
import kha.Window;

class Main {
    public static function main() {
        var opt = new kha.System.SystemOptions("My Kha Project", 800, 600);
        System.start(opt, onStart);
    }

    public static function onStart(win:Window):Void{
        new Project();
    }
}

Sources/Project.hx

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
import kha.System;
import kha.Scheduler;
import kha.Assets;

class Project {
    public function new() {
        Assets.loadEverything(onAssetsLoaded);
    }

    public function onAssetsLoaded(){
        System.notifyOnFrames(render);
        Scheduler.addTimeTask(update, 0, 1 / 60);
    }

    public function update(){
        //game logic here
    }

    public function render(framebuffers:Array<Framebuffer>){
        //render here
    }
}

That's all you need for now. Haven't explained any of the code yet, but everything should be relatively straightforward so far. Only weird thing is the part about the asset loading. In short: Kha abstracts the bundling/loading of assets. This might seem like a bit of an annoying restriction, but it makes sense once you consider that Kha is designed to target native/C++ as well as HTML5/Javascript from one codebase.

Building and Running The Project

Building the project is actually pretty easy, just use this command:

1
$ node path/to/Kha/make <target>

Where <target> is any supported target. If no target is given, it will build native for your platform. For example:

1
$ node ~/repos/Kha/make html5

will generate the javascript to run your game, along with a basic HTML file to easily serve from the build directory.

Targeting Krom

Again, we want to use Krom because of the fast compile times. To do this is a two-step process. First, build the project using the 'krom' target:

1
$ node ~/repos/Kha/make krom

When that completes, it will generate the folders build/krom and build/krom-resources. With that, we can run the game using the appropriate Krom binary that we checked out earlier:

1
$ /path/to/Krom_bin/win32/Krom.exe /path/to/project/build/krom /path/to/project/build/krom-resources

If all went well, this should launch your recently-built project! If you're not using windows, of course you should use either the Linux or macOS binaries.

Note about Linux

The Krom_bin repository includes a binary for Linux, along with the shared libraries needed to run it. This means that you need to make sure the program loader finds those libraries. The easiest way that should work on most if not all Linux distros is to change the LD_LIBRARY_PATH variable to point to the Krom_bin/linux directory.

Example:

1
$ LD_LIBRARY_PATH=/path/to/Krom_bin/linux /path/to/Krom_bin/linux/Krom /path/to/project/build/krom /path/to/project/build/krom-resources

Using A Makefile

Instead of typing out those commands every time, we can easily create a tiny Makefile to automate the process:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
pathKha=/path/to/Kha
pathKrom=/path/to/Krom_bin
krom=$(pathKrom)/win32/Krom.exe

build: .PHONY
    node $(pathKha)/make krom

run: build
    $(krom) build/krom build/krom-resources

.PHONY:

If on linux, you may want to replace the variable krom with something like this:

1
krom=LD_LIBRARY_PATH=$(pathKrom)/linux $(pathKrom)/linux/Krom

Just save that as a file called Makefile in your project directory (next to the khafile.js), and then run

1
$ make

to build it, or

1
$ make run

to build and run it in Krom!

Next Steps

That's all you need to do to start working with Kha if you don't want to use KodeStudio. I personally like to use SublimeText3 for my projects, and having a Makefile enables me to build and run from within the editor by pressing CTRL+B.

After this, I'll make another short tutorial showing how to actually use some Kha APIs to draw stuff on-screen.