turbulenz / turbulenz_engine

Turbulenz is a modular 3D and 2D game framework for making HTML5 powered games for browsers, desktops and mobile devices.
http://turbulenz.com
MIT License
4.57k stars 513 forks source link

================ Turbulenz Engine

Turbulenz is an HTML5 game engine and server-side APIs available in JavaScript and TypeScript for building and distributing 2D and 3D games that run on platforms that support HTML5 features such as modern browsers without the need for plugins.

.. contents:: :local:

Examples using the Turbulenz Engine

Games

Apps

Prototyping

Samples

Features

Low-level API

Graphics

Math

Physics

3D

2D

Sound

Networking

Input

High-level API

Scene Graph

Animation

Resource Manager

Server Requests

Deferred Renderer

Forward Renderer

Default Renderer

Simple Renderer

2D Rendering

Draw2D

Canvas2D

Utilities

Turbulenz Service API

Leaderboards

Badges

Payments

Userdata

Userprofile

Gameprofile

Multiplayer

Datashares

Notifications

Metrics

Bridge

Utilities

What Are the Design Goals of the Turbulenz Engine

The main design goals of the Turbulenz Engine are performance, modularity and customizability. Users of the engine should be able to build any kind of game without limitations, in an efficient manner and with an end product that performs optimally when loading and during play.

To achieve this target the Turbulenz team followed these rules when writing code:

Modularity

High performance

Asynchronous loading

Data driven

Simple well documented file formats

Scalability

Power without control is nothing

Fault tolerant

Fast loading

Maintainability

Targeted

History

The Engine was created and is maintained by Turbulenz Limited <http://biz.turbulenz.com>__ and was open sourced in April 2013.

The latest release is 1.3.2 which is tagged in the repository or a tarball/zip can be can be downloaded from here <https://github.com/turbulenz/turbulenz_engine/archive/release_1.3.2.tar.gz>__

A full history of changes can be found in the Changelog <docs/source/changelog.rst>__

Pre-Requisites

The pre-requisites for the open source version of the Turbulenz Engine allowing you to use the various commands are

Pre-requisites for building the tools cgfx2json and NvTriStrip via python manage.py tools

Setup Guide

There are two ways to get up and running with the Turbulenz Engine, you can downloaded a packaged fully QA'd snapshot release from the Turbulenz Hub <https://hub.turbulenz.com>. These installers are available for Windows, Mac OSX and Linux and will install all the required packages and dependencies to get started, a full guide can be found at <http://docs.turbulenz.com/installing.html>

Note: SDK versions prior to 0.26.0 were released under a non open source license.

If you want to run with the latest version or would like to contribute to the open source project the steps for getting setup are included below. Use of the open source repository is tested against Windows, Mac OSX and Linux but may also work on other unix-like operating systems.

Setup

  1. Clone the repository <http://github.com/turbulenz/turbulenz_engine>__ (or if you wish you can fork the repository on GitHub and clone that). To clone the repository maintained by Turbulenz use ::

    $ git clone git://github.com/turbulenz/turbulenz_engine.git
  2. The Turbulenz Engine submodules the following technology in the external folder

    Initialize the Git submodules with ::

    $ git submodule update --init
  3. Check you have the pre-requisites_ installed

  4. From the cloned repository create a VirtualEnv environment to install the required Python packages and NodeJS, allowing you to use all the features of the Turbulenz Engine. Note if Python is not on your shell's path you will need to specify the full path for this first command. ::

    $ python manage.py env
  5. Activate the environment in your shell. ::

    $ source env/bin/activate - for bash and similar shells
    > env\scripts\activate.bat - for Windows
  6. If you want to move onto the API tutorial section next then your final command is to build the JavaScript sources from the TypeScript sources. The next section will detail some of the additional actions you can perform or you can move onto Getting Started With The API_ ::

    $ python manage.py jslib

Working With The Open Source Project

The manage.py script at the top level of the repository provides a set of commands for managing the Engine, the script should be run as python manage.py command on Windows but can usually be shortcut to ./manage.py command on unix shells. Running the script with --help will give a list of commands available, most of these are described below. All the commands other than the env command expect to have the VirtualEnv environment activated as described in the setup section.

Getting Started With The API

To try the Turbulenz APIs requires only a text editor and a browser such as Google Chrome or Mozilla Firefox. Create an HTML file with the following content and place it in the root of the Turbulenz directory::

<html>
<head>
    <title>Turbulenz - API - Clear Screen Example</title>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/debug.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/webgl/turbulenzengine.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/webgl/graphicsdevice.js"></script>
</head>
<body>
    <canvas id="canvas" width="640px" height="480px"/>
    <script>
        TurbulenzEngine = WebGLTurbulenzEngine.create({
            canvas: document.getElementById("canvas")
        });
        var graphicsDevice = TurbulenzEngine.createGraphicsDevice({});

        var bgColor = [1.0, 1.0, 0.0, 1.0];

        function update() {
            if (graphicsDevice.beginFrame()) {
                graphicsDevice.clear(bgColor, 1.0);
                graphicsDevice.endFrame();
            }
        }

        TurbulenzEngine.setInterval(update, 1000 / 60);
    </script>
