Getting Unity 3D and node.js talking

I’m working on a Unity 3D game at the moment that needs a global leaderboard system that works across platform and not tied into the likes of Google Play or Game Centre. After taking a look at various technologies including my old favourite .NET (specifically thew newish .NET Core) I decided to use node.js because a) I want to learn it and b) .NET is a bit of overkill I think.

So I installed node.js then wrote a small server:

[sourcecode language=”js”]
"use strict";

var http = require("http");

class Server
{
constructor()
{
this.port = 8080;
this.ip = "localhost";

this.start();
}

start()
{
this.server = http.createServer((req, res) =>
{
this.processRequest(req, res);
});

this.server.on("clientError", (err, socket) =>
{
socket.end("HTTP/1.1 400 Bad Request\r\n\r\n");
});
console.log("Server created");
}

listen()
{
this.server.listen(this.port, this.ip);
console.log("Server listening for connections");
}

processRequest(req, res)
{
// Process the request from the client
// We are only supporting POST
if (req.method === "POST")
{
// Post data may be sent in chunks so need to build it up
var body = "";
req.on("data", (data) =>
{
body += data;
// Prevent large files from benig posted
if (body.length > 1024)
{
// Tell Unity that the data sent was too large
res.writeHead(413, "Payload Too Large", {"Content-Type": "text/html"});
res.end("Error 413");
}
});
req.on("end", () =>
{
// Now that we have all data from the client, we process it
console.log("Received data: " + body);
// Split the key / pair values and print them out
var vars = body.split("&");
for (var t = 0; t < vars.length; t++)
{
var pair = vars[t].split("=");
var key = decodeURIComponent(pair[0]);
var val = decodeURIComponent(pair[1]);
console.log(key + ":" + val);
}
// Tell Unity that we received the data OK
res.writeHead(200, {"Content-Type": "text/plain"});
res.end("OK");
});
}
else
{
// Tell Unity that the HTTP method was not allowed
res.writeHead(405, "Method Not Allowed", {"Content-Type": "text/html"});
res.end("Error 405");
}
}

}

module.exports.Server = Server;
[/sourcecode]

Create a file called server.js and add the above code.

Note that the above code is designed as a module so you can import it into your own code, e.g.:

[sourcecode language=”js”]
var server = require(‘./server’);

var httpServer = new server.Server();
httpServer.listen();
[/sourcecode]

Create a file called main.js and add the above code. Run the server by running node main.js

In the server code we create an instance of a HTTP client then we begin listening for connections. When a connection comes in we read the POST data and print out the key / value pairs that are sent.

On the Unity side we write the following code to test out our mini server:

[sourcecode language=”csharp”]
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;

public class Leaderboards : MonoBehaviour
{
private static string _Url = "http://localhost";
private static string _Port = "8080";

public void SubmitScore(int which, int score)
{
StartCoroutine(SubmitScoreToServer(which, score));
}

private IEnumerator SubmitScoreToServer(int which, int score)
{
Debug.Log("Submitting score");

// Create a form that will contain our data
WWWForm form = new WWWForm();
form.AddField("which", which.ToString());
form.AddField("score", score.ToString());

// Create a POST web request with our form data
UnityWebRequest www = UnityWebRequest.Post(_Url + ":" + _Port, form);
// Send the request and yield until the send completes
yield return www.Send();

if (www.isError)
{
// There was an error
Debug.Log(www.error);
}
else
{
if (www.responseCode == 200)
{
// Response code 200 signifies that the server had no issues with the data we went
Debug.Log("Form sent complete!");
Debug.Log("Response:" + www.downloadHandler.text);
}
else
{
// Any other response signifies that there was an issue with the data we sent
Debug.Log("Error response code:" + www.responseCode.ToString());
}
}
}
}
[/sourcecode]

In the above code we create a form, add the data that we wish to send then create a web request (UnityWebRequest) to send the form to our test server. We send the request then yield the coroutine until the send completes. We finally test the response code to ensure that our data was sent ok,

To test, add the component to an object and then call SubmitScore(1, 100), you should see the following displayed from node:

Server created
Server listening for connections
Received data: which=1&score=100
which:1
score:100

And in the Unity console you should see:
Submitting score
Form sent complete!
Response:OK

At the moment this is still pretty much test code and doesn’t handle security other than to check for idiots sending really POST data. You should really encrypt the data sent to the server to prevent even bigger idiots from spamming your server with false information.

