Script Parsing
by Pat Wilson · in Technical Issues · 12/14/2000 (3:53 pm) · 6 replies
I started to work on an animation class for Tide, just to do simple stuff, then I thought, I should really use a script to do this stuff...which got me on the idea of a script parser, and this is what I came up with...
This is a sample block of an animation sequence script:
&&
/ \
foo bar
Now what this means, is an expression tree, with a left pointer to another expression tree, that holds the data "foo" and has null pointers, and a right pointer to a expression tree that has the data "bar" and has null pointers, this signifies that it is a leaf. It then looks at what is next, because it is a { it will evaluate the expression tree, if it is true, it will push the expression tree onto a stack, which signifies that it is now within another level of code blocks. This may seem weird, but look at the case if it was a while loop, it would store that expression tree, so that for each iteration, it could re-evaluate the tree and decide to continue or not. Back to the example, it sees another if block, and builds an expression tree that looks like so:
||
/ \
/ \
== !
/ \ \
foo 5 bar
It then evaluates the block, if it's true, it pushes the block onto the stack. And comes to the function call, so it calls the function, then it sees a }, and pops the stack (because it's an if block, if it was while, or what not, it would iterate) it sees another } so it pops the stack again...and there you have it.
Let me know what you think.
This is a sample block of an animation sequence script:
begin(); atTime( 0 ); // Time is 0 miliseconds, the object was just put into the world position( 0, 0, 0 ); // It is at position (0,0,0) in (x,y,z) rotX( 0, 1 ); // Rotation 0 degrees, but it is increasing // Second argument is 1 if increasing 1 if decreasing 0 if neither rotY( 0, 0 ); // No Y rotation either, and it's not moving rotZ( 0, 0 ); // No Z rotation atTime( 300 ); // Time is now 300 miliseconds after the object was started position( 0, 0, -50 ); // Position is 50 along the Z axis rotX( 0, 0 ); // The object rotated 360 degrees and is now back to 0 rotY( 0, 0 ); rotZ( 0, 0 ); end();Ok, this is a real basic script that pretty much makes an object move 50 degrees backwards along the Z axis over 3 seconds, while rotating 360 degrees. So it's spinning pretty fast and moving backwards pretty fast. Now, the animation controller will divide the movement and rotation by how many milliseconds it will be animated for, and get how much it should increment it each time. Easy to parse, but the parser will have to be able to do difficult things too. Example:
if( foo && bar ) {
if( ( foo == 5 ) || !bar ) {
makeItStop();
}
}This is how the parser will do things. It sees the 'if' block, and then creates an expression tree that will look like this:&&
/ \
foo bar
Now what this means, is an expression tree, with a left pointer to another expression tree, that holds the data "foo" and has null pointers, and a right pointer to a expression tree that has the data "bar" and has null pointers, this signifies that it is a leaf. It then looks at what is next, because it is a { it will evaluate the expression tree, if it is true, it will push the expression tree onto a stack, which signifies that it is now within another level of code blocks. This may seem weird, but look at the case if it was a while loop, it would store that expression tree, so that for each iteration, it could re-evaluate the tree and decide to continue or not. Back to the example, it sees another if block, and builds an expression tree that looks like so:
||
/ \
/ \
== !
/ \ \
foo 5 bar
It then evaluates the block, if it's true, it pushes the block onto the stack. And comes to the function call, so it calls the function, then it sees a }, and pops the stack (because it's an if block, if it was while, or what not, it would iterate) it sees another } so it pops the stack again...and there you have it.
Let me know what you think.
About the author
#2
05/01/2001 (1:10 pm)
hi bryan. out of curiosity, did you write your own xml parser, or use something freely available like expat?
#3
It's the same language Bioware used for the Infinity Engine (Baulders Gate et al.).
05/01/2001 (1:17 pm)
Try lua. It's a free scripting language that I find extremely powerfull and fast. Find it at www.lua.org.It's the same language Bioware used for the Infinity Engine (Baulders Gate et al.).
#4
05/01/2001 (8:21 pm)
Yes, i wrote my own. Its actually a fairly straight forward parser to write.
#5
05/02/2001 (5:38 am)
Is it possible to make a scripting program that can auto-program some of this stuff, maybe pasting certain areas of code wherever you need, and more importantly, visually creating these events, without having to do any complex scripting?
#6
There was a suggestion for LUA in this thread, which is what i've used as well and it is definatly a great langauage to work with. If that doesn't suit your needs there's always, Python, Ruby.. etc.. but writing and maintaining your own scripting langauge can be a bear to do. Cratered currently uses LUA to all it's data loading which works out quite well. It doesn't run any scripts in real time, but the camera and basic movement scripts we've tested seemed to work quite well. And from your example from above, it would only take about 5 minutes to bind those functions so they're available to LUA and then you're pretty much done with a fully featured scripting language working in game.
Thomas
http://www.cratered.com
05/02/2001 (7:57 am)
I would really recommend not re-eventing the wheel and use an off the shelf scripting langauge. Even most game companies don't have the resources to brew their own that meets all their needs.There was a suggestion for LUA in this thread, which is what i've used as well and it is definatly a great langauage to work with. If that doesn't suit your needs there's always, Python, Ruby.. etc.. but writing and maintaining your own scripting langauge can be a bear to do. Cratered currently uses LUA to all it's data loading which works out quite well. It doesn't run any scripts in real time, but the camera and basic movement scripts we've tested seemed to work quite well. And from your example from above, it would only take about 5 minutes to bind those functions so they're available to LUA and then you're pretty much done with a fully featured scripting language working in game.
Thomas
http://www.cratered.com
Torque Owner Bryan Dube
I myself have been writing a scripting language for the user interface system for our game XenWars. I did the whole thing in XML because non-programmers seem to be familiar with HTML and picking up a custom XML script is easy. Here is a sample from our ui scritpts in XenWars, this is a popup window that quits the game (btw, the parser, renderer, and input system are all in place and working great!).
Now there are plenty of conditions in here but i hid them using "events". This method doesnt work for every situtation but if you step back from what you are trying to solve and attempt to rearrange it such that its less linear its possible to remove the need for conditions. Here is a quick example of a animation script using the above method (note that i didnt think through it very much, just whipped it together).
Some times its not easy or not possible to replace conditionals in a scripting language but I personally belive that every effort should be made to try. If the problem is looked at from a different angle there is most often a solution that can replace the need for conditionals.
Well, thats my 2cents.