Nexus: The Jupiter Incident

Nexus: The Jupiter Incident

Not enough ratings
Advanced scripting manual (EN)
By TehnoMag
This manual is intended for in-depth study of the structure and capabilities of Nexus: TJI scripts. Here I will describe all the found, but undocumented functions; mark functions and events that do not work in the latest version; specify features of the work of a number of functions that are poorly documented in the official manual, or not documented at all. Part of the information is taken from the Wiki http://nexusthegame.net/wiki/Nexus_-_The_Jupiter_Incident and I do not claim authorship. Such content is marked as a quotation or linked to the original article.

If you have any comments or corrections on this manual (aspecialy spelling and translation from Russian), please let me know.
   
Award
Favorite
Favorited
Unfavorite
Required content and tools
To work with Nexus: TJI scripts, you will need 3 things:
  • A text editor for working with scripts
    I recommend using Notepad ++ (Official site[notepad-plus-plus.org]).

  • Microsoft Excel for easy editing of the parameters of ships and devices.
    You can also use LibreOffice.Calc, if you can adapt the macro for it (Me, for example, did not succeed).

  • A set of optional mods.
    Of course, they are not required, and you can create your own implementation, but in this manual I will constantly refer to them, so for a better understanding of the process it is better to have these mods at hand.
    https://steamhost.cn/steamcommunity_com/sharedfiles/filedetails/?id=1139261112
Variable Scopes and visibility
Wiki article[nexusthegame.net]

  • "D." scope
    It is presented in the official manual as a dialogue scope, but does not really work.

  • "T." scope
    Presented in the manual, as the scope of tactical subroutine variables, and it`s actually works, but useless, because in the subroutine to transfer variables better use the scope "E."
Scripting Structure
Wiki article[nexusthegame.net]

Additionally, the 'RULE' block can take the following syntax, if the condition are specified:

In general, the description of the body ':else' noticed in the official manual, but for some reason does not exist on the Wiki and is not used in the original campaign

RULE event DoSomething condition somevar=1 :action Debug("somevar eq 1"); :end :else Debug ("somevar not eq 1"); :end END

In case the condition is fulfilled, the commands in the body :action will be executed
If not, then in the body :else

Also, you can specify several bodies :action in the RULE block

RULE event DoSomething condition somevar=1 :action Debug("somevar eq 1"); :end :else Debug ("somevar not eq 1"); :end condition somevar2=1 :action Debug("somevar2 eq 1"); :end :else Debug ("somevar2 not eq 1"); :end END

In this case, the first condition will be checked and selected body will be executed, and then the second.
uTypeObject list
List of type ids that can be checked through the uType() function;

uType
id
string
0
entity/*
1
system/
100
effect/
103
nexus/
106
location/**
200
station/
201
asteroidfield/
203
fleet/
204
location/***
205
celestial/
206
navigationpoint/
207
ship/
302
device/
305
asteroidscene/
310
npc/
400

* - Story depot
** - stellar subojects like comets
*** - Nexus gates

Example: uSelect(0, uGetUniverse(), S:uType() = 207) returns all navpoints are defined in universe on strategic level
Undocumented functions
  • uGetUniverse
    Returns root game object

    Syntax
    uGetUniverse()
    Features
    None

  • uCamera_Enter
    Starts the procedure for entering to tactical mode with animation.
    Unlike uEnterMission does not require a separate mission file.

    Syntax
    uCamera_Enter(uTypeObject)
    Supported argument types
    • system/*
    • nexus/*
    • celesital/*
    • fleet/*
    • navigationpoint/*
    • asteroidfield/*
    • station/*
    • location/*
    Features
    • Works only in the campaign modifications
    • Mission 99 should be defined
    • Does not require a function uSetNextMission call
    • Unstable in tactical mode. Use with caution.

  • uCamera_PutInto
    Starts the procedure for entering to tactical mode without animation.
    Unlike uEnterMissionQuick does not require a separate mission file.

    Syntax
    uCamera_PutInto(uTypeObject)
    Supported argument types
    • system/*
    • nexus/*
    • celesital/*
    • fleet/*
    • navigationpoint/*
    • asteroidfield/*
    • station/*
    • location/*
    Features
    • Works only in the campaign modifications
    • Mission 99 should be defined
    • Does not require a function uSetNextMission call
    • Unstable in tactical mode. Use with caution.

  • QuitMission
    Starts the procedure for exiting from tactical mode with the animation.
    Unlike uQuitMission, it does not require an argument. When exiting from tactical mode, the debriefing screen will not be displayed, and there will also be no exit to the main menu if the function uSetNextMission was not called. U.ActMission and U.ActEpisode variables did not will increment.

    Syntax
    QuitMission()
    Features
    • Works only in the campaign modifications
    • Stable only if the tactical mode was entered using uCamera_Enter or uCamera_PutInto functions
    • Does not require a function uSetNextMission call
    • Requires a manual GuiSelect(2) function call
    • Does not hit MissionQuit event. So, it`s can not be catch in story scripts

  • isat
    Returns 1 if the calling object is a child. Otherwise 0.

    Syntax
    uTypeObject:isat(uTypeObject)
    Supported argument types
    Any uTypeObject
    Features
    Нет

  • uGetC
    Returns an object if it is a child of the specified.

    Syntax
    uTypeObject:uGetC(string)
    Features
    Нет

  • get
    alias to GetSceneObj

    Syntax
    get(string)
    Features
    Same as GetSceneObj

  • makeMainShip
    Unknown

    Syntax
    MakeMainShip(Ship, string)
    Features
    Unknown
