Flight Commander Scripting Documentation

by Ed Benowitz

Scripting Introduction

Fligth Commander scripting is only for those who want to create advanced missions.  It is not required for simple missions, which can be done via the mission editor only.  

To begin creation of a scripted mission, first contruct nav points and ships within the mission editor.  Once this is done, you can assign scripts to both nav points and ships.  

All Flight Commander scripts are done in the Lua scripting language. The book Programming in Lua is a good introduction.
Flight Commander comes with a number of example scripted missions.  The files of interest start with "scriptexample".

Nav Point Scripts

For nav points,  press the Nav Script button in the mission editor.  This allows you to specify functions which will be called at 3 different instances:
  1. When the nav point is entered, the function name you specify under "on creation" will be called.
  2. After the nav point has been exited from, the function name you specify under "on destroy" will be called.
  3. Often times, you want a function to be called all the time while the nav point is active.  The function name you specify under "on time advance" will be called once a second while the player is at this nav point.
The nav functions do not take any parameters.  For example, if in the mission editor you specified a function named nav2create, in your lua file, you should have a function like the following

function nav2create()  
  -- your code goes here
end

Ship Scripts

Ships can be manipulated by many Ship_ functions provided by the Flight Commander engine.  You can refer to a specific ship using its shipid.  The shipid is a string which is specified in the mission editor for each ship, under "name in scripts".  A common convention is to use names that start with $, but this is not necssary.  

For  example, if you give a ship an id $bugship, then in a script, you can call
  radius =  Ship_getRadius("$bugship");

Like nav points, ships can have functions attached to them as well.  Any ship with functions must also have a ship id specified.  By pressing the ship script button within the mission editor, you can attach script functions to a ship.
This allows you to specify functions which will be called at 3 different instances:
  1. When the ship is created, the function name you specify under "on creation" will be called.
  2. After the ship is destroyed, the function name you specify under "on destroy" will be called.
  3. Often times, you want a function to be called all the time while a ship is active.  The function name you specify under "on time advance" will be called once a second while the ship is alive..
Here is an example ship function

function onbugdead(shipid)
  bugsdead = bugsdead + 1;
end

Notice the shipid.  This string allows you to know the shipid of the ship you are currently working with.  Sometimes this makes it easier for multiple ships to share the same ship functions.

Other info

The first line should always be
dofile "flightcommander.lua"
which includes a number of predefined flight commander variables which you will need.

Your script file must be named in a special way.  If the mission file is called scriptexample1.mission.xml, your script file must be named scriptexample1.lua.

If there are errors in your script Flight Commander can alert you.  However, sometimes it is easier to check the syntax of your script before trying it in Flight Commander.  Run
    luac scriptname.lua
to check the syntax.

It is best to start out by looking at the example scripted missions.  The scripts are named scriptexample1.lua through scriptexample4.lua.  


Saving Variables Between Missions


New in 1.5

Sometimes it is useful to store variables between mission.  Now this is possible: those values will be saved by the engine within a savegame, and will  be carried over to all future missions automatically.

It's very easy to use saved variables.  There is a special lua table named savedvars.  Use it in the following way:

Just store or retrieve any number, string, or boolean in the savedvar.

Examples:  Writing to saved variables.

savedvars.numberofkills = 25;
savedvars.asavedstring = "Hello world";
savedvars.criticalplotoccured = true;

Examples: Reading from saved variables.

print( savedvars.anumber);
id = savedvars.someid;

After saving a game, you can inspect the saved variables by opening up savegames.xml


Script Control


There are two ways to do scripting.  Basic, and full script control.  

Basic Full Script Control
Advantage: Easier scripting

By default, Flight Commander starts up in basic mode.  
The game automatically does the following:

  • computes when autopilot can be enabled
  • Determines when a mission is complete.
  • Automatic landing
  • Multiple waves
  • Assigns all autopiloting ships to the player's wing
Advantage: More control
 
For example, only in this mode can you
  • Add new ships in the middle of a mission, depending on the actions of the player
  • Allow the player to visit nav points in any order
  • Have multiple wings of friendly fighters

You will have to keep track of the following in your own script.

  • When to allow autopiloting
    • call Mission_setAutopilotEnabled
  • When all the enemies at a nav have been killed
  • Multiple waves
  • Landing
    • call Mission_doLanding()
  • When the mission is won or failed
    • call Mission_setAccomplished();
    • or call  Mission_setFailed()
  • When the mission is complete
    • call Mission_setComplete();
  • When there are no more enemies left
    • call Mission_setEnemiesAreAlive
  • Which navs are visitable
    • call Navpoint_setVisitable() in the nav's create function
  • Wing creation and membership.
    • call Wing_create and Wing_addWingman
