Scripting Java applications with XML and Simkin

by Simon Whiteside
22/01/2001

Storing behaviour in XML files

XML is increasingly being used as a means for storing data in Java applications. This article describes how XML can be extended to incorporate behaviour, using the author’s Open Source scripting language Simkin (http://www.simkin.co.uk).

The paragraph above begs a question – why would you want to have behaviour stored within XML files? I’ll illustrate with a real-life example, which led me to develop Simkin in the first place.

Imagine you’re working on an adventure game: the game is divided into scenes, and each scene contains a number of characters. A natural representation would be to have Java Scene and SceneObject classes, and to store an XML file for each scene:

<scene name=”OwlWood”>
<object name=”Owl”/>
</scene>
This is a scene in the Owl Wood, and the wood contains an owl.

The game requires that characters be visible at different times during the action, so we might add a visibility property:

<object name=”Owl” visible=”false”/>

Expressions

What would be good would be to make the visibility dependent on something else, for example the result of a method call:
<object name=”Owl” visible=”isOwlVisible()”/>
We need some glue to evaluate “isOwlVisible()” – perhaps the Java code could do some introspection to find the matching method (which it would assume would return a boolean).

What would be even nicer would be to be able to write expressions:

<object name=”Owl” visible=”not have_visited_owl_wood and not owl_spoken”/>

Here we have some imaginary variables “have_visited_owl_wood” and “owl_spoken“, and a simple expression syntax using “and” and “not”. We also need quite a bit more Java code: an expression evaluator, and some way of storing or retrieving values.

Statements

It turns out that the game requires that the owl has to say one thing if it’s the first time the player has seen it, and something else the second time. This requirement takes us beyond the need for a simple expression evaluator into the realms of program logic.

In pseudo code, we want something like this to be called when the player enters the scene:

if  num_visits=0 then play(“FirstVisit.au”) else play(“NextVisit.au”) num_visits=num_visits+1

There is no standard way of embedding this kind of script within XML, although there are two basic approaches:

· use XML tags for keywords
· embed a script within the text between tags

There aren’t really any standards for using XML tags for behaviour, although common ways are emerging. Here’s how we might represent the pseudo code:

<object name=”Owl”>
<function name=”initialise”>
<if condition=”num_visits=0”>
 <play file=”FirstVisit.au”/>
<else>
 <play file=”NextVisit.au”/>
</if>
<assign variable=”num_visits” value=”num_visits+1”/>
</function>
</object>

In Simkin I chose to use the second approach. Here’s the same code in Simkin:

<object name=”Owl”>
<function name=”initialise”>
if (num_visits=0){
  play(“FirstVisit.au”);
}else{
  play(“NextVisit.au”);
}
num_visits=num_visits+1;
</function>

I find this style more readable, and it has the advantage that the rules for character encoding within PCDATA sections are more relaxed than for attribute values.

The Simkin Interpreter

In either case you now need Java code to parse and interpret the statements, as well as evaluate expressions and access variables.

In the case of Simkin I decided to develop an Interpreter class, and use JavaCC, a “compiler-compiler” like YACC to develop a parser.

Once the interpreter has parsed the script, it executes the statements one by one. The interpreter uses Java introspection to find methods and fields within Java objects.

I wanted the script to be able to call other Simkin functions and Java methods using the same syntax. This makes it easy to move subroutines into or out of Java as required. In the example above, “play” might have started life as Java method, but become a Simkin wrapper method.

To achieve this, the interpreter uses introspection to find a method, unless an object implements a special interface called Executable. In this case it delegates the responsibility of finding the method to the object itself. This means an object could first look for a Simkin method with the matching name.

The example above shows that it is useful for script to be able to access variables. Simkin supports 4 kinds of variables:

1. locally defined variables within a function
2. other elements within the same XML document
3. fields within Java objects
4. “global” objects which are accessible from any script

I found Simkin very useful when developing my real-life adventure game – “The Animals of Farthing Wood”. I ended up developing quite a small amount of generic “game” code, which was used by a team of 3 scripters to create the logic of the whole adventure.

You can obtain the Simkin interpreter free from the Simkin website: http://www.simkin.co.uk

 Simon Whiteside is an experienced software architect and developer, using Java and other languages such as C++.