Difference between revisions of "Programming Guide"

From Space Engineers Wiki
Jump to: navigation, search
(Wheel Suspension 3x3)
(External links)
(23 intermediate revisions by 6 users not shown)
Line 1: Line 1:
==Known Limitations==
+
Programming in Space Engineers is done with the [[Programmable Block]] which can be given scripts written in C# (pronounced C Sharp). This can be used to make autonomous mining drones, long-range player-killing torpedoes, automated welding arms for ship construction and much more.
Below is a list of the known limitations that we are aware of and the possible workarounds for each of them:
 
  
===Foreach not working at 64- bit===
+
== Introduction ==
''Problem'':
+
=== Editor access ===
Currently using of foreach loop inside script will cause “bad program exception” at some configurations and prevent script from running. We are working of fixing this issue.  
+
Only one player can edit the same script at time. If someone else has an editor for the current block open and someone else tries to open that block's editor, a notification will be shown that the editor is already open.
  
''Workaround'':
+
=== Main method ===
All our interfaces used in in-game scripting are using lists as collections. Please use For loop for iteration across these lists
+
When the editor is opened for first time, void Main() method is present inside the code editor.
 +
This is entry point that will be called when executing script. If Main method is removed / renamed, the script will not run and you will be notified in the programmable block details area.
 +
Custom methods/variables can be defined and used, but only the Main method will be called without reference.
  
===Lambda functions not working===
+
=== Variables life ===
''Problem'':
+
There are two types of variables for scripting:
Currently lambda functions are not supported, if you use them in script, exception will be thrown and script will not run.
+
Local (inside the methods) – these variables will keep their value only during execution of a method.
 +
Value will be “lost” when the method ends.
 +
Global (outside the methods) - these variables will keep their values during the lifetime of script. E.g.
 +
If the variable needs to keep value between separate runs of program, it needs to be defined outside the methods.
 +
After pressing “Remember & Exit” or “Remember” buttons, the previous script will be overwritten and all Global variables will be lost.
 +
All variables, local and global except for the built-in Storage variable will lose their value or return to their default value when recompiling the code and between saved game loads.
 +
The Storage variable is unique in that that it store data as string between saved seasons and recompile.
  
''Workaround'':
+
=== Compiling ===
Please use method instead of lambda function if possible.
+
When the “Check code” button is pressed, the code will be compiled and the result of the compilation will be shown.
 +
There are two steps of the compilation process:
 +
First the code inside editor is compiled by c# compiler for language errors.
 +
If there are any errors during compilation the following dialog is shown:
 +
It this case “aaa” string is placed before Main method. This is the wrong language construction and the compilation failed.
 +
In the error dialog the Line number error and description of the error is shown.
  
===User defined static variables and methods not working===
+
After compilation, the code is checked for usage of disallowed namespaces and types. In case that check fails,
''Problem'':
+
the following dialog is shown:
Currently using user defined static members or methods will cause script to throw exception and the script will not run.
 
 
 
''Workaround'':
 
Please don’t define static methods or variables.
 
 
 
===User defined variables are not saved===
 
''Problem'':
 
None of user defined variables inside the script is saved, therefore after loading the game they are reset into their default values.
 
 
 
Workaround:
 
None.
 
 
 
==GUI Overview==
 
===Programmable block===
 
 
 
The programmable block terminal panel screen currently contains two buttons:
 
 
 
''Edit'' – it will open the editor for editing scripts and the ability to save/load scripts from and to disk.
 
Also, you can upload your scripts to workshop and download subscribed scripts.
 
 
 
''Run'' – it will run the script that was remembered in editor. It will run the script only once. However this button is terminal action, so you can attach it to sensor, timer block, and button or add it to toolbar.
 
 
 
[[File:Steamworkshop webupload previewfile 360966557 preview.jpg|500px]]
 
 
 
''Details section'' – In this area the script exception will be shown (if any will occur)
 
 
 
===Editor===
 
 
 
[[File:Steamworkshop webupload previewfile 360966557 preview (1).jpg|500px]]
 
 
 
Code editor contains these buttons:
 
''Help'' – it will open the help guide inside the game.
 
''Check Code'' – it will check the code for code mistakes and also check if used code isn’t forbidden.
 
''Remember & Exit'' – it will save the code for execution, close editor screen and returns to terminal panel.
 
''Remember code'' – it will save code for execution and leave editor open.
 
''Browse Workshop'' – it will open a window for script management, you can save/load scripts from disk , upload scripts to workshop and download subscribed scripts.
 
''Line counter'' – it shows current line number and total number of lines in code
 
 
 
===Browse Workshop===
 
 
 
[[File:Browse workshop.jpg|200px]]
 
 
 
This screen is similar to blueprint screen and contains these buttons :
 
''Ok'' – it will load the selected script into the editor and close the screen
 
''Cancel'' – it will close the screen (no changes to code in editor)
 
''Details'' – it will open the "details" screen, where you can see description of script
 
''Rename (only for local scripts)'' – it will rename the selected script, if you try to rename to existing script, the game will ask you if you want to overwrite the existing script.
 
''Delete (only for local scripts)'' – it will ask you if you really want to delete the script, after the confirmation script will be deleted.
 
''Create from editor''– it will create new script with default name Script_XX it starts with 0 and if the script with the selected name already exists, it will increment the value. E.g. first there will be Script_0 then Script_1 etc…
 
''Replace from editor (only for local scripts)'' – it will replace (after user confirmation) the selected script with script from the editor.
 
''Refresh Scripts'' – will reload the local and subscribed script list
 
 
 
===Details (local script)===
 
 
 
[[File:Details (local script).jpg|500px]]
 
 
 
This screen will show up when you press details for local script and contains the following buttons:
 
''Rename'' – it will rename the selected script, if you try to rename to existing script, the game will ask if you want to overwrite the existing script.
 
''Delete'' – it will ask you if you want to delete the script, after confirmation script will be deleted.
 
''Publish'' – it will publish the script into workshop and show the workshop page with the script.
 
''Browse Workshop'' – it will open the workshop screen to browse and subscribe scripts.
 