</body>
</html>

After defining a element of 640x480 pixels, this code will create the TurbulenzEngine and request the GraphicDevice module. Using an update function called at a frequency of 60fps, the GraphicsDevice will clear the screen yellow. To run the example, open the HTML file in your browser. You should see a yellow rectangle.

To use assets such as images you will need to host a HTML file and assets on a webserver. Any webserver will work, a quick way to try is to activate the Turbulenz environment in the root of the Turbulenz directory and run::

python -m SimpleHTTPServer

This command will host the contents of the Turbulenz directory on your machine as a webserver.

To demonstrate loading an asset you can try loading an image file and drawing it as a textured sprite using the Draw2D API. Create another HTML file with the following content and also place it in the root of the Turbulenz directory::

<html>
<head>
    <title>Turbulenz - API - Textured Sprite Example</title>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/debug.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/webgl/turbulenzengine.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/webgl/graphicsdevice.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/draw2d.js"></script>
</head>
<body>
    <canvas id="canvas" width="640px" height="480px"/>
    <script>
        TurbulenzEngine = WebGLTurbulenzEngine.create({
            canvas: document.getElementById("canvas")
        });
        var graphicsDevice = TurbulenzEngine.createGraphicsDevice({});
        var draw2D = Draw2D.create({
            graphicsDevice: graphicsDevice
        });

        var bgColor = [1.0, 1.0, 0.0, 1.0];

        var sprite = Draw2DSprite.create({
            width: 100,
            height: 100,
            x: graphicsDevice.width / 2,
            y: graphicsDevice.height / 2,
            color: [1.0, 1.0, 1.0, 1.0],
            rotation: Math.PI / 4
        });

        var texture = graphicsDevice.createTexture({
            src: "assets/textures/crate.jpg",
            mipmaps: true,
            onload: function (texture)
            {
                if (texture)
                {
                    sprite.setTexture(texture);
                    sprite.setTextureRectangle([0, 0, texture.width, texture.height]);
                }
            }
        });

        var PI2 = Math.PI * 2;
        var rotateAngle = PI2 / 360; // 1 deg per frame

        function update() {

            sprite.rotation += rotateAngle;
            sprite.rotation %= PI2; // Wrap rotation at PI * 2

            if (graphicsDevice.beginFrame()) {
                graphicsDevice.clear(bgColor, 1.0);

                draw2D.begin();
                draw2D.drawSprite(sprite);
                draw2D.end();

                graphicsDevice.endFrame();
            }
        }

        TurbulenzEngine.setInterval(update, 1000 / 60);
    </script>
</body>
</html>

This time, instead of opening the file in the browser, navigate your browser to http://127.0.0.1:8000 or http://localhost:8000 and select the HTML file you created. You should see a spinning textured box in the middle of a yellow rectangle.

The next step is render a simple textured mesh in 3D. To do this you will need to build some assets from their source files. Make sure you have run the tools command to build the tools for your platform::

$ python manage.py tools

Note: The requirements for building the tools is different per platform. See the Pre-Requisites_ section.

For this example you should use the Protolib <http://docs.turbulenz.com/protolib/protolib_api.html>__ library, which is ideal for prototyping games using Turbulenz. You will need these assets::

- models/duck.dae
- textures/duck.png
- textures/default_light.png
- shaders/shadowmapping.cgfx
- shaders/zonly.cgfx
- shaders/forwardrendering.cgfx
- shaders/forwardrenderingshadows.cgfx
- shaders/debug.cgfx
- shaders/font.cgfx
- shaders/simplesprite.cgfx
- fonts/opensans-8.fnt
- fonts/opensans-16.fnt
- fonts/opensans-32.fnt
- fonts/opensans-64.fnt
- fonts/opensans-128.fnt
- textures/opensans-8_0.png
- textures/opensans-16_0.png
- textures/opensans-32_0.png
- textures/opensans-64_0.png
- textures/opensans-128_0.png

Copy this text into a file called "deps.yaml" and place it in the root of the Turbulenz directory. Having built the tools you can now run this command with the Turbulenz environment activated::

$ python scripts/buildassets.py --root . --assets-path assets

This will build the assets listed in the deps.yaml and output a "staticmax" directory and "mapping_table.json" file containing the processed assets and a mapping to them for the webserver. When a library tries to request one of these files, it will be able to find it in the staticmax directory. Now you can create the mesh example HTML file and place it at the root of the Turbulenz directory::

