Difference between revisions of "Script (OpenXcom)"

From UFOpaedia
Jump to navigation Jump to search
(added first version of modscript documentatin)
 
Line 24: Line 24:
  
 
Note: ohartenstein23 also maintains a copy of the API reference [https://raw.githubusercontent.com/ohartenstein23/Yankes-Scripting/master/yankesScript.txt| here]. Might be enough for a quick peek.
 
Note: ohartenstein23 also maintains a copy of the API reference [https://raw.githubusercontent.com/ohartenstein23/Yankes-Scripting/master/yankesScript.txt| here]. Might be enough for a quick peek.
 +
 +
Note 2: You might want to disable verboseLogging after dumping the API documentation since your logfile will become pretty bigh otherwise.
  
 
=== Scope ===
 
=== Scope ===

Revision as of 19:35, 7 January 2020

ModScripting Basics

ModScripts are scripts for OXCE which are able to change the behaviour of the game while it is running.

They are not based on any pre-existing programming language but borrow from assembler syntax. The language was created by Yankes, so for any details of the implementation you might want to ask him.

ModScript API

Since the ModScript feature is a work in progress, the API can change heavily between OXCE versions. Fortunately the game included code to dump the currently active API. In order to acquire the API Documentation you will have to set the following options in your options.cfg

  debug: true
  verboseLogging: true

Then start up the game and it should generate quite a large log file in openxcom.log.

The documentation starts at a line that looks like this:

[20-12-2019_21-14-46]	[DEBUG]	Available built-in script operations:

The API Documentation includes the names of all available script hooks, their input/output parameters and variables and all the available script commands, objects and their methods.

Currently the ModScript engine only supports integer as a data type. So no strings, no lists, etc.

Note: ohartenstein23 also maintains a copy of the API reference here. Might be enough for a quick peek.

Note 2: You might want to disable verboseLogging after dumping the API documentation since your logfile will become pretty bigh otherwise.

Scope

Scripts can be created in local or global scope. The Syntax for them differs slightly.

Global Script example

extended:
  scripts:
    createUnit:
      - offset: 2
        code: |
          return;

Local Script example

armors:
  - type: MIMIC_ARMOR
    scripts:
      createUnit: |
        return;

So while global scripts have to be under the top-level name "extended", local scripts are attached directly to a gameobject.

Scripts are executed in order of their offsets. So a script with offset 10 will be executed after a script with offset 5. When scripts with the same name define the same offset one overrides the other, as with every other value in OXC rulesets.

Under the hood, the global scripts will later be "sorted" into the respective local ones. Internally, local scripts always have offset 0. So a global script with offset -1 would run before the local one. Offsets are also a valuable tool make sure two mods and their scripts don't conflict with each other.

While global scripts execute for every gameobject, local ones only run for the gameobjects they are bound to.

The name of the script is pre-defined. You can find a complete list of all script hooks in the ModScript API.

Syntax

The syntax relies on Polish notation for its operations. Commands are derived from assembler so we can write the following:

var int x; # declare variable x as integer type
var int y; # declare variable y as integer type
set x 3;   # set variable x to the value 3, so x=3 is true afterwards
set y 2;   # set variable y to the value 2, so y=2 is true afterwards
add x y;   # add the value of variable y to variable x and store the result in variable x
debug_log "X is now" x; # will print the string "X is now" followed by the value of x which is now 5

This would of course only execute if embedded into a ruleset like this:

extended:
  scripts:
    createUnit:
      - offset: 2
        code: |
          var int x;
          var int y;
          set x 3;
          set y 2;
          add x y;
          debug_log "X is now" x;
          return;

This would execute for every unit created at the start of a mission. So if you have 10 soldiers and fight 5 aliens this would print "X is now 5" 15 times into your openxcom.log file.