Taking a look at the Turbulenz HTML5 game engine

So a couple weeks back there was an announcement that the Turbulenz HTML5 game engine was being open sourced. It was one of those projects I had intended to check out when I got the time…. which I finally did.

 

What is Turbulenz?

Turbulenz is an HTML5 game engine and platform. You can create and publish your game on Turbulenz and they take a 30% cut of sales ( this of course is their business model, and 30% is fast becoming the digital norm ). You can also publish to other sites ( your own, Facebook, Kongregate ) completely free. The most recent version of Turbulenz now offers TypeScript support.

 

Installing

You need to sign up and verify your email then log in to the developer portal.

There are downloads available for Windows, MacOS and LInux. Windows ships as a exe installer, while the other two ship as .run files. On Mac or Linux simply open a terminal window and chmod +x the file you downloaded, then execute it.

Before you install you need to install the CG Toolkit! It is available from nVidia right here. With that done, the install is simply a series of yes/no questions. The script will however prompt for your admin password. I was running Snitch ( packet detector ) during the install and no outbound requests were made, so you should be safe entering it.

 

What you get?

Now that it is installed, you should see a file hierarchy like this:

Turbulenze doc structure

 

Samples are pretty impressive, there are dozens of them covering topics from physics, to video, particles, model loading and more. In the assets folder, there are a fair number of resources to get you started. They include models, shaders, materials, fonts, video etc.

 

Perhaps most impressive though is the documentation. In the docs folder there is a pdf and html… now get this…

Turbulence Doc Length

 

That’s the end of the table of contents, and yes… that is 949 pages! So, lets just say Turbulenze is well documented! You should be able to access the documentation online by clicking here.

 

Running Turbulenz

Open a Terminal and change directory to the SDK install location. In my case, installed using the defauls the directory is /Users/Mike/Turbulenz/SDK/0.25.1

Then type source env/bin/activate

Now finally run it by typing ./start_local.sh

Local turbulenze running in browser

Here is one of the samples, a 3D model sample, running in the browser. Please not, the choppiness is the results of the gif framerate, not the demo. It runs at least 30fps on my Macbook Air.

 

Turbulenze3DSample

 

 

Hello Turbulenz — A simple Turbulenz project

We are going to create a “simple application” that displays a Hello World graphics on scene. We may be redefining the word “simple” in the process!