Next I will be looking at redis as a persistent store for my leaderboard data. I will be extending the node.js server code to include this functionality. I may do a blog on redis soon and then one another that includes details on how to use redis to create a leaderboard.

Finally Game / App Editor Started

Note to self, update my blog more often. These days my blog seems to have turned into an AppEasy update feed, well I want to change that and start blogging about other things (besides AppEasy).

Well, this blog post is not completely devoid of AppEasy news as the game editor will target AppEasy to begin with.

Today I want to blog about a new game editor that I have started work on (its a bit of a pet project because I’m getting fed up of writing game or app specific editors). The editor is tentatively called Groove Game Editor which will have the following features when finished:

  • Completely customisable – You can define all of the types of objects that can be edited along with all of the properties for those objects using an input XML file
  • Placement, scaling, rotation of game objects on a large virtual canvas
  • General layout, tile and zone maps
  • Automatic atlas generation
  • Resource management
  • Music and sound effects
  • Physics
  • Actions, events and triggers
  • Key frame animation editor
  • Lua scripting
  • Support for all XOML types out of the box
  • Support for HTML5, Marmalade Quick, Cocos2d-x, Corona, Gideros and other game / app development SDK’s and systems
  • Binary, xml and JSON export

Thus far I have implemented the customisation system which enables developers to create a single XML file that describes the following elements to the editor:
Enumerations – You can use these to define sets of possibilities, e.g.

Here’s an example that shows an enum for the Joint Type used by XOML joints:

[sourcecode language=”xml”]
<Enum Name="JointTypeEnum" Info="Physics joint type">
<Property Name="weld" />
<Property Name="distance" />
<Property Name="revolute" />
<Property Name="prismatic" />
<Property Name="pulley" />
<Property Name="wheel" />
</Enum>
[/sourcecode]

You can later use this as a type for object properties

Object Types – These represent specific types of objects that can be edited, for example Actors, Scenes, Images, Programs, Actions etc are each single types, e.g.*

Heres an example of a Box2D material:
[sourcecode language=”xml”]
<Type Name="Box2dMaterial" Base="Common" Info="Box2D material resource" Colour="#ffe4ff00">
<Property Name="Type" Type="Box2dMaterialTypeEnum" Category="General" Value="" Info="Type of material" />
<Property Name="Density" Type="double" Category="General" Value="1" Info="Material density" />
<Property Name="Friction" Type="double" Category="General" Value="1" Info="Materials coefficient of friction" />
<Property Name="Restitution" Type="double" Category="General" Value="0.1" Info="Materials coefficient of restitution / bounciness" />
<Property Name="IsBullet" Type="bool" Category="General" Value="" Info="Treat object as moving at high speed" />
<Property Name="FixedRotation" Type="bool" Category="General" Value="" Info="Prevent rotation of body" />
<Property Name="GravityScale" Type="double" Category="General" Value="1" Info="Amount to scale gravity" />
</Type>
[/sourcecode]

As you can see you can define the name of the type, the base, which is kind of like a base class in C++, the type inherits all properties of the base. Info is used for tool tips and the colour is the colour that will be used to display objects of this type in the resource view. There are other properties but I wont go into them right now. Within the TYpe tag is the properties, thee define the properties that can be edited along with their types, the category they appear under and the tool tip

Type Groups – Type groups are used to group together types that share similar function, e.g.

[sourcecode language=”xml”]
<Group Name="Basic Actors">
<Type Name="ActorImage" />
<Type Name="ActorConnector" />
<Type Name="ActorText" />
<Type Name="ActorParticles" />
</Group>
[/sourcecode]

Here we group together four different types into a group called Basic Actors. We can later use these to set up menu groups and other interesting stuff

Menu Groups – Finally we have Menu Groups. These are used to define how the user can create hierarchical data. Each menu group defines a list of types that can be creayed when the user attempts to create a child object within its hierarchy, e.g.:

[sourcecode language=”xml”]
<MenuGroup Name="NewAnimationChild" Context="Animation">
<Section Name="">
<Type Name="Frame" />
<Type Name="Atlas" />
</Section>
</MenuGroup>
[/sourcecode]

Here we create a Menu Group called NewAnimationChild that contains two possible types (Frame and Atlas), these are the only two possible types of objects that an Animation object can contain. The Context attribute specifies what type of object will use this menu for creating new child objects in its hierarchy. The Section tag specifies the name of the sub-menu that the type should appear under. In this case the section name is blank so Frame and Atlas will appear in the root.