''Close'' – it will close the screen
 
 
 
===Details (workshop script)===
 
 
 
This screen will show up when you press details for script from workshop and it contains these buttons:
 
Open in Workshop – it will open the current script workshop page.
 
Close – it will close the screen
 
Programming Guide
 
Introduction
 
 
 
Editor access
 
Only one player can edit same script at time. If someone else have open editor for current block and someone else will try to open editor, notification will be shown that editor is already open.
 
 
 
Main method
 
When editor is opened for first time, void Main() method is present inside code editor.
 
This is entry point that will be called when executing script. If Main method is removed / renamed, script will not run and you will be notified in programmable block details area.
 
Custom methods/variables can be defined and used, but only Main method will be called by script.
 
 
 
Variables life
 
There are two types of variables for script:
 
Local (inside the methods) – these variables will keep theirs value only during execution of method.
 
Value will be “lost” when method ends.
 
Global (outside the methods) - these variables will keep theirs values during lifetime of script. E.g.
 
If variable needs to keep value between separate runs of program ,it needs to be defined outside the methods.
 
After pressing “Remember&Exit” or “Remember” buttons, previous script will be overwritten and all Global variables will be lost.
 
 
 
Compiling
 
When “Check code” button is pressed, code will be compiled and result of compilation will be shown.
 
There are two steps of compilation process:
 
First code inside editor is compiled by c# compiler for language errors.
 
If there is any error during compilation following dialog is shown:
 
It this case “aaa” string is placed before Main method. This is wrong language construction and compilation failed.
 
In error dialog Line number error and description of the error is shown.
 
 
 
After compilation, code is check for usage of not allowed namespaces and types. In case that check fails,
 
Following dialog is shown:
 
 
In this case System.IO.Directory was used to delete some directory. This is forbidden and error is shown that “Not allowed type was used in script”.
 
In this case System.IO.Directory was used to delete some directory. This is forbidden and error is shown that “Not allowed type was used in script”.
  
If compilation and check passes following dialog is shown:
+
If compilation and checks pass, a dialog is shown, confirming the checks passed, and the code is saved.
This means that code doesn’t contain any language errors or not allowed methods.
 
  
Script execution
+
=== Script execution ===
 
When “Run” button is pressed or “Run” is assigned as terminal action, script is executed. Currently “Run” needs to be called manually e.g. user need to click on “Run” button or attach it as terminal action.
 
When “Run” button is pressed or “Run” is assigned as terminal action, script is executed. Currently “Run” needs to be called manually e.g. user need to click on “Run” button or attach it as terminal action.
 
Script is executed only on server even if it’s triggered from client. If there is any exception during script execution, all clients will be notified in programmable block details area about failure.
 
Script is executed only on server even if it’s triggered from client. If there is any exception during script execution, all clients will be notified in programmable block details area about failure.
 
In case of exception during script execution, script will not run again unless User opens editor and change script.
 
In case of exception during script execution, script will not run again unless User opens editor and change script.
 +
A timer can also continuesly run the script by having a run action (you may be prompt to input an argument) and then starting/triggering itself or being started/triggered via script code (if going by the letter the timer will stop if the script crash).
  
Counting of instructions
+
=== Counting of instructions ===
 
Every time script is executed, every instruction of script is counted. If script executes more instruction than limit, execution is stopped and user is notified that script is too complex for execution. This prevents scripts to “freeze” game.
 
Every time script is executed, every instruction of script is counted. If script executes more instruction than limit, execution is stopped and user is notified that script is too complex for execution. This prevents scripts to “freeze” game.
  
==Available interfaces==
+
=== Whitelist ===
 +
The types and classes allowed in scripts are restricted. Refer to the [[Scripting Whitelist]] to see what you are allowed to use.
 +
 
 +
== Available interfaces ==
  
===Possible actions===
+
=== Possible Actions ===
 
Currently only terminal actions can be triggered inside scripts. User can access terminal system for grid on which programmable block is located and trigger any terminal action on any block at grid.
 
Currently only terminal actions can be triggered inside scripts. User can access terminal system for grid on which programmable block is located and trigger any terminal action on any block at grid.
 +
:* [[Programming_Guide/API_List|API List]]
  
===GridTerminalSystem variable===
+
=== Block Classes (Action List) ===
Currently only following “built-in” variable that user can use: GridTerminalSystem. This is entry point of entire grid terminal system.<br />
+
:* [[Programming_Guide/Action_List|Block Action List]]
It has following methods available:<br />
 
List<IMyTerminalBlock> Blocks{get;}<br />
 
List<IMyBlockGroup> BlockGroups { get; }<br />
 
void GetBlocksOfType<T>(List<IMyTerminalBlock> blocks, Func<IMyTerminalBlock, bool> collect = null);<br />
 
void SearchBlocksOfName(string name,List<IMyTerminalBlock> blocks, Func<IMyTerminalBlock, bool> collect = null);<br />
 
IMyTerminalBlock GetBlockWithName(string name);<br />
 
With these methods all terminal blocks of grid can be collected.
 
 
 
Blocks property will get all block of grid terminal, this method internally allocates new memory. <br />
 
BlockGroups will get all groups of grid terminal, this method internally allocates new memory<br />
 
GetBlocksOfType will get all blocks of given type.<br />
 
SearchBlocksOfName method will fulltext search between all blocks and returns block that contains searched string , search is case insensitive.<br />
 
GetBlockWithName method will get first block with exact name as provided , search is case sensitive.<br />
 
 
 
Func<IMyTerminalBlock, bool> collect method can be used for defining search condition within search. E.g. Collect method for IMyRadioAntenna can define search function to search only for turned on antennas or antennas with specific range.
 
 
 
===IMyCubeBlock===
 
IMyCubeBlock is base class for every terminal block. It has following Properties and methods:<br />
 
bool IsBeingHacked { get; }<br />
 
bool IsFunctional { get; }<br />
 
bool IsWorking { get; }<br />
 
VRageMath.Vector3I Position { get; }<br />
 
 
 
