Space Engineers

Space Engineers

268 ratings
Easy Automation V2.0 Tutorial
By Coren
A comprehensive guide on how to use the Easy Automation V2.0 Ingame script.
2
2
3
3
   
Award
Favorite
Favorited
Unfavorite
Introduction
Congratulations on your acceptance into the CoreTech engineering program cadet. Here you will learn the set of skills which will be required of you in your future service to the Coren Industries Engineer Corps. Not only will your service help expand the influence of your host corporation (thus ensuring the safety of your friends and family), it will also grant you elevated status among your peers and increased access to the finer products that Coren Industries has to offer. It's a dangerous universe out there and you can take pride in making it a safer place (KLANG be willing).

Your first task is to learn the Easy Automation operating system which is used in all Coren Industries products. Your understanding of this system is vital to your future here so stay focused and remember your basics.

The Easy Automation system offers great versatility to the skilled user. Those who do well in this course will be able to:
  • Delay actions to a milliseconds precision
  • Stop the Automation until a desired situation happens and then resume
  • Rotate a rotor to a desired angle at a desired speed
  • Create complex logic which will govern how your automation’s react to different situations
  • Write and manipulate text on LCD's
  • Write current values of blocks to LCD's (such as a pistons current position)
  • Write to the core LCD the actions and properties of a block you may want to manipulate
  • modify block names (Especially useful when interacting with other tech such as Digi's Control Module)
  • Create and destroy specialized groups as well as use built in groups (the built in groups can't be created or destroyed with this system)
  • run other programs with arguments you define in your program
  • Reset the Easy Automation system in case of a systems failure
  • Read and understand the debug info of a non functioning automation
In other words the ability manipulate and program all known technology to react based on the situation at hand.

So with out further adieu, let us begin.
Basic Setup of Physical Components
All that is necessary to get started are these three components:
  • Programmable Block
  • The Custom Data field of any component where you will be storing your EA2 code
  • Activator (a button, sensor, or timer block)

Setting up Components
  • Begin by constructing a Programming Block.
  • Load The Easy Automation program on to the Programming Block.
  • Compile and click OK
Creating Your First CodeBlock
Good job cadet, All you need now is the Custom Data field of any block in which to write your instructions and an activator that will trigger your code, bringing whatever you create jumping to life.
(Coren Industries is not responsible for any Injury, Loss of limbs, or Loss of life that may result from the use and/or proximity to the Easy Automation System. Improper use has been known to slow and/or completely destroy local pockets of space/time.)


Important Note:
-All Blocks must belong to the same person in order for the Easy Automation System to work correctly.

Setting up the block you plan on storing your code in and creating a CodeBlock
  • Construct a component that has a terminal interface and name it something unique
  • Enter the Custom Data field of this component from the terminal interface. This is where you will be writing all your instructions
  • The instructions that the Easy Automation System reads from the Custom Data are separated out into CodeBlocks.
  • You may have any number of CodeBlocks in your Custom Data field
  • A CodeBlock with the name "Piston Block" looks like this
@Piston Block{ your instructions go here }
  • Refer to the Info-graph below to understand the anatomy of the CodeBlock





















CodeBlocks follow these rules:
  • You may name a CodeBlock how ever you wish as long as you never use brackets of any kind in the name (it's best to stick to letters and numbers). Take note of capitalization and spacing as you will be using this name to tell the Easy Automation program where to look.
  • The first open curly bracket must be located right after the name of the CodeBlock. Not on a separate line
  • The closing curly bracket must be alone on its own line at the very end of the CodeBlock.
The Activator
Great! So now you know how to construct a CodeBlock. What now? Well now's as good a time as any to brake the bad news.

All programs are dumb as rocks.

That's right, No intuition or curiosity or ability to infer what you may have wanted them to do... well unless your getting into AI, but that's a whole nother can of worms.
What I am trying to say here is that it is all up to you. Programming is like setting up dominoes. Each one needs to be in the exact right place for the whole thing to go down the way you want. One giant Rube Goldberg machine, and what do you need to get it all started? A simple tap in the right place. That's where the Activator comes in. An Activator can be a button, a sensor, or a timer block. Basically anything that can run the Easy Automation programming block with an argument when it is triggered.

Setting Up The Activator
  • Click the Setup Actions Button in the menu of your chosen activator
  • Drag the Easy Automation Programing Block to the desired slot and choose “Run” from the menu that pops up
  • A text box with a single line will pop up and request an argument
  • In the text box write the name of the component that your CodeBlock is in flowed by round brackets(some people call these parentheses)
  • Within these parentheses put the name of the CodeBlock, making sure to get all capitalization and spacing correct.
  • If your component is named “Tutorial LCD” and your CodeBlock is named “My Block” then It should look like this
Tutorial LCD(My Block)

  • Click Confirm

Congratulations, your activator now tells the Easy Automation system to look at the component and the CodeBlock in the Custom Data field of that component that you have indicated. All the Physical components and code connections are now set up.

Now its time to get to the good stuff.
The Who's Who of What You Can Do
I will be calling instructions that you put in your CodeBlock "Statements" from here on out.

So now your all dressed up, where do you go? Well The Easy Automation System now has built in Statements that allow you to display what actions and properties are available for any component you may be interested in manipulating.

These Statements are:
  • Show actions of
  • Show properties of

After the "of" in each of these statements you will put the name of the block you are interested in.

if you want to view the Properties of a block named "MyPiston" It will look like this:





Show Properties of MyPiston


You will need an LCD to display this information on and by default any LCD with "debug LCD" in it's name will show the requested information. If you do not have this LCD then you will be given an error when attempting to use the Show statement.


Now when you activate this CodeBlock with the Activator (The one you linked to this component and CodeBlock), the "debug LCD" will display the properties of the "MyPiston" block like so.


















  • The text to the left of the colon on each line is the name of the Property and must be used exactly as you see it with capitalization and all.
  • The text to the right of the colon on each line indicates what that Property's type is and will be important when you want to check or set it to what you want.

The Easy Automation system can also check any Detailed Info that contains a colon.
this Detailed Info must also be used exactly as you see it displayed
the picture below shows where you can find the Detailed Info




















As you can see, the "MyPiston" block has a Detailed Info like this:





So "Current position" can be checked by the Easy Automation system.

  • Detailed Info can be looked at but not changed directly.
  • Properties can be looked at and changed.
  • Actions can be triggered

Comments

If you want to write comments in the CodeBlocks that are ignored by EA then write them in their own line with a * as the first character in the line.
Value Types
There are 4 different types of values
  • Text
  • Number
  • True/False
  • Color

Text
Text can be any number of characters on any number of lines as long as it is encompassed by quotation marks. If you wish to use a quotation mark in your text then you must mark it by putting a backslash directly before it.

Number
A number can be a decimal number of any length but keep in mind the length of number that you see used with the block you are relating it to and try to mach it as best you can.

True/False
This value can be True or False. It can also be On or Off. On is the same as True. Off is the same as False.

Color
Color is separated into Red, Green, and Blue. three numbers represent the amount of each color that will be displayed. This numbers must be whole numbers, No decimals. Each of these numbers has a maximum value of 255 and are separated by colons.
  • 255:0:0 is Bright Red
  • 0:255:0 is Bright Green
  • 0:0:255 is Bright Blue

Now that you know how to look-up all the information and capabilities a block can provide, and understand the value types, you are ready to get into the meat of creating your own Automation's.

...Mmm meeeeat
Action and Property Statements
Actions and Properties are preaty much the buttons and sliders you see in the terminal window of each block. It is importent to note that the names for these buttons and sliders that are desplayed on the Terminal window can be different from the names you will be using to manipulate them within this script. Always use the Property and Action names that you find using the Show Statement previously described.

Triggering an Action:
this is one of the most simple Statments avalable.
Just input the name of the action and then the name of the block(s) you want that action to be applied to.
for instance:





  • Will Extend all blocks with "MyPiston" in their name
    • Of coarse this will only work if all of those blocks have an Action called "Extend"
  • If any one of them do not have an action called "Extend" then you will run into an error which will be desplaid in the Detailed Info of the Easy Automation programing block.


Changing a Property:
Properties have a bit more complexity but are still fairly easy to modify.
  1. Put the name of the Property first,
  2. Then the word "of",
  3. Then the name of the block(s)
  4. Then the operator "="
  5. Then the desired value

for instance:





will set the Velocity slider of all blocks with the "MyPiston" in their name to exactly -1.2435

For those of you who are coming from the previous version:
A unit indicator is no longer nessesary, just a plain number will now work.



Grouping
There are two ways to affect more than one block with one statement:
  1. Use the in game group system
  2. Name blocks similarly

Using the in game group system
To affect a group that you have created using the terminal, just encompass the name of the group in parentheses.

Example: You have created a group named "MyGroup" which contains multiple piston blocks.
'





Will set the velocity slider of all blocks in the "MyGroup" group to -1.2435


Naming blocks similarly
if you have a block named "Piston 1" and a block named "Piston 2"
then:
'




Will set the Velocity Slider of Both "Piston 1" and "Piston 2" to -1.2435

An important distinction to make is that if you affect All blocks with the name "Piston 1"
then you will also be affecting "Piston 10" through "Piston 19" as each one of these other blocks names contain "Piston 1" within them. This is not a good way to name and refer to your blocks if you plan on having more then nine.

If you want to affect only one block and be certain that you wont be affecting other blocks that may have the name of the block you are affecting as part of their own names then you can use the # in front of the name.
Lets say that we have two LCD's, one is named "testLCD" and the other is named "testLCD 2"
we execute the following LCD code:
which results in this:
as you can see the first statement only affects the LCD with the exact name "testLCD" and leaves the LCD "testLCD 2" alone even though testLCD is within the name "testLCD 2".

This second way of grouping takes a bit more effort on your part but also allows much more versatility.
This extra versatility comes from the fact that the Easy Automation system allows you to rename blocks, thus adding and removing blocks from groups that are used in this way.

In fact, let's cover that next.
Rename Statement
Ahh what power there is in a name. Names give purpose, direction. Names are what defines me from you, this from that. Now you will weld that power with a simple Statement.

It is interesting to note that changing the name of a block can cause the program to no longer affect that block because the code still refers to it by the old name. There are ways around this using ingame groups as the name of the group will not be changed, just the names of the blocks in the group. Many strange and interesting complexities await those who play with this dynamic.

The Easy Automation system gives you multiple ways to modify a blocks name:
  1. Completely rename a block
  2. Add to the end of the name of a block
  3. Add to any position within the name of a block [v2.019]
  4. Remove all instances of a set of characters from a block

Renaming Blocks
  1. To rename block(s) simply input "Rename"
  2. Then the name of the block(s) or name of the group (using parentheses if it's a group)
  3. Then the operator "=" or "+" or "-"
    • "=" will completely rename the block(s)
    • "+" will add to the end of the name of the block(s)
    • "+" followed by a number will add to that position within the name of a block [v2.019]
    • "-" will remove all instances of the indicated set of characters from the name(s)
  4. Then the text you wish to
    • Replace the old name
    • Add to the end of the old name
    • Add to a specified position within the old name [v2.019]
    • Subtract from the old name
    1. This name must be within quotation marks

Examples:





Renames all Blocks with "MyPiston" in their name to "YourPiston". Be vary careful with complete renames like this as there could now be many blocks with the exact same name and there is no longer any way for the Easy Automation program to differentiate one from another.







Adds " YourPiston" to the end of the name(s) of all blocks that have "MyPiston" in their name. This means
"MyPiston 1" and "MyPiston 2" will now be
"MyPiston 1 YourPiston" and "MyPiston 2 YourPiston"
Take note of the space at the very begining of " Your Piston". This does get added.


Adds "ot" after the 1st character in the name of all blocks that contain Ror in their name. Thus "Ror" becomes "Rotor" and "Error" becomes "Eotrror" [v2.019]







subtracts all instances of "Pist" from all blocks with "MyPiston" in their name.
"MyPiston" will now be "Myon"
"MyPiston 1 YourPiston" will now be "Myon 1 Youron"








Adds " MyPiston" to the end of the names of all the blocks that are in the ingame group named "CraneGrav".
Interestingly enough this means that all these blocks will now be affected by any statements that affect blocks with "MyPiston" in their name.

  • Ingame groups can be thought of as immutable.
  • Similar name groups can be thought of as mutable.
Playing with the interactions between these two types of groups can allow for some very interesting automations.


Many other mods and scripts depend on names of blocks to determine how they act as well. This means that The Easy automation script can interact with these other mods using its renaming capabilities. Digi's "Control Module" is one that offers particularly interesting interaction potential.
Rotor Statements
The Rotation Statement is a special statement that only works with rotors. This Statement will allow you to rotate a rotor to a specified angle at a specified speed. It also has the option to choose the shortest path to that angle depending on its current rotational angle...
CADET JENKINS Kindly remove yourself from that rotor and get back in line, This is NOT an amusement park!

Now as I was saying please direct your attention to the InfoGraph below.
As you can see, first you input:
  1. "Rotate" or "ShortRotate"
    • "ShortRotate" will make the rotor rotate in the direction that is the shortest path to the desired angle
  2. Then the text that is in the name of your rotor(s)
  3. Then "to"
  4. Then a number that represents the angle in degrees you wish the rotor to stop at
    • (It is important to to note that if the torque on the rotor is to high then the rotor will stop a few degrees beyond or below this depending on which direction it approached it from)
  5. Then "at"
  6. Then a number that represents the speed in RPM at which the rotor will be moving A positive number equals a clockwise rotation, a negative number equals counterclockwise
    • If you use ShortRotate then only the absolute value of this number matters, The direction will be chosen based on current angle compared to desired angle.

Setting limits to Unlimited
As this question has been asked fairly often I will add it to the guide.
In order to set the upper and lower limits of a rotor to unlimited you must set them to greater then 360 for the upper limit or lower then -360 for the lower limit.

@LimitlessRotor{ UpperLimit of Rotor01 = 361 LowerLimit of Rotor01 = -361 }
Variables
Variables are the Powerhouse of the Easy Automation script. Changing one variable can allow you to completely alter and modify a complex piece of code. Basically a variable in EA is a pointer to a specific value (like the brightness of a light or a number you set the variable to reference) that can be called up in multiple places within your code and if you want to change that reference then you can change the variable in the Variables code block instead of having to go through your code changing every instance of that value.

On a side note, it seems as if cadet Jenkins has been skipping his classes recently. If any of you see him please impart to him the importance of attendance.
  • Note: Attendance is not mandatory but those who show a penchant for lassitude will have this behavioral trait recorded in their Coren Industries personal profile.

Variables are stored in a special CodeBlock that is always named "Variables". As such, "Variables" is a reserved name for CodeBlocks and may not be used as a name for any other CodeBlocks.

Numerical Variables
In the case below:












We have a variable named MyVariable that is storing the value 1.2435.
In the "My Block" CodeBlock we replace the number at the end of the Property Statement with the name of the variable.
Now when the "My Block" CodeBlock is run the Velocity of all blocks with MyPiston in their name will be set to 1.2435.


Variable names have a few rules that must be followed
  • Can Not contain any spaces " "
  • Can Not contain any commas "," 
  • Can Not contain any parentheses "()"
  • Can Not contain any asterisk "*"
When in doubt just stick to Alpha Numeric when naming a variable.


Text Variables
Variables can also store text as well. In order to do so you will need to encompass this text in quotation marks:






Multi line pieces of text can also be stored:














As long as it is still encompassed with quotation marks.


Linked Variables
It is also possible to link a property or bit of Detailed Info to a variable. Variables of this kind will always equal the value of the property or Detailed Info at the time the Statement which contains this variable is executed. This allows you to link a value of one block to the value of another as well and produce many other fascinating connections.

Storing a Property in a Variable and using it:
Here we are storing the Velocity property of all blocks with MyPiston in their name in the variable called MyPistonVelocity.
When The "My Block" CodeBlock is run it will set the Velocity of all blocks with MyRotor in their name to the Velocity of the first block with MyPiston in its name.

It is important to note that when storing Properties and Detailed Info in a variable, the variable will contain a list of the values of all the blocks with the designated text in their names.
  • When using this variable in a Property Statement, it will only look at the FIRST block in this list.
  • When using this variable in an "If" or "When" Statement, it will check if ANY of these blocks satisfy the conditions.

the Properties or Detailed Info of ingame groups can also be stored in a variable in the same way that ingame groups are denoted everywhere else, with parentheses:






Links the Variable "Grav" to the Detailed Info "Gravity" of all blocks in the InGame group named "GravGen".

Storing a bit of Detailed Info works exactly like storing Properties. As long as the that spesific piece of Detailed Info has a colon in it, it should work:





Links the Variable "MyPosition" to the Detailed Info "Current position" of all blocks with "MyPiston" in their name.

Immutability of variables
It is important to acknowledge the variables in EA are immutable. This means that they are unable to be easily changed by the code itself. If you set a variable to equal 1.2435 then there is no easy way for EA code to change that variable to equal anything else. This is because there is no back end storage.

When a peace of code like:
Velocity of MyPiston = MyVarable
is run, EA just reads the text after "MyVarable =" in the variables code block and exchanges that for the value after the = operator in "Velocity of MyPiston =".

This means that in order for the code to change the value of a variable while it is running, it would have to rewrite itself. This is possible with the Customwrite operation but I would highly recommend avoiding this. It is very inefficient and it is very easy to do wrong.

If you do want a value that can be changed during runtime then the best option is to use the value of a block such as the brightness of a light. In this way the code can modify the brightness and then reference it later to set the angle of a rotor or something else.
MAAAAAATH[new as of V2.010]
As of V2.010 The Easy Automation system has gained the ability to do simple Algebraic operations through the Variables Code Block. By assigning a variable an equation, when ever that variable is used the equation will be run and the answer will be given to what ever statement requested the variable. In order to give a variable an equation it must be contained within the brackets of a math statement which is only usable within the Variables CodeBlock.

The math statement looks like this: "math()".

So
'










Here, when the RotorMath CodeBlock is run then the property statement that changes the velocity of all blocks that have "TestRotor" in there name will look at the variable named "newVel". This variable will see that it has a "math()" statement and will calculate the answer and return that answer to the property Statement.

Order of operations do apply so: "4*5 = 20" happens first, then "3+20 = 23"
so: "newVel = 23"

The Velocity of all blocks with TestRotor in their name will be set to 23rpm.


It is also possible to use brackets in the "math()" statement to indicate a different order of operations like so
'










Here, "3+4 = 7" happens fist and then "7 * 5 = 35"
so: "newVel = 35"


the math statement will also take properties of blocks as well

Here newVel will equal the velocity of the first block with the name "Piston 1" plus the first block with the name "Piston 2" at the time this variable is requested by another statement. It is unclear to me how the game decides which block is the first block so it is important that there is only one block with "Piston 1" in it's name and one block with "Piston 2" in it's name so that you can be sure of which blocks the Velocity information is coming from.

Use UNIQUE names in the math statement.


Now as you can see, if you want to use math equations of any type of complexity then you are quickly going to run out of space on a single line. The ability to have the math statement cover multiple lines solves this.
Here, the compleate equasion is:
math((Velocity of Piston 1 + Current Position of Piston 1) * (Velocity of Piston 2/(Velocity of Piston 1 + Velocity of Piston 2 + 1)))

as you can see we can split it onto separate lines as long as the entire equation is still encapsulated in the math statements parentheses as well as not spiting it onto a new line in the middle of a token word (remember that "Piston 1" and "Current position" are each considered single token words because they represent one thing so DONT split them at the space). If you are missing a matching parentheses you will be notified in the detailed info of the programing block.

so lets say that in this case:
a: Current position of Piston 1 = 1
b: Velocity of Piston 1 = 2
c: Velocity of Piston 2 = 3

so we have:
math(( b+a ) * ( c/( b+c+1 ))) and this equals
math(( 2+3 ) * ( 3/( 2+3+1 )))

so:
1st: 2+3+1 = 6
2nd: 3/6 = 0.5
3ed: 2+3 = 5
4th: 5*0.5 = 2.5

so in this case the velocity of all Blocks with TestRotor in there name would be set to 2.5rpm


Now lets say we want to directly convert a value from one kind to another
example: we want our rotor's speed to be based on the position of a piston
The range of speed of a rotor is from -60 to 60 rpm
The range of position of a piston(small) is from 0 to 2 meters

we want our rotor to go from 0 to 60 rpm based on the position of extension of the piston
fully extended = 60 rpm
fully retracted = 0 rpm

in other words we want to convert a range of "0 to 2" into a range of "0 to 60"
the equasion for range conversion is:
NewValue = (((OldValue - OldMin) * NewRange) / OldRange) + NewMin

so:
newVel = math(((Current position of Piston 1 - 0) * 60) / 2)

or if we want the rotor to go backwards when the piston is less then half extended and forwards when the piston is more then half extended.
newVel = math(((Current position of Piston 1 - 0) * 120) / 2)

This is just one example of a useful thing you can do with the new math statement. There are plenty of other uses which I will leave to you to find and explore.

As of V2.048 Math can now use other variables, This can save a lot of typing by setting a short variable name to the value in a component and then using that variable in another variables Math function.
LCD Statements
There are many ways Easy Automation V2.0 allows you to modify text on LCDs. Not only that, with the correct statement you will be able to modify the images that are displayed as well. If you would direct your attention to the screen...
It looks as if cadet Jenkins has already mastered this art and has deemed it necessary to use this functionality to animate me in a rather compromising position. Were he actually here, he would be punished severely. I assure you that as soon as we find him he will face the unpleasant consequences of his actions. I apologize for this disruption. Let us continue.

Let's go over the statements and what they do:
  • Image: displays the indicated texture to the indicated LCD(s)
  • Write: adds the text to the public text of the LCD(s) and displays it
  • WriteLine: adds the text to the public text of the LCD(s) on a new line and displays it
  • WriteNew: Writes over everything currently on the public text of the LCD(s) and displays it
  • Clear: Clears the public text of the LCD(s)
  • CustomWrite: adds the text to the Custom Data of the LCD(s) [v2.019]
  • CustomWriteLine: adds the text to the Custom Data of the LCD(s) on a new line [v2.019]
  • CustomWriteNew: Writes over everything currently on the Custom Data of the LCD(s) [v2.019]

Image Statement
the "Image" Statement is used like a Property Statement:






This Statement will display the image with the name "Danger" on all LCDs that have "Tutorial LCD" in their name

Write Statements
The "Write", "WriteLine", "WriteNew" and "Clear" Statements are used like this:
This will affect all blocks with "Tutorial LCD" in their names.
The "Clear" Statement is used like an Action Statment

The others are used like this:
  1. "Write", "WriteLine", or "WriteNew", followed by
  2. "to", followed by
  3. text that is in the names of the LCDs, followed by
  4. "=", followed by
  5. text you wish to display encompassed by quotation marks

The Text you display can cover multiple lines as long as it is encompassed with quotation marks and can contain spacing and empty lines:














looks like:


















Back Slash
the option to display the current value of a variable is also available:
looks like:
As you can see a back slash "\" is used to tell the write statement that "MyPistonPosition" is a Variable and not just more text.

Back slash can also be used to add quotation marks into your text:
looks like:
Without these back slashes in front of each of the "in text" quotation marks, the code would get confused and think you were ending the write statement to soon.

Selecting a screen in a multiscreen block

Some Blocks (like the cockpit) have multiple screens. If you wish to write to or clear a screen that isn't the first one all you need to do is write the number of the screen you want to modify right after the write or clear statement like so:

WriteNew2 to MyCockpit = "Text"
Clear2 MyCockpit

This will modify screen 2 in the cockpit instead of screen 1.

If you have multiple blocks in a group and wish to write to screen 3 but some of those blocks only have 2 or 1 screen, the blocks with 3 or more screens will write to screen 3 and the blocks with fewer screens will write to screen one as a default.
Running Other Programs
Easy Automation V2.0 can run other programming blocks with other programs loaded up on them. This allows Easy Automation to be set up as an interface for any program that is on the workshop.

There are three ways in which you can activate Other programming blocks
  1. Run the program without any arguments
  2. Run the program with its default argument
  3. Run the program with an argument you define in the Statement

The first two ways are used like Action Statements.

Run With No Arguments
Running a programming block with out any arguments looks like this:





This Runs all programming blocks that have "MyProgrammingBlock" in their name


Run Whit a Default Argument
Running a programming block with it's default argument looks like this:






This Runs all programming blocks that have "MyProgrammingBlock" in their name with the argument that is stored in each one's own "default argument" field. This can be found in the terminal of each programing block when it is selected.


Run With an Argument
The Third and most powerful way is to run it with an argument that you define in the "Run" Statement which looks like this:







This Runs all programming blocks that have "MyProgrammingBlock" in their name with the argument "This Argument".

If you want to use a value from the variables CodeBlock as an argument you just have to us the name of the variable after the =.

@Variables{ Pvel = Velocity of Piston } @Run{ Run MyProgrammingBlock = Pvel }

This Runs all programming blocks that have "MyProgrammingBlock" in their name with an argument equal to what ever the current value of the Velocity of Piston is. Lets say the velocity of the block named Piston is 1.2435, then that value is passed as the argument.

if you want to the value of a variable with some additional text then you will need to compile the variable in the Variables CodeBlock and then use that variable in the run statement.

@Variables{ Pvel = Velocity of Piston PvelText = "The Velocity of the Piston is \Pvel" } @Run{ Run MyProgrammingBlock = PvelText }

This Runs all programming blocks that have "MyProgrammingBlock" in their name with an argument "The Velocity of the Piston is ". \Pvel puts the value of Pvel at the end of that text. Lets say the velocity of the block named Piston is 1.2435, then the argument will be "The Velocity of the Piston is 1.2435"

Hay there cadet, I am accessing your PDA through a terminal I just hacked. It was so simple. You know how the programmable block can't affect other blocks that don’t belong to the same person that it belongs to? Well there's a tricky way around that. I just created a CodeBlock that affects the LCD on your PDA. Normally this wouldn't do anything because YOUR LCD and MY Programmable block belong to different people, but I then GAVE the whole Easy Automation setup to YOU: Programable block, Timer block, Custom Data component, and Activator button (this button is set to be able to be activated by anyone regardless of ownership). Now I can press this button and Bam, you been hacked SON. Now that you know, go cause some chaos and spread the LOOOVE.
Smell ya later.
Cadet Jenkins
Delay Statement
from "tao te ching, a new English version" Stephen Michell

We join spokes together in a wheel,
but it is the center hole
that makes the wagon move.

We shape clay into a pot,
but it is the emptiness inside
that holds whatever we want.

We hammer wood for a house,
but it is the inner space
that makes it livable.

We work with being,
but non-being is what we use


Using the Delay Statement is as easy as the empty space it represents:







  1. Extends all blocks that have "MyPiston" in their name
  2. Delays for 1000 milliseconds (that's 1 second)
  3. Retracts all blocks that have "MyPiston" in their name

Through testing I believe that the shortest delay possible is around 15 to 20 milliseconds and the Delay statement should be accurate to within around 10 to 20 milliseconds but this really depends on the power of your computer and the current load on the game.
When Statement
The "When" Statement is like a more complex delay statement. Instead of delaying for a set amount of time, it delays until a desired situation becomes true.

A When Statement looks like this:







When activated, The Easy Automation Programmable Block will cycle itself until the Detailed Info "Current position" of ANY block that has "MyPiston" in it's name is equal to 1. When this becomes true, it will proceed to the next line in the Custom Data code. In this case that means all blocks with "MyPiston" in their name will Retract.

It is important to understand that while a Programming block with the Easy Automation scrip on it is running, no other inputs will be accepted. This means that if this Easy Automation Programmable Block is waiting for something or delaying or is in the middle of an automation then it will NOT be able to be activated by any activators during this time. This period of inaccessibility can be avoided by using the Run statement to have another programmable block with EA on it do the waiting for you while your original Programmable block is free to continue (See the "Running Other Programs" section of this guide above).

We will call the equals sign "=" an "operator".

Now the equals operator "=" is not the only operator available for this statement.
Here is a list of the operators available:
  1. "="
    • Continue when it equals "=" the proposed value from any one of the blocks in the group
  2. "!="
    • Continue when it does NOT equal "!=" the proposed value from any one of the blocks in the group
  3. "<"
    • Continue when it is less than "<" the largest value out of all the blocks in the group
    • This means it will only continue if the proposed value is less then ANY of the actual values of the blocks in the group
  4. "<<"
    • Continue when it is less then "<<" the smallest value out of all the blocks in the group
    • This means it will only continue if the proposed value is less then ALL of the actual values of the blocks in the group
  5. ">"
    • Continue when it is greater than ">" the smallest value out of all the blocks in the group
    • This means it will only continue if the proposed value is greater then ANY of the actual values of the blocks in the group
  6. ">>"
    • Continue when it is greater than ">" the largest value out of all the blocks in the group
    • This means it will only continue if the proposed value is greater then ALL of the actual values of the blocks in the group

It is best to NOT use the equals operator "=" when ever you can use one of the others because it is rair that a Property or Detailed Info will be exactly equal to a number. Also if the number is changing rapidly it is completely possible that the script will not be checking the Property or Detailed Info exactly when it does equal the desired number, thus skipping it. This is especially true with a rotors "Current angle" Detailed Info.

if you are checking a Property that has a true/false value then you must use the equals operator "=". The value that comes after the equals oporator "=" will be one of these 4 words:
  • True
  • False
  • On
  • Off

"True" and "On" mean the same thing.
"False" and "Off" mean the same thing.

Example:







Here, after an Activator tells the Easy Automation Programming block to run the "My Block" CodeBlock, the Programming block will become unavailable to be activated again while it cycles over and over, waiting for ANY device with "MyDoor" in its name to have a Property named "Open" equal to "True". When this happens then ALL devices with "MyPiston" in their name will "Extend" and the Easy Automation Programming block will once again be available to complete more tasks.

When Open of Your Mom = On
Extend My@%*&

hehe...

O crap, I think they found me.
Gota go.

Cadet Jenkins
If, Else If, and Else Statements
LLLLLLLLOGIC!

Here we are girls and boys. This is where the magic happens. The "If" Statement allows your automation to take different paths of actions depending on "If" something is true.

an "If" Statement looks like this:










When this CodeBlock is run it will Extend ALL blocks with "MyPiston" in their name only if ANY blocks with "MyRotor" in there name have a "Current angle" of greater than 30 degrees. If no blocks that have "MyRotor" in their name have a "Current angle" of greater than 30 degrees then nothing will happen.

All "If" Statements have a pair of open and close curly brackets after it "{ }". These curly brackets contain all the statements that will or will not happen based on whether the "If" Statement proves to be true or not. We will call this the "IfBlock". Any statements that are outside an "IfBlock" will be executed regardless.

In Easy Automation Custom Data code, these brackets must be alone on their own lines as you see in the example above. This is different from the placement of the CodeBlock's curly brackets where the opening curly bracket must be right after the name of the CodeBlock and the closing curly bracket must be alone on its own line.

the operators available for the "If" Statement are the same as the ones for the "When" Statement
Here is a list of the operators available again:
  • Exicute Statements in IfBlock if it equals "="
  • Exicute Statements in IfBlock if it does NOT equal "!="
  • Exicute Statements in IfBlock if it is less than ANY "<"
  • Exicute Statements in IfBlock if it is less than EVERY "<<"
  • Exicute Statements in IfBlock if it is greater than ANY ">"
  • Exicute Statements in IfBlock if it is greater than EVERY ">>"

if you want to have something "Else" to happen if the "If" Statement is not true then you can add an "ElseBlock" right after the closing curly bracket of the "IfBlock" like so:
In this case If no blocks that have "MyRotor" in their name have a "Current angle" of greater than 30 degrees then ALL blocks with "MyPiston" in there name will Retract instead of nothing happening. This means that whether blocks with "MyPiston" extend or retract when the Activator is triggered depends on the position of all blocks with "MyRotor" in their name, essentially changing the function of the Activator one way or the other based on the situation.


if you want to check for more than one possibility then you can stack "ElseIfBlocks".
This looks like:
In this situation:
  1. if any block with "MyRotor" in its name has a "Current angle" of more than 100 degrees then all blocks with "MyPiston" in their name will Extend. If this is not the case then
  2. if any block with "MyRotor" in its name has a "Current angle" of more than 75 degrees then all blocks with "MyPiston" in their name will Retract. If this is not the case then
  3. if any block with "MyRotor" in its name has a "Current angle" of more than 50 degrees then all blocks with "MyPiston" in their name will Extend. If this is not the case then
  4. Nothing will happen since there is no "ElseBlock"
In this case there is an "IfBlock" and two "ElseIfBlocks". Only one of these "Blocks" may execute. The order that the "If" and "Else If" statements are checked is from top to bottom. when one of these checks proves to be true then all the other "ElseIfBlocks" and "ElseBlock"(if it was present) are skipped. An "ElseBlock" can be added to the end of this if you want to make sure that something happens even if none of the checks prove to be true.


if statements can be encased within other "IfBlocks".
This looks like this:




















Here you can see that you can use spacing to make it easier for yourself to see what "IfBlocks" are contained within other "IfBlocks" and what curly brackets go together.

In this CodeBlock we have an embedded "If" statement that will only be reached if any block with "MyRotor" in its name has a "Current angle" of greater then 100 degrees. if this is true the the Activator will Retract all blocks with "MyPiston" in their name if ANY block with "MyPiston" in its name has a "Current position" of more then 1. If there are no blocks with "MyPiston" in their name that have a "Current position" of more then 1 then ALL blocks with "MyPiston" in their name will Extend.

Using Variables
If you want to have a variable on the left side of the operator then you will need to use the "value" Key Word like this.

if value of variableName = thisValue { code here }
Referencing Other CodeBlocks
Programing is all about utility and there is nothing more utilitarian then reusing what you got. The Easy Automation program allows you to execute other CodeBlocks within the currently running CodeBlock through the use of Referencing.

Referencing looks like this:























When The "My Block" CodeBlock is activated this Program will:
  • Reference the "Extend Block" CodeBlock
    • Delay for 3 seconds
    • Then Extend ALL blocks with "MyPiston" in their name
  • Reference the "Retract Block" CodeBlock
    • Delay for 3 seconds
    • Then Retract ALL blocks with "MyPiston" in their name
  • Reference the "Extend Block" CodeBlock
    • Delay for 3 seconds
    • Then Extend ALL blocks with "MyPiston" in their name
As you can see, simply putting the name of the CodeBlock you wish to run in front of an "@" symbol will run that CodeBlock and then continue on to the next line in the original CodeBlock. This can be done multiple times and the CodeBlocks you Reference can themselves Reference other CodeBlocks and so on. This can drastically reduce the amount of code you need for more complex but highly repetitive Automations.

A CodeBlock can even Reference itself:
When The "My Block" CodeBlock is activated this Program will:
  • Extend ALL blocks with "MyPiston" in their name
  • Delay for 1 second
  • Retract ALL blocks with "MyPiston" in their name
  • Delay for 1 second
  • Reference itself and repeat FOREVER
This is an infinite loop. It will never stop until the Easy Automation Programming block is turned off. This is good for repetitive tasks like moving a leg back and forth... but how do you stop? Turning off the programming block is not a good way as it could end the program in an odd spot and cause problems.

Here is an infinite loop that relies on the status of a light in order to continue:
















Now the "My Block" CodeBlock will only continue to Loop if there is a block with "MyLight" in it's name that is currently on. I like using lights because they can also serve as an indicator as to when the programing block is busy with an infinite loop (and can't be triggered by anything else) and when it is free to be used again.

A CodeBlock is NOT restricted to Referencing a CodeBlock that is on it's own component. CodeBlocks on other components can be referenced as well.
Here we are Referencing a CodeBlock named "Other Block" on an LCD named "Other LCD":
When the "My Block" CodeBlock is activated then it will Reference the "Other Block" CodeBlock which is located on the Private text of the LCD named "Other LCD". This CodeBlock will Extend ALL blocks with "MyPiston" in their name and then Delay for 1 second. After this the "My Block" CodeBlock will continue on and Retract ALL blocks with "MyPiston" in their name.

As you can see here, in order to Reference a CodeBlock that is located on the Custom Data of another component, you will need to use the "@" symbol
followed by the name of the component which contains the other CodeBlock
followed by the name of the CodeBlock you are Referencing contained within Parentheses "()"

Remember that all components affected and components involved must belong to the same person that the Easy Automation programming block belong to.
Dynamic Values
So you've built a nice CodeBlock that automates a few things for you. Say you have an elevator and your CodeBlock takes you to the first floor when you press the button that activates it. It does this by extending or retracting pistons in the InGame group named "Elevator Pistons" depending on if they are currently above or below the first floor (Which is reached when the pistons are at 2.1 meters).
It looks something like this:
























Now you want your elevator to take you to 3 other floors. You could create one CodeBlock per floor. Each one being almost exactly the same as this one except for each one's values...
Ooooor you could use Dynamic Values.

Dynamic Values allow you to change the values in your CodeBlock from your Activator. This allows you to have one CodeBlock that can act in different ways based on which Activator activated it. In the case of an elevator this is very useful as you can have one CodeBlock that can take you to all the floors.

Using Dynamic Variables in this case looks like this:
The only difference is that after the values for the "Current position" of the blocks in the InGame group named "Elevator Pistons" you will see a space and then a STAR ONE "*1", and after the values given to the Write statements you will see a space and then a STAR TWO "*2". These are the indicators that tell the Easy Automation script to replace the "Default Value" with a value that will be given in the argument. The "Default Values" are the 2.1 and "1st Floor" values you see right before the "*1" and "*2" Dynamic indicators. These values can also be Variables

Lets take a look at this new type of argument that the Activator will be activating the Easy Automation Programing Block with:
Here we can see:
  1. The name of the LCD "Elevator LCD"
  2. Within parentheses we see the name of the CodeBlock "Elevator"
  3. Within a new set of parentheses we see (4.1, "2nd Floor").
    • 4.1 will replace all values with *1 after them in the CodeBlock
    • "2nd Floor" will replace all values with a *2 after them in the CodeBlock
    • The comma separates the *1 value from the *2 value

The position of the values in the argument determine what number they will relate to in the CodeBlock. *1 = first value in the argument, *2 = second value in the argument, *3 = third value in the argument and so on.

If you want all the values to be the "Default Values" then you can enter the argument like you normally would without the extra set of parentheses:
Here we are not replacing any of the values that are marked with *1 or *2.
The Elevator CodeBlock activated like this will bring the pistons to 2.1 and display "1st Floor" on the Elevator LCD.



If you only want to replace the Dynamic Values that come before any of the other Dynamic Values which you plan to be Default Values then you can just not put those values in:
Here we are replacing all values that have *1 with 4.1 and letting the values marked with a *2 be default by not putting a value in for it in the argument.
The Elevator CodeBlock activated like this will bring the pistons to 4.1 and display "1st Floor" on the Elevator LCD.



if you want a Dynamic Value to be Default but there are other Dynamic Values that come after it in the order of the argument, then use a STAR to indicate that you want it to be default:
Here we are indicating that we want all values marked with *2 to be "2nd Floor" but we want the values marked with *1 to be Default Values.
The Elevator CodeBlock activated like this will bring the pistons to 2.1 and display "2nd Floor" on the Elevator LCD.



Variables can also be used in the dynamic argument that the Activator passes to the Easy Automation Programming block.
if you have a Variable named Level3 that is storing 6.1 in it
and a Variable named Write3 that is storing "Floor 3" in it
then:
Will bring the pistons to 6.1 and display "Floor 3" on the LCD.
This is the best way to use Dynamic Values because it is much easier to edit a value in a Variable then it is to edit a value in an argument. Plus there is no way to see what an argument is once it has been set.

Dynamic values can be assigned to CodeBlocks within your Custom Data code from other CodeBlocks as well.

"@LCDName(CodeBlockName(DynamicVariables))"

When doing this you MUST use the full address of the CodeBlock as you would if you were using it as an argument.
The CodeBlock "BGColorSequ" references the CodeBlock "BGColor" 4 times. Each time with different dynamic Variables. This will cause the background of all LCD's with "bgLCD" in their name to cycle through colors with an increasing amount of time between each color change. This code is located on an LCD named "bgLCD"
"Number of" Statement [v2.019]
You can check the number of blocks:
  • with the requested charicter string in their name
  • with the exact name
  • within a group of the requested name

with these variables:

This CodeBlock

will result in this being printed on all LCD's with "newIfLCD" in their names

when there are 8 blocks with Piston in their name,
there are 2 blocks named "Ref Piston",
and there are 6 bocks in a group by the name of "OddPist"

it can also be used in "if" and "when" statements.
Special Cockpit Properties[v2.019]
The following properties of cockpits are now available
(add sum to any gravity property to get a sum of the vector)
  • Natural Gravity (Planetary, 3D Vector)
  • Natural Gravity Magnitude (Planetary, meters per second)
  • Artificial Gravity (Gravity Generator, 3D Vector)
  • Artificial Gravity Magnitude (Gravity Generator, meters per second)
  • Total Gravity (Planetary + Gravity Generator, 3D Vector)
  • Total Gravity Magnitude (Planetary + Gravity Generator, meters per second)
  • Ship Speed
  • X Y Z Linear velocity (can be all together or each individually)
  • X Y Z Angular Velocity (can be all together or each individually)
  • Base Mass (not Including Cargo)
  • Total Mass (Including Cargo)
  • Planet Position
  • Planetary Elevation

The following is an example of these new properties being stored in Variables (Minus angular velocity for each of the individual axis (they wouldn't fit in one screen). these are used exactly like the linear velocity ones)
'

And here is an example of a CodeBlock that uses these Variables in order to display them on to an LCD


You may notice that after some of the variables which are being displayed there is a number within parenthesis. This allows you to determine the scale of the number. Scale is the number of digits to the right of the decimal point. This is handy because the scale of these number can be ridiculously high and can easily extend off the edge of your LCD. This scale is only available in a write statement, all other uses will use the full scale of the number.
Special Sound Block Property[v2.023]
It has recently been brought to my attention that Keen has added the ability to select which sound a sound block currently has selected. I have added the capability for EA2 to select a sound.

To do so just us the “Sound” Key word as you would use a property. eg.

Sound of Sound Block = Lights off

Be sure to get the capitalization and spelling of the name of the sound correct.
Special Connector block Property v2.051
To get the connected status of a connector block, use the "connected" Key word.
This will return one of the following

"Connectable"
"Connected"
"Unconnected"

This can be used in a if or when statement like:

if connected of Connector_1 = Connectable
{
do something
}
Troubleshooting Your Custom Data Code
The Easy Automation System comes with built in trouble finding capabilities. Not everything is covered, but the most common mistakes will be caught and explained in the Detailed Info of the Programming block that contains this script. If What is in the Detailed Info looks obscure then it is likely that you have run into a problem that is not covered by the built in system. In this case you will have to reset the script by hitting the "Edit" button and then the "Remember and Exit" button. After this you should look through your Custom Data code for any mistakes. When you find the mistake, fix it and try to run the script in the same way you did before. Rinse and repeat until it is working how you want it to. If you are still having problems then don't hesitate to ask in the "Questions on Use" discussion located on the Easy Automation V2.0 Workshop page or in the comments below.

Running the Programming block with the argument "Reset" will reset the program as long as it is not stuck in an infinite loop.

Running the Programming block with the argument "Check Storage" will show the text which is used to keep track of where the Easy Automation program is currently looking in the Custom Data code. This is useful if you want to know where the program stopped when it ran into a problem. The number after the first "§" is the line in the CodeBlock at which the program stopped. If this is not 0 then you will need to use the "Reset" argument before you run the program again. The text before the first "§" are the component and CodeBlock names as you would normally indicate them in an argument. Any thing after these two things is an indication that the current CodeBock was referenced from another CodeBlock.
End of Class
[color=orange]Congratulations cadet![/color]

You have made it through the Coren Industries CoreTech classes on the Easy Automation V2.0 system. Your personal profile has been updated and you now possess orange42 clearance to all Coren Industries facility’s and services. You have done well to secure a bright future for yourself and your family here at Coren Industries. Be proud!

your first tour of duty begins at O five hundred, good luck.
916 Comments
PimpMyDog Apr 12 @ 2:32pm 
Hi. Is there a way to read data from a block's Custom Data if it's formatted in a specific way? I'd like to get some communication going on between EA code and another programmable block.
Coren  [author] Apr 8 @ 7:39pm 
@AN Marc Appledash
Or you could set up some groups in the terminal and activate those groups.

Eg: with terminal groups named G2, and G3 respectively.

@Merge{
if value of Subs = 1
{
OnOff_On sub-unit [tag=M1]
}
else if value of Subs = 2
{
OnOff_On (G2)
}
else if value of Subs = 3
{
OnOff_On (G3)
}
}
Coren  [author] Apr 8 @ 7:25pm 
@AN Marc Appledash
So to activate 3 mergeblocks, EA would need to know which exact merge blocks to activate. If you can not rename them into a group that EA can activate then you will be stuck with having to call them individually. If you need to do this in multiple places in your script then i would recomend creating codeblocks for each instance which you can call in those places later.
eg:

@1mb{
OnOff_On sub-unit [tag=M1]
}

@2mb{
OnOff_On sub-unit [tag=M1]
OnOff_On sub-unit [tag=M2]
}

@3mb{
OnOff_On sub-unit [tag=M1]
OnOff_On sub-unit [tag=M2]
OnOff_On sub-unit [tag=M3]
}


@Merge{
if value of Subs = 1
{
@1mb
}
else if value of Subs = 2
{
@2mb
}
else if value of Subs = 3
{
@3mb
}
}
AN Marc Appledash Apr 8 @ 4:22pm 
but i cant use renaming because that would mean i have to recomp the Missile Script and that i cant do with EA2 or a script
AN Marc Appledash Apr 8 @ 4:20pm 
so if i input 3 as a dynamic value it uses 3 mergeblocks
AN Marc Appledash Apr 8 @ 4:19pm 
Basically what i need is a way to active Merge Blocks dependent on a number that being Subs (Launcher amount aka mergeblocks used for Missiles)
Coren  [author] Apr 8 @ 3:14pm 
@AN Marc Appledash
You likely want to look a the "Grouping", "Rename Statements", and "Dynamic Values" sections of this guide.
Coren  [author] Apr 8 @ 3:10pm 
@AN Marc Appledash
What is "Subs"?
AN Marc Appledash Apr 7 @ 3:43pm 
question is there a better way to do this here ?


@Merge{
if value of Subs = 1
{
OnOff_On sub-unit [tag=M1]
}
else if value of Subs = 2
{
OnOff_On sub-unit [tag=M1]
OnOff_On sub-unit [tag=M2]
}
else if value of Subs = 3
{
OnOff_On sub-unit [tag=M1]
OnOff_On sub-unit [tag=M2]
OnOff_On sub-unit [tag=M3]
}
}


is there some Varible i can use or math to do this so it only actives the amount of merge blocks i want?
wyldfury Apr 7 @ 2:32am 
Thanks! I'll give those a try.