Most other items and other parts of the editor will be defined in this customisable editor file.

The editor is not currently in a usable state and only has the following functionality:
* Allows editing using all custom types, enumerations and menu groups that are specified in the editors definition XML file
* Loads files that are based on the editors definition XML file
* SUpports all AppEasy XOML types and enumerations using colour coding

Next on the list is export to XML. However, before I do that I need to get objects that are specified inside templates working. The problem I face is that the editor creates UI that allows you to edit specific types. For example, a bool type will use a check box and an enumeration will use a drop down list. Problem with this is that objects that are defined inside a XOML template can have parameters that are template parameters (strings), so the UI needs to change for all objects that are sat inside a template to allow these parameters to be modified. Problem is that Windows Presentation Foundation (WPF the technology that I am using to create the editor) uses data binding to specific types. I need to figure a way around this. I have a few ideas that I can try.

Once I have export working I will release a version for those that are interested in taking a look to play around with. For now I will leave this screen shot that shows my porgress so far:

Groove game editor
Groove game editor

Marmalade SDK Tutorial – Integrating LUA Script Language

This tutorial is part of the Marmalade SDK tutorials collection. To see the tutorials index click here

Its been a while since I wrote a Marmalade SDk tutorial and to be honest I’ve been itching for the chance to start them back up, so I freed up a little time today to bring you this new tutorial.

Ok, decided that it was high time that IwGame had a proper scripting language, so took a look around various scripting languages including LUA, Javascript and AngelScript. Whilst we like them all and would like to integrate them all at some point, our first choice is LUA.

And as I am a complete LUA noob I decided to write a short tutorial showing how to integrate LUA so a) everyone can see how “not so difficult” (had to avoid the word easy, because that would be wrong) it is to integrate LUA and b) so I don’t forget how to do it myself in the future

I have created a small Marmalade app called lua_test that demonstrates the following:

  • Execute a string containing lua commands
  • Load and execute a lua file from C
  • Load and execute a specific function in a lua file from C
  • Load a lua file that executes a C function

With these basics you should be able to integrate LUA into your own project quite easily.

I’m not going to pretend that I am now a LUA expert after spending but a few hours learning how to integrate it, but I know a few things now to be confident to write this tutorial.

Setting up the MKB to support LUA

The first thing you need to do is edit your projects MKB file and the following sections:

packages
{
    lua
}

subprojects
{
    lua
}

LUA is not distributed with Marmalade, instead it is downloaded from the code repository when you run your MKB file. When you open up your MKB file you will notice a new lua filter has been added

Note that the version of LUA that is supported by the Marmalade SDK is currently 5.1.4

LUA header files

In order to access LUA you need to include the headers. However as we are including C headers into a C++ app we need to let the compiler know. With that in mind we add the headers as follows:

[sourcecode language=”cpp”]
// LUA headers
extern "C"
{
#include "lua.h"
#include "lauxlib.h"
#include "lualib.h"
}
[/sourcecode]

LUA State

LUA holds no global variables so the interpreters current state has to be stored somewhere where it can be accessed from your code. In our simple examples, we create the LUA state using lua_open() which returns a pointer to the state then close it when we have finished using lua_close(). Ideally you would want to manage this pointer to the LUA state, depending on the scope and lifetime of LUA scripts in your app. All of our examples start and end with:

[sourcecode language=”cpp”]
// Open LUA
lua_State *lua = lua_open();

// Add LUA libraries (standard libraries are libraries of code that provide some basic functionality such as print)
luaL_openlibs(lua); // See http://www.lua.org/manual/5.1/manual.html#luaL_openlibs

//
// Do something with LUA
//

// Shut down the lua state
lua_close(lua); // See http://www.lua.org/manual/5.1/manual.html#lua_close
[/sourcecode]

LUA Stack

LUA passes information between C and LAU code via a stack. To pass information to a LUA function from C you push the name of the function that you wish to call onto the stack followed by any parameters that you wish to pass. When the LUA function returns it returns any return values (LUA can return multiple values) or an error on the stack. Similarly when calling a C function from LUA, LUA pushes the parameters onto the stack then calls the C function. The C function examines the parameters on the stack (C does not remove them, LUA removes them when it returns) and utilises the data passed from LUA, carries out some logic and returns.

More info on the LUA stack can be found at http://www.lua.org/pil/24.2.html