IsFunctional property tells if current block is constructed to the level it can operate<br />
 
IsWorking property tells if current block is powered<br />
 
 
===IMyTerminalBlock===
 
IMyTerminalBlock is base class for every terminal block, all of the block will have following properties and methods:<br />
 
 
 
string CustomName <br />
 
string CustomNameWithFaction <br />
 
string DetailedInfo <br />
 
bool HasLocalPlayerAccess()<br />
 
bool HasPlayerAccess(long playerId)<br />
 
void RequestShowOnHUD(bool enable)<br />
 
void SetCustomName(string text)<br />
 
void SetCustomName(StringBuilder text)<br />
 
bool ShowOnHUD <br />
 
void GetActions(List<Sandbox.ModAPI.Interfaces.ITerminalAction> resultList, Func<Sandbox.ModAPI.Interfaces.ITerminalAction, bool> collect = null);<br />
 
void SearchActionsOfName(string name,List<Sandbox.ModAPI.Interfaces.ITerminalAction> resultList, Func<Sandbox.ModAPI.Interfaces.ITerminalAction, bool> collect = null);<br />
 
Sandbox.ModAPI.Interfaces.ITerminalAction GetActionWithName(string name);
 
 
 
GetActions method will get all action available for current block. <br />
 
SearchActionsOfName method will fulltext search between all blocks actions and returns actions that contains searched string e.g. if block has actions : OnOff ,OnOff_On ,OnOff_Off
 
 
 
SearchActionsOfName with “OnOff” returns all actions SearchActionsOfName with _On will return only “OnOff_On”, searching with “On” will return all actions, search is case insensitive.
 
 
 
GetActionWithName method will get first action with exact name as provided , search is case sensitive.
 
 
 
===ITerminalAction===
 
ITerminal action is representation of concrete action that can be triggered. It has following properties and methods:<br />
 
string Id { get; }<br />
 
StringBuilder Name { get; }<br />
 
void Apply(Sandbox.ModAPI.Ingame.IMyCubeBlock block);<br />
 
 
 
Id is Id of action e.g. OnOff, OnOff_On<br />
 
Name is name of the action shown in UI e.g. Toggle block On/Off ,Toggle block On<br />
 
Apply will apply action for given block (you need to provide block from which you took actions)<br />
 
 
 
===IMyFunctionalBlock===
 
IMyFunctionalBlock is base class for every block that can be turned on or off, it’s derived from IMyTerminal block e.g. every Functional block is Terminal block but not all terminal blocks can be turned on or off.<br />
 
It has one Property:<br />
 
bool Enabled <br />
 
This property indicates if block is turned on or off by user.<br />
 
Terminal block and action name list - 1/3<br />
 
Disclaimer<br />
 
All terminal blocks have the following properties:<br />
 
Interface name: this name is the name of the block in code, it can differ from the name as displayed in the building screen. E.g. Antenna interface name is IMyRadioAntenna - you need to use this interface if you want to get all antennas.
 
 
 
Parent: this is parent of the block (all blocks have IMyTerminalBlock as parent), this can be used for getting type of blocks instead of concrete block type. E.g. if you want to get all lights in grid you will use IMyLightingBlock, if you want only interior light you can use IMyInteriorLight.
 
 
 
Field: this is read only field available for block e.g. for IMyBeacon you can get Radius property. Based on this property you can increase/decrease radius of beacon.
 
 
 
Actions: these are all available actions for block with their names in game, so if you want to increase broadcast radius for antenna, you need to execute DecreaseRadius action for block.
 
  
===Same block class for different SubTypeID===
+
=== Same block class for different SubTypeID ===
 
Some blocks have same parent (e.g. <TypeId> in cubeblocks.sbc) and differs only by subtype (e.g. <SubtypeId>). This means there is no distinction between these block in code. <br />
 
Some blocks have same parent (e.g. <TypeId> in cubeblocks.sbc) and differs only by subtype (e.g. <SubtypeId>). This means there is no distinction between these block in code. <br />
 
Example of these blocks is the Cargo Container: there are 3 types of cargo containers in the game: small, medium and large. These three types differ only by subtype and Type is same for them e.g. large cargo container id is: <br />
 
Example of these blocks is the Cargo Container: there are 3 types of cargo containers in the game: small, medium and large. These three types differ only by subtype and Type is same for them e.g. large cargo container id is: <br />
Line 230: Line 75:
 
In this case there is only one class IMyCargoContainer for all types of cargo containers.
 
In this case there is only one class IMyCargoContainer for all types of cargo containers.
  
===Block Classes===
+
== Example programs ==
 
 
====Antenna====
 
Interface name: IMyRadioAntenna<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: float Radius<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseRadius -> Increase Broadcast radius<br />
 
DecreaseRadius -> Decrease Broadcast radius<br />
 
 
 
====Arc furnace====
 
Interface name: IMyRefinery<br />
 
Parent: IMyProductionBlock<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool UseConveyorSystem<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Artificial Mass====
 
Interface name: IMyVirtualMass<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: None<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
 
 
====Assembler====
 
Interface name: IMyAssembler<br />
 
Parent: IMyProductionBlock<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool UseConveyorSystem<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Battery====
 
Interface name: IMyBatteryBlock<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool HasCapacityRemaining<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Recharge -> Recharge On/Off<br />
 
 
 
====Beacon====
 
Interface name: IMyBeacon<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: float Radius <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseRadius -> Increase Broadcast radius<br />
 
DecreaseRadius -> Decrease Broadcast radius<br />
 
 
 
====Button Panel====
 
Interface name: IMyButtonPanel<br />
 
Fields: bool AnyoneCanUse<br />
 
Actions:<br />
 
AnyoneCanUse -> Anyone Can Use On/Off<br />
 
 
 
====Camera====
 
Interface name: IMyCameraBlock<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: None<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
View -> View<br />
 
 
 
====Cockpit====
 
Interface name: IMyCockpit<br />
 
Parent: IMyShipController<br />
 
Fields:<br />
 
bool ControlWheels<br />
 