First you start off creating a new project using the Turbulenz web interface ( http://127.0.0.1:8070 ). Full instructions are in the documentation.


Creating a new application

CreateNew

 

Once your project is made you need to run a build process.

makehtml –mode canvas-debug -t templates -t . -o HelloTurbulenz.html HelloTurbulenz.js

This generates the HTML file ( HelloTurbulenz.html in this case ) for your project. Each time you change your source, you need to run this process again. I have to admit I found this annoying, as the lack of a build cycle is exactly what I like about HTML5 development in the first place! Anyways, next up we need to create a resource mapping file. You can’t simply access files like “myImage.png”, you need to create a mapping.

Create a new file named mapping_table.json and add the following contents:

 

{    "version": 1.0,    "urnmapping": {        "textures/helloWorld.jpg": "helloWorld.jpg"    }}

 

 

This file basically says The file at “/textures/helloWorld.jpg” actually resides in the file “helloWorld.jpg”. Once you have defined your mapping table, you need to add it to your application configuration in the Turbulenz web app!

 

Configuring the mapping table

Manage1

Manage2

 

You need to create a folder in your application directory named staticmax ( no idea why that name btw… ) and put your image there, I used the following image:

HelloWorld

 

Textures in Turbulenz need to be power of 2. This particular image is 512×256 and named helloWorld.jpg.

 

Now let’s take a look at the code:

/*{{ javascript(“jslib/draw2d.js”) }}*/

/*{{ javascript(“jslib/requesthandler.js”) }}*/

/*{{ javascript(“jslib/services/turbulenzservices.js”) }}*/

/*{{ javascript(“jslib/services/turbulenzbridge.js”) }}*/

/*{{ javascript(“jslib/services/gamesession.js”) }}*/

/*{{ javascript(“jslib/services/mappingtable.js”) }}*/

/*{{ javascript(“jslib/canvas.js”) }}*/

/*global TurbulenzEngine: true */

/*global TurbulenzServices: false */

/*global RequestHandler: false */

/*global Canvas: false */

 

TurbulenzEngine.onload = function onloadFn() {

var intervalID;

 

var gd = TurbulenzEngine.createGraphicsDevice({});

 

var draw2D = Draw2D.create({graphicsDevice: gd});

 

var requestHandlerParameters = {

};

var requestHandler = RequestHandler.create(requestHandlerParameters);

 

var helloTextureLoading, helloTexture = null;

 

 

var mappingTableReceived = function mappingTableReceivedFn(mappingTable) {

helloTextureLoading = gd.createTexture({

src:mappingTable.getURL(“textures/helloWorld.jpg”),

mipmaps:true,

onload: function(texture){

helloTexture = texture;

}

});

};

 

var gameSessionCreated = function gameSessionCreatedFn(gameSession) {

TurbulenzServices.createMappingTable(requestHandler, gameSession, mappingTableReceived);

};

var gameSession = TurbulenzServices.createGameSession(requestHandler, gameSessionCreated);

 

function tick() {

gd.beginFrame();

draw2D.begin();

if(helloTexture !== null)

draw2D.draw({

texture: helloTexture,

sourceRectangle:[0,0,512,256],

destinationRectangle:[0,0,512,256],

origin:[0,0]

});

draw2D.end();

gd.endFrame();

}

intervalID = TurbulenzEngine.setInterval(tick, 1000/60);

 

};

 

If you run that code, you see:

HelloWorldTurbulenz

 

One thing that needs to be looked at right away is the comments at the top of your code:

/*{{ javascript(“jslib/draw2d.js”) }}*/

/*{{ javascript(“jslib/requesthandler.js”) }}*/

/*{{ javascript(“jslib/services/turbulenzservices.js”) }}*/

/*{{ javascript(“jslib/services/turbulenzbridge.js”) }}*/

/*{{ javascript(“jslib/services/gamesession.js”) }}*/

/*{{ javascript(“jslib/services/mappingtable.js”) }}*/

/*{{ javascript(“jslib/canvas.js”) }}*/

/*global TurbulenzEngine: true */

/*global TurbulenzServices: false */

/*global RequestHandler: false */

/*global Canvas: false */

 

These are build instructions for Turbulenz and are processed when you run makehtml. These are the dependencies of your application. You will spend some time adding and removing libraries to resolve various build snafus.

 

The rest of the code is fairly straight forward, if a bit more involved than you would normally expect. If you are new to JavaScript asynchronous programming, following the programs execution might be a bit confusing.

 

We start off creating a number of required Turbulenz subsystems. Then we define a method that will be called once the mapping table is loaded. Inside we create our texture, then when it’s unload function is fired, we assign the results to our variable helloTexture. Next we create our game Session, this is where createMappingTable is actually called, leading to the above callback being fired.

 

Next we create a function tick(), which is essentially our game loop. Each “loop” through the game loop ( or each time tick is called ) we call beginFrame() on the GraphicsDevice and begin() on our Draw2D object. If you have done any OpenGL programming, this will look immediately familiar. If our texture is loaded ( the joys of async processing… ) we draw our texture on screen.

 

After we define our tick() function, we then set Turbulenz to call it every 60th of a second by calling setInterval.

 

 

Of course, this is a very simple example, it doesn’t use 95% of what Turbulenz has to offer, but does show you the workflow of working an Turbulenz, as well as what a simple application looks like. The framework itself is amazingly comprehensive and performs quite well on every browser I tested. On the other hand, it’s complicated… sometimes needlessly so. This simple sample took me FARRRRRRRR too much time to figure out all the various hurdles ( adding assets, project layout, running and hosting applications, the compilation process, etc… ), but you only have to do that once. In all honesty, I spent about 3x longer on this than I expected to! Turbulenz has very good documentation, but you need to know what you are looking for and that is often the most difficult process. What I haven’t shown today are the supporting tools that ship with Turbulenz, like the Collada -> JSON converters, nor the platform services that the Turbulenz server offers.

 

If ease of use or simplicity is a priority for you, I highly suggest you look elsewhere ( three.js perhaps ). If you want to bundle your application for portables using PhoneGap, CocoonJS, etc… I think you are out of luck with Turbulenz. However if you want a complete and capable 3D HTML engine, with a complete asset pipeline and backend services and are willing to put up with the build process and the occasional bout of head scratching, Turbulenz is certainly worth checking out. Just advanced warning… it aint easy!

 

Edit there is a nearly 2 hour getting started webcast I’ve embedded below

 

 


Scroll to Top