This AI is still in early stages of development.
Sequence API
Sometimes there's a need to sequence a number of actions, one after the other, for example in campaign scripts to unfold part of the plot.
In WZScript, there seems to be a pause() command, although I can't find it documented anywhere. Here's an excerpt from Goth's cam4 script:
showConsoleText(_("Sgt.Gibbs: Next objective is to the north. Then we'll cut eastward and rendevous with Team Two."), player); pause(50); showConsoleText(_("Sgt.Wilkes: -- Wilkes to Gibbs. You folks have got a horde of angry Scavengers headed your way from the north. --"), player); pause(50); showConsoleText(_("Sgt.Gibbs: Thanks for the heads up, Sergeant. We'll be ready!"), player);
If you did something like that in Javascript, the game would hang. So we're going to need to use queue(), but even then the code would be a mess because we'd need vast numbers of functions.
However, we can probably create a little API that will help us achieve our goals in a fairly clean manner. Using it would look something like this...
include("path/to/APIs/Sequence.js"); // define a sequence, probably store in in an external .js file and include() it // (note that pauses are now expressed in milliseconds) Sequence.define("introSequence", processor, [ "Sgt.Gibbs: Next objective is to the north. Then we'll cut eastward and rendevous with Team Two.", 5000, "Sgt.Wilkes: -- Wilkes to Gibbs. You folks have got a horde of angry Scavengers headed your way from the north. --", 5000, "Sgt.Gibbs: Thanks for the heads up, Sergeant. We'll be ready!", Sequence.END ]); // start a sequence, eg. during an event function eventGameInit() { // various init Sequence(introSequence); // various other stuff }
The sequence above is simplified version of what Goth is doing in cam4 – the sequencer also needs to be able to handle function calls, because code is often running in between console messages (eg. to spawn droids, etc).
Anyway, that's the sort of thing Sequence API should handle. Currently working on a prototype...
Sequence.define()
Defines a new sequence. Any number of sequences can be created, both during script initialisation or at any other time.
Sequence.define( name, processor, steps );
Parameters
Parameter | Type | Mandatory | Notes | API Version |
---|---|---|---|---|
name | String | A unique name for the sequence, for example "Intro Sequence" | ||
processor | Function | A function that will process steps in the sequence. See "Processor Function" for more info. | ||
steps | Array of Steps | An array containing the steps in the sequence. See "Steps Array" for more info. Also the name of a British pop band from the '90s. |
Sequence()
Starts a sequence. Multiple sequences can be running at the same time. They even survive the game save/load cycle (requires sequences to be defined during script initialisation though).
Sequence( name[, command] );
Parameters:
Parameter | Type | Mandatory | Notes | API Version |
---|---|---|---|---|
name | String | The name of the sequence to start. Note: If the sequence is already running, this will immediately trigger the next step in the sequence. | ||
command | Constant | Run an internal command on the sequence:
Default: Sequence.NEXT |
Steps Array
An array defining each step in the sequence, and the amount of time to wait before the next step starts.
A step consists of a pair of array elements:
- data – data associated with the step, this can be any data type you want
- delay – how long to wait before starting the next step, in milliseconds:
- -1 = next step requires manual progression (ie. use Sequence() function to trigger next step)
- Sequence.PAUSE = same as -1
- 0 = next step runs immediately with no delay
- Sequence.NEXT = same as 0
- <number> = a positive number defines number of milliseconds to wait before next step is automatically triggered
- Sequence.END = the sequence is finished, and will be reset to the beginning should it be needed again later
- <string> = same as Sequence.END, but also start another sequence (the string defines the name of that sequence)
- <function> = same as Sequence.END, but will also call the function (useful if you want to run some code at the end of the sequence)
In terms of the data elements, it's recommended that you define yourself some sort of vocabulary. For example:
- If data is a string, it gets localised and sent to the console
- If data is a function, the function is processed
- If data is an array, iterate the array calling the processor function for each item in it
- If data is an object, decide how to process it based on the data.type property
- If data is a number, ...
And write down it down somewhere, with examples of the types of data you want to process, then implement the code to process those types of data in your processor function...
Processor Function
The sequencer has no idea what your data (in the Steps Array) looks like or means, so when a step is triggered a function is required to process the data. The function is defined along with steps array when you call Sequence.define(). The neat thing about this is that you can have sequences with completely different data formats - just provide a processor that understands it. And, you can use the same processor for multiple sequences.
function <name>( sequence, step, data ) { // process data }
The function has two parameters:
- sequence – the name of the sequence that's being processed
- step – the index of this step in the sequence (eg. first step is 0)
- data – the data portion of the step that needs processing
Note: The function doesn't need to worry about how the next step gets triggered, the sequencer takes care of that. Your processor function should focus entirely on processing the data passed to it.
Return values:
- No return value or undefined – sequence will continue running as normal
- Sequence.END – abort the sequence
- Sequence.DELETE – same as Sequence.END, but also deletes the sequence data
- Sequence.PAUSE
- Sequence.NEXT
- <string> – same as Sequence.END, but also start another sequence (string defines the name of the sequence to start)
- <function> – same as Sequence.END, but also run the function
Sequence.END
This constant is used to define the end of a sequence in the Steps array. Your Processor Function can also return this value to abort a sequence.
Other constants
Getting sleepy so just jotting these down for now:
- Sequence.DELETE – same as Sequence.END, but also deletes the sequence
- Sequence.PAUSE – pauses the sequence, call Sequence(<sequence>) to continue at the next step
- Sequence.NEXT – immediately trigger next step in sequence