bool ControlThrusters<br />
 
bool HandBrake <br />
 
bool DampenersOverride<br />
 
Actions:<br />
 
ControlThrusters -> Control thrusters On/Off<br />
 
ControlWheels -> Control wheels On/Off<br />
 
HandBrake -> Handbrake On/Off<br />
 
DampenersOverride -> Inertia dampeners On/Off
 
 
 
====Collector====
 
Interface name: IMyCollector<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool UseConveyorSystem<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Connector====
 
Interface name: IMyShipConnector<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool ThrowOut <br />
 
bool CollectAll <br />
 
bool IsLocked <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
ThrowOut -> Throw Out On/Off<br />
 
CollectAll -> Collect All On/Off<br />
 
SwitchLock -> Switch lock<br />
 
 
 
====Control Panel====
 
Interface name: IMyControlPanel<br />
 
Fields: None<br />
 
Actions: None<br />
 
 
 
====Control Station====
 
Interface name: IMyCockpit<br />
 
Parent: IMyShipController<br />
 
Fields:<br />
 
bool ControlWheels<br />
 
bool ControlThrusters<br />
 
bool HandBrake <br />
 
bool DampenersOverride<br />
 
Actions:<br />
 
ControlThrusters -> Control thrusters On/Off<br />
 
ControlWheels -> Control wheels On/Off<br />
 
HandBrake -> Handbrake On/Off<br />
 
DampenersOverride -> Inertia dampeners On/Off<br />
 
 
 
====Door====
 
Interface name: IMyDoor<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool Open<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Open -> Open/Closed<br />
 
Open_On -> Open<br />
 
Open_Off -> Closed<br />
 
 
 
====Drill====
 
Interface name: IMyShipDrill<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool UseConveyorSystem<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Flight Seat====
 
Interface name: IMyCockpit<br />
 
Parent: IMyShipController<br />
 
Fields:<br />
 
bool ControlWheels<br />
 
bool ControlThrusters<br />
 
bool HandBrake <br />
 
bool DampenersOverride<br />
 
Actions:<br />
 
ControlThrusters -> Control thrusters On/Off<br />
 
ControlWheels -> Control wheels On/Off<br />
 
HandBrake -> Handbrake On/Off<br />
 
DampenersOverride -> Inertia dampeners On/Off
 
 
 
====Gatling Turret====
 
Interface name: IMyLargeGatlingTurret<br />
 
Parent: IMyLargeConveyorTurretBase<br />
 
Parent: IMyLargeTurretBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool UseConveyorSystem <br />
 
bool CanControl<br />
 
float Range<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Control -> Control<br />
 
IncreaseRange -> Increase Radius<br />
 
DecreaseRange -> Decrease Radius<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Gravity Generator====
 
Interface name: IMyGravityGenerator<br />
 
Parent: IMyGravityGeneratorBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
float FieldWidth <br />
 
float FieldHeight <br />
 
float FieldDepth <br />
 
float Gravity <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseWidth -> Increase Field width<br />
 
DecreaseWidth -> Decrease Field width<br />
 
IncreaseHeight -> Increase Field height<br />
 
DecreaseHeight -> Decrease Field height<br />
 
IncreaseDepth -> Increase Field depth<br />
 
DecreaseDepth -> Decrease Field depth<br />
 
IncreaseGravity -> Increase Acceleration<br />
 
DecreaseGravity -> Decrease Acceleration<br />
 
 
 
====Grinder====
 
Interface name: IMyShipGrinder<br />
 
Parent: IMyShipToolBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: None<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Gyroscope====
 
Interface name: IMyGyro<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
float GyroPower <br />
 
bool GyroOverride <br />
 
float Yaw <br />
 
float Pitch <br />
 
float Roll <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreasePower -> Increase Power<br />
 
DecreasePower -> Decrease Power<br />
 
Override -> Override controls On/Off<br />
 
IncreaseYaw -> Increase Yaw override<br />
 
DecreaseYaw -> Decrease Yaw override<br />
 
IncreasePitch -> Increase Pitch override<br />
 
DecreasePitch -> Decrease Pitch override<br />
 
IncreaseRoll -> Increase Roll override<br />
 
DecreaseRoll -> Decrease Roll override<br />
 
Terminal block and action name list - 2/3<br />
 
====Interior Light====
 
Interface name: IMyInteriorLight<br />
 
Parent: IMyLightingBlock<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
float Radius<br />
 
float Intensity<br />
 
float BlinkIntervalSeconds<br />
 
float BlinkLenght<br />
 
float BlinkOffset<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseRadius -> Increase Radius<br />
 
DecreaseRadius -> Decrease Radius<br />
 
IncreaseBlink Interval -> Increase Blink Interval<br />
 
DecreaseBlink Interval -> Decrease Blink Interval<br />
 
IncreaseBlink Lenght -> Increase Blink Length<br />
 
DecreaseBlink Lenght -> Decrease Blink Length<br />
 
IncreaseBlink Offset -> Increase Blink Offset<br />
 
DecreaseBlink Offset -> Decrease Blink Offset<br />
 
 
 
====Interior Turret====
 
Interface name: IMyLargeInteriorTurret<br />
 
Parent: IMyLargeTurretBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool CanControl<br />
 
float Range<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Control -> Control<br />
 
IncreaseRange -> Increase Radius<br />
 
DecreaseRange -> Decrease Radius<br />
 
 
 
====Landing Gear====
 
Interface name: IMyLandingGear<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
float BreakForce<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Lock -> Lock<br />
 
Unlock -> Unlock<br />
 
SwitchLock -> Switch lock<br />
 
Autolock -> Autolock On/Off<br />
 
IncreaseBreakForce -> Increase Break Force<br />
 
DecreaseBreakForce -> Decrease Break Force<br />
 
 
 
====Small Cargo Container====
 
Interface name: IMyCargoContainer<br />
 
Fields: None<br />
 
Actions: None<br />
 
 
 
====Medium Cargo Container====
 
Interface name: IMyCargoContainer<br />
 
Fields: None<br />
 
