Space Engineers

Space Engineers

Not enough ratings
MECS Advanced Guide (Currently out of date.)
By Trekki
An advanced guide detailing how to use MECS, a motor sequencer for walkers and factories.
   
Award
Favorite
Favorited
Unfavorite
Quick explanation of arguments
start - Starts the sequence with the defined name. You can also define an offset if you need to.
eg.
[start sequence], [start sequence 2]
delete - Deletes the sequence with the defined name.
eg.
[delete sequence]
stop - Stops the current sequence when it reaches the end. (When you need to end a sequence but can't afford to stop in-between.)
eg.
[stop]
train - Puts MECS into training mode and creates a new sequence, or adds to an existing one if the name is the same.
eg.
[train sequence]
In training mode:
~ (no arguement) - Records the current state of the grouped blocks and puts it into the list.
~ wait - waits for a specified number of ticks. Normal behavior resumes after the time expires.
eg.
[wait 120]
~ end - ends the sequence and saves it in custom data. It flags the sequence as a loop if you add " loop".
eg.
[end], [end loop]
trigger - Triggers the timer block named on run. The name you input and the name of the timer block must have no spaces. It is also caps sensitive. You can include this argument with the "wait" command.
eg.
trigger TimerNoSpacing
wait 180 trigger TimerNoSpacing
Special:
dontwait - This is an argument that you type directly into the custom data of a block you don't want to wait for. This is saved per step in the sequence. It will also cause the program to completely ignore the block on runtime if you leave it in.
unlocked - <WARNING DEPRECIATED> Enter this into the custom data of a rotor you want to become a continuous servo. This is a relic from older versions and no tested version of this has ever worked properly, so use at your own risk.
Configuration
TOLERANCE = 0.2;// The dead zone of rotors and pistons expressed in degrees.
connectedProg = null;// Assign a programmable block by name here.
connectedTime = null;// Assign a timer block by name here.
precisionMode = false;// Enable for increased accuracy; Program runs every tick instead of every 10 ticks.
Every group listed can have the name changed.
Servos - Rotors (acts like a 360 degree non-continuous servo.)
Motors - Rotors (acts like a continuously spinning motor.)
Pistons - Pistons
Doors - Any type of door that opens and closes.
Generics - Anything you can turn on and off.
Gears - Landing Gear.
Projectors - Projectors. Reads projectors and waits for the correct state. Had to perform some wizardry to get this to work.
Gyros - Gyros. Gyro overrides will be set using sequence data.

Ensure everything is in the correct groups.
Important! Make sure all your rotors you have set as servos have both minumum and maximum settings as the angle output will be different if the servo has no limits. I like to start by setting both to 0 before trying to make the rest.

Also! Always make sure everything has a unique name. The program will search for the blocks by name within the groups. Therefore, any identical names will result in only the first one in the list being read, while all the other blocks will fail to be used by the program, even if they are in the correct group.
Block behavior by group
Servos - Rotors. Acts like a 360 degree non-continuous servo. On train, it saves the current position and the velocity of the rotor. On run, it takes that save and moves the rotor into the angle it was saved in at the same speed it was set to, regardless of direction. It will wait until it achieves the angle within the error set in TOLERANCE. In addition, rotors can lock and unlock based on their setting. This happens at the start of a step, so I don't reccomend locking the servo on a step you want to move it in.

Motors - Rotors. Acts like a continuously spinning motor. On train it saves the velocity of the rotor. On run it sets the rotor's velocity to match. In addition, it can lock and unlock it's rotor according to the sequence. This does not wait.

Pistons - Pistons. Acts like a linear servo. On train, it saves the current position and velocity of the piston. On run, it takes that save and moves the piston into the length it was saved in at the same strength and speed it was set to, regardless of direction. It will wait until it achieves the length within the error set in TOLERANCE.

Doors - Any type of door that opens and closes. On train, it stores the open/closed state of the door, and the percentage the door is open/closed. On run, it toggles the door to open or close if the door's state doesn't match the saved state. It will wait until the door's percentage equals or surpasses the saved threshold. This makes it so that you could have the program advance once the door opens or closes enough, without having to wait for the inevitable clank.

Generics - Anything you can turn on and off. On train, it saves the on/off state of the block. On run, it toggles the power of the block if it's state doesn't match the saved state. It does not wait.

Gears - Landing Gear. On train, it saves the current lock state of the landing gear, and if autolock is on or off. On run, it's behavior reflects three states:
If you have autolock enabled, but not attatched at save, it will enable autolock but it doesn't wait.
If you have nothing connected to it at save, it will detatch, keeping the autolock state. It doesn't wait.
if you have something connected to it at save, it will enable autolock, and will wait until it locks on.

Projectors - Projectors. Reads projectors and waits for the correct state. Had to perform some wizardry to get this to work. It saves the remaining blocks to be added to the blueprint the projector is projector, plus any terminal blocks that are unwelded. It reads the last step to determine if it should check for the blocks to be greater than, or less than the saved value. If there are no unwelded blocks it will refresh the projector's state by power cycling it.

Gyros - Gyros. On train, it saves the state of the gyro, and uses those settings as an override on run.

Trigger - Timer block. You can define a timer block to be triggered at any given sequence step. This allows the program to cover some settings it isn't made to cover. Since there is no good way to read the state of a timer, it can be taken as an argument when you run the programmable block. Be aware, you cannot have spaces in the name of the timer block or when you type it in as an argument. eg. "trigger [name]"

Per-Block-Setting:
dontwait. Custom data tag. When put in a block it prevents the normal waiting behavior. On train it will save this as a state per step. Otherwise, leaving the tag in after the fact will cause the program to ignore it despite the internal setting. This means you can effectively exclude different blocks from detection at different steps in the sequence, which can come in handy.
Recording a sequence
The program will read the positions and states of the blocks in it's groups and store them as part of a sequence.

0) Run MECS with the argument "train [insert_name_here]". A prompt will appear indicating you are in training mode.
1) Now, go through the objects you want to have the program control, and adjust their settings until they are where you want them to be/in the state you want. Remember to use "dontwait" tags when you want to exlude a block from being waited for.
2) Record the sequence step by running MECS with no argument. The number of steps stored counter will increase. If you wish to add another step go back to 1).
3) End your sequence by running MECS with "end". If you want this to be a repeating loop, run MECS with "end loop".
If you end your sequence too early, you can resume adding to it by using "train [existing_sequence]".

