Repository navigation
OFP Lua Scripting
Revision information OFP Revision: #171 Set the revision to your PR when your PR changes what this page documents. Leave it alone for edits that only fix or improve the documentation.
This page covers the Lua scripting API that OFP adds on top of stock FreeSpace Open. The full, always-current reference is the scripting documentation the engine writes itself (run with -output_scripting). This page adds context and examples for the OFP-specific parts. Everything else works as described on the FreeSpace Wiki scripting pages.
- Coordinate points
- Ship custom data
- Intel entry tech models
- Briefing closeups
- Documentation corrections
- Sample
Coordinate points are an OFP object type: named locations in a mission that can be drawn in-game as a shape and targeted by the player. See coordinate_points.tbl for their shapes and mission-file fields.
A library (part of mn) for accessing the mission's coordinate points.
| Member | Returns | Description |
|---|---|---|
mn.CoordinatePoints[IndexOrName] |
coordinatepoint |
Gets a point by name, or by 1-based index. Returns an invalid handle if not found. |
#mn.CoordinatePoints |
number |
The number of coordinate points in the mission. |
- A name is tried first, then a number. So
mn.CoordinatePoints["2"]returns a point named2if there is one, and otherwise the second point.
A handle to one coordinate point. It derives from object, so everything available on an object handle also works on it: Position, Orientation, isValid(), getBreedName() and so on. tostring() on it gives "<name> coordinate point".
Every property below can be read and set. On an invalid handle, reading returns the default shown in the table.
| Member | Type | Description | Invalid-handle value |
|---|---|---|---|
Name |
string |
The point's name. SEXPs refer to the point by this name. | "" |
DisplayName |
string |
The name shown on the HUD (target box, brackets, escort list) instead of Name. Doesn't have to be unique. Empty means the HUD shows Name, so set it to "" to go back to that. |
"" |
Category |
string |
Free-text label, shown on the HUD target box and brackets in place of a class name. | "" |
EscortPriority |
number |
0 = not on the escort list. Any value above 0 means it is on the list, and higher values sort higher. Setting a negative value stores 0. |
0 |
VisibleInMission |
boolean |
Whether the shape is drawn in-game (not just in the editor). Also allows target-in-front targeting. A hidden point can't stay targeted and isn't shown on the escort list. Same as the mission flag visible_in_mission. |
false |
AlwaysRenderLabels |
boolean |
While the point is visible, the HUD draws its display name and category beside it even when it isn't targeted. Same as the mission flag always_render_labels. |
false |
MultiTeam |
number |
-1 = seen by all teams. 0 or higher = seen only by that team in team-vs-team multiplayer. Single player ignores it. Out-of-range values become -1. |
-1 |
| Function | Returns | Description |
|---|---|---|
addToEscortList() |
boolean |
Adds the point to the player's escort list. Does nothing, and returns false, unless EscortPriority is above 0. Returns true if the point was added or was already on the list. |
removeFromEscortList() |
boolean |
Removes the point from the escort list. Does nothing if it isn't on it. Returns false only for an invalid handle. |
Colour, shape, size and angle are not exposed to Lua. They come from the mission file.
-
object: any API that hands back a generic object (for example, the player's current target) returns acoordinatepointhandle when the object is a coordinate point. -
oswpt: SEXP arguments that accept a ship/wing/waypoint/team can also hold a coordinate point. On such an argument,getType()returns"coordinatepoint"andget()returns thecoordinatepointhandle.
Ships can carry named custom data values, set in qtFRED's Ship Editor, by SEXPs, or by these methods. Values are always strings. A key exists only if the mission saved it or a SEXP or script set it; editor.tbl defaults are editor-only and are not applied at runtime.
string ship:getCustomData(string key, [string defaultValue = ""])
- Returns the stored value, or
defaultValueif the key isn't set. - Returns
defaultValuefor an invalid ship handle.
boolean ship:setCustomData(string key, [string value])
- Sets the key to
value. With no value, removes the key. - Returns
falsefor an invalid ship handle, otherwisetrue.
boolean ship:hasCustomData([string key])
- With a key: whether that key is set. Without: whether the ship has any custom data.
- Returns
falsefor an invalid ship handle.
boolean ship:clearCustomData([string key])
- With a key: removes it. Without: removes every key.
- Returns
falsefor an invalid ship handle, otherwisetrue.
Changes made through Lua are local: unlike the SEXP writes, they are not sent to other players in multiplayer.
Intel entries can have a 3D model through $Tech Model: in intel.tbl (see intel.tbl). These functions draw that model from a script, for example in a custom tech room UI.
boolean intelentry:renderTechModel(number X1, number Y1, number X2, number Y2,
[number RotationPercent = 40, number PitchPercent = 0, number BankPercent = 0,
number Zoom = 1.3, boolean Lighting = true])
- Draws the entry's tech model inside the screen rectangle
X1,Y1toX2,Y2, using the entry's+Closeup_pos:and+Closeup_zoom:. -
RotationPercent,PitchPercentandBankPercentset the model's orientation, each as a percentage of a full turn (0 to 100). -
Lighting = falseuses flat lighting. - Returns
falseif the entry has no tech model.
This matches shipclass:renderTechModel.
boolean intelentry:renderTechModel2(number X1, number Y1, number X2, number Y2,
[orientation Orientation = nil, number Zoom = 1.3])
- Same as
renderTechModel, but the orientation is given as anorientationobject. Useful when a script tracks rotation itself. - Returns
falseif the entry has no tech model.
This matches shipclass:renderTechModel2.
A briefing icon can show a ship class, a prop class (see props.tbl), or a plain model file in its closeup. A briefing UI script needs to know which, to draw it the right way.
string, number, vector, string, number, enumeration ui.Briefing.checkStageIcons(number xPos, number yPos)
- OFP adds a sixth return value:
BRIEF_CLOSEUP_SHIP,BRIEF_CLOSEUP_PROPorBRIEF_CLOSEUP_POF, saying what the first value names. -
BRIEF_CLOSEUP_SHIP: a ship class. Draw it withtb.ShipClasses[name]:renderTechModel(...). -
BRIEF_CLOSEUP_PROP: a prop class. Draw it withtb.PropClasses[name]:renderTechModel(...). -
BRIEF_CLOSEUP_POF: a model file, for asteroid, jump node and unknown icons. Draw it withui.Briefing.renderBriefingModel(...), passing the returned closeup zoom and position. - On stock FSO and on OFP builds before this change, the sixth value and the
BRIEF_CLOSEUP_*constants are allnil. Lua treatsnil == nilas true, so check that the value isn'tnilbefore comparing, as the sample does, or every icon will look like a prop. - The first five values are unchanged, so scripts that ignore the sixth keep working for ships and model files. A script that looks the name up in
tb.ShipClassesand otherwise treats it as a model file won't draw prop closeups, since a prop class name isn't a file:renderBriefingModeldraws nothing and returnsfalse. In OFP, any model file namerenderBriefingModelcan't find does the same, with a warning in debug builds (once per name), where stock FSO stops the game with an error.
local name, zoom, pos, label, id, kind = ui.Briefing.checkStageIcons(mx, my)
if name then
if kind ~= nil and kind == BRIEF_CLOSEUP_PROP then
tb.PropClasses[name]:renderTechModel(x1, y1, x2, y2)
elseif kind ~= nil and kind == BRIEF_CLOSEUP_SHIP then
tb.ShipClasses[name]:renderTechModel(x1, y1, x2, y2)
else
ui.Briefing.renderBriefingModel(name, zoom, pos, x1, y1, x2, y2)
end
endOFP corrects the documented defaults for shipclass:renderTechModel, weaponclass:renderTechModel, propclass:renderTechModel and ui.Briefing.renderBriefingModel. The docs used to list RotationPercent = 0, BankPercent = 40, but the engine has always used RotationPercent = 40, BankPercent = 0. Only the documentation changed, so existing scripts behave as before.
List every coordinate point, and put the visible ones on the escort list:
for i = 1, #mn.CoordinatePoints do
local cp = mn.CoordinatePoints[i]
if cp:isValid() then
ba.print(string.format("%s [%s] at %s\n", cp.Name, cp.Category, tostring(cp.Position)))
if cp.VisibleInMission and cp.EscortPriority == 0 then
cp.EscortPriority = 10
cp:addToEscortList()
end
end
endRead a ship's custom data, with a fallback when it isn't set:
local ship = mn.Ships["Alpha 1"]
if ship:isValid() then
local bounty = tonumber(ship:getCustomData("Bounty", "0"))
if ship:getCustomData("Veteran") == "true" then
bounty = bounty * 2
end
ship:setCustomData("Bounty", tostring(bounty))
endReveal a point by name when an event fires:
local rally = mn.CoordinatePoints["Rally Alpha"]
if rally:isValid() then
rally.VisibleInMission = true
endGetting Started
Features
SEXPs
Lua Scripting
Tables
-
Tables
- ai.tbl
- Animation (-anim.tbm)
- armor.tbl
- asteroid.tbl
- autopilot.tbl
- cheats.tbl
- colors.tbl
- controlconfigdefaults.tbl
- coordinate_points.tbl
- credits.tbl
- curves.tbl
- cutscenes.tbl
- Decals (-dcl.tbm)
- default_settings.tbl
- Dynamic SEXPs (-sexp.tbm)
- editor.tbl
- fireball.tbl
- fonts.tbl
- game_settings.tbl
- generated_nebula.tbl
- glowpoints.tbl
- help.tbl
- hud_gauges.tbl
- icons.tbl
- iff_defs.tbl
- intel.tbl
- lighting_profiles.tbl
- lightning.tbl
- mainhall.tbl
- medals.tbl
- messages.tbl
- mflash.tbl
- mission_profiles.tbl
- music.tbl
- nebula.tbl
- objecttypes.tbl
- Particle Effects (-part.tbm)
- post_processing.tbl
- props.tbl
- rank.tbl
- scripting.tbl
- ships.tbl
- sounds.tbl
- species_defs.tbl
- ssm.tbl
- stars.tbl
- strings.tbl
- tips.tbl
- traitor.tbl
- tstrings.tbl
- virtual_pofs.tbl
- weapons.tbl