This feature gives the script more power to control when these events occur, but this comes at the cost of more complicated scripts.

To give a script full control, call this
Mission_setScriptControl(true);




Debugging: Adding a print() to your .lua file

Sometimes your script does not quite do what you expect it to.  The process of fixing a script is called debugging.
There are a few methods to debugging.   The simplest way is to add prints to your script.  Let's say you have a counter
in your game called "c", and it is not behavior.  Within your script  add a line

    print(c)

You can then look at the command line window, and see the value of c.

Debugging Lua in a running game 

Since 1.7

It could get tiresome going back and forth, adding a print to the script, starting the game, stopping the game, etc.

To make it easier to debug, you can now type any line of lua and have it executed immediatley within a running game.  Here's how to access this functionality.

                lua>


Built-in functions



Camera_setCameraType(int cameratype)

Changes the camera.  The cameratype is one of

CAMERA_COCKPIT
CAMERA_LEFT
CAMERA_RIGHT
CAMERA_REAR
CAMERA_CHASE
CAMERA_AUTOPILOT
CAMERA_SCRIPTABLE

If you want to script movement of the camera directly, use CAMERA_SCRIPTABLE, as the other cameras do not directly support scripting.  When you are done with a cutscene, you should set the camera back to the cockpit  camera.

The scriptable camera has two numbers to consider: its "position", and its look at.   The position is the location of the camera.  The "look at"  is used to tell the camera what direction it should look at.  The look at is a point in space that the camera is focussed on.  The Camera_setLocation functions change the camera's position.  The Camera_setLookAt functions change the camera's look at.

example:
Camera_setCameraType(CAMERA_SCRIPTABLE);

since 1.4

Camera_setFocusShip(string shipid)

Some cameras can focus on a particular ship.  That is, the camera will always look at the center of a given ship. Other cameras are attached to a ship.  This function tells the camera which ship to focus on.  This is only intended for use with one of the following cameras:

CAMERA_CHASE
CAMERA_AUTOPILOT

Be sure to set the focus back to the player after a change.

since 1.4

Camera_setLocationFixed(float x, float y, float z)

Sets the camera's position. For use only with CAMERA_SCRIPTABLE.

since 1.4

Camera_setLookAtFixed(float x, float y, float z)

Sets the camera's look at. For use only with CAMERA_SCRIPTABLE.

since 1.4
Camera_setLocationInterpolated(float fromx, float fromy, float fromz,
                                                   float tox, float toy, float toz,
                                                   int timeinmilliseconds)

Moves the camera's position from the from location to the tolocation, over a time period.  The time it takes to do this is
timeinmilliseconds. For use only with CAMERA_SCRIPTABLE.

since 1.4


Camera_setLookAtInterpolated(float fromx, float fromy, float fromz,
                                                   float tox, float toy, float toz,
                                                   int timeinmilliseconds)

Moves the camera's look at from the from location to the tolocation, over a time period.  The time it takes to do this is
timeinmilliseconds. For use only with CAMERA_SCRIPTABLE.

since 1.4
Camera_setLocationRelative(string shipid, float offsetx, float offsety, float offsetz)

Sets the camera's location relative to the position of the ship.  As the ship moves, the camera moves with it. For use only with CAMERA_SCRIPTABLE.  The offset is in world space, not object space.  This differs from Camera_setLocationRelativeObject in that if the ship rotates, the camera does NOT rotates along with it.

since 1.4

Camera_setLocationRelativeObject(string shipid, float offsetx, float offsety, float offsetz)

Sets the camera's location relative to the position of the ship.  As the ship moves, the camera moves with it. For use only with CAMERA_SCRIPTABLE.  The offset is in object space, not world space.  This differs from Camera_setLocationRelative in that if the ship rotates, the camera rotates along with it.

since 1.5

Camera_setLookAtRelative(string shipid)

Sets the camera's look at the be the ship.  As the ship moves, the camera's look at moves with it. For use only with CAMERA_SCRIPTABLE.

since 1.4

Camera_setLookAtInterpolatedShips(string fromshipid, string toshipid, int timeinmilliseconds)