You can access the generated sequence in the custom data of the programmable block. The first line is going to be the metadata that defines the different sequences. Below will be the actual sequence data. If you know what you are doing, you can edit this and save the changes by recompiling MECS.
Running the sequence
You can start any sequence with "start [insert_name]"

It will now go though the sequence, and will loop if it is set to. You can interrupt the sequence at any time to enter any other sequence, and you can end the sequence at it's normal conclusion with "stop".

When the sequence reaches the end, it will run any linked programmable block (with the argument "finished") and will trigger any linked timer.
(Optional) Setting up Keybinds
To enable keybinds for MECS, go into the script editor. You will see this:
string connectedController = "";
Put the exact name of the ship controller in between the quotation marks and save the changes.
For example:
string connected Controller = "Cockpit";

If the debug console shows up with "Set Up Controller", or "Found Controller" then the script set up the cockpit with an ini file and you are ready to set up keybinds.

You can either set up the keybinds in the script's menus (safe), or you can set it up in the ini file of the cockpit (not as safe).

Method 1: Through Menus:

To access the keybinds menu, type "keybinds config" into the console and run it. This toggles the keybind manager to start listening to your commands.

Commands:
  • "keybinds end" - Tells the keybind manager to save and resume normal operation.

  • "keybinds delete [sequence]" - Tells the keybind manager to delete the keybind associated with the provided sequence. If you run just "keybinds delete" it brings up a list of keybinds you can delete instead.

  • "keybinds [sequence] [keys]" - Tells the keybind manager to associate a new keybind with a sequence. Supported keys are:
    WASD+QE+J(jump)+C(crouch)+O(default)+*(tells the script to wait for this sequence.) You can use multiple keys in a keybind, for example, WA, or J*, or WDE.
    If you try to reuse a keybind or sequence, it will instead replace that keybind or sequence.

  • "keybinds toggle" - Tells the keybind Manager to switch between default and toggle mode. Toggle will run continuously until a new keybind is entered or the same keybind is entered a second time. This puts it on a sort of cruise control.

  • Running with no argument brings up the set up menu again.

Method 2: Through Config:

If you go into the custom data of the ship controller, you should see this:
[Keybinds] ;If we toggle on button presses. Toggle=false ---
To add a keybind, just add a newline with:
"[sequence]=[keys]"
Supported keys are:
wasd+qe+j(jump)+c(crouch)+o(default)+*(tells the script to wait for this sequence.)
For example, if I want to run a sequence when I want to move forward, I can do "forward=w".
You can put multiple keys in so long as there are no spaces.

You can also change "Toggle=false" to "Toggle=true" to enable toggle mode in the config.

Note: When configuring the keybinds this way, you must use lower case or the script will not recognize the keys or the sequences. In addition, changes are not recognized until after you recompile.

Behavior:
When you press keys that you have set in the keybinds, the keybind manager will intercept this and try to run MECS with the sequence associated with those keys, including combinations of keys.

With toggle set to false, the script will run the sequence associated with that keybind as long as you are pressing the keys, and run the default when you let go of the keys.

With toggle set to on, the script will run the sequence associated with that keybind when you press the keys once, and change when you press different keys, and run the default sequence when you press the same keys a second time.