Calling a string containing LUA from C

Here’s some example code showing how to execute a piece of LUA contained within a string:

[sourcecode language=”cpp”]
void CallLuaString(const char* string)
{
s3eDebugOutputString("==== Calling a LUA string");

// Open LUA
lua_State *lua = lua_open();

// Add LUA libraries
luaL_openlibs(lua); // See http://www.lua.org/manual/5.1/manual.html#luaL_openlibs

// Pass the string to lua to execute
if (luaL_loadbuffer(lua, string, strlen(string), "line") == 0) // See http://www.lua.org/manual/5.1/manual.html#luaL_loadbuffer
{
if (lua_pcall(lua, 0, 0, 0) != 0)
{
// Output the error
s3eDebugOutputString(lua_tostring(lua, -1));

// Pop error message off the stack
lua_pop(lua, 1); // see http://www.lua.org/manual/5.1/manual.html#lua_pop
}
}

// Shut down the lua state
lua_close(lua); // See http://www.lua.org/manual/5.1/manual.html#lua_close
}
[/sourcecode]

In this example, we open LUA then ad the standard LUA libraries. We then load the supplied string as a LUA chunk using luaL_loadbuffer() then call it using lua_pcall(). If an error occurs then we display the error and pop it off the stack

Calling a LUA file from C

Our next example looks at how to call a LUA file from C, lets take a look at the code:

[sourcecode language=”cpp”]
void CallLuaFile(const char* lua_filename)
{
s3eDebugOutputString("==== Calling a LUA file");

// Open LUA
lua_State *lua = lua_open();

// Add LUA libraries
luaL_openlibs(lua); // See http://www.lua.org/manual/5.1/manual.html#luaL_openlibs

// Load our test LUA file
if (luaL_loadfile(lua, lua_filename) == 0) // See http://www.lua.org/manual/5.1/manual.html#lua_load
{
if (lua_pcall(lua, 0, 0, 0) != 0) // See http://www.lua.org/manual/5.1/manual.html#lua_pcall
{
// Output the error
s3eDebugOutputString(lua_tostring(lua, -1));

// Pop error message off the stack
lua_pop(lua, 1); // see http://www.lua.org/manual/5.1/manual.html#lua_pop
}
}

// Shut down the lua state
lua_close(lua); // See http://www.lua.org/manual/5.1/manual.html#lua_close
}
[/sourcecode]

We begin this example much like we did our previous example, but instead of load_buffer() we call luaL_loadfile(), which basically does the same thing except it loads the data from a file.

Calling a LUA function from C

This example gets a little more complicated as we need to begin dealing with pushing data onto the LUA stack. Lets take a look at the code:

[sourcecode language=”cpp”]
void CallLuaFunctionInFile(const char* lua_filename, const char* function_name, double arg0, double arg1)
{
s3eDebugOutputString("==== Calling a LUA function from C");

// Open LUA
lua_State *lua = lua_open();

// Add LUA libraries
luaL_openlibs(lua); // See http://www.lua.org/manual/5.1/manual.html#luaL_openlibs

// Load our test LUA file
if (luaL_loadfile(lua, lua_filename) == 0) // See http://www.lua.org/manual/5.1/manual.html#lua_load
{
// Init the loaded lua file
if (lua_pcall(lua, 0, 0, 0) == 0) // See http://www.lua.org/manual/5.1/manual.html#lua_pcall
{
// Push the name of the function that we want to call onto the stack
// NB: LUA uses a stack to pass information back and forth between LUA and C (see http://www.lua.org/pil/24.2.html)
lua_getglobal(lua, function_name); // Push function name that we want to call ontothe stack (see http://www.lua.org/manual/5.1/manual.html#lua_getglobal)
lua_pushnumber(lua, arg0); // Push function call argument 1
lua_pushnumber(lua, arg1); // Push function call argument 2

if (lua_pcall(lua, 2, 1, 0) != 0) // See http://www.lua.org/manual/5.1/manual.html#lua_pcall
s3eDebugOutputString(lua_tostring(lua, -1));
else
{
if (!lua_isnumber(lua, -1)) // http://www.lua.org/manual/5.1/manual.html#lua_isnumber
s3eDebugOutputString("Function muust return a value");
else
{
// Get th result returned from the LUA function
double result = lua_tonumber(lua, -1);
}
}
lua_pop(lua, 1); // see http://www.lua.org/manual/5.1/manual.html#lua_pop
}
}

// Shut down the lua state
lua_close(lua); // See http://www.lua.org/manual/5.1/manual.html#lua_close
}
[/sourcecode]

