Yet another interesting (hopefully) question about game design from Demonpants.
I have a level editor for my game that should theoretically let you do anything you want. It can. Anyway, aside from the general interface that places different objects, resizes, identifies them, edits them, etc., there is an advanced event script that is used to do everything in-game, like for example killing a character if the player moves somewhere.
The code is fairly simple, but I couldnāt think of a good way to compile it, really. The usual 3 pass method didnāt seem like it would work here because I am not turning it into any sort of byte code or whatever, I am putting it into a readable in-game format.
So here is what I do:
if: (man.getX() > 200):
{
man.move(200,man.getY());
}:
The example code will keep the object named āmanā from moving past the 200 pixel spot on the screen. It complies like so:
First, the string is split up by the colons ā:ā. This theoretically splits it into the statement (if, else if, else), the condition (either boolean or comparator), and the action (statements separated by semicolons), and keeps doing this until it runs out of what I have called phrases.
In this case, it finds if, and so creates a new statement, which it passes the condition and the action to. The statementās constructor then automatically creates conditions and actions as it needs to.
It knows how to evaluate it all in this way:
The LinkedList of phrases contains other LinkedListās. Each separate LinkedList within the main list represents a different group of if/elses. Each LinkedList that does not contain another LinkedList contains Statements. It tries to perform the statements from left to right, if any of them evaluate to true, then it exits from that LinkedList. (it is a string of if⦠else if⦠else if⦠etc. statements)
In this case, there is the list of phrases with a single LinkedList that has a single Statement to represent the one above.
Each statement has a LinkedList for conditions and a LinkedList for actions. The conditions list can contain other lists, like the phrases list, only in this case it represents AND/OR conditions, along with paranthetical evaluation. The exact way it saves it unimportant, as long as you understand it does it in much the same way as the phrases list. The actions list is simply a list of actions to be performed.
In this case, the conditions list has a single LinkedList with a single Condition stored in it to represent the one above.
Each condition holds a single left operand, operator, and right operand. The operands are arrays of integers. If the operand is only length one, then it simply stores an integer value. Whereas if the operand is greater than length one, then it stores a reference to an object and one of their methods. Each object that has been given a variable name is added to a special ordered IDList upon compilation, and each object has a collection of static final ints to represent methods, and ways to access them. Therefore, every spot in the operand following the first is calling the method off the item before. (pretty convoluted, no?) Then, the operator is a simple integer that is assigned one of 6 static final values to represent the different types of operators. If there is no operator, then the left operand is a boolean condition.
In this case, the left operand might be {0,1}, the operator is 2, and the right operand is {200}
Each action is an array of integers that is accessed in the same way as the operands in each condition, but each parameter is added to the array after the actual call to the method. Any method calls within method calls are stored separately, in their own array within the main array,
In this case, the action might be {0,3,200,{0,2}}
And there you have it, more or less. Every single timestep, the game cycles through every phrase it needs to (ignoring any elses after a performed if), and performs any of them that evaluate to true. This is ALL saved through integers so it is much more efficient than compile on the fly or something like that, but Iāve had a lot of bugs getting it to work and wonder if thereās a better way.
So anybody got any suggestions? Anyone followed me at all? If you have questions about it, just ask. How do people usually do this? Should I use maps like in normal compilation?