Actions:None<br />
 
 
 
====Large Cargo Container====
 
Interface name: IMyCargoContainer<br />
 
Fields: None<br />
 
Actions: None<br />
 
 
 
====Small Reactor====
 
Interface name: IMyReactor<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool UseConveyorSystem<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Large Reactor====
 
Interface name: IMyReactor<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool UseConveyorSystem<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Small Thruster====
 
Interface name: IMyThrust<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: float ThrustOverride<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseOverride -> Increase Thrust override<br />
 
DecreaseOverride -> Decrease Thrust override<br />
 
 
 
====Large Thruster====
 
Interface name: IMyThrust<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: float ThrustOverride<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseOverride -> Increase Thrust override<br />
 
DecreaseOverride -> Decrease Thrust override<br />
 
 
 
====Medical Room====
 
Interface name: IMyMedicalRoom<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: None<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
 
 
====Merge Block====
 
Interface name: IMyShipMergeBlock<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: None<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
 
 
====Missile Turret====
 
Interface name: IMyLargeMissileTurret<br />
 
Parent: IMyLargeConveyorTurretBase<br />
 
Parent: IMyLargeTurretBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool UseConveyorSystem <br />
 
bool CanControl<br />
 
float Range<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Control -> Control<br />
 
IncreaseRange -> Increase Radius<br />
 
DecreaseRange -> Decrease Radius<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Ore Detector====
 
Interace name: IMyOreDetector<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
float Range <br />
 
bool BroadcastUsingAntennas <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
 
 
====Passenger Seat====
 
Interface name: IMyCockpit<br />
 
Parent: IMyShipController<br />
 
Fields:<br />
 
bool ControlWheels<br />
 
bool ControlThrusters<br />
 
bool HandBrake <br />
 
bool DampenersOverride<br />
 
Actions:<br />
 
ControlThrusters -> Control thrusters On/Off<br />
 
ControlWheels -> Control wheels On/Off<br />
 
HandBrake -> Handbrake On/Off<br />
 
DampenersOverride -> Inertia dampeners On/Off<br />
 
 
 
====Piston====
 
Interface name: IMyPistonBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
float Velocity <br />
 
float MinLimit <br />
 
float MaxLimit <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Reverse -> Reverse<br />
 
IncreaseVelocity -> Increase Velocity<br />
 
DecreaseVelocity -> Decrease Velocity<br />
 
ResetVelocity -> Reset Velocity<br />
 
IncreaseUpperLimit -> Increase Maximal distance<br />
 
DecreaseUpperLimit -> Decrease Maximal distance<br />
 
IncreaseLowerLimit -> Increase Minimal distance<br />
 
DecreaseLowerLimit -> Decrease Minimal distance<br />
 
 
 
====Programmable block====
 
Interface name: IMyProgrammableBlock<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool IsRunning<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Run -> Run
 
Terminal block and action name list - 3/3<br />
 
====Refinery====
 
Interface name: IMyRefinery<br />
 
Parent: IMyFunctionalBlock<br />
 
Parent: IMyProductionBlock<br />
 
Fields: bool UseConveyorSystem<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Spotlight====
 
Interface name: IMyReflectorLight<br />
 
Parent: IMyLightingBlock<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
float Radius<br />
 
float Intensity<br />
 
float BlinkIntervalSeconds<br />
 
float BlinkLenght<br />
 
float BlinkOffset<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseRadius -> Increase Radius<br />
 
DecreaseRadius -> Decrease Radius<br />
 
IncreaseBlink Interval -> Increase Blink Interval<br />
 
DecreaseBlink Interval -> Decrease Blink Interval<br />
 
IncreaseBlink Lenght -> Increase Blink Length<br />
 
DecreaseBlink Lenght -> Decrease Blink Length<br />
 
IncreaseBlink Offset -> Increase Blink Offset<br />
 
DecreaseBlink Offset -> Decrease Blink Offset<br />
 
 
 
====Remote Control====
 
Interface name: IMyRemoteControl<br />
 
Parent: IMyShipController<br />
 
Fields:<br />
 
bool ControlWheels<br />
 
bool ControlThrusters<br />
 
bool HandBrake <br />
 
bool DampenersOverride<br />
 
Actions:<br />
 
ControlThrusters -> Control thrusters On/Off<br />
 
ControlWheels -> Control wheels On/Off<br />
 
HandBrake -> Handbrake On/Off<br />
 
DampenersOverride -> Inertia dampeners On/Off<br />
 
Control -> Control<br />
 
 
 
====Rocket Launcher====
 
Interface name: IMySmallMissileLauncher<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool UseConveyorSystem<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
 
 
====Reloadable Rocket Launcher====
 
Interface name: IMySmallMissileLauncherReload<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields: bool UseConveyorSystem<br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
UseConveyor -> Use Conveyor System On/Off<br />
 
  
====Rotor====
+
=== Hello world ===
Interface name: IMyMotorStator<br />
+
The standard Hello World program in Space Engineers can be written as such:
Parent: IMyMotorBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool IsAttached <br />
 
float Torque<br />
 
float BrakingTorque <br />
 
float Velocity <br />
 
float LowerLimit <br />
 
float UpperLimit <br />
 
float Displacement <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Reverse -> Reverse<br />
 
Detach -> Detach<br />
 
Attach -> Attach<br />
 
IncreaseTorque -> Increase Torque<br />
 
DecreaseTorque -> Decrease Torque<br />
 
IncreaseBrakingTorque -> Increase Braking tor.<br />
 
DecreaseBrakingTorque -> Decrease Braking tor.<br />
 
IncreaseVelocity -> Increase Velocity<br />
 
DecreaseVelocity -> Decrease Velocity<br />
 
ResetVelocity -> Reset Velocity<br />
 
IncreaseLowerLimit -> Increase Lower limit<br />
 
DecreaseLowerLimit -> Decrease Lower limit<br />
 
IncreaseUpperLimit -> Increase Upper limit<br />
 
DecreaseUpperLimit -> Decrease Upper limit<br />
 
