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”.
If compilation and check passes following dialog is shown: This means that code doesn’t contain any language errors or not allowed methods.
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.
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.
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.
GridTerminalSystem variable
Currently only following “built-in” variable that user can use: GridTerminalSystem. This is entry point of entire grid terminal system.
It has following methods available:
List<IMyTerminalBlock> Blocks{get;}
List<IMyBlockGroup> BlockGroups { get; }
void GetBlocksOfType<T>(List<IMyTerminalBlock> blocks, Func<IMyTerminalBlock, bool> collect = null);
void SearchBlocksOfName(string name,List<IMyTerminalBlock> blocks, Func<IMyTerminalBlock, bool> collect = null);
IMyTerminalBlock GetBlockWithName(string name);
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.
BlockGroups will get all groups of grid terminal, this method internally allocates new memory
GetBlocksOfType will get all blocks of given type.
SearchBlocksOfName method will fulltext search between all blocks and returns block that contains searched string , search is case insensitive.
GetBlockWithName method will get first block with exact name as provided , search is case sensitive.
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:
bool IsBeingHacked { get; }
bool IsFunctional { get; }
bool IsWorking { get; }
VRageMath.Vector3I Position { get; }
IsFunctional property tells if current block is constructed to the level it can operate
IsWorking property tells if current block is powered
IMyTerminalBlock
IMyTerminalBlock is base class for every terminal block, all of the block will have following properties and methods:
string CustomName
string CustomNameWithFaction
string DetailedInfo
bool HasLocalPlayerAccess()
bool HasPlayerAccess(long playerId)
void RequestShowOnHUD(bool enable)
void SetCustomName(string text)
void SetCustomName(StringBuilder text)
bool ShowOnHUD
void GetActions(List<Sandbox.ModAPI.Interfaces.ITerminalAction> resultList, Func<Sandbox.ModAPI.Interfaces.ITerminalAction, bool> collect = null);
void SearchActionsOfName(string name,List<Sandbox.ModAPI.Interfaces.ITerminalAction> resultList, Func<Sandbox.ModAPI.Interfaces.ITerminalAction, bool> collect = null);
Sandbox.ModAPI.Interfaces.ITerminalAction GetActionWithName(string name);
GetActions method will get all action available for current block.
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:
string Id { get; }
StringBuilder Name { get; }
void Apply(Sandbox.ModAPI.Ingame.IMyCubeBlock block);
Id is Id of action e.g. OnOff, OnOff_On
Name is name of the action shown in UI e.g. Toggle block On/Off ,Toggle block On
Apply will apply action for given block (you need to provide block from which you took actions)
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.
It has one Property:
bool Enabled
This property indicates if block is turned on or off by user.
Terminal block and action name list - 1/3
Disclaimer
All terminal blocks have the following properties:
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
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.
Changes: Allowed namespaces
Currently you can use only the following namespaces from Modding API:
Sandbox.ModAPI.Ingame
Sandbox.ModAPI.Interfaces
Sandbox.Common.ObjectBuilders
VRageMath
VRage
You cannot use Sandbox.ModAPI namespace or any other game namespaces