Much of the code remains the same as the previous example, where we initialise LUA, load a LUA file and execute it. The difference is that we now push an actual function name and a number of parameters onto the stack using lua_getglobal() and lua_pushnumber(). We then make another call to LUA which executes the LUA function that we just stacked, e then check the return value and if itis not a number we display an error otherwise we pop the returned number off the stack and store it locally.

Calling a C function from LUA

Things get a little more complicated when you find that you need to call C functions from LUA. The first thing that we need to do is let LUA know that our C function is available to be called as well as define a protocol for how it should be called from LUA. Lets take a look at an example:

[sourcecode language=”cpp”]
static int test_function(lua_State *lua)
{
double d = 0;
// Get the argument that was passed from lua
if (lua_isnumber(lua, 1))
d = lua_tonumber(lua, 1);
else
s3eDebugOutputString("test_function can only accept a number");

// Square it
d = d * d;

// Push the result back onto the stack as a return value
lua_pushnumber(lua, d);

// Return the number of result arguments that were passed back to lua
return 1;
}

void CallCFunctionFromLua()
{
s3eDebugOutputString("==== Calling a C function from LUA");

// Open LUA
lua_State *lua = lua_open();

// Add LUA libraries
luaL_openlibs(lua); // See http://www.lua.org/manual/5.1/manual.html#luaL_openlibs

// Push the test function
lua_pushcfunction(lua, test_function); // See http://www.lua.org/manual/5.1/manual.html#lua_pushcfunction

// Set the global test_function to the pushed C function
lua_setglobal(lua, "test_function"); // See http://www.lua.org/manual/5.1/manual.html#lua_setglobal

// Load our test LUA file
if (luaL_loadfile(lua, "lua_test3.lua") == 0) // See http://www.lua.org/manual/5.1/manual.html#lua_load
{
if (lua_pcall(lua, 0, 0, 0) != 0) // See http://www.lua.org/manual/5.1/manual.html#lua_pcall
{
// Output the error
s3eDebugOutputString(lua_tostring(lua, -1));

// Pop error message off the stack
lua_pop(lua, 1); // see http://www.lua.org/manual/5.1/manual.html#lua_pop
}
}

// Shut down the lua state
lua_close(lua); // See http://www.lua.org/manual/5.1/manual.html#lua_close}
}
[/sourcecode]

Firstly we create a C function called test_function() which is declared from LUA’s standard C function prototype:

static int test_function(lua_State *lua)

This function accepts a lua state which we can query for information that was passed to it by LUA (on the stack). In our example, we firstly check to see if the value on the top of the stack is a number, if not we display an error, if so then we retrieve that number. Next we modify the number then push it back onto the stack so that it can be retrieved (returned to) by the calling LUA function. Note that the value returned from our C function represents the number of arguments that we returned on the stack. Lets take a quick look at the LUA code that made the call to our C test_function in the first place:

d = test_function(12);
print(d);
d = test_function("hello");    -- This will cause an error because we passed a string instead of a number
print(d);

As you can see it calls test_function twice. The first time it is successful because we passed a number, the second time we passed a string which test_function() detected as an error.

Ok, lets now take a look at the code that registers our C function so that LUA can use it (see CallCFunctionFromLua() above)

Firstly we call lua_pushcfunction(lua, test_function); which places our C function onto the stack. Next we call lua_setglobal(lua, “test_function”); to assign the function an actual name that LUA script can use to call the function.

Well that’s about it. I have included the source code for the lua_test app which you can download from here

cOnnecticOns is now available on the Android Market!

Hey everyone, some good news. We finally got the first version of the first IwGame Engine game  cOnnecticOns up on the Android Market at https://market.android.com/details?id=com.pocketeers.connecticons. Playbook, Bada and iOS builds will be available within the next few weeks.

And the even better news is that we are on schedule for releasing the full source this weekend! We’ve had a bit of a delay because we decided to upgrade the game a bit. We added an extra zone with 10 additional levels, as well as a game editor to allow players to create and play up to 20 of their own levels. Oh, and players can also post their scores to Facebook using the new CIwGameFacebook class (coming in the next IwGame engine update 0.31 this weekend)

cOnnecticOns for Android, iPhone, Bada and Blackberry
cOnnecticOns for Android, iPhone, Bada and Blackberry

