In the interest of brevity I’ll cover only a small subset of the game functionality which is currently handled by my scripting engine – the in-game tutorial system. This should provide a good foundation to build on for your own games.
Given the linearity of my in-game tutorials it makes sense to be able to “pause” script execution until certain goals
machines relying on a single threaded execution model. All I/O is typically non-blocking and asynchronous. So how do we
JSVirtualMachine? Well I’ll get to that, first lets lay
the foundations for the scripting engine itself.
We’ll get to the implementations shortly but nothing too tricky here. They closely match up with the functions seen earlier in the tutorial script.
Next lets start to look at the definition of the scripting engine:
engineQueue is a dispatch queue to which we will submit any task that manipulates the
The key thing notice in the above code snippet is that the
JSContext is instantiated on a separate thread
and not the main thread. This needs to be the case (unfortunately for reasons that are not entirely obvious or
$ variable. In the
call we expose the core functions from
(not on the main thread) on the
ScriptEngine object instance.
Loading a running a script is relatively straightforward. Included is some logic that means the extension is assumed to
.js if not specified. Notice again how we manipulate the
JSContext off the main thread by submitting
a task to the
A script can be run in the following fashion:
Pausing JSVirtualMachine execution
wait() functions. We’ll start with the
simplest variant that pauses execution for a specified period of time:
wait() function (as well as all others that we’ll cover shortly) is guaranteed to be called on a separate thread
managed by the
engineQueue i.e. not on the main thread.
sleepForTimeInterval will thus
sleeping whilst our main thread is still free to handle user input and run other game simulation logic. Next onto the
marginally trickier wait functions:
are invoked, they’re guaranteed to be run off the main thread.
waitForCondition(condition:predicate:) is where
notifyLevelEnd() signal on the appropriate condition and wake the
engineQueue thread (assuming it
your game engine when the appropriate events arise.
Triggering game events
The remaining exported functions are implementation specific and will vary from game to game. The way I like to
deal with them in the
ScriptEngine is to post
NSNotification’s and then deal those notifications elsewhere as
Hopefully the above should provide a foundation to build on for your own games. I’ll be sure to update here with a link to the full game source code once it hits the App Store.