Nexus:TJI Scripting Structure
Contents
NEXUS scripting language
MACHINE TUTORIAL
This tutorial is meant for beginners. It covers the basics of how MACHINES and their STATES work and how they can be used for full effect in your own mission.
What is a MACHINE?
The MACHINE consists of STATES and these consist of RULES.
The term “machine” fits these constructs surprisingly well, because they work just like most machines you would encounter in real life. Like a ticket automat for example: normally he waits for a new customer. We can say, he is in an “idle” STATE. If someone comes along and presses some keys, the automat changes to an “awaiting money” STATE. Then the user inserts some coins and the automat begins processing the input, prints the ticket and switches back to the “idle” STATE again. Now he waits for the next customer…
MACHINES just work like this. They can have multiple STATES, of which only one is active at the same time. The RULES give the MACHINE exact guidelines about what he has to do in a given STATE… for example, how he should process the given input or what conditions he has to check.
Basic Structure
The basic Syntax is as follows:
MACHINE “name”
STATE <name>
[RULE event <event-name>
...
END]
END
END
What happens here?
MACHINE “name” => defines the MACHINE’s name
STATE <name> => defines a STATE’s name
RULE event <event-name> => defines a RULE event
… => here is the place, where all your commands will go
MACHINE, STATE and RULE each have their own “block”, which is ended with the keyword END. That keyword tells Nexus, that this RULE, STATE or MACHINE is finished now.Lets take a closer look at each block separately
The RULE block
The basic syntax of the RULE block:
RULE event <event-name>
[:condition
Condition1
Condition2
...
:end]
:action
[Command1]
[Command2]
...
:end
END
Every RULE follows this syntax. First Nexus will look into the “:condition” block and see if all defined conditions are met. If they are not, Nexus won’t run any of the commands in the “:action” block. If they are met, then Nexus will continue with the “:action” block.
Hint: You can leave out the whole “:condition” block, if you don’t want to set any conditions.
Hint: Instead of “:condition … :end” you can write “condition condition”, if you have only one or a few simple conditions to check. You can link conditions with & (AND) and | (OR).
The “:action” block is the part of the RULE, where all your commands go. You can give orders to ship, script cutscenes, assign variables and a lot of other stuff here. A more detailed explanation can’t be given here, because this would exceed this tutorial’s scope by far. Look at the provided Mod Documentation by Mithis for more details.
Some quick examples for RULES:
RULE event display_title
:action
Title(0,0,0,”Mission completed”);
:end
END
RULE event do_nothing
:action
:end
END
RULE event process_condition
:condition
raven.damage>100
raven.race=#race_Gorg
:end
:action
Title(0,0,0,”Mission completed”);
:end
END
RULE event short_condition
Condition a>b
:action
Debug(“A is bigger than B”);
:end
END
Naming conventions: Basically you can set about every name you can think of. But keep in mind, that Nexus knows three predefined RULES: In, Out, Tick. Every STATE needs a “RULE event In”. This RULE is being run, when the MACHINE reaches a given STATE. Without the In event, Nexus won’t know, which of the multiple RULES in a single STATE it should run first, so make sure, you have the In event.
The Out event is not needed at all, but it’s always good to create a proper “end” RULE. That would be the RULE, where you leave the current STATE.
The Tick event is a very special event. This event runs every few moments and doesn’t need to be called by another event. You need to write “TICK <time_in_seconds>” somewhere between the RULES blocks. This way you can define, how often the Tick event is run. TICK 5 runs it every 5 seconds. Tick is great for monitoring certain events. Tick could check every few seconds, if ship X has lost his shield for example. Based on the result, it could trigger another RULE to be run. Here is an example:
TICK 5
RULE event tick
:action
If(a>b, a_bigger_b);
:end
END
RULE event a_bigger_b
:action
DEBUG(“A is bigger than B”);
:end
END
As you see, a STATE can have multiple RULES of course. You can even have multiple RULES with the same name!
Something like this for example:
RULE event ab_compare
Condition a>b
:action
DEBUG(“A is bigger than B”);
:end
END
RULE event ab_compare
Condition a<b
:action
DEBUG(“A is smaller than B”);
:end
END
Calling a RULE from within a RULE: Now how do you do that? Simple:
LocalEvent(name_of_event);
or even
name_of_event;
Note, that you can only call a RULE that is given in the current STATE. You can’t call RULES from different STATES that way.
The STATE block
The basic syntax of the STATE block:
STATE <name>
[RULE event <event-name>
...
END]
...
END
There is nothing special to be seen here. You define the different STATES of your MACHINE given the above syntax. Don’t forget to choose appropriate names for your STATES (and RULES, too), so you can easily see, what happens in this STATE or RULE.
You can have as much RULES as you want in a single STATE as you can have as much STATES as you like in a single MACHINE. It’s up to you to decide, where you could use a separate STATE and where it is sufficient to define a few more rules in an already existing STATE. Do whatever you like more, but try to create a clear structure of MACHINES, STATES and RULES, so that other people have a chance to understand, what your code achieves.
Hint: Don’t forget to give every STATE his own “In” RULE. If you switch to another STATE, the program will run this RULE at first.
How to switch to another STATE: Simple… use:
ChangeState(name_of_state, parameter);
With this you can change only to a STATE in this MACHINE. To change the STATE of a different MACHINE, use:
M:GetMachine(name_of_machine):ChangeState(name_of_state, parameter);
With “parameter” you can give local variables to another STATE. If you don’t want to do this, just write 0 (zero) instead of the variables. Here’s an example for two simple STATES in a MACHINE:
MACHINE “ab_compare”
STATE a_bigger_b
RULE event In
:action
Debug(“A is bigger than B”);
:end
END
TICK 5
RULE event tick
:action
If(a<b, ChangeState(a_smaller_b,0));
:end
END
END
STATE a_smaller_b
RULE event In
:action
Debug(“A is smaller than B”);
:end
END
TICK 5
RULE event tick
:action
If(a>b, ChangeState(a_bigger_b,0);
:end
END
END
END
The MACHINE block
The basic Syntax is as follows:
MACHINE “name”
STATE <name>
[RULE event <event-name>
...
END]
...
END
...
END
Now you know almost every important aspect of a MACHINE’s structure. Here are some additional bits of information as well as some repetition of important facts you learned throughout the tutorial:
Multiple RULES: You can define multiple RULES per STATE, but you only have access to the RULES in the currently active STATE. RULES can be run simultaneously.
Multiple STATES: You can define multiple STATES per MACHINE. You have access to all the RULES defined for that STATE. STATES can’t be run simultaneously – only one STATE can be active at a time. However, you can switch between the STATES as you like.
Multiple MACHINES: One thing, that wasn’t covered yet. You can define multiple MACHINES in a mission. These run all at the same time. This way you can create totally different MACHINES for totally different purposes. For example you create one MACHINE for the enemy AI, another MACHINE, that constantly checks, if the winning conditions have been already met and a third MACHINE, that controls the in-game cutscenes.
Activating MACHINES: You do that best in the “sceneInit” RULE of your mission with the command “M:GetMachine(name_of_machine):ChangeState(name_of_state, parameter);
Closing words
I wish you luck and much fun while trying to create new mission and mods for Nexus. Hopefully this tutorial will help you understand the basics of MACHINE scripting and get things rolling for you.
Author: Arparso