IncreaseDisplacement -> Increase Rotor displacement<br />
 
DecreaseDisplacement -> Decrease Rotor displacement<br />
 
  
====Sensor====
+
public void Main()
Interface name: IMySensorBlock<br />
+
{
Parent: IMyFunctionalBlock<br />
+
    Echo ("Hello, world!");
Fields:<br />
+
}
float LeftExtend <br />
 
float RightExtend <br />
 
float TopExtend <br />
 
float BottomExtend <br />
 
float FrontExtend <br />
 
float BackExtend <br />
 
bool DetectPlayers <br />
 
bool DetectFloatingObjects <br />
 
bool DetectSmallShips <br />
 
bool DetectLargeShips <br />
 
bool DetectStations <br />
 
bool DetectAsteroids <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseLeft -> Increase Left extent<br />
 
DecreaseLeft -> Decrease Left extent<br />
 
IncreaseRight -> Increase Right extent<br />
 
DecreaseRight -> Decrease Right extent<br />
 
IncreaseBottom -> Increase Bottom extent<br />
 
DecreaseBottom -> Decrease Bottom extent<br />
 
IncreaseTop -> Increase Top extent<br />
 
DecreaseTop -> Decrease Top extent<br />
 
IncreaseBack -> Increase Back extent<br />
 
DecreaseBack -> Decrease Back extent<br />
 
IncreaseFront -> Increase Front extent<br />
 
DecreaseFront -> Decrease Front extent<br />
 
Detect Players -> Detect players On/Off<br />
 
Detect Floating Objects -> Detect floating objects On/Off<br />
 
Detect Small Ships -> Detect small ships On/Off<br />
 
Detect Large Ships -> Detect large ships On/Off<br />
 
Detect Stations -> Detect stations On/Off<br />
 
Detect Asteroids -> Detect Asteroids On/Off<br />
 
  
====Solar Panel====
+
If this program is entered into a programmable block and run, it will result in "Hello, world!" being displayed in the programmable block's interface on the lower right hand side of the screen.
Interface name: IMySolarPanel<br />
 
Fields:None<br />
 
Actions:None<br />
 
  
====Sound Block====
+
=== Getting your position ===
Interface name: IMySoundBlock<br />
+
This program will show the current GPS coordinates of your programming block's position in the world.
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
float Volume <br />
 
float Range <br />
 
bool IsSoundSelected<br />
 
float LoopPeriod <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseVolumeSlider -> Increase Volume<br />
 
DecreaseVolumeSlider -> Decrease Volume<br />
 
IncreaseRangeSlider -> Increase Range<br />
 
DecreaseRangeSlider -> Decrease Range<br />
 
PlaySound -> Play<br />
 
StopSound -> Stop<br />
 
IncreaseLoopableSlider -> Increase Loop time<br />
 
DecreaseLoopableSlider -> Decrease Loop time<br />
 
  
====Spherical Gravity Generator====
+
public void Main()
Interface name: IMyGravityGeneratorSphere<br />
+
{
Parent: IMyGravityGeneratorBase<br />
+
    var pos = Me.GetPosition();
Parent: IMyFunctionalBlock<br />
+
    Echo (pos.ToString());
Fields:<br />
+
}
float Radius <br />
 
float Gravity <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseRadius -> Increase Radius<br />
 
DecreaseRadius -> Decrease Radius<br />
 
IncreaseGravity -> Increase Acceleration<br />
 
DecreaseGravity -> Decrease Acceleration<br />
 
  
====Timer Block====
 
Interface name: IMyTimerBlock<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool IsCountingDown <br />
 
float TriggerDelay <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
IncreaseTriggerDelay -> Increase Delay<br />
 
DecreaseTriggerDelay -> Decrease Delay<br />
 
TriggerNow -> Trigger now<br />
 
Start -> Start<br />
 
Stop -> Stop<br />
 
  
====Warhead====
+
=== Checking a sensor ===
Interface name: IMyWarhead<br />
+
It's easy to get a sensor to open a door or trigger some other action even without any programming if you just place that action in the sensor's "Setup actions" list. However, triggering an action when a sensor does ''not'' detect something is more difficult, and cannot be done with timer blocks. This program will automatically check a sensor every 10 ticks (working out to about 6 times per second) and close a door if the sensor does not detect anything. This can easily be applied to other purposes, like turning off drills when asteroids are not in sensor range.
Fields:<br />
 
bool IsCountingDown <br />
 
float DetonationTime <br />
 
Actions:<br />
 
IncreaseDetonationTime -> Increase Detonation time<br />
 
DecreaseDetonationTime -> Decrease Detonation time<br />
 
StartCountdown -> Start countdown<br />
 
StopCountdown -> Stop countdown<br />
 
Safety -> Safety On/Off<br />
 
Detonate -> Detonate<br />
 
  
====Welder====
+
List<MyDetectedEntityInfo> entity_list = new List<MyDetectedEntityInfo>();
Interface name: IMyShipWelder<br />
+
public Program()
Parent: IMyShipToolBase<br />
+
{
Parent: IMyFunctionalBlock<br />
+
    Runtime.UpdateFrequency = UpdateFrequency.Update10;
Actions:<br />
+
    //This makes the program automatically run every 10 ticks.
OnOff -> Toggle block On/Off<br />
+
}
OnOff_On -> Toggle block On<br />
+
public void Main()
OnOff_Off -> Toggle block Off<br />
+
{
UseConveyor -> Use Conveyor System On/Off<br />
+
    var door_sensor = GridTerminalSystem.GetBlockWithName("Door Sensor 1") as IMySensorBlock;
 +
    door_sensor.DetectedEntities (entity_list);
 +
    if (entity_list.Count == 0)
 +
    {
 +
        var door = GridTerminalSystem.GetBlockWithName("Door 1") as IMyDoor;
 +
        door.ApplyAction ("Open_Off");
 +
    }
 +
}
  
====Wheel Suspension 1x1====
+
For this script to work, the sensor must be named "Door Sensor 1" and the door must be named "Door 1". If you configure the sensor to open the door, the door will automatically open when the player enters the sensor range and close when the player leaves the sensor range.
Interface name: IMyMotorSuspension<br />
 
