Lachlan's misadventures in games programming

Monday, 23 January 2012

Logical Script Interpreter

1/23/2012 12:55:00 am Posted by Lachlan , , , No comments
I've finally added some logic to my script interpreter "Puppet Master"

OK. Script interpreter is a bit of a misnomer. It more can accept commands for classes (like the game, the player or a platform), and change variables in classes. So, for instance, the following would change the platform f_1's x1 to 10
f_1 x1 = 10
I've taken the laziest reasonable possible approach to making this into as much of a language as I need: I've tacked on a basic stack - like on a reverse polish notation calculator (see So whenever I get a value from somewhere (like getting f_1 x1), it now drops it on the stack, which goes up to 6 numbers - for really no good reason other then it was simple to code and won't take much memory.

However, this still left how to put "literals" on the stack. So - if I wanted to directly put the number 5 rather then part of another one. This would violate the relatively simple parser which looks for an object name (defaulting to the puppetmaster itself if it can't find it), then the member and triggers/sets/looks at the variable. So I added 5 basic commands to the puppetmaster that simply say the type of literal you want. So to add the literal integer "234" to the stack, you would go
i 234
I'll add some arithmetic and other commands soon to allow better use to be made of the stack.

Now - how I'm handling the very basic logic (which I'll extend as need be): I've got two commands that deal with it: if_equal and endif_equal takes the top two elements off the stack, uses boost::lexical_cast<std::string> to compare them, and if equal keeps going. If not, it increases the new variable inactive_blocklevel by 1. In general, if  inactive_blocklevel = 0, the program processes the line as usual. However, if its any greater, it  will ignore any lines other then the ifs (which will increase it again, to allow nested ifs), and end (which decreases blocklevel by 1, meaning that if its gone back to 0, code will be running again). The point of this is that it can allows ifs inside of ifs. It doesn't allow the possibility of elses at the moment though - its a really fairly simple method of parsing that will do its job in this program. I'll be adding more versions of if to make up for the lack of else.

Edit: 3/02/2012
Turns out lacking else is very limiting. Hence, I added it - and it was simpler then I thought. All I did is after checking for end and if_equal's when inactive_blocklevel > 0, I added a further check that if inactive_blocklevel = 1 and the command was else, drop the inactive_blocklevel. And, vice verca, increase it if inactive_blocklevel = 0.

At some stage, I will have to write down the details of the scripting language. But it is mostly simple, and is very limited in power. However - its adequate for its job of describing the logic inside levels, and would probably continue to serve for any other games I make with a modified version of this engine. It is a bit limited by my abilities from when I started writing it though and I would probably do it different if I'd started now. But refactoring is the root of all unfinished indie games.

As you may have noticed as well from the picture, levels can now have backgrounds. This took a little longer then expected, but works well.

I'm going to start adding some of the buttons soon. I might add another function to allow BASIC style subs to be called - or at least extend the load script from file function so I can have multiple functions in a file to prevent needing to have stacks and stacks of files for a single level. I hope to have a level in two files - one of scripts, and the other of the level. GFX/Sound will be stored separately.

Also need to code the stuff to make a teleporter work as it's needed extensively in the later puzzles. But have to work out priorities. Still need to code the stuff to turn Jack into a sprite rather then a white box, for instance. Or do a few of the levels as mockups after I add buttons. We'll see. Just - the more engine I do before doing levels, the less I'll have to redo levels.

Still trying to figure out when to aim for a release. Considering aiming for mid to late February - depending if a couple of other commitments arise or not. Would prefer earlier but unsure if it's tenable. Either way, the foundation is slowly being laid.


Post a Comment