Hacks
  • Transition to tactical mode through the map menu (strategic mode))
    In order for this hack to work we need set DetectionLevel to 5 for all required system objects (#UDET_SPYCAM)

    Example:
    RULE event EpisodeStart condition ActEpisode=1 :action sel := GetFreeSel(); uSelect(sel, uGet("sys_sol"), S:celestial()|S:colony()); ExecList(sel, S:uSetDetectionLevel(#UDET_SPYCAM)); :end END

    Now an additional button will appear on the object description panel.
    When it is pressed, the uCamera_Enter function will be called and we will be in tactical mode.






  • Wormhole jump animation
    In Mission 16 of the original campaign, we see the animation of Angelwings`s jump throw the wormhole. I think many noticed that this animation does not work anywhere else. This is not quite true.

    The ship classes (Universe / tactics / tacticstypes.ini file) have the HPRegen parameter (it is specified only for the Angelwing class). If this parameter is greater than zero, then when you enter the wormhole, animation will be shown (it is enough to specify the value 0.001 or similar, so as not to destroy the balance). Moreover, after playing the animation, the scene will be unloaded and you can safely use the uCamera_Enter or uCamera_PutInto function in MissionQuit event to switch the scene. However, unfortunately, this only works with nexusgate / * object type and before calling function we need to play some bink movie for complete scene destruction (empty movie will be enough)
Object-oriented scripting
This section is out of date. Will be updated after Universe Script Library 2.0 release

In big complex mods, it becomes necessary to use objects with the same set of functions and variables, but with different states. Unfortunately, the original game does not provide this functionality, so I wrote a module to extend the capabilities of the standard StateMachine and is included in the uSL mod.
  • Basic concepts
    • Class: StateMachine created through the Class module of the uSL library
    • Reference: Class instance
    • Object: Class machine itself

  • Definitions
    Each class can have one or more instances with its own unique state of variables. Access to the instance can be obtained through a class object, or via the __ changeInstance function.

  • Macros
    Macros are specified via directive #include.
    • uSL/class/declaration
      This macro tells the game that this StateMachine is a class.
      It should be defined immediately after the definition MACHINE
      .

    • uSL/class/instance
      This macro defines the method as the instance method.
      It should be specified immediately after the definition RULE event
      .

    • uSL/class/end_instance
      This macro determines the end of the instance method.
      It should be specified immediately after the definition :end
      .

    • uSL/class/end
      This macro determines the end of the instance method.
      It must be specified after all methods
      .

Class Example
MACHINE "uSL/Class/Example" #include "uSL/class/declaration" RULE event __Constructor #include "uSL/function/private" :action //Init variables var1 := 3; var2 := 2; var3 := 1; //Doing something :end END //This function need for instancing RULE event __var #include "uSL/function/private" :action if (!E.flag, E.flag := #uSL_CLASS_SETGET); var1 := this:localEvent(__instvar, E.flag := P.flag; E.id := 1; E.value := var1); var2 := this:localEvent(__instvar, E.flag := P.flag; E.id := 2; E.value := var2); var3 := this:localEvent(__instvar, E.flag := P.flag; E.id := 3; E.value := var3); :end END //Simple instanced function RULE event ExampleFunc #include "uSL/class/instance" :action var3:= var1+var2; Return(var3); :end #include "uSL/class/end_instance" END #include "uSL/class/end" END

Usage Example

//Create one instance of class Example object := U.uSL.Class:localEvent(New,E.class := "Example"); //Get class object example:=U.uSL.Class:last; //Create second instance object2 := U.uSL.Class:localEvent(New, E.class := "Example"); //Change var1 state in object2 instance example:var1:=4; //Call method for instance 'object' example:localEvent(ExampleFunc, E.ref := M.object); //Return 5 //Check var3 in instance 'object2' Debug(example:var3); //Return 1 //Call mathod for instance 'object2' example:localEvent(ExampleFunc, E.ref:=M.object2); //Return 6 //Check var3 again Debug(example:var3); //Let's change the instance of the class, passing the needed reference in the argument example:localEvent(__changeInstance,E.ref:=M.object); //var3 must be contain 5 Debug(example:var3); //Destroy instances U.uSL.Class:localEvent(Del, E.ref := M.object); U.uSL.Class:localEvent(Del, E.ref := M.object2);
Universe Script Library v2
The work of uSLv2 will be described below.

NOTE: This version of the library is NOT present in the Steam workshop yet, and can only be downloaded from my github
Mod Structure
Entry point
The entry point is a routine that will cause your mod to be initialized. In the Case of the Script Library, this will be the main menu (a feature of the Nexus Black Ruller scripting engine is that it resets all the necessary values ​​to the save file, as well as the script breakpoint, so when we load the game, we will immediately receive initialized scripts).
Also, I will separately note that the mod must be a modification of the company so that the Script Library can fully load. In addition, we will need a pointer to the main state machine of the mod in a certain format, so we will additionally need to write a small function to pass it.

CheckList
  • Modification is campaign modification
In the mod directory, you need to create the Universe directory (if it does not exist) and create an empty file in it with the name .campaign (dot campaign)
  • The Script Library entry point is assigned to the "New Game" button
In the Universe directory of your mod, you need to create a main.ini file, which will contain the following code:
Title "My Mod" MAINMENU "Start It!" uCall(ModMain, 0) "Load A Saved Game" loadgame END
, where
Title - the name of your mod
the MAINMENU block describes all the buttons that will appear in it.
The first parameter is the text of the button, the second is the event that will be triggered when it is clicked.
uCall(ModMain, 0) - Entry point to the Script Library
  • There is a properly formatted main mod state machine
Main mod state machine is the state machine that manages all the main mod events. In it, you must specify all the necessary logic, all the necessary transitions, etc. More about it will be discussed later in the documentation.

This machine should be located in strategic subroutines. Therefore, in the following code, you need the following subdirectories in your mod's Universe directory, namely, Strategy\Subroutines. In it, you need to create a file in the Mod.ModName.ini format, where ModName is the name of your mod.

In this file, you must specify the state machine and routine code, which will pass its pointer to the Script Library.
RULE event ModMain :action //Get Main Mod Machine e:mod := getMachine("/MdName"); //We want use ScriptLibrary, so lets init it. //As argument we sending Mod main machine uCall(UniverseScriptLibrary, e:mod := p:mod); :end END MACHINE "/ModName" STATE _INIT_ RULE event In :action //If you whant use some modules. You can include them here. _class := usl:localEvent(Use, e:module := "Class"); :end END END STATE _MAIN_ RULE event In :action //Real mod start. All staff already initialized and you can do whatever you whant :end END END END
Custom Module (Optional Mod) Structure
"Class" Embedded Module
1 Comments
Nico 4 Jun, 2021 @ 11:24am 
Any bit helps