Interpolates the camera's lookat between the location of two ships.  The time it takes to do this is
timeinmilliseconds. For use only with CAMERA_SCRIPTABLE.

since 1.4

Camera_setShowDust(boolean showdust)

Set this to true to have the camera show moving space dust.  For use only with CAMERA_SCRIPTABLE.  By default
the scriptable camera does not show space dust.

since 1.4
Comm_playVideo(string wavname, string videoname, string displayedpilotname, int iffcode);
Comm_playVideo(string wavname, string videoname, string displayedpilotname, int iffcode, string caption);

This function is outdated, you should use Comm_playShipVideo in new scrips.  It will still work, but the ship currently speaking will not be highlighted in the game.

Only one comm can play at a time.

where iffcode is one of the following
    IFF_ENEMY
    IFF_NEUTRAL
    IFF_FRIEND

The new caption argument is optional.

Example:
  Comm_playVideo("maestro_yes.wav", "kilrathi.avi", "fromlua", IFF_FRIEND, "Yes, sir");

Since 1.5 (added caption parameter)

Comm_playShipVideo(string wavname, string videoname, string caption, string shipid);

Only one comm can play at a time.

shipid is used to highlight the ship that is currently speaking.

Since 1.6

Comm_playSound(string wavname);
Comm_playSound(string wavname, string caption);

Do not use this to play music, as this will block all comms.  Use the music functions instead.  Only one comm can play at a time.

Example:
  Comm_playSound("missionfailed.wav", "Mission failed");

Since 1.5 (added caption parameter)

int Comm_getLastChoice();

Returns the last comm choice the player made.  This will be a number between 1 and 5, or 0 if the player has not made a menu choice yet.

Comm_setMenuOverride(boolean);

You can override comms to give the player a menu of choices instead of the usual comm display.  When Comm_setMenuOverride(true) is called, the following  happens:
If Comm_setMenuOverride(false) is called, the menu will disappear, and normal comm functionality returns.
Comm_setMenuText(int index, string newtext);

Sets the menu text that will appear if  Comm_setMenuOverride(true) is called.  Index is a number 1-5.  Text remains in the menu for the entire mission, so it may be necessar to pass in empty strings "" to clear a previous menu.  An index of 0 will set the menu title.


Cutscene_start(string callback)

Starts up a cutscene, preventing the user from steering the player Ship.  The callback is the name of a script function that will be called by the cutscene once a second.  The callback takes no parameters.

since 1.4

Cutscene_end()

Ends the current cutscene, restores the camera, and returns control back to the player.

since 1.4
int Mission_getElapsedTime();

Returns the number of milliseconds since the start of the mission.

Example:   
    print(Mission_getElapsedTime() );


Mission_setScriptControl(boolean scriptcontrol);

By default, Flight Commander automatically computes when autopilot can be enabled, based on internal enemy counts. By giving a script control, the following automatic behaviors are disabled:
Instead, they will have to be implemented manually via scripting.  This feature gives the script more power to control when these events occur, but this comes at the cost of more complicated scripts.

To give a script full control, call this
Mission_setScriptControl(true);


Mission_setAutopilotEnabled(boolean enabled);
This function will only be allowed to succeed if  Mission_setScriptControl(true) has been called first.  
Mission_setAutopilotEnabled is the way the script can enable or disable the autopilot light.

example
Mission_setAutopilotEnabled(true);

Mission_setAccomplished();

Plays the mission accomplished sound, and sets the accomplished flag.

Mission_setFailed();

Plays the mission failed sound, and sets the failed flag.

Mission_setComplete();

When script has full control,  in other words,  Mission_setScriptControl(true); has been called, the function must be called when all of  the following conditions:
Once this function is called the following happen automatically:  music changes to reflect that the mission is complete. Also, the landing carrier comms will have the request landing option available.  This also affects whether the player can land on the carrier.

Mission_setEnemiesAreAlive(boolean)

This only needs to be used if Mission_setScriptControl(true) has been called.  If this is the case, as soon as a nav is created in which enemies will  appear, Mission_setEnemiesAreAlive(true) must be called.  Otherwise, music will not change to combat music, and the play will not be able to issue wing commands.  When the last enemy has been destroyed at the nav point, you must call Mission_setEnemiesAreAlive(false).  Which reverts to a normal patrol music, and then the player will only be able to ask wingmen for status.  The mission defaults to the false condition.


Mission_setFriendlyEjectPickup(boolean)

Call this function with true to allow a friendly eject pickup.  False shows the enemy pickup cutscene on eject.  


