Mod:Creation Kit/Script File Structure

( | | | | | | | | )*

A Papyrus script is a text file with the extension ".psc" that consists of a header line at the beginning of the file, followed by a collection of imports, variables, structs, properties, groups, states, functions, events, and custom event definitions. The order of these elements is not important as long as the header line is the first non-comment line in the file.

Header Line
 ::= 'ScriptName' ['extends' ] ['Native'] *

The header line of the script consists of the keyword "ScriptName" followed by the identifier of the script (which must match the name of the file).

If the script extends another script, then the name of the script is followed by the "Extends" keyword and the name of the script it extends. And finally, by any flags.

Scripts can be specified as 'native' by adding the "Native" keyword to the scriptname line. This signals that the object is defined as a native object in game, allows the script to define new events, define native functions, and does not allow it to contain any variables or auto properties.

Scripts can be specified as 'const' by adding the "Const" keyword to the scriptname line. This signals that the object does not contain any data and the game can throw it away at will. Const scripts may not contain any non-const auto properties, states, or any variables. They may also not be stored in object-level variables.

Scripts can be specified as 'debug only' by adding the "DebugOnly" keyword to the scriptname line. This signals that all functions defined by this script are only for use in debug scripts and they will be removed from release scripts.

Script Extension
Extending another script will let you override its functions and events to do something different, or add additional functionality while keeping the functionality of the older script. The only limitations are that any function or event in the child script whose name matches one in the parent script must have the same return type and parameter list.

Examples
ScriptName MyScript ScriptName HiddenScript Extends ParentScript Hidden
 * MyScript.psc
 * HiddenScript.psc This script is hidden from the editor's normal script list, and extends ParentScript

Contents
The rest of the file, after the header, consists of imports, variable definitions, custom event definitions, properties, groups, states, functions, and events in any order. You do not have to define script variables, custom events, properties, functions, states, and events before you use them in the script. (Variables in functions and events, however, must be defined before use)

Imports
'Import'

The "Import" keyword lets you use global functions and structs in a script without prefixing them with the name of the script they are in. It can also be used to let you use scripts in namespaces without having to prefix them with their namespace. Simply use "Import" followed by the name of the script or namespace to import. If a function, struct, or script name then becomes ambiguous, then you will still have to prefix it with the name of the script or namespace which contains the version you want.

Examples
Function MyFunction Utility.MyGlobal EndFunction import Utility
 * Call MyGlobal in Utility, with no import
 * Call MyGlobal in Utility, with import

Function MyFunction MyGlobal EndFunction MyNamespace:MyScript Property MyProp Auto import MyNamespace MyScript Property MyProp Auto MyNamespace:MyScript:MyStruct Property MyProp Auto import MyNamespace:MyScript MyStruct Property MyProp Auto
 * Get at MyScript inside the MyNamespace folder, with no import
 * Get at MyScript inside the MyNamespace folder, with import
 * Get at MyStruct inside MyScript, which is inside MyNamespace without import
 * Get at MyStruct inside MyScript, which is inside MyNamespace, but with import

Whitespace
Whitespace in Papyrus is unimportant, with the exception of line terminators which are explained below. Whitespace may be inserted anywhere as long as it doesn't split up a keyword, operator, literal or similar.

Examples
x    =    (10+1*    2 ) as   float x = = 1 10 12
 * Valid use of white space (if perhaps not as readable)
 * Whitespace between the two equals signs in an equality operator will be interpreted as two equals signs, and fail to compile
 * Whitespace between the 10 and 12 is interpreted as two numbers, 10 and 12, and not a single number 1012, and fail to compile

Line Terminators
Papyrus scripts are delineated into lines which determine where one statement ends and another begins. However, if you have a particularly long statement that you want to put on multiple lines, then you can add a "\" character to the end of the line and continue it on the next line. Slash characters inside comments are ignored (because everything in a comment is ignored), but you can put a comment after the slash if you wish

Examples
x = 1 + 2 y = 2 * 3 x = 1 + 2 \ + 3 + 4 x = 1 + 2 ; This line isn't inside the above comment
 * Two statements separated by a line terminator
 * One long statement broken into two lines
 * Slash in this line is ignored, because it is in a comment \

Comments
Comments in Papyrus come in three forms: Single line, multi-line, and documentation

Single-line Comments
They consume all text after the semicolon, including any backslash characters that would otherwise let you continue onto the following line.

Examples

 * A simple single line comment

Multi-line Comments
 ::= ';/' '/;' Multi-line comments start with ";/" and consume any text (including newlines) until it finds "/;"

Examples
Multi-line comment /; x = 2 * 1 y.DoCoolStuff /;
 * / A simple
 * / You can also have code in here, if you want to comment it out:

Documentation Comments
Documentation comments start at a "{" character and go until the terminating "}" character, including eating newlines and such. These comments show up as tooltips in the editor when you mouse over the script in the script picker, or when mousing over a property or struct member in the property editor.

Examples
ScriptName MyCoolScript {Documentation for my cool script here! I can even use more then one line...} int Property MyProperty Auto {This property is fun, if you set it to 1, watch cool stuff happen!}