How to lua

Introduction

Finally we now have support for lua scripting in our lovely game! So now you can make mods which are not just changed 3d model… your mods now can do stuff!

Available since version 0.18.*

Getting Started

Before we start you need to read how to make a simple mod. If you already can make a simple mod you can continue reading this article.

To add a script to your mod you need to add a .lua file to your mods directory and reference it in your info.json file.

You can name your script however you want. I recommend creating a folder “scripts” and put all your scripts there just dont forget to add the folder name in the path like “scripts/script.lua”

Scripting

And now you want to know what you can write to a script.lua.

In your script you can define functions with these names and they will be called by Evertech Sandbox game at some events.

onPlace will be called when the player placed your modded item.

start will be called after initializing the object, it can be called after you placed an item or after the level loaded from a save file.

update will be called every frame

fixedUpdate will be called 50 times per second and is used for things related to physics

Hello world

Let’s write a hello world program.

You see, it is very small… It just writes a “Hello world” string to a console. But wait, what is console?

You can activate a console if you go to a pause menu in a game, then go to settings -> lua settings and click the “Show Console” button. Wait a little bit while it loads itself, then you can close it and since this moment it will log all messages from lua programs.

Now if you created your hello world mod we can test it. Activate a console, then place your modded item somewhere. If you did everything right you should see  “LUA: Hello world” in the console.

By the way you can also enable debug info in (Settings -> Common Settings -> Show Debug Info) and you will be able to see last 5 messages from lua while you are playing.

Evertech Sandbox API

In order to do something useful we need to call Evertech Sandbox API methods. To access them we will use a “es” object.

For example let’s create a modded item which will delete itself in 5 seconds after it was placed.

startTime = os.time()

Here we created a global variable named startTime and used a function time() of the os module. You can read about it on official lua website. The time function, when called without arguments, returns the current date and time, coded as a number. (In most systems, that number is the number of seconds since some epoch.)

So we stored a time when the script was initialized, then we initialized a new variable named timer with a value 5.

In the update function which is called every frame we check how many seconds have passed since initialization of our script. And if is more than 5 seconds we destroy are item.

To destroy an item we used “es” object, got a MultiBlock object which represents current object, and called a method of it named Destroy().

Now if you test this mod, you can place an item and it will delete itself in 5 seconds.

MultiBlock

Now it is time to talk about MultiBlock type. In Evertech Sandbox almost every Item is a MultiBlock. It may contain several Blocks, which is also a type. More than that we have a Root type which contains Blocks and MultiBlocks…

Root is a place where every item is stored. It is like a grid, and you can put a block in each cell. But we have Items which are bigger than 1x1x1 cube. And in order to unite the blocks of one Item we have a type MultiBlock.

Here we created a local variable p to store a coordinates of a block of our mod. Simple blocks have only one block in it. MultiBlock type contains an array of Blocks, arrays in lua are indexed starting with 1. To access the first element of an array we use square brackets and a number 1. The Block type contains a property PointInRoot which stores a coordinate of this block in the root.

If you created a mod with this script you can test it out. Don’t forget to activate a console first by going to settings and pressing the button “Show Console”.

After you placed couple of modded items you should see something like this in the console .

 

The Clock

Now let’s just look at one example and I will try to explain what is going on here.

This mod works in such a way that when you place it it will check his 6 neighbors and if it finds an item of type Sign it will write a current time to it. In order for it to work you need to place a Sign, then remove some blocks behind it if there is no place for a new one, then place a mod block so it will find a sign. And if everything is right it will show the current time.

Now let’s see how it works.

You can ignore an onPlace function, it left here from previous example.

Let’s look at start function. Here we call a function findMultiBlockOfType(itemType). It is the function which we defined ourselves, it checks neighbors at left,right,top,bottom,back and forward. If it finds the item of a needed type it will return the MultiBlock, otherwise it will return nil.

The signMB variable will store a result of findMultiBlockOfType function, MB in it’s name is because it is of type MultiBlock, but you can name your variables hovewer you want.

Then we check if signMB not equals nil, if it is not nil, then we found a Sign and we can continue to work with it. We print a message to a console ‘sign found’ then we store an object of type Sign to a variable sign. The MultiBlock type has a field Sign, it will return nil if it is not a Sign, but if it is a sign it will return an object of type Sign with help of which we can change the text and colors of a Sign.

In the update function we check if the sign variable is not a nil and if it is not a nil then we put a result of a call os.date(“%X”) which returns a time in a format (“hh:mm:ss”). You can read about os.date here.

And now let’s focus on the body of findMultiBlockOfType function and I will try you to explain how it works.

In a local variable p we store the coordiates of a first block of our multiblock. (mod blocks have only one block in MultiBlock).

Then we store a Root object in a variable called r just not to write es.Root every time.

For each of 6 sides we call a function GetBlock(x,y,z) of a Root. This function will return a block or a nill if this cell is empty.

Then for each of these 6 variables we check if they are not nil, and if they are not nil we compare their type with the type we passed as an argument. And if the types match we return a MultiBlock object of this block. If we don’t find the object of needed type (Signe) then we return nil.

Another example

This mod will paint each of his neighbors to a different color, if there is a neighbor and if it is paintable. Block.DownBlock,Block.UpBlock etc, will return a neighbor block relative to a block orientation.

Reference

es