Parent: IMyMotorBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool Steering <br />
 
bool Propulsion <br />
 
float Damping <br />
 
float Strength <br />
 
float Friction <br />
 
float Power <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Steering -> Steering On/Off<br />
 
Propulsion -> Propulsion On/Off<br />
 
IncreaseDamping -> Increase Damping<br />
 
DecreaseDamping -> Decrease Damping<br />
 
IncreaseStrength -> Increase Strength<br />
 
DecreaseStrength -> Decrease Strength<br />
 
IncreaseFriction -> Increase Friction<br />
 
DecreaseFriction -> Decrease Friction<br />
 
IncreasePower -> Increase Power<br />
 
DecreasePower -> Decrease Power<br />
 
  
====Wheel Suspension 3x3====
+
== Compilation errors ==
Interface name: IMyMotorSuspension<br />
+
This is a list (in progress) of known compilation errors and what causes them.
Parent: IMyMotorBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool Steering<br />
 
bool Propulsion <br />
 
float Damping <br />
 
float Strength <br />
 
float Friction <br />
 
float Power <br />
 
float Speed Limit <br />
 
float Travel <br />
 
float Height <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Steering -> Steering On/Off<br />
 
Propulsion -> Propulsion On/Off<br />
 
IncreaseDamping -> Increase Damping<br />
 
DecreaseDamping -> Decrease Damping<br />
 
IncreaseStrength -> Increase Strength<br />
 
DecreaseStrength -> Decrease Strength<br />
 
IncreaseFriction -> Increase Friction<br />
 
DecreaseFriction -> Decrease Friction<br />
 
IncreasePower -> Increase Power<br />
 
DecreasePower -> Decrease Power<br />
 
  
====Wheel Suspension 5x5====
+
* Method name expected: The compiler found parentheses when it wasn't expecting them. You could be missing a method name before the parentheses, or you might be inappropriately using parentheses instead of square or curly brackets, depending on what you're trying to do.
Interface name: IMyMotorSuspension<br />
 
Parent: IMyMotorBase<br />
 
Parent: IMyFunctionalBlock<br />
 
Fields:<br />
 
bool Steering <br />
 
bool Propulsion <br />
 
float Damping <br />
 
float Strength <br />
 
float Friction <br />
 
float Power <br />
 
float Speed Limit <br />
 
float Travel <br />
 
float Height <br />
 
Actions:<br />
 
OnOff -> Toggle block On/Off<br />
 
OnOff_On -> Toggle block On<br />
 
OnOff_Off -> Toggle block Off<br />
 
Steering -> Steering On/Off<br />
 
Propulsion -> Propulsion On/Off<br />
 
IncreaseDamping -> Increase Damping<br />
 
DecreaseDamping -> Decrease Damping<br />
 
IncreaseStrength -> Increase Strength<br />
 
DecreaseStrength -> Decrease Strength<br />
 
IncreaseFriction -> Increase Friction<br />
 
DecreaseFriction -> Decrease Friction<br />
 
IncreasePower -> Increase Power<br /><br />
 
DecreasePower -> Decrease Power<br />
 
  
==Changes: Allowed namespaces==
+
== See also ==
Currently you can use only the following namespaces from Modding API:<br />
+
* [[API:Sandbox.ModAPI.Ingame.MyGridTerminalSystem|MyGridTerminalSystem]] - Methods for getting object references to your various ship components.
Sandbox.ModAPI.Ingame<br />
+
* [[Programming Guide/Action List]] - Actions you can apply to objects via the Object.ApplyAction method. Also includes some of the object properties. Data appears incomplete as of March 19th, 2018.
Sandbox.ModAPI.Interfaces<br />
 
Sandbox.Common.ObjectBuilders<br />
 
VRageMath<br />
 
VRage<br />
 
  
You cannot use Sandbox.ModAPI namespace or any other game namespaces
+
== External links ==
 +