In both cases, if you have no default set, the script instead runs MECS with "stop". Keep in mind that that only tells MECS to end the sequence,. It does not cause MECS to stop rotors or turn blocks on or off. For this, I reccomend you have an "idle" sequence set up that does this.

If any keybind includes an asterisk(*), the keybind manager will pause and wait for the sequence to reach the end before accepting new input.

This is the notation as of version 1.3.9
Notes
0) The text UI will only show if the last thing that triggered the program to run was a player. If you ever need to see the diagnostic readouts as it runs, just run the program (from the terminal) with no argument and the UI will display again.

1) Each step of the sequence applies it's settings at the start of each step, and waits for parts to move into the correct positions before moving on to the next step. The exception are particular blocks, and anything tagged with dontwait in the custom data.
Custom Data Editing
Let this be our example:
example:0:0:False 0~servo:Rotor:0.00277873:4.999999:False:True`piston:Piston:0:-0.5:50000:True`motor:Rotor 2:4.999999:false`door:Airtight Hangar Door:True:1:True`generic:Spotlight 2:True`gear:Landing Gear:False:True:True`projector:Projector:0:False`gyro:Gyro 1:0:0:0
Now let's break this down.

Metadata: Defines where each loop begins and ends.
example:0:0:False
(string)name:(int)start:(int)end:(bool)loop
Wait: Defines the amount of time to wait in ticks.
0~
(int)ticks~
Servos: Defines the position the servo has to achieve, and the speed to move into place with.
servo:Rotor:0.00277873:4.999999:False:True
servo:(string)name:(float)angleRad:(float)speedRPM:(bool)locked:(bool)wait
Motors: Defines the velocity of a continuous rotor.
motor:Rotor 2:4.999999:False
motor:(string)name:(float)speedRPM:(bool)locked
Pistons: Defines the extension of the piston and the speed used to achieve it.
piston:Piston:0:-0.5:50000:True
piston:(string)name:(float)extension:(float)speed:(float)strength:(bool)wait
Doors: Defines the open or closed state of the doors.
door:Airtight Hangar Door:True:1:True
door:(string)name:(bool)isOpen:(float)openPercentage:(bool)wait
Generics: Defines the basic on/off state of a functional block.
generic:Spotlight 2:True
(string)name:(bool)isOn
Gears: Defines the lock and autolock states of the landing gear.
gear:Landing Gear:False:True:True
gear:(string)name:(bool)isLocked:(bool)autolockOn:(bool)wait
Projectors: Defines the remaining blocks you must equal, surpass, or fall under in order to advance.
projector:Projector:0:False
projector:(string)name:(int)remainingBlocks:(bool)wait
Gyros: Defines the override settings of the gyro.
gyro:Gyro 1:0:0:0
gyro:(string)name:(float)yaw:(float)pitch:(float)roll
Trigger: Special value that can be added or dropped from the sequence list depending on the situation. Defines the timer block to be triggered during the sequence step. Normally, this will always lack spacing, since you have to define the name with a console command. However, you can theoretically change this however you want in the custom data.
trigger:Timer0
trigger:(string)name

A good example of when you might have to edit the custom data of the block would if you changed the name of blocks. I like using notepad++ for things like this, because I can easily find the old names and use the replace feature.

Note: Always keep a copy of the original in case you mess something up. Also, remember to recompile in order for the changes to take effect.

This is the notation as of v1.2.0.
Troubleshooting
0) If the program crashes on recompile, something has been broken in the custom data. You will have to manually fix/delete it. The most common cause of this would be having an extra new line with nothing inside, or a splitter character is missing or in the wrong place.

1) If the program gets stuck at any point of the sequence and it is perpetually waiting for something like a rotor trying to get into position, then you should increase the value of TOLERANCE. If it seems to be stuck with no reasonable explanation why, it could be getting caught on voxels. You can fix this by increasing the strength of the rotor/piston until it stops getting caught.

2) If the mechanism spazzes out, make sure you didn't leave unnecessary "dontwait" tags in the blocks. This often causes the mechanism to shake in precision mode, and move back and forth in regular mode.

3) The mechanism has jerky movements. Enable precision mode to increase the refresh rate of the program. I highly reccomend this for things such as walkers that need to have more precise timings.
Video Tutorials
0) Basic setup + Walker leg simple animation.

1) Ship Controller setup on a basic tank design.
Footnote
I hope this guide is helpful for anyone trying to use my script. If there is any way I could make this guide better, I would be happy to hear any feedback.

Last update covered. MECS v1.3.9
2 Comments
Blckspawn92 14 Aug, 2020 @ 6:34am 
I HAVE SO MANY QUESTIONS! Can I talk to you about them?
Cringenormie 21 Jan, 2019 @ 4:03pm 
oh god my brain