Nexus:TJI Scripting Structure

From NexusWiki
Jump to: navigation, search

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