The next update of the game will feature sharing levels between users using a web service, for which we will release the full source code, including the server side scripts.

The update after that will feature in-app purchase content using new classes that e are developing for the IwGame engine.

If you download the game then please consider leaving a nice review

IwGame Engine v0.3 Released – The 36 hour game

New here? What’s IwGame? IwGame is an open source free to use cross platform game engine for iPhone, iPad, Android, Bada, Playbook, Symbian, Windows Mobile, LG-TV, Windows and Mac, built on top of the Marmalade SDK. You can find out more and download the SDK from our IwGame Engine page.

Well, Dan said a few weeks ago that “it’s only until you eat your own dog food that you know you have to improve the taste of it”. I thought about this and decided that we really needed to create a game using the engine to show its various features in action. So with this, I began work on a game (currently unnamed), but decided that the game would take a few weeks to finish off, so moved over to producing a completely new game from scratch but with a simpler design. The end result was a game that was created in less than 36 man hours, including art production, coding, design and scripts (I was aiming for 24 hours but I came across a a few nasty bugs that took a fair bit of time to fix). In addition,. I underestimated how difficult it would be to put levels together without an actual editor. I will very likely build an actual editor into the cOnnectiCons game itself to allow players to create their own levels. So the game ended up with 20 levels, with an additional 20+ levels coming later.

You can take a quick look at cOnnecticOns at http://www.youtube.com/watch?v=sVa8TWYQEsQ and here are a few screen shots of our 36 hour game cOnnecticOns:

Connecticons screen shot
Connecticons screen shot
Connecticons screen shot
Connecticons screen shotConnecticons screen shot
Connecticons screen shot
Connecticons screen shot

We have already started submitting the game to app stores, so when we release the source “Don’t go getting any ideas lol”. The source will be provided as a learning exercise, and not for someone else to make a quick buck off.

Ok, now that’s out the way, lets take a brief look at the changed that have arrived in IwGame v0.3:

  • Support added for particle based actors via CIwGameActorParticle and CIwGameActorParticles as well as XOML via ActorParticles and Particle tags. Particles can be defined individually or in batches using random parameters. Particles have position, linear velocity, angular velocity, scale velocity, colour velocity, depth velocity, velocity damping, lifespan and repeat
  • Support for Marmalade fonts has been added via CIwGameFont wrapper and a new XOML Font tag
  • All rendering now uses IwGx instead of Iw2D. This offers more control over rendering as well as makes the code more portable / versatile in the future
  • All internal rendering upgraded to sub pixel coordinates offering MUCH smoother rendernig
  • New 2D rendering class added CIwGameRender2d. This cklass allows batch rendering of primitives and rendering of text CIwGxFontPreparedData prepared text
  • New very powerful template system added to XOML. The template system allows you to create a complex piece of XOML using paramaters that can be passed in when the template is instantiated. Templates can also be instantiated from code using CIwGameTemplate::Instantiate()
  • CIwGame::addScene() can now auto bring a scene to the front of scene stack
  • New global actions added to XOML – Launch, setBGColour, SetCurrentScene and BringtSceneToFront
  • Actors and sprites now have a depth property allowing you to add 3D depth to them
  • Actors and sprites now have an origin attribute
  • Support added for sprites and actors for none uniform scaling
  • Support added for linked actors. A linked actor will utilise the transform, colour and visibility of the actor it is linked to. In XOML, you can use the new LinkedTo tag to set linkage or the more natural and readable method of defining actors within actor tags. This system allows complex multi-patr actors to be created and animated
  • Actors now support OnCreate and OnDestroy events in code and in XOML
  • Scenes now support OnCreate, OnDestroy OnGainedFocus and OnLostFocus events in code and in XOML
  • New text based actor and sprite types added CIwGameActorText and CIwGameTextSprite.
  • Animation system now supports linear, quadratic, cubic and quartic on / out easing in code and in XOML. In addition value interpolation can be enabled / disabled
  • Animations now support absolute and delta values
  • Animation timelines now support OnStart, OnEnd and OnRepeat events in code and in XOML
  • CIwGameAudio::PlayMusic now supports repetition with additional parameter in XOML
  • New CIwGameSlotArray class added for efficient resizable arrays
  • Actor Box2D collision system was broken and inefficient. The system has been completely reworked and now uses the new more efficient CIwGameSlotArray
  • CIwGameBox2dBody now has new awake and active methods
  • CIwGameCamera now supports velocity, damping and touch panning. Touch panning will pan the camera to follow the users finger
  • More than one scene can now receive input events using the new AllowFocus functionality in code and in XOML
  • New findClosestActor and findFurthestActor methods added to CIwGameScene
  • CIwGameBitmapSprite now supports colour per vertex
  • CIwGameSpriteManager supports enabling / disabling of batching and a new centre of projection property for depth used by depth sprites
  • CIwGameInput reworked to better support multi-touch
  • PlayTimeline, StopTimeline and SetTimeline now supports a second parameter which points to the scene or actor that the timeline change should be made to
  • Actors can now be marked for hit testing in XOML
  • Image files can now be loaded directly from XOML without the need for Marmalade resources files
  • CIwGameScene and CIwGameActor based objects are now marked as destroyed when they are removed so they cannot be found in a scene or actor search
  • CIwGameXmlNode now supports cloning
  • Bug Fix: Actors now take into account their visibility when being hit tested
  • Bug Fix: CIwGameActor::setCollidable no works
  • Bug Fix: StartTimeline action now restarts a stopped timline properly
  • Bug Fix: Clipping rect is now transform by the scenes transform (will not clip correctly against rotated scenes however)
  • Bug Fix: XML parser fixes
  • Bug Fix: CIwGame game scene switch scene bug fixes
  • Bug Fix: CIwGameAds::ErrorFromResponse fix that were causing some valid ads to be in error
  • Bug Fix: CIwGameAnim fixes
  • Bug Fix: Polygon based Box2D bodies now fixed
  • Bug Fix: Sprite rendering transform fixed
  • Bug Fix: CIwGameBitmapSprite with no loaded image no longer crash
  • Bug Fix: CiwGameString crashes fixed (were causing rare problems with XML system)
  • Bug Fix: Fixed issue with CIwGameXmlAttribute::GetValueAsColour not checking for correct parameter count
  • Bug Fix: On device scene shut down camera deletion fixed

