April 7, 2012

Failure: Unity Javascript in Java VM

Tags: Technical, Unity

School science teachers like to emphasize that the failure of an experiment is as useful a learning experience as its success. Of course the high-achieving student knows that is bollocks and ensures their experiements always succeed - if you need a straight line, only gather two data points! Despite that I think the underlying idea is correct and experimental failure should not be hidden.

A recent experiment of mine failed. I am writing a game with an online component and wanted the same code running on both the client and server - as this would reduce the chance of bugs. For ease of development Unity3D is being used for the client end, so the code there is either Javascript or C#. I have been writing Java servers professionally for years so it seemed silly not to use that knowledge. Clearly there is no common ground there. However, there is a project called Rhino to allow Javascript to run inside the Java JVM.

So can Javascript from Unity run in a Java environment? The short answer is “no”, but the longer answer is “sometimes, with many caveats”.

Firstly it is possible to run Javascript functions in Java. Load up the Rhino library into the classpath and if you have Javascript code like:

function square(i) {
	return i*i;

then you can run it in Java with the folowing:

Context cx = Context.enter();
Scriptable scope = cx.initStandardObjects();
Function f1 = cx.compileFunction(scope, readFile("src/test_fn.js"), "<cmd>", 1, null);
System.out.println(f1.call(cx, scope, f1, new Object[] {5}));

So far so good. If your Unity Javascript is just a collection of simple functions then this is all that is required. However, there is a good chance this is not the case. Obviously any Unity specific functions and classes are not available (eg Ray, Input, etc). However, more important are the big differences between Unity Javascript and standard (ECMA) Javascript.

Many people say that Javascript in Unity should more accurately be referred to as UnityScript. I think that is definitely true. Although it looks like Javascript there are some fundamental changes. Most importantly, Javascript uses a prototype-based scheme to define classes. UnityScript has an inheritance model, and the two schemes are not compatible. To me these differences are enough to prevent want I wanted to achieve.