<html>
<head>
    <title>Turbulenz - API - Textured Mesh Example</title>
    <script>
        var TurbulenzEngine = {};
    </script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/debug.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/vmath.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/webgl/turbulenzengine.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/webgl/graphicsdevice.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/webgl/inputdevice.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/webgl/sounddevice.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/webgl/mathdevice.js"></script>

    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/aabbtree.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/assettracker.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/camera.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/draw2d.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/effectmanager.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/fontmanager.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/forwardrendering.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/geometry.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/indexbuffermanager.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/light.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/loadingscreen.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/material.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/observer.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/renderingcommon.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/requesthandler.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/resourceloader.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/scene.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/scenenode.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/shadermanager.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/shadowmapping.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/soundmanager.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/texturemanager.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/utilities.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/vertexbuffermanager.js"></script>

    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/services/turbulenzbridge.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/services/turbulenzservices.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/services/gamesession.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/jslib/services/mappingtable.js"></script>

    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/protolib/duimanager.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/protolib/jqueryextend.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/protolib/simplesprite.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/protolib/simplefonts.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/protolib/simplesceneloader.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/protolib/debugdraw.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/protolib/sceneloader.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/protolib/soundsourcemanager.js"></script>
    <script src="https://github.com/turbulenz/turbulenz_engine/raw/master/protolib/protolib.js"></script>

</head>
<body>
    <canvas id="canvas" width="640px" height="480px"/>
    <script>
        TurbulenzEngine = WebGLTurbulenzEngine.create({
            canvas: document.getElementById("canvas")
        });
        var mathDevice = null;

        var mesh = null;
        var rotationMatrix = null;
        var rotationAngleMatrix = null;

        var protolib = Protolib.create({
            onInitialized: function onIntializedFn(protolib)
            {
                mathDevice = protolib.getMathDevice();
                protolib.setCameraPosition(mathDevice.v3Build(0, 1, -2));
                protolib.setCameraDirection(mathDevice.v3Build(0, 0, 1));
                protolib.setAmbientLightColor(mathDevice.v3Build(1, 1, 1));
                protolib.addPointLight({
                    v3Position: mathDevice.v3Build(-1, 1, -1),
                    v3Color: mathDevice.v3Build(1, 1, 1),
                    radius: 10
                });
                mesh = protolib.loadMesh({
                    mesh: "models/duck.dae"
                });
                rotationMatrix = mathDevice.m43BuildIdentity();
                rotationAngleMatrix = mathDevice.m43BuildIdentity();
                mathDevice.m43SetAxisRotation(rotationAngleMatrix,
                                              mathDevice.v3Build(0, 1, 0),
                                              (Math.PI * 2) / 360);
            }
        })

        function update() {

            if (protolib.beginFrame())
            {
                if (mesh)
                {
                    mesh.getRotationMatrix(rotationMatrix);
                    mathDevice.m43Mul(rotationMatrix, rotationAngleMatrix, rotationMatrix);
                    mesh.setRotationMatrix(rotationMatrix);
                }
                protolib.endFrame();
            }
        }

        TurbulenzEngine.setInterval(update, 1000 / 60);
    </script>
</body>
</html>

This file is quite similar to the previous examples, but it requires a few more Turbulenz libraries to run. This time you should see a spinning duck with a yellow texture on a white background and lit by a static point light.

For more information on how to build your own assets see the assets section <http://docs.turbulenz.com/starter/getting_started_guide.html#assets>__ in the getting started guide.

If you would like to learn more or work through this example step-by-step (with troubleshooting hints), see the Getting Started Guide <http://docs.turbulenz.com/starter/getting_started_guide.html>__ in the documentation.

For more information on the various APIs, see the following links:

Documentation

Full documentation for the Turbulenz Engine can be found at <http://docs.turbulenz.com/index.html>__

This documentation is built from the source restructured text in the docs/source folder of the repository, the latest version online is maintained from the latest release tag in the repository. If you wish to build up to date documentation follow the setup guide and the run the manage.py docs command, this will generate html docs in the build/docs/html folder.

Known Issues

The following known issues exist with using the open source repository version of the Turbulenz Engine, additional known issues also existing in the SDK releases of the engine can be found here <http://docs.turbulenz.com/known_issues/index.html>__

Licensing

The Turbulenz Engine is licensed under the MIT license <LICENSE>__

Contributing

Our contributors are listed here <docs/source/contributors.rst>__

Contributions are always encouraged whether they are small documentation tweaks, bug fixes or suggestions for larger changes. You can check the issues <http://github.com/turbulenz/turbulenz_engine/issues>_ or discussion forums <https://groups.google.com/group/turbulenz-engine-users> first to see if anybody else is undertaking similar changes.

If you'd like to contribute any changes simply fork the project on Github and send us a pull request or send a Git patch to the discussion forums detailing the proposed changes. If accepted we'll add you to the list of contributors.

We include a .pylintrc file in the repository which allows you to check your code conforms to our standards. Our documentation is built from restructured text sources in the docs folder so please consider how your changes may affect the documentation.

Note: by contributing code to the Turbulenz Engine project in any form, including sending a pull request via Github, a code fragment or patch via private email or public discussion groups, you agree to release your code under the terms of the MIT license that you can find in the LICENSE <LICENSE>__ file included in the source distribution.

Links

| Turbulenz game site - turbulenz.com <https://turbulenz.com> | Turbulenz developer service and SDK download - hub.turbulenz.com <https://hub.turbulenz.com> | Documentation for this module and the SDK - docs.turbulenz.com <http://docs.turbulenz.com> | About Turbulenz - biz.turbulenz.com <http://biz.turbulenz.com>