Script a mission
Create and edit mission scripts in the Mission Graph, as nodes or as Lua.
The Mission Graph edits mission scripts: the Lua files Sunrise runs while an activity is live. It shows a script as a node graph and as Lua. Mission Scripting explains what a script is and how it runs.
Mission scripts are plain Lua files, not package data. They are never stored as deltas.
script
lives in
save writes
installed script
bin/x64/Sunrise/scripts/<stem>/<stem>.lua
that file, in place; no project needed
mod script
the project’s scripts/<stem>/<stem>.lua
the project file; needs its project open
Open the Mission Graph
- Choose View > Mission Graph.
It opens in its own area of the layout, or in its own window when it is popped out. See Arrange the layout. To open a script, choose it in Installed scripts, or in Mod scripts with a project open.
The toolbar holds these controls. Icon buttons name themselves in their tooltip.
control
does
+ (New script)
starts a new script
Installed scripts
opens an installed script; its tooltip shows the open script’s file
circular arrow (Reload scripts and API schema)
reads the scripts and the SDK again
Mod scripts
opens a script of the open project
Save
saves the script; it shows Save* while there are unsaved changes
export (Export Lua for review)
writes a copy to a folder outside the installation
Read only
shows when the script’s project is not open for editing
warning icon
shows when there is no API schema; its tooltip says why
forward arrow (Finish switching scripts)
shows while a switch waits on unsaved changes; opens its dialog again
Press reload after the game or a git pull changes the scripts or the SDK. Undo and redo are in the Edit menu.
Create a new script
- Press + (New script), or choose File > New mission script….
- In Activity, search for and choose an activity from the installed SDK.
- In Arrival region, choose the region where the script starts.
- Check Graph key. It defaults to the script’s name.
- Under Save to, choose Installed scripts or This project (mod).
- Press Create script.
The activity sets the folder and file name, so a place holds one script per activity. Create refuses a script that already exists. Open that one instead. A new script targets an existing activity. It does not create a new activity.
The dialog names any SDK file that is missing or damaged. Start the game once to rebuild it. When scripts/lib/flow.lua is missing, the dialog says so and Create script stays off.
The starter script waits until the player enters the arrival region, then runs its first step. It resumes saved progress on load. It does not complete the mission on its own.
Add a step
- Open the Nodes tab.
- Select the facts group or the steps group.
- Press + (Add node).
- Type a Node id.
- Choose a Template.
- Choose the Sensor, Target, Navpoint, Scene, Input, Output or Inputs the template asks for.
- Press Create.
template
group
does
Observe trigger
facts
waits for a player-trigger report, then disarms the trigger
Scene output
facts
waits until a scene reports one of its outputs
Immediate step
steps
starts with an empty action
Arm trigger
steps
arms an SDK trigger slot
Show objective
steps
sets a directive on its sensor, with an optional navpoint
Play dialogue
steps
plays a cue on its dialogue sensor
Select state
steps
selects an SDK state
Complete mission
steps
completes the mission
Start scene
steps
starts a scene, then sends the inputs you tick, in the order you tick them
Send scene input
steps
sends one input to a scene
In a campaign graph, the steps group offers other templates: Immediate step, Reach trigger, Complete ghost scan and Use interactable.
Scene inputs and outputs
A scene is a scripted piece of a mission, such as an explosion or a character’s performance. Each scene has its own inputs and outputs.
- An input is an event the scene waits for. A script sends it.
- An output is an event the scene reports. A script waits for it.
Pickers only offer the inputs and outputs of the scene you chose. They come from the installed SDK’s mission.SceneInput and mission.SceneOutput tables. An SDK generated before these tables existed lists none. Start the game once with the current Sunrise to regenerate it, then press reload on the toolbar. See Generated SDK and The world model.
A Scene output fact needs the script to pass scene outputs to its flow. New scripts do this. For an older script, add on_event_scene_output to the table it returns, the same way as its other on_event_ callbacks. Until then, Checks reports the fact.
Campaign steps
Campaign steps run in list order. Select a step and press the up or down arrow (Move before the previous node, Move after the next node) to move it. Links between campaign steps show that order and cannot be dragged.
Select a step to edit its fields:
field
does
Objective, Navpoint, Waypoint volume
what the step shows the player
Start scene
starts this scene when the step starts
Inputs
sends the ticked inputs right after the scene starts; needs a start scene
Arm in leg, Trigger
ends the step on that trigger; the leg arms it
Ghost scan, Interaction
ends the step on that scan or interaction
Scene finished
ends the step when that scene finishes
Output scene, Scene output
ends the step when that scene reports that output after the step started
Encounter cleared, Region reached
ends the step on that encounter or leg
Barrier
a later step’s trigger cannot end this step early
Revisit
the step’s trigger and region count only after the step starts
Dialogue
cue lines, each with an optional filter volume
A step with no end condition completes at once. The inspector then shows Completes immediately.
Choosing another start scene drops inputs that belong to the old one. Clearing it drops all inputs. Choosing another output scene clears the output until you pick a new one.
Select a leg to set its State. Edit its trigger and monitor lists in Advanced Lua.
Encounter nodes and a step’s destroyed-object list have no typed fields. Edit them in Advanced Lua.
Make a step wait for another
This works for flow steps only. Campaign steps run in list order.
- Drag from the first step’s output arrow, on its right, to the second step’s input ring, on its left.
The second step then runs after the first finishes. The Dependencies checkboxes of a selected step set the same links.
To remove a link, do one of these:
- Click it and press Disconnect.
- Right-click it and choose Disconnect.
- Drag it off its input ring onto empty space.
Dropping a link on an invalid target keeps the old link.
Edit a step’s action
Flow steps only.
- Select the step.
- Under Action, press Edit action.
- Choose the Action type and fill its fields.
- Press Apply.
Set when a step starts and finishes
Flow steps only.
- Select the step.
- In Start when, choose Immediately, Fact, All or Any.
- In Finish when, choose the same way.
- For All or Any, press Add condition for each child condition.
condition
means
Immediately
no condition
Fact
a named fact in this flow is set
All
every child condition holds
Any
at least one child condition holds
All and Any do not pick one branch: every eligible step can run. Facts stay set for the attempt unless a checkpoint resets them. Tick Checkpoint on a step to make it one.
Edit Lua directly
A Lua box opens as a preview. Press Edit to type in it, and Preview to go back.
where
apply
drop the edit
a Custom Lua field, or a node written as Lua
Apply
Revert
the Lua section of a typed action or condition
Apply
Revert
Code or Advanced Lua on a script-view node
Apply
Revert
Inputs of a script-view node
Apply
Revert
Advanced Lua on a flow or campaign node
Apply
select the field again
the Lua tab
Apply
Revert
Script-view inputs and the flow or campaign Advanced Lua box have no preview. In Advanced Lua, pick a field from the list or type its path, then edit the box.
Unapplied Lua marks the script as unsaved.
- A pending field edit blocks Save, Undo, Redo, Export and other edits. Apply or revert it first.
- Save, Export and graph edits apply a pending Lua tab edit first. Undo drops it, and Redo brings it back.
- While a Lua tab edit is pending, the Script group is read only and no field edit applies. Redo is refused until you revert it.
Studio reads Lua 5.4 and refuses any edit that leaves a syntax error. On the Lua tab, the error names its line and column, and the draft stays so you can fix it. A script file with a syntax error does not open; fix it in a text editor first.
Save
- Press Save, or press Ctrl+S while the Mission Graph has focus.
An installed script saves in place. A mod script saves into the project. The export button (Export Lua for review) writes a copy for review to a folder outside the installation. Node positions are kept in your local settings, per script.
When you switch scripts, projects or installations with unsaved changes, the Unsaved mission script dialog asks you to Save and continue, Discard or Cancel. After Cancel, the switch waits. Press the forward arrow (Finish switching scripts) on the toolbar to choose again. Saving also finishes the switch.
Check the script
- Open the Checks tab. Its title shows the number of problems.
It lists graph errors, such as unknown dependencies or facts, cycles, invalid conditions, duplicate ids and over-long state keys. It also lists scene errors:
- an input sent to a scene that does not have it
- an output waited for on a scene that does not report it
- a campaign step with inputs but no start scene
- a campaign step whose scene is a slot, not a
mission.Sceneentry - an input or output name that the installed SDK does not list
- a scene output fact in a script with no
on_event_scene_outputcallback
It also names a missing or damaged SDK file, and lists the problems of typed calls. See Checks on typed calls. With nothing to report, it says No problems found. With no API schema, it also says that API calls were not checked.
Graph errors block Export Lua for review, Build and install and Update running game. They do not block Save. Scene and call problems block nothing.
It is not a Lua compiler, and a passing check does not prove the mission plays in game.
Run it in the game
- An installed script runs the next time its activity starts. In game, the Script page’s Reload script loads it again. See Your first script.
- A mod script needs Build > Build and install while the game is closed.
- While the game runs, Build > Update running game reloads changed mod scripts. See Build and install a mod.
The whole-script view
The Script group shows the whole Lua file as a graph. Every top-level statement is a node, and so is every field of the returned callback table. A link runs from the node that defines a name to each node that uses it. A module node shows its local name, with its require line below.
control
effect
double-click a function or callback
opens its control flow
folder (Open the body), forward arrow (Open the flow)
open the selected node’s body or flow
folder on a flow or campaign node (Open run, for example)
opens that field’s function
back arrow (Up to script)
returns to the whole-script view
corners (Frame all)
fits the group in view
grid (Arrange as a tree)
lays the group out again as a tree
up and down arrows
move the node within its scope
trash can (Remove node)
removes the node
+ (Add node)
adds a function, value, callback or statement
+ next to a body or branch name, under Add inside
adds a statement or an API call there
Add else if, Add else, under Branches
adds a branch to an if node
A group opens framed, but text never shrinks too small to read. A long chain wraps to the width of the canvas. Pan or zoom out to see a graph that is still wider.
To add a function or a value, type its name in the Name box of the Add node popup, then choose Function or Value.
If, else-if, else, while, for, repeat, local scopes, calls, assignments, returns and breaks have their own nodes. Code the graph cannot show as nodes stays a Custom Lua block, and the inspector says why. Its neighbors still show as nodes. Edits replace only their own source and keep comments and line endings.
Typed API nodes
A statement that is one Sunrise API call is a typed node. Its arguments are fields you edit, not Lua text. A call inside a larger statement, such as an if condition, gets the same editor in that statement’s inspector. The statement’s own call is open. Other calls fold under their own Call headers. Calls the schema cannot describe stay Custom Lua blocks, so every script still opens and edits in full.
The types come from the generated SDK file sdk/lua/sunrise/mission_api.json. Sunrise writes it from the same table the runtime uses to check arguments. See Generated SDK. An installation that has not written it yet shows every call as Lua, and the toolbar shows a warning icon. Start the game once with the current Sunrise, then press reload on the toolbar.
How a call is typed
Studio types parameters named context, state and event, and the handles their calls return. A Sunrise API call it cannot type stays a Custom Lua block, and the inspector says why. Any other call is a call node with Call and Arguments inputs.
Edit a typed call
- Select the node. Under Call, each argument has a row. A
*marks a required argument. - Change a value. The edit replaces only that value in the source.
A text or number field applies when you press Enter or leave the field.
argument kind
editor
boolean
checkbox
integer, number
number field, kept inside the allowed range
string, name
text field
scalar (boolean, number or string)
text field; type the Lua value, such as true, 3 or "name"
enum, such as a device transition
list of the collection’s entries
generated entry, such as a directive or a scene input
picker of the installed SDK’s entries
slot, squad or scene handle
picker of the entries that match the slot type
list
one row per entry
table
one row per field
atom of run_atoms
its kind, then the fields of that kind
function
Lua
A picker offers only what the schema allows. A slot picker lists slots of the slot type the call needs. A scoped picker lists the receiver’s own entries, such as the inputs of that scene.
button
effect
Lua
edits the value as Lua; it stays lit while on, and pressing it again goes back
+ on an absent argument
adds it with its default or a valid placeholder
+ (Add entry) under a list
adds a list entry, up to the allowed count
trash can
removes an optional argument or a list entry
In Lua mode the box is open for typing at once. Press Apply to apply it, or Revert to drop it. An absent optional argument shows its default, greyed out.
A value that is not a literal or a generated entry, such as a local, opens as Lua.
Adding keeps the table’s style: one line or one field per line, and a trailing comma only where the table has one.
A call that passes a table built in Lua, such as squad:place(args), shows no argument rows. Edit it in Advanced Lua.
Checks on typed calls
Studio checks literal values the way the runtime does. It finds problems such as:
- the wrong call form:
:where.belongs, or the wrong number of arguments - a required argument that is missing, or a key the call does not take
- a value of the wrong type, such as text where a number belongs
- a number outside its range, or a string of the wrong length
- a list with too few or too many entries
- an entry that is not in the installed SDK, or that comes from another table
- a slot of the wrong slot type, or an entry that belongs to another slot or scene
- an atom with no kind, or a field its kind does not have
A problem shows on the node, in its inspector and on the Checks tab. It blocks nothing. Code the checks cannot read, such as a value computed at run time, is not checked.
Add a callback or a call
- On the script view, press + (Add node). Under Callbacks, choose one. It is added to the returned table with the parameters the runtime passes. A callback the script already returns is greyed out.
- In a function, press a + under Add inside. Choose a statement, such as If or While, or a call under Sunrise API.
The list holds the calls that a value in scope can make, such as context and what it reaches. A call that needs a slot type the mission does not have is not listed.
A new call has a placeholder for each required argument. The placeholder is valid: the default, the first matching SDK entry, or zero moved into the allowed range. Change it before you save. A callback node shows the fields its event carries.
Helpers and SDK modules
file
example path in the project
loaded with
helper module
scripts/lib/tools.lua
require("lib.tools")
own SDK module
sdk/my_mod/bindings.lua
require("my_mod.bindings")
Folder and module names use ASCII letters, digits and underscores. A controller must fit 128 KiB. Other modules can be up to 16 MiB. Edit helpers in a text editor. The Mission Graph lists controllers. Studio does not copy the generated SDK into projects.
Legacy scripts
Mod scripts lists a project’s .sunrise-mission.json scripts under Legacy scripts. Open one and save it to create its Lua file. To get its exact source, right-click the entry and choose Export original Lua.
