This article details an upcoming feature in V0.3 that is only available in pre-releases.
Scripting is programmed level-specific behaviour that is currently defined by inputting command lines in the level files' "script" section. It has three main components: Variables, triggers and events. Variables are used to keep track of what's happening in the level. Triggers check for when something specific occurs in the level. Events are executed to alter the level or player in some way.
To assist you, the Level Editor can show the Row, Column and Tile ID you are currently hovering by clicking the Script Interface button. There is also a handy log that tells you exactly what has occured and if any errors happen.
If you are going to use class references in your scripting, head over to the scripting classes page.
Scripting structure
The scripting works by calling events from triggers. The syntax is the following:
OCCURENCE(TRIGGER)((CONDITION))[EVENT1][EVENT2]
Where you replace each word with a proper scripting sentence.
- OCCURENCE
- Defines how many times the event can happen.
- when - Fires every time the trigger happens. Triggers such as "walk" and "drive" execute once every time the tile is entered, not while someone is there.
- if - Fires once, and then the trigger is removed forever
- TRIGGER
- Defines when the event should be called.
- CONDITION optional
- If the condition equals true the event will be executed.
- EVENT1
- Defines what should happen.
- EVENT2 optional, requires condition
- Defines what should happen. Only usable in branches, see conditions for more info.
Variables
First you might want to declare some variables. Variables keep track of user-defined values such as how many times the player has reinforced walls or how many caverns they have opened. They can also read values from the level as well, such as the current crystal count or the amount of miners in the level. Always declare variables at the start of the script.
Your value/string is saved to whatever name you specify for the variable. When you later use that name anywhere it will be replaced by value/string specified.
Variable | Declaration | Comment |
---|---|---|
string | string MessStr="This is a message!" | Citations are not a requirement yet. |
integer | int MyInteger=5 | Only whole numbers. |
float | float MyFloatNumber=2.6 | Decimal numbers. |
boolean | HasFinishedTask=true | Usable in conditions. Any initialization except "=true" is false. In Math events they are evaluated as 1 if true and 0 if false. |
miner | miner Charlie=3 | This binds the miner with the ID specified to the variable name at the time of initialization.* |
vehicle | vehicle BigBoye=2 | This binds the vehicle with the ID specified to the variable name at the time of initialization.* |
*miner and vehicle binds to the unit that currently holds the specified ID, not to the ID itself. If the associated unit dies and another is assigned their ID, the associated events will NOT trigger.
Reserved variables
There are also variable names that are reserved as macros and cannot be overwritten. When used in scripting, these will return information about the game status. You can use these to e.g. show a message when the player has collected 3 crystals or to trigger a monster invasion if the player constructs too many buildings (with a fair warning first).
crystals | Returns the crystal count |
ore | Returns the ore count |
studs | Returns the studs count |
air | Returns the air status in miner-seconds |
miners | Returns the amount of miners |
vehicles | Returns the amount of vehicles |
buildings | Returns the amount of buildings |
time | Returns the amount of seconds that have passed since the level began. |
Triggers
A trigger activates in response to things that happen in the world, such as a wall being drilled or a miner walking over a tile.
Trigger | Syntax | Description |
---|---|---|
drill | (drill:ROW,COLUMN) | Call the corresponding event when a wall at ROW,COLUMN is drilled, or the wall there collapses. |
laser | (laser:ROW,COLUMN) | Call the corresponding event when a wall at ROW,COLUMN is destroyed by a laser. |
laserhit | (laserhit:ROW,COLUMN) | Call the corresponding event when a wall at ROW,COLUMN is hit by a laser, but not destroyed. |
change | (change:ROW,COLUMN)
(change:ROW,COLUMN,ID) |
Call the corresponding event when a wall at ROW,COLUMN is changed in any way. This includes reinforcing, shoveling once, drilling, finding a cave etc. Optionally add a ID requirement for the trigger to fire only if the tile is changed to a specific tile ID. |
reinforce | (reinforce:ROW,COLUMN) | Call the corresponding event when a wall at ROW,COLUMN is reinforced by any unit. |
time | (time:SECONDS) | Call the corresponding event when SECONDS seconds have been reached. Supports decimal floats. |
hover | (hover:ROW,COLUMN) | Activates when the player hovers that tile. The tile has to be visible. |
click | (click:ROW,COLUMN) | Activates when the player clicks that tile. The tile has to be visible. |
walk | (walk:ROW,COLUMN)
(walk:ROW,COLUMN, ID) |
Activates when a miner walks on a tile. Optionally add a ID requirement to make the trigger fire only for a specific miner.* |
drive | (drive:ROW,COLUMN)
(drive:ROW,COLUMN, ID) |
Activates when a vehicle drive over a tile. Optionally add a ID requirement to make the trigger fire only for a specific vehicle.* |
enter | (enter:ROW,COLUMN)
(enter:ROW,COLUMN, ID) |
Activates when a unit enters a tile. Optionally add a ID requirement to make the trigger fire only for a specific unit.* |
comparisation | (VARIABLE>=OTHERNUMBER) | Activates when VARIABLE is larger than, or equal to, OTHERNUMBER. The operands can be replaced by any valid float or integer variable, and also regular numeric values. All variables used here are converted to integers, which cuts off any decimals, so if you compare 2.2 and 2.9 they will be equal. |
*ID only works with named miner or vehicle variables. Whole numbers are not supported at the moment.
> | Larger than |
>= | Larger than or equal to |
<= | Less than |
< | Less than or equal to |
== | Equal to |
!= | Not equal to |
Conditions
Inserting a condition before an event means the condition has to be true for the event to be executed.
Syntax: OCCURENCE(TRIGGER)((CONDITION))[EVENT_IF_TRUE]
when(click:1,1)((MyBoolean==true))[msg:BoolTrue] when(drill:3,3)((crystals>30))[ReleaseTheSlugs]
Notes
- A condition being false does NOT break a event chain.
- IF-occurances with a condition are disabled.
Branches
A branch can select one of two events depending on a condition. If the condition equals TRUE the first event is called, otherwise the second event is called.
when(SomeInteger>10)((air>=6000))[msg:BranchTrue][msg:BranchFalse]
Events
Events describe to the game what you want it to do when a trigger is activated.
Event | Syntax | Description |
---|---|---|
drill | [drill:ROW,COLUMN] | Drill tile ROW,COLUMN. It will play the appropriate effect and place rubble, ignoring what tile it is.* |
message | [msg:MsgStr] | Display the message string MsgStr, as defined above. |
place | [place:ROW,COLUMN,ID] | Place tile with ID at ROW,COLUMN. You can find IDs of the tiles here.** |
wait | [wait:GAME SECONDS] | Ask the game to wait a set amount of seconds before executing the next command. Only supported within a event chain. Scales with game speed. |
truewait | [truewait:SECONDS] | Ask the game to wait a set amount of seconds before executing the next command. Only supported within a event chain. Does not scale with game speed. |
win | [win:MsgStr] | Player wins the level with the message defined by string MsgStr |
lose | [lose:MsgStr] | Player loses the level with the message defined by string MsgStr |
sound | [sound:MySoundName] | Plays the .ogg file of that name from /ManicMiners/Levels/ASSETS/Sounds (do not include the ".ogg" extension in the script) |
pan | [pan:ROW,COLUMN] | The player's camera pans to the tile at ROW,COLUMN |
shake | [shake:1.0] | The player's camera shakes with magnitude 1.0. The magnitude has no limit. |
*Drilling will get fixed later to check that the tile can actually be drilled.
**If you place a wall on top of a miner or vehicle, they will just phase through the ground. This behaviour will be updated in the future to simply bury them until they are dug out.
Math events
Variables int, float, string and boolean have specific events that makes it possible to alter them while the game is running.
+ | Addition | += | Addition by |
- | Subtraction | -= | Subtraction by |
* | Multiplication | *= | Multiplication by |
// | Division (note the double lines) | /= | Division by |
Unit Events
Unit events are predefined events bound to a specific unit or unit type.
Syntax: UNIT.EVENT
UNIT can be one of the following:
- miner - refers to if the event occur to any miner EXCEPT miners named with variables.
- vehicle - refers to if the event occur to any vehicle EXCEPT vehicles named with variables.
- vehicle type - trigger when the specified event occur to any vechicle of that type. See classes for more info.
- named miner or vehicle variable - refers to if the event occur to that specific unit.
Note that vehicles and named vehicles also call their Class-based unit event.
Event | Syntax | Description |
---|---|---|
dead | UNIT.dead | Activates when a unit dies. |
new | UNIT.new | Activates when a unit is created. |
clicked | UNIT.clicked | Activates when a unit is clicked. |
example: When miner Charlie dies a message will be shown.
miner Charlie=3 string MyString="Oh no! We lost Charlie!" when(Charlie.dead)[msg:MyString]
example: When you lose your Small Digger named Sofia you will get a message, and when any other Small Digger is lost, you will get another message.
vehicle Sofia=1 string MyString="Oh no! We lost Sofia!" string MyOtherString="We lost a Small Digger!" when(Sofia.dead)[msg:MyString] when(VehicleSmallDigger_C.dead)[msg:MyOtherString]
Event chains
You can also declare events as chains (functions) that can be called all at once. Event chains only contain events, The syntax is like this:
EVENT_CHAIN::EVENT; EVENT; EVENT;
where EVENT_CHAIN is replaced by whatever name you want and EVENT are the events you want to execute, in order. When you then write EVENT_CHAIN instead of a regular event anywhere, it will call the EVENT_CHAIN instead and execute the EVENT lines one by one. This can occur multiple times. You can put delays in event chains using the "wait" event, at which point the rest of the event will execute at a later time. Note that after each event chain there must be an empty line to signal the end of the event.
Conditions in event chains
You can use conditions and branch cases in event chains too! You don't need any "if" or "when". Syntax example:
EVENT_CHAIN::EVENT; (CONDITION)EVENT; # Only happens if condition is true. Otherwise, moves on (CONDITION)[EVENT_TRUE][EVENT_FALSE]; # Executes EVENT_TRUE if CONDITION==true, EVENT_FALSE otherwise
==== Objectives
You can bind objectives to scripting using the "variable" keyword as such:
variable:NumDrilledWalls>=10/Drill these 10 walls!
This will create an objective called "Drill these 10 walls!" that will be fulfilled when the variable NumDrilledWalls becomes 10 or larger.
Other examples
A simple message
string HappyBirthday="Happy birthday, cadet!" when(drill:2,2)[msg:HappyBirthday]
When any unit drill the wall in row 2, column 2, call the message event which in this case will display the text saved in the string variable HappyBirthday. As that string was defined above, drilling this wall wishes the player a happy birthday!
Time based event
when(time:10)[place:6,7,11]
When time reaches 10 seconds, place a tile of water (ID 11) at row 6, column 7.
Crystal count
int myCrystals=0 string myStr="Crystals: " string myMsg if(crystals>=5)[myChain] myChain::myCrystals=crystals; myMsg=myStr+myCrystals; msg:myMsg;
When you collect 5 or more crystals a message will appear once and display your currently collected crystals. This example includes an event chain.
Increasing counter
int counter=0 string myStr="Counter: " string myMsg when(click:6,6)[myChain] myChain::counter+=1; myMsg=myStr+counter; msg:myMsg;
Every time you click on the tile at row 6, column 6 the value of counter increases and a message is displayed with the new value. This example includes an event chain.