Ok, that’s a shed load of changes, but I can assure you that they are all for the better. IwGame is now a professional grade and fairly stable engine that can be used to create games in as little as 36 hours!

Lets take a look at some of the new additions in more detail.

Templates

I want to start with my utmost favourite change to 0.3 which is templates. I am so in love with templates that I feel like I could almost marry one! They saved me so much time when developing cOnnecticOns. Templates allow you to create large sections of XOML as templates then instantiate those large
pieces of XOML somewhere else using custom parameters that you pass to the template when you instantiate it. Lets take a quick look at a super simple example:

<Template Name="ActorTemplate">
        <InertActor Name="Explosion$name$" Image="$image" Position="$pos$" Scale="$scale$" Depth="$depth$" Layer="1" AngularVelocity="0" />
</Template>

Here we define a template called ActorTemplate that contains a basic InertActor definition. You may notice some strange markers in there surrounded by double dollars signs ($name$, $image$,$pos$, $scale$ and $depth$).

Now when we instantiate this template somewhere we would use:

<FromTemplate Template=”ActorTemplate” name=”actor1″ scale=”1.0″ pos=”300, 150″ depth=”1.0″ image=”sprites1″ />

The above XOML command will instantiate whatever is in the ActorTemplate template passing all of its parameters, replacing the double dollar definitions inside the template (Hmm, sounds very much like calling a function? Which I guess in some ways it is)

Templates can be as massive and as complicated as you like, allowing you to design and instantiate some very complex objects with very few lines of XOML.

Rendering Engine Upgrade

Up until version 0.29 of the IwGame Engine we used Marmalade’s Iw2D engine as the rendering core. As of v0.30 we have switched to Marmalade’s IwGx rendering system as it offers much more versatility as well as brings the engine into the realms of 3D rendering, which is where we will eventually be steering the engine.

To facilitate this change over and to keep the game engine code nice and readable, all rendering has been abstracted away into a nice simple class called CIwGameRender2d. CiwGameRender2d is and will in future be the centre point for all rendering that takes place within IwGame.

At the moment CiwGameRender2d offers:

  • Batch and none batch sprite rendering of quad based polygons
  • Rendering of prepared text from the Marmalade IwGxFont system

In the near future we will be adding support for various other types of primitives, 3d models and hopefully our own custom shaders etc..

Lastly, all rendering now uses sub-pixel accuracy which looks much much smoother.