es is an object which is used to access Evertech Sandbox Mod API

es.MultiBlock – returns MultiBlock object of current Item

es.Root – is a shortcut of MultiBlock.Root

es.TryGetMultiBlock(Vector3 pos, Vector3 dir, float rayLength) – casts a ray of length rayLength and if it intersects with a multiblock then this multiblock will be returned, otherwise nil will be return;

es.PlaySound(string pathToSound) – plays a sound from your mod folder

es.SetSoundVolume(float volume) – sets a volume of sound

es.SetSoundLoop(bool loop) – sets if this sound should start playing again after it ends

MultiBlock

MultiBlock – almost everything in evertech sandbox is a multiblock, it has info about the type of object and it contains array of Blocks which are stored in a root grid.

MultiBlock.Blocks – an array of blocks of this multiblock

MultiBlock.Type – returns a type of this item. It is a string.

MultiBlock.IsPaintable – a boolean property which tells if this item can be painted

MultiBlock.Paint({r,g,b}) – is a method which takes an array of red green and blue components of a color. Each component should be from 0 to 1, example {0.5,0.23,0.79}

MultiBlock.Sign – if the multiblock has type “Sign” then this property will return an object of type Sign

MultiBlock.Switch – if the multiblock has type “Switch” then this property will return an object of type Switch

MultiBlock.Destroy() – this method will destroy this item.

MultiBlock.Root – this property will return a Root object

MultiBlock.Rigidbody – is a shortcut for MultiBlock.Root.Rigidbody

MultiBlock.Position – is a shortcut for MultiBlock.Transform.Position

MultiBlock.Transform – returns a transform

Block

Block is a type which is stored in a root grid to reserve a place for a MultiBlock so two big multiblocks cannot be placed at one spot and will not intersect each other. Each block has a mass of 1 kg, the Root object will sum up all blocks and calculate it’s mass depending on blocks count.

Block.PointInRoot – returns a coordinate in a root grid. Coordinates are of type Point

Block.MultiBlock – returns a multiblock to which this block belongs to.

Block.Type – is a shortcut to Block.MultiBlock.Type

Block.Position – is a shortcut to Block.Transform.Position. Is a position in world coordinates and is just an array of 3 numbers

Block.Transform – is a transform of this block. Contains Position and direction vectors.

Block.Root – this property will return a Root object

Block.DownBlock – will return a Block which is below current Block relatively to the transform of a current block, if there is no block it will return nil

Block.UpBlock – returns Upper block

Block.LeftBlock – return Left block

Block.RightBlock – return Right block

Block.BackBlock – return Back block

Block.ForwardBlock – return Forward block

Point

Point is an object which stores a coordinates in root grid.

X – x coordinate, integer

Y – y coordinate, integer

Z – z coordinate, integer

ToString() – returns a string representation of a point in format X:Y:Z

Root

Root is an object which is parent to all Multiblocks and blocks. There is a ground root and dynamic roots.

Root.GetBlock(x,y,z) – returns a block if it has it in these coordinates

Root.GetBlock(Vector3 coords)- the same as above but you can pass an array of 3 numbers to it ({x,y,z})

Root.Rigidbody – returns a rigidbody if it is not a ground root.

Rigidbody

Rigidbody – With rigidbody you can apply forces or change velocity of the object.

Rigidbody.IsKinematic – is a boolean property. False by default. If it is true then no forces are applied to this object and it will just freeze in space like if you used a tv remote on it.

Rigidbody.Mass  – ReadOnly. returns a mass of this root. The mass is calculated as a count of blocks in a root multiplied by 1.

Rigidbody.WorldCenterOfMass – ReadOnly. is an array of 3 numbers. Returns a position of a center of mass of this object in world coordinates.

Rigidbody.LocalCenterOfMass – ReadOnly. returns a position of a center of mass relative to a root transform.

Rigidbody.Velocity – an array of 3 numbers. Returns a velocity vector. You can also set it by yourself.

Rigidbody.UseGravity – is a boolean property. If it is false this object will behave as it is no gravity.

Rigidbody.Position – returns an array of 3 numbers. The position in world coordinates. You can also set the value. For example: Rigidbody.Position = {10,20,30}

Rigidbody.AddForceAtPosition(Vector3 force, Vector3 pos) – Applies a force at position. Vector3 is an array of 3 numbers. Example of use: es.MultiBlock.Rigidbody.AddForceAtPosition({0,30,0},es.MultiBlock.Position)

Rigidbody.AddTorque(Vector3 torque)

Transform

Transform stores a position, rotation and direction vectors

Transform.Position – world position of the object. Is a Vector3 aka array of 3 numbers

Transform.Up – a vector of up direction relative to this object.

Transform.Right – a vector of right direction relative to this object.

Transform.Forward – a vector of forward direction relative to this object.

Transform.Down – you can guess

Transform.Back – same as above

Transform.Left – same as above

— rotation coming soon

Sign

Sign is a type to control a Sign Item.

Sign.Text – is a string property. You can read or write a string from or to it.

Sign.TextColor – a color property. You can set or read a color of text. Example: Sign.TextColor = {1,0,0}

Sign.BackgroundColor – a color property. The Color of a background of a sign.

Switch

Switch is a type to control a Switch button

Switch.IsOn – is a boolean property. You can read or write the value.

Add a Comment

Your email address will not be published. Required fields are marked *