Mission_doLanding()

Plays the landing cutscene, and exits the engine.

Mission_exit()

Exits the mission without running the default landing cutscene.
since 1.4

Mission_addShip(
   string filename;
   string comm;
   string video;
   bool autopilot;
   string pilot;
   int  iffcode;
   float x, float y, float z.
   string tag,
   string createfunction,
   string destroyfunction,
   string duringfunction);

Where filename is the name of the ship file.  If the shipfile name is myship.ship.xml, the filenameparameter is myship. Comm is the name of the comm choice (as shown in the mission editor).  Video is the name of the video choice (as shown in the mission editor.  If autopilot is true, the ship will autopilot with the player to the nav.  The pilot string appars as the target id.  Iff code can  be one of     IFF_ENEMY,     IFF_NEUTRAL,     IFF_FRIEND.  x, y and z are the initial position of the ship.  Tag is the variable name passed to any Ship_ scripting calls.  The last three parameters
are the names of scripting functions attached to the ship. If no script function is desired, pass in "" instead.


Mission_setFormation(int formationnumber)

This function should no longer be used since 1.7.  Instead, use Wing_setFormation

By default, the player's wing will use formation 0 as defined in the formations.xml file.  Use this function
to change the formation used.  The formationnumber is the 0-indexed formation within the formations.xml file.


Mission_setDebugText(string text)

Displays the text on the cockpit screen.  Will remain on the screen until it is changed.  This is useful for debugging scripts from within the game, and is sometimes more convenient than a print to the console.

Mission_setCollisionDetectionEnabled(boolean enabled)

Allows the script to turn on and off collision detection.  Useful for cutscenes.  By default, this is enabled.

since 1.4

boolean Mission_isPlayerTraitor();

Returns true if the player is a traitor.

since 1.5

Mission_setPlayerTraitor();

Forces the player to be a traitor, making all formerly friendly ships enemies.

since 1.5

Mission_setTotalScore(int score);

Sets the total mission score.  This is displayed in debriefings, and is used in the high score list for the simulator.

since 1.6

Mission_setOverallPercent(float percent)

Sets the overall mission percentage complete.  This is displayed in debriefings.

since 1.6

Music_play(string filename)

Overrides any existing music and plays this file in a loop.  Usually cutscenes will use this only.  

Filename should be an mp3 file.

example:

Music_play("mymusicfile.mp3");

since 1.4

Navpoint_setName(int navnumber, string name);

Changes the user visible name of the specified nav point.  navnumber starts at 0 for the first nav point.

since 1.5

Navpoint_setVisitable(int navnumber, bool visitable)

When in full script control mode, the player change chose the next nav point to visit.  The game designer may want to
have certain nav points hidden until later in a mission.  Or they may want to restrict which nav points a player can visit next.
This function allows this.  In full script mode, all navs are by default not visitable.

It is the script writer's responsibility to keep track of whether a nav has been visited already or not, and to ensure that
the enemies at the nav are spawned the appropriate number of times, rather than over and over again on every nav visit.

For those ships that are in the XML file, if they are only created on the first visit to the nav.  However, any ships that are
not wingment that are left at a nav are saved for the next visit to that nav.


since 1.6

Navpoint_setAllVisitable()

Allows the player to visit any nav point, except the current nav.  If  script control mode is on, this should be called on creating every nav point, if you want
the user to be able to navigate to anywhere at any time.

since 1.6


Objective_setState(int objectivenumber, int state)

Objective number is the index of the objective in the mission.xml file, starting with 0

where state is one of the follwoing
  OBJECTIVE_COMPLETE 
  OBJECTIVE_INCOMPLETE 
  OBJECTIVE_FAILED

Objective_setName(int objectivenumber, string name);

Overrides the name for the objective originally specified in the mission.xml file.
Objective number is the index of the objective in the mission.xml file, starting with 0

Objective_setPercent(int objectivenumber, float percent)

Objective number is the index of the objective in the mission.xml file, starting with 0
percent is a number from 0.0 to 1.0,    
1.0 means 100%

since 1.6

Overlay_setEnabled(boolean enabled)

The overlay is a blue transparent rectangle displayed at the bottom of the screen, and is used to display text on top of the normal game graphics.  This is useful for cutscenes, and is used in the mission briefing.  By default it is disabled.

since 1.4

Overlay_setText(string newtext)

Sets the text that is displayed by the overlay.

since 1.4

Sector_change(string newfilename)

example:
Sector_change("red.sector.xml")

since 1.4

Ship_setIff(string shipid, int iffcode)

Changes the iff code of a ship.

where iffcode is one of the following
    IFF_ENEMY
    IFF_NEUTRAL
    IFF_FRIEND

Example:
  Ship_setIff("midway", IFF_ENEMY);

int Ship_getIff(String shipid);

where thre return value  is one of the following predefined integers
    IFF_ENEMY
    IFF_NEUTRAL
    IFF_FRIEND

since 1.5

float x, float y, float z   Ship_getLocation(string shipid)

This function returns three values, the location of the ship.  This is the location in world space of the ship's center of rotation.  If the ship cannot be found, 3 nil values are returned.

Example:
    x, y, z = Ship_getLocation("midway");

Ship_setLocation(string shipid, float x, float y, float z);

Sets the ship location in world space.

boolean Ship_isActive(string shipid);

Returns true if the ship currently exists.


float Ship_getHitPoints(string shipid)

Returns the percetage (between 0 and 1) of hit points. If shipid doesn't exist, returns nil.


Ship_setHitPoints(string shipid, float percent)

Changes the ships hit points, on a  the percetage (between 0 and 1).

example:
Ship_setHitPoints("midway", .4);


boolean Ship_isWithinRange(string shipid1, string shipid2, float range);

Returns true if the distance between ship1 and ship2 is less than the range.  Returns nil if either of the ships is invalid.

Ship_destroy(string shipid)

Destroys the ship.

Ship_eject(string shipid)

Ejects the ship programatically.


int Ship_getNumTurrets(string shipid)

Returns the number of  turrets on the ship (those which have not been destroyed).  Returns 0 for fighters.


int Ship_getNumComponents(string shipid)

Returns the number of  turrets on the ship (those which have not been destroyed).  Returns 0 for fighters.


float Ship_getRadius(string shipid);

returns the radius of the ship.


Ship_setFuel(string shipid, float percentage)

Sets the amount of fuel in the ship, where percentage is from 0 to 1

Ship_setForceEject(string shipid, boolean forceject);

When forceeject is true, this ship will always eject instead of being destroyed.  This is useful if a pilot is plot-critical. Probably should only be used on friendly craft.  By default, forceject is set to false on a ship.

Ship_setAutopilot(string shipid, boolean autopilot);

If autopilot is true, this ship will autopilot with the player to the next nav point.


Ship_setCargo(string shipid, string cargoname);

Sets the cargo name.

boolean Ship_isCargoIdentified(string shipid)

Returns true if the ship's cargo has been identified


Ship_setTarget(string myshipid, string targetshipid)

Sets the current target of myshipid to be targetshipid.



Ship_setOrientation(string shipid, float rx, float ry, float rz);

Sets the ship's orientation. rx, ry, and rz are angles, in degrees.  They are angles rotated about the x, y, and z axis.  Typically, users will only need to change ry, and leave rx and rz zero.

float Ship_getSpeed(string shipid)

Returns the ship's speed.

boolean Ship_isAfterburning(string shipid)

Returns true if the ship is afterburning.


Ship_setAIEnabled(string shipid, boolean enabled)

Enables or disables the ship's movement AI.

since 1.3.1

Ship_setScanAllowed(string shipid, boolean scanallowed);

By default, only the player can scan ships for cargo.  This allows other designated ships, preferrably friendlies, to scan for cargo as well.

since 1.3.1

Ship_setDesiredVelocity(string shipid, float percentage)

This should be used only when the AI is disabled.  Sets the desired velocity of the ship, as a percentage from 0 to 1.0.

since 1.4

Ship_setAfterburner(string shipid, boolean on)

This should be used only when the AI is disabled.  Turns on or off the afterburner.

since 1.4

Ship_replenishMissiles(string shipid)

Gives the ship back all the missiles it started with

since 1.4

Ship_replenishGuns(string shipid)

Gives the ship back all the guns it started with

since 1.4

int Ship_getArmor(string shipid, int region)

Returns the ship's current armor value.  Region must be one of:

since 1.4


int Ship_getShields(string shipid, int region)

Returns the ship's current shield value.  Region must be one of:

since 1.4

Ship_setShields(string shipid, int region, int newvalue)

Sets the ship's current shield value.  Region must be one of

since 1.4

Ship_setArmor(string shipid, int region, int newvalue)

Sets the ship's current armor value.  Region must be one of

since 1.4

int Ship_getMaxShields(string shipid, int region)

Returns the ship's maximum shield value.  Region must be one of:

since 1.4

int Ship_getMaxArmor(string shipid, int region)

Returns the ship's maximum armor value.  Region must be one of:

since 1.4

Ship_setArmorValue(string shipid, int region, float percentage)

Changes the ship's shield region, as a percentage (between 0 and 1).  Region must be one of since 1.4

float Ship_getArmorValue(string shipid, int region)
Returns the current ship's armor region as a percentage (between 0 and 1).  If shipid doesn't exist, returns nil. Region must be one of since 1.4

Ship_setShieldsValue(string shipid, int region, float percentage)

Changes the ship's shield region, as a percentage (between 0 and 1).  Region must be one of
since 1.4

float Ship_getShieldsValue(string shipid, int region)

Returns the current ship's shield region as a percentage (between 0 and  1). If shipid doesn't exist, returns nil. Region must be one of
since 1.4
Ship_setShieldsAll(string shipid, float percentage)

Changes all the ship's shields regions to a percentage value (between 0 and 1).

since 1.4

Ship_setArmorAll(string shipid, float percentage)

Changes all the ship's armor regions to a percentage value (between 0 and 1).

since 1.4

Ship_jumpOut(string shipid)

The ship jumps out.  

since 1.4

Ship_jumpIn(string shipid)

The ship jumps in.  This must be called immediately after Mission_addShip if it is called at all.

since 1.4
Ship_remove(string shipid)

Similar  to Ship_destroy, except that this function does not show an explosion, and kill counts are not affected.   The ship's on kill function will also not be called.

since 1.4


Ship_setMaxVelocity(string shipid, float value);

Changes the ship's maximum velocity.  This should really only be used for cutscenes.  If this function is not called, this ship's maximum velocity is limited by its xml file's value.

since 1.4

Ship_setVisible(string shipid, bool visible);

This should only be used by cutscenes. It is primarily used to force the engine to render a ship, or to temporarily hide a ship during placement or movement in a cutscene.   Do not attempt to implement cloaking with this.  

since 1.4


Ship_setLandOn(string shipid, bool landon);

True if this will be the ship the player can land on.  Usually used with scriptcontrol mode.
This allows the ship to have a request landing comm, and to do the landing if you bump into it.
Can only be used on capital ships.

since 1.6

Wing_create(string shipid_wingleader)

Creates a wing, with the wingleader given by the shipid of shipid_wingleader.  The wingleader's shipid will be used to identify the wing.
A wing should be created and completely filled out at the nav point's entry function.  Only friendly wings should be created.
This must only be used with scriptcontrol.

since 1.7

Wing_addWingman(string shipid_wingleader, string shipid_wingman)

Adds a wingman to a wing.
A wing should be created and completely filled out at the nav point's entry function.  Only friendly wings should be created.
This must only be used with scriptcontrol.

since 1.7

Wing_removeWingman(string shipid_wingleader, string shipid_wingman)

This should  be used if a wingman is not autopiloting to the next nav point.  Typically used in a nav's exit function.
This must only be used with scriptcontrol.

since 1.7
Wing_setName(string shipid_wingleader, string name)

When a player pulls up the comm menu, part of the menu displays the wing name.  The default wing name is "Alpha".  This allows you to change
the wing name that is displayed.  shipid_wingleader should be the player's shipid.

since 1.7

Wing_setFormation(string shipid_wingleader, int formationnumber)

By default, friendly wings will use formation 0 as defined in the formations.xml file.  Use this function
to change the formation used.  The formationnumber is the 0-indexed formation within the formations.xml file.
Each wing can now have its own formation.

since 1.7

Wing_setAutopilotOffset(string shipid_wingleader, float x, float y, float z)

This only needs to be called for friendly wings that are not the player's wing.
It only affects autopilot cutscenes.  

x, y, z, :  The offset of this wing's leader with respect to the player's location.


since 1.7

math.random

The math.random function generates pseudo-random numbers. We can call it in three ways. When we call it without arguments, it returns a pseudo-random real number with uniform distribution in the interval [0,1). When we call it with only one argument, an integer n, it returns an integer pseudo-random number x such that 1 <= x <= n. For instance, you can simulate the result of a die with random(6). Finally, we can call random with two integer arguments, l and u, to get a pseudo-random integer x such that l <= x <= u.

Example:
print(math.random(-5, 5) );