Text and Fonts

IwGame now supports definition of Marmalade fonts and custom rendering of those fonts using a new text based sprite and actor. Text based sprites and actors are treat just like any other sprite or actor objects, so they can be spun, scaled, linked, colour changed etc.. Unlike generic actors text based actors can be instantiated without deriving your own class from CIwGameActorText

3D Sprites / Actors

Another one of my favourite additions to 0.3 is 3D sprites. All sprites and actors can now have a depth value (think iof this as a z value) that allows you to project sprites into 3D.  This system is great for create parallaxing effects etc..

Oh and sprites / actors also get an adjustable origin and none uniform scaling

Linked Actors

Actors can be created within other actors to form a parent / child relationship. Inner actors will be linked back to their containing actor forcing them to be transformed by their parent actors. This system allows you to create a very powerful intuitive multi-part actor system complete with animations per actor part. Note that all positions, depths etc will be relative to the container actor, so for example, if the parent actor has a Depth value of 1.0f and the child actor has a Depth value of 1.0f then the child’s effective Depth will be 2.0f. Here’s an example showing parent / child actors:

<InertActor Name="Level1" Style="LevelButtonStyle" Position="0, 0" OnBeginTouch="BeginTouch11" OnTapped="StartLevel1">
    <ActorText Name="Record1" Style="LevelButtonTextStyle" Colour="255, 80, 80, 255" Position="0, 0" Text="0" Depth="0" />
    <ActorText Style="LevelButtonTextStyle" Position="0, 60" Text="Round 1" Depth="0" />
    <InertActor Name="LevelComplete1" Size="74, 67" Image="sprites2" SrcRect="582, 423, 148,134" Position="60, -20" HitTest="false" Depth="0" Timeline="tick_scale_anim" />
</InertActor>

In the above XOML the parent actor level1 contains three children actors that will all follow theLevel1 actors visual transform.

Particle System Actors

This actor is special in that it is optimised for creating, displaying and updating a complete system of sprites (kind of like its own sprite manager). The advantage of this actor is that it does not have to deal with each particle as a separate actor object. The CIwGameActorParticles actor supports both manual and auto generation of particles. Auto generation can be controlled using a number of a control parameters.

Particles have a number of properties that can be adjusted:

  • Visual
  • Position
  • Velocity
  • Velocity Damping
  • Gravity
  • Scale
  • Scale Velocity
  • Scale Velocity Damping
  • Angle
  • Angle Velocity
  • Angle Velocity Damping
  • Colour
  • Colour Velocity
  • Colour Velocity Damping
  • Depth
  • Depth Velocity
  • Depth Velocity Damping
  • Active state
  • Visible state
  • Lifespan – Duration of particle in seconds
  • SpawnDelay – The amount of time to wait before spawning for the first time
  • Lives – Number of times the particle will re-spawn (-1 for infinite)

The particle actor system allows auto generation of particles within certain limits as well as manual generation. Patricles can be defined and placed both in code and in XOML.

Animation Frame Easing

Animations now support in and out easing on a per frame basis using the “Ease” attribute of the frame tag or in code. Valid values of easing include:

  • linear – No easing
  • quadin / quadout – Quardatic in / out easing
  • cubicin / cubicout – Cubic in / out easing
  • quarticin / quarticout – Quartic in / out easing

Time lines now in the Events System

Its now possible to attach actions to timeline events such as OnStatr, OnEnd and OnRepeat. So for example, each time an animation repeats you could play a sound effect or maybe when an animation finishes yu kill destroy the actor or start a particle system off going etc..

Animations now support delta / absolute coordinates

Every animation can now be specified as absolute or delta. An absolute animation will write its interpolated frame values directly into the target objects properties (such as position), whilst a delta animation will update the current target properties. So for example, a delta animation for position would adjust the position by dx, dy, where dx and dy is the current interpolated frame value.

Automatic Touch Panning for Cameras

Cameras now have X and Y axis touch panning. When a camera is touch pan enabled it will track the users finger drag on screen to determine a velocity to move the camera by. Touch panning can be enabled on the X an Y axis independently.

Other cool changes

Multi-focus scenes – More than one scene can now receive input events
Local images can now be loaded from XOML

There are many other changes but I don’t really have the time to go through them all. There’s also a mound of bug fixes that weer found during development of cOnnecticOns.

We will be releasing the full source to cOnnecticOns later this week along with an additional 10-20 levels.