* [https://forums.keenswh.com/threads/guide-programmable-block-c-101-for-space-engineers.7225150/ <nowiki>[Guide]</nowiki> Programmable Block - C# 101 For Space Engineers] - Basic intro to C# programming for Space Engineers.
 +
* [https://forum.keenswh.com/threads/guide-programmable-block-c-102-for-space-engineers-loops-strings-and-other-things.7229828/ <nowiki>[Guide]</nowiki> Programmable Block - C# 102 for Space Engineers: Loops, Strings, and Other Things] - Basic intro to using loops and strings in C#
 +
* [https://forum.keenswh.com/threads/guide-programmable-block-c-103-for-space-engineers-math-class.7231429/ <nowiki>[Guide]</nowiki> Programmable Block - C# 103 for Space Engineers - Math Class] - Basic intro to using the Math library in C#
 +
* [https://forums.keenswh.com/threads/programmable-block-inter-grid-communication-guide.7392031/ Programmable Block Inter-Grid Communication Guide] - Using antennas to enable programming blocks to remotely communicate with each other.
 +
* [https://github.com/malware-dev/MDK-SE/wiki/Continuous-Running-No-Timers-Needed Continuous Running No Timers Needed] - Configuring programming blocks to run automatically without needing to use a timer.
 +
* [https://forum.keenswh.com/threads/tutorial-constructor-and-save.7382338/ Tutorial: Constructor And Save] - Saving and reloading data
 +
* [https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/ C# Operators] - C# language reference for all operators, such as and, or, greater than, less than, etc.
 +
* [https://fresc81.github.io/SpaceEngineers/index.html Space Engineers API documentation]
 +
* [https://bloc97.github.io/SpaceEngineersModAPIDocs/html/b2d609dc-672a-3d90-cdc0-3753ce60d06f.htm Space Engineers ModAPI Documentation] - Includes many API methods and properties which can be used by Programmable Blocks.
  
 
[[Category:Game Mechanics]]
 
[[Category:Game Mechanics]]

Revision as of 08:44, 20 March 2018

Programming in Space Engineers is done with the Programmable Block which can be given scripts written in C# (pronounced C Sharp). This can be used to make autonomous mining drones, long-range player-killing torpedoes, automated welding arms for ship construction and much more.

Introduction

Editor access

Only one player can edit the same script at time. If someone else has an editor for the current block open and someone else tries to open that block's editor, a notification will be shown that the editor is already open.

Main method

When the editor is opened for first time, void Main() method is present inside the code editor. This is entry point that will be called when executing script. If Main method is removed / renamed, the script will not run and you will be notified in the programmable block details area. Custom methods/variables can be defined and used, but only the Main method will be called without reference.

Variables life

There are two types of variables for scripting: Local (inside the methods) – these variables will keep their value only during execution of a method. Value will be “lost” when the method ends. Global (outside the methods) - these variables will keep their values during the lifetime of script. E.g. If the variable needs to keep value between separate runs of program, it needs to be defined outside the methods. After pressing “Remember & Exit” or “Remember” buttons, the previous script will be overwritten and all Global variables will be lost. All variables, local and global except for the built-in Storage variable will lose their value or return to their default value when recompiling the code and between saved game loads. The Storage variable is unique in that that it store data as string between saved seasons and recompile.

Compiling

When the “Check code” button is pressed, the code will be compiled and the result of the compilation will be shown. There are two steps of the compilation process: First the code inside editor is compiled by c# compiler for language errors. If there are any errors during compilation the following dialog is shown: It this case “aaa” string is placed before Main method. This is the wrong language construction and the compilation failed. In the error dialog the Line number error and description of the error is shown.

After compilation, the code is checked for usage of disallowed namespaces and types. In case that check fails, the following dialog is shown: In this case System.IO.Directory was used to delete some directory. This is forbidden and error is shown that “Not allowed type was used in script”.

If compilation and checks pass, a dialog is shown, confirming the checks passed, and the code is saved.

Script execution

When “Run” button is pressed or “Run” is assigned as terminal action, script is executed. Currently “Run” needs to be called manually e.g. user need to click on “Run” button or attach it as terminal action. Script is executed only on server even if it’s triggered from client. If there is any exception during script execution, all clients will be notified in programmable block details area about failure. In case of exception during script execution, script will not run again unless User opens editor and change script. A timer can also continuesly run the script by having a run action (you may be prompt to input an argument) and then starting/triggering itself or being started/triggered via script code (if going by the letter the timer will stop if the script crash).

Counting of instructions

Every time script is executed, every instruction of script is counted. If script executes more instruction than limit, execution is stopped and user is notified that script is too complex for execution. This prevents scripts to “freeze” game.

Whitelist

The types and classes allowed in scripts are restricted. Refer to the Scripting Whitelist to see what you are allowed to use.

Available interfaces

Possible Actions

Currently only terminal actions can be triggered inside scripts. User can access terminal system for grid on which programmable block is located and trigger any terminal action on any block at grid.

Block Classes (Action List)

Same block class for different SubTypeID

Some blocks have same parent (e.g. <TypeId> in cubeblocks.sbc) and differs only by subtype (e.g. <SubtypeId>). This means there is no distinction between these block in code.
Example of these blocks is the Cargo Container: there are 3 types of cargo containers in the game: small, medium and large. These three types differ only by subtype and Type is same for them e.g. large cargo container id is:
<Id>
<TypeId>CargoContainer</TypeId>
<SubtypeId>LargeBlockLargeContainer</SubtypeId>
</Id>
Medium is:
<Id>
<TypeId>CargoContainer</TypeId>
<SubtypeId>SmallBlockMediumContainer</SubtypeId>
</Id>
And small is:
<Id>
<TypeId>CargoContainer</TypeId>
<SubtypeId>LargeBlockSmallContainer</SubtypeId>
</Id>

In this case there is only one class IMyCargoContainer for all types of cargo containers.

Example programs

Hello world

The standard Hello World program in Space Engineers can be written as such:

public void Main()
{
   Echo ("Hello, world!");
}

If this program is entered into a programmable block and run, it will result in "Hello, world!" being displayed in the programmable block's interface on the lower right hand side of the screen.

Getting your position

This program will show the current GPS coordinates of your programming block's position in the world.

public void Main()
{
    var pos = Me.GetPosition();
    Echo (pos.ToString());
}


Checking a sensor

It's easy to get a sensor to open a door or trigger some other action even without any programming if you just place that action in the sensor's "Setup actions" list. However, triggering an action when a sensor does not detect something is more difficult, and cannot be done with timer blocks. This program will automatically check a sensor every 10 ticks (working out to about 6 times per second) and close a door if the sensor does not detect anything. This can easily be applied to other purposes, like turning off drills when asteroids are not in sensor range.

List<MyDetectedEntityInfo> entity_list = new List<MyDetectedEntityInfo>(); 
public Program()
{
    Runtime.UpdateFrequency = UpdateFrequency.Update10;
    //This makes the program automatically run every 10 ticks.
}
public void Main()
{
    var door_sensor = GridTerminalSystem.GetBlockWithName("Door Sensor 1") as IMySensorBlock;
    door_sensor.DetectedEntities (entity_list);
    if (entity_list.Count == 0)
    {
        var door = GridTerminalSystem.GetBlockWithName("Door 1") as IMyDoor;
        door.ApplyAction ("Open_Off");
    }
}

For this script to work, the sensor must be named "Door Sensor 1" and the door must be named "Door 1". If you configure the sensor to open the door, the door will automatically open when the player enters the sensor range and close when the player leaves the sensor range.

Compilation errors

This is a list (in progress) of known compilation errors and what causes them.

  • Method name expected: The compiler found parentheses when it wasn't expecting them. You could be missing a method name before the parentheses, or you might be inappropriately using parentheses instead of square or curly brackets, depending on what you're trying to do.

See also

  • MyGridTerminalSystem - Methods for getting object references to your various ship components.
  • Programming Guide/Action List - Actions you can apply to objects via the Object.ApplyAction method. Also includes some of the object properties. Data appears incomplete as of March 19th, 2018.

External links