Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- discord.gg/fwKEAJF
- Block Universal
- don't mind the format because it's supposed to be in Unity and looks better there, but since it's in build 5 and specifically in the Lobby I can't share, sorry
- if you want to test your scripts, DM me in discord and I'll test them for you
- ok now have fun reading this wonderful guide
- (===) means new chapter
- (===) Introduction
- <size=18>Introduction</size>
- Welcome to Block Universal's official Lua API guide.
- In this guide the fundamentals of Lua and BU's integration for it are explained and worked on.
- Any word or sentence in this guide under Italics represent Lua code.
- If you'd like to skip to BU API, please move on to the chapter <i>BU and Lua</i>.
- This chapter is only recommended for Lua beginners or people who aren't familiar with Lua.
- <size=18>Starting off easy</size>
- To begin with Lua, you must understand its syntax and logics. This isn't a hard thing to do, seen by how Lua is so easy and easily learnt.
- One key function in BU Lua is <i>print()</i>.
- This function adds text into the output. (This will be explained shortly)
- If you do <i>print('Hello World!')</i>, Hello World! will appear under the output.
- <size=18>Output</size>
- The output is a list of messages that come from the scripts. As the word indicates, 'output', these are messages who come out of the script.
- Remember the <i>print('Hello World!')</i> from earlier on? That is going to output 'Hello World!'.
- Any print will, infact, output. This is a special function that only outputs.
- <size=18>Strings</size>
- Strings are another way of saying 'sentence' or 'line'. A string is basically text.
- Anything that represents text is a string; for example, 'I am not a string', is a string.
- You can form strings with two characters, as long as it starts and ends with the same character. These characters are <i>'double</i> and <i>'</i>.
- This means 'doubleHey I am beautiful'double and 'Hey I am beautiful' represent no difference, meaning both are strings.
- <size=18>Math</size>
- Mathematics are used in Lua, of course.
- Don't worry though, you don't need to go all advanced with Maths!
- In Lua there are basic math operators, such as sum or subtract.
- Respectively,
- + -> Sum
- - -> Subtract
- / -> Divide
- * -> Multiply
- % -> Modulus
- ^ -> Exponent
- Surprisingly enough, you can use any type of data in <i>print()</i>!
- This means doing <i>print(5 * 5 / 25 + 5 - 2.5 * 2)</i> is possible!
- <size=18>Data types</size>
- There are multiple data types in Lua, but they don't require specification!
- Strings were specified earlier on this guide;
- Integers are whole numbers, such as 1, 2, 3...;
- Decimals are numbers that aren't whole, as for example 1.23, 6.74, 9.99...;
- Booleans represent true or false values, literally. The only booleans that exist are <i>true</i> and <i>false</i>;
- Nil is a special data type which represents no value. This data type also only exists under the keyword <i>nil</i>;
- Arrays are lists of stuff together, for example, {1, 2, 3}.
- There are strings, integers, decimals, arrays and some couple others.
- * Arrays are named 'tables' in Lua.
- (===) Basics
- <size=18>Variables</size>
- Ah, finally the good stuff.
- Variables can be any data type, and you can name them.
- For example, if you do a script <i>i = 'Hello World!'</i>, <i>i</i> will represent 'Hello World!' anywhere in the script.
- Of course, you can use variables in functions.
- Example script:
- <i>i = 'I hate variables, eh'
- print(i)</i>
- (Output would be <i>I hate variables, eh</i>)
- <size=18>If Statements</size>
- Now, on to more serious stuff.
- If Statements are the most common logical condition found on Lua scripts, and they're essential to scripting.
- With these, you can do predictions, checks and other stuff.
- They start with an <i>if</i>, that must be followed by the condition and the target result.
- Seems confusing?
- Here's an example:
- Applying everything in this guide so far, you could make a calculator, and a prediction for it:
- <i>i = 5 * 5
- x = i / 2.5
- if x == i * 2.5 then
- print('I had a F on maths.')
- end
- if x == i / 2.5 then
- print('I had a A on maths.')
- end</i>
- If it seems a bit confusing, don't worry! This is normal for anybody who isn't familiar with Lua.
- If Statements must be specified on what you want to check.
- You've got multiple logical conditions:
- == -> Equal to
- ~= -> Not equal to
- >= -> Greater or equal to
- <= -> Smaller or equal to
- > -> Greater than
- < -> Smaller than
- The If Statement model is usually this: <i>if condition then</i>
- They also require a keyword to note that the condition code is over: <i>end</i>
- Let's say you want to check if a certain formula results in a higher value than another, you can do this:
- <i>x = 7 * 9 / 3.7
- y = 9 * 4 / 1.1
- if x > y then
- print('seems like x is greater')
- end
- if x < y then
- print('seems like x is smaller')
- end
- if x == y then
- print('seems like x equals to y (how)')
- end</i>
- Of course, typing all these would be a bit boring and tiring, but don't worry! Lua has got the solution for you.
- Instead of only doing <i>if</i>, there are also two other If Statement beginning keywords: <i>elseif</i> and <i>else</i>.
- These different keywords require an initial <i>if</i> to exist, which means without one they can't be there, or the script will result in an error.
- The <i>elseif</i> keyword checks if another condition applies, and the <i>else</i> keyword is for when none of the conditions specified before apply.
- Here's the previous code, but with the new keywords:
- <i>x = 7 * 9 / 3.7
- y = 9 * 4 / 1.1
- if x > y then
- print('seems like x is greater')
- elseif x < y then
- print('seems like x is smaller')
- else
- print('seems like x equals to y (how)')
- end</i>
- As you can see, the code is a whole lot cleaner and nicer!
- <size=18>Functions</size>
- Uh oh, even more serious stuff.
- Functions are basically sets of code that run when you call them.
- Our good ol' friend <i>print()</i> is a function itself.
- When making a function, you must define a name.
- Here's an empty function's code:
- <i>function empty()
- end</i>
- Note the keyword <i>function</i>. This keyword is necessary for any function that is created.
- <i>empty</i> is, in this case, the function's name.
- And yes, functions require an <i>end</i>.
- Now, you may be curious about the <i>()</i>.
- These are the function's arguments. When calling a function, you may or may not send arguments.
- As an example, when calling <i>print('Hello World!')</i> you are passing the argument 'Hello World!'.
- You may be wondering how to initialize arguments in a function.
- Well, it's pretty simple!
- All you have to do is set a name for the argument in the function's header.
- Oh yes, function header. It's this code here: <i>function empty()</i>.
- Now, let's rewrite our function but with an argument!
- <i>function empty(arg)
- end</i>
- This means that every time you call <i>empty</i>, <i>arg</i> will be there.
- To call a function, you use the name followed by the argument.
- <i>function empty(arg)
- print(arg)
- end</i>
- If you were to call <i>empty('Hello World!')</i> now, it'd output <i>Hello World!</i>.
- But what if you want to call multiple of them...?
- Well, there is yet another solution.
- <i>function empty(arg1, arg2)
- print(arg)
- print(arg2)
- end</i>
- Yep. All you need to do is literally add a comma after the first argument and then name the second one.
- Pretty simple, isn't it?
- Here's our total script:
- <i>function empty(arg1, arg2)
- print(arg)
- print(arg2)
- end
- empty('Hello World!', 'You are very big.')</i>
- <size=18>String Concatenation</size>
- Yep, it is possible to concatenate strings!
- It is fairly easy to do so.
- All you need to do is add <i>..</i> after the last character of a string and then add the next string after that.
- Here's an example:
- <i>print('Hello '.. 'World!')</i>
- Of course, you can use variables in this.
- <i>x = 'World!'
- print('Hello '.. x)
- y = 'Hello '
- print(y..x)</i>
- (===) Loops
- <size=18>Loops?</size>
- Oh boy, now it's getting serious.
- Although loops aren't advanced, they are required for most scripts to function properly.
- Loops can be used for a variety of things and are extremely useful.
- There are different types of loops; for loops, while loops (...)
- Let's start easy...
- <size=18>For Loops</size>
- For Loops are mostly 'counters', as they depend on a numeric value.
- Here's an example for loop:
- <i>for i = 1, 10 do
- end</i>
- Yes, for loops also need the <i>end</i> keyword. Infact, all loops need it, except <i>repeat until</i>.
- This kind of loops increment the value by 1 (by default), and stop when the value reaches the specified number.
- Here's an example output of a for loop script:
- <i>for i = 1, 3 do
- print(i)
- end</i>
- -> 1, 2, 3
- When a for loop is made, a new variable with the name you specify is assigned locally in the loop area.
- Confused? Here's an example:
- <i>i = 5
- for i = 1, 3 do
- print(i)
- end
- print('real value of i is '.. tostring(i))</i>
- -> 1, 2, 3, real value of i is 5
- Using these loops is very useful when scripting.
- Here's an example application of a for loop in a script:
- <i>function math(number)
- for i = 1, number do
- number = number * number
- end
- print(number)
- end</i>
- math(2) -> 8
- You can also increment the variable differently from the default value, 1.
- It's very simple to do so:
- <i>for i = 3, 1, -1 do
- print(i)
- end</i>
- -> 3, 2, 1
- <size=18>While Loops</size>
- While Loops are loops that never stop unless a condition is no longer met.
- They're fairly simple to work with, and are extremely useful when scripting.
- Here's an example of a While Loop:
- <i>x = 0.1
- while x < 10 do
- x = x + x / 2
- end</i>
- As you can see, it starts with the <i>while</i> keyword and requires a condition right next to it, followed by the <i>do</i> keyword.
- You can use While Loops for multiple purposes, including waiting until something is done.
- <size=18>Repeat Until</size>
- Repeat Until is a special loop, and acts as a While Loop does, except it has the inverse role.
- Basically, it repeats the code inside it until a condition is met.
- Here's an example:
- <i>x = 1
- repeat
- x = x + 1
- until(x == 10)</i>
- <size=18>Stopping Loops</size>
- In Lua, it's possible to stop loops while they are running.
- This is done with the <i>break</i> keyword.
- Here's this keyword in action:
- <i>target = 7
- for i = 1, target do
- if i == target then
- break
- end
- end</i>
- With that script, when the For Loop <i>i</i> variable reaches the target value, it stops.
- <size=18>tostring() and tonumber()</size>
- They've been used here and there before in this guide.
- But what do they really mean?
- Well, it's actually pretty easy to understand.
- As their names indicate, they convert the value to a different data type.
- This means <i>tostring(5)</i> will convert <i>5</i> to <i>'double5'double</i>.
- The opposite also applies; <i>tonumber('double5'double)</i> results in <i>5</i>.
- Of course, converting a data type to another one that is impossible will result in error.
- So remember, never convert a string that doesn't represent a numeric value into a integer/decimal. Never. Ever.
- (===) Lua Basics End
- <size=18>Return keyword</size>
- The <i>return</i> keyword is yet another keyword belonging to functions.
- It is used for a variety of things, but the most common cause of its use is returning a value.
- To make an example for this, you can do:
- <i>function test(a)
- return a * 2
- end</i>
- This function will multiply <i>a</i> by 2 and return the new value.
- Here's an example use for this purpose:
- <i>function double(a)
- return a * 2
- end
- print(double(5))
- print(double(10))</i>
- -> 10, 20
- However, <i>return</i> can also be used to stop functions from running.
- <i>function test(a)
- if a < 0 then
- return
- end
- print(tostring(a).. ' is positive!')
- end</i>
- <size=18>Conditional keywords</size>
- There are three very important keywords for conditions: <i>and</i>, <i>or</i> and <i>not</i>.
- The <i>and</i> and <i>or</i> are used very often in Lua for conditions, and these alongside <i>not</i> can be used in If Statements and in Loops, alongside another special use for them.
- The <i>and</i> and <i>or</i> as their name indicates represent, respectively, the need for another condition to be met or for the other condition to be met.
- Seems confusing? Here's an example:
- <i>function test(number)
- if number * number / 10 == 1 or number / 5 == 1 then
- print('my random equation is met')
- end
- end
- function test2(number)
- if number - 5 == 0 and number + 5 == 10 then
- print('I think the number is 5')
- end
- end
- test(10)
- test(5)
- test(1)
- test2(5)</i>
- -> my random equation is met, my random equation is met, I think the number is 5
- Note how <i>test(1)</i> had no response. This is because none of the conditions matched.
- Then, we have the <i>not</i> keyword.
- This keyword acts as a negator, that inverts the condition's expected result.
- For example, if you do <i>if x == 5</i> and <i>if not (x == 5)</i>, you are doing inverse conditions.
- Here's a script using <i>not</i>:
- <i>x = 1
- if not (x == 1) then
- print('the cake is a lie')
- else
- print('welp')
- end</i>
- -> welp
- However, this keyword can also be used with booleans.
- These haven't been spoke about in this guide yet, so here is a quick tutorial on them:
- You've got either <i>true</i> or <i>false</i> as the value. Nothing else.
- Of course, these represent conditional values.
- This means doing <i>if true then</i> will just result in the code in that statement to be ran, because the condition is <i>true</i>.
- You can negate them using the <i>not</i> keyword:
- <i>b = false
- if not b then
- print('I am always right')
- end</i>
- -> I am always right
- <i>b = (5 * 5 == 20)
- if not b then
- print('5 * 5 actually equals '.. tostring(5 * 5))
- end</i>
- -> 5 * 5 actually equals 25
- As it can be deducted from this quick tutorial, booleans are extremely easy.
- <size=18>Comments</size>
- Comments are pieces of code or text that don't run. Basically, they're notes.
- It is fairly easy to do a note, just add two of the <i>-</i> character and you've got yourself a comment.
- Here's an example:
- <i>-- I am a note, so I don't run in the code
- x = 1 -- 3 (old value changed)</i>
- <size=18>Local keyword</size>
- The keyword <i>local</i> is used quite a lot in Lua, and is one of the most important ones to exist in this scripting language.
- This keyword makes a variable limited to the scope it is in.
- Seems confusing? Don't worry. This concept is extremely confusing at first.
- But here's a quick example that might help:
- <i>local x = 5 -- This variable is still global, because the 'doublelocal'double keyword is used in the global scope.
- function z(y)
- local x = y * 2
- print(x)
- end
- print(x)
- z(x)
- print(x)</i>
- -> 5, 10, 5
- As you can see, even though x was changed inside the function, it's value remained equal in the global scope.
- <size=18>Tables</size>
- Tables are, in other words, arrays.
- For those unfamiliar with what arrays are, they're lists.
- Basically, a group of data.
- Making tables in Lua is extremely easy, but also useful.
- Here's an example table:
- <i>x = { 'I am a string', 5, 'I am another string' }</i>
- You can access the table's content using indexers. Indexers are also easy to comprehend and use; simply use <i>[number]</i>. Remember to replace number with the index.
- Tables in Lua start at the index 1.
- You can also obtain the table's content count using the <i>#</i> character.
- Here's an example:
- <i>x = { 'I am a string', 5, true }
- print(x[0])
- print(x[1])
- print(x[2])
- print(x[3])
- print(#x)</i>
- -> nil, I am a string, 5, true, 3
- There're also other fun ways to use tables in Lua.
- Here's a common way of using tables in Lua:
- <i>x = { }
- x.testing = 'hello'
- print(x.testing)</i>
- -> hello
- There are, also, multi-dimensional tables. Basically, tables that contain tables inside themselves.
- <i>x = { 'hello', { 'hello' } }
- print(#x)
- print(#x[2])</i>
- -> 2, 1
- (===) BU and Lua
- <size=18>BU Lua API</size>
- Block Universal's Lua API's full list of additions and changes can be seen on the Discord server (https://www.discord.gg/fwKEAJF)
- These can be seen in the channel #api.
- Using Lua in Block Universal is quite easy, but requires attention and some understandment of how it works beforehand.
- To begin with scripting with Lua in Block Universal, it is necessary to understand how Lua is applied in Block Universal first.
- In Block Universal, there is only one script, which the universe's owner must set/script.
- That script is then ran clientsided when a player joins the universe.
- * Extremely important note: The script isn't serversided, which means you must use workarounds to make it act as a server script.
- <size=18>Timed infinite loops</size>
- With Block Universal's Lua API, it's possible to make infinite loops that have a delay between being ran again.
- This can be done with the <i>wait(seconds)</i> function.
- This function stops the script from being executed for a specific seconds amount.
- Here is a normal while loop, with a 1 second delay per run:
- <i>while true do
- wait(1)
- end</i>
- However, that doesn't seem too pratical and clean.
- Fortunately for you, BU Lua API supports a conditional <i>wait(seconds)</i> function.
- Here is the same code, but with <i>wait(seconds)</i> as a condition:
- <i>while wait(1) do
- end</i>
- As you can see, the loop seems cleaner now.
- You can also use decimals as an argument, which means you can do half seconds or even lower amounts of time.
- BU Lua API supports a decimal down to <i>0.001</i>, which is 1 millisecond.
- The fastest delayed loop would be this:
- <i>while wait(0.001) do
- end</i>
- <size=18>[GAME] messages</size>
- It is possible to make the script add [GAME] messages to the chat.
- However, only the person on the script's end can see it.
- Remember; scripts run clientsided.
- The function for this is <i>chat(message)</i>, which will add to the chat a [GAME] message.
- Example welcome script:
- <i>chat('Welcome to my universe!')</i>
- -> [GAME]: Welcome to my universe!
- However, it'd be nice to be able to welcome the player by their name.
- This is also possible, using <i>localname()</i>.
- This function returns the local player's name.
- Here is the same welcome script, but calling the player by their name:
- <i>chat('Welcome to my universe, '.. localname() ..'!')</i>
- <size=18>Block Class</size>
- The <i>block</i> class is a small but useful class that allows block manipulation.
- Currently, it consists of two functions: <i>id</i> and <i>place</i>.
- Using these, it is possible to do a variety of things.
- * Remember that to place a block, the local player requires edit access.
- A possible application of the <i>id(layer, x, y)</i> function is telling the player every used block id in the universe.
- Of course, for this, you'd need the universe's width and height. This is possible to obtain using <i>universe_width</i> and <i>universe_height</i>.
- Here's a script that tells the local player every used block id in the universe:
- <i>local blocks = { }
- function table_contains(table, id)
- if #table == 0 then return false end
- for i = 1, #table do
- if table[i] == id then return true end
- end
- return false
- end
- for l = 0, 1 do
- for x = 0, universe_width - 1 do
- for y = 0, universe_height - 1 do
- if not table_contains(blocks, block:id(l, x, y)) then
- table.insert(blocks, block:id(l, x, y))
- end
- end
- end
- end
- local block = ''
- for i = 1, #blocks do
- block = block.. tostring(blocks[i]).. ', '
- end
- chat(block)</i>
- Quite a long script, but returns exactly every used block id in the universe, non-repeating.
- * For lua beginners, <i>table.insert(table, object)</i> adds the specified value into the specified table.
- * You can also use <i>table.remove(table, index)</i> to remove the value at the specified index from the specified table.
- (===) Digging further
- <size=18>Optimization</size>
- Optimizing your scripts is a huge deal, since it increases efficiency and performance.
- This is a step that is optional, but if done can be very useful.
- The script wrote to return every used block id in the universe isn't optimized, because it's constantly checking the same table for the id.
- To fix this, it is possible to use string indexers, which helps a ton.
- Here's the same script, but optimized:
- <i>local blocks = { }
- for l = 0, 1 do
- for x = 0, universe_width - 1 do
- for y = 0, universe_height - 1 do
- if blocks[block:id(l, x, y)] == nil then
- blocks[block:id(l, x, y)] = block:id(l, x, y)
- end
- end
- end
- end
- local block = ''
- for i = 1, #blocks do
- block = block.. tostring(blocks[i]).. ', '
- end
- chat(block)</i>
- The result is a lot of less time to compile the same script.
- This is, of course, useful and good for the script.
- Plus, the resulting string will now have the ids ordered, because we are now using indexes to store the ids.
- Note how the script also reduced in size, because the function was no longer needed.
- <size=18>Placing blocks</size>
- There is also another function in <i>block</i>. <i>place(layer, x, y, id)</i>.
- This function is used to place blocks, as deducted from it's name.
- * Note that since scripts are clientsided, the blocks per second limitation still applies.
- <size=18>Events</size>
- Events are functions that are called every time a specific event occurs.
- To use functions, you must type their names in your script, so that they can be called.
- Here's an example of a simple snake mechanic, but in Lua:
- <i>-- Green block is id 7 and red block is id 4
- function onBlockPlaced(layer, x, y, id, placer)
- local newId = 0
- if id ~= 4 and id ~= 7 then return end
- if id == 7 then newId = 4 end
- block:place(layer, x, y, newId)
- wait(18 / 1000) -- 18ms delay
- end</i>
- <size=18>More into events</size>
- There are also more events, and it will eventually come in handy to get the player's name and id.
- This is, of course, possible.
- Here's a sample welcome/goodbye script:
- <i>function onJoin(name, id)
- chat('Welcome, '.. name..'!')
- end
- function onLeave(player)
- chat('Goodbye, '.. player.name..'!')
- end</i>
- Now, what if your script required a list of every player in the game?
- Fortunately for you, that's also possible to obtain!
- And surprisingly enough, it is relatively easy to do so.
- Here's an example script that returns the name of every player in the game and their id:
- <i>names = ''
- for i = 1, #players() do
- names = names.. players()[i].name.. ' ('.. tostring(players()[i].id).. '), '
- end
- chat(names)</i>
- But what if you only have the player's name, and need their id?
- It is also possible to get the player's id with only their name, even without a list of players.
- Here is the function that collects a player's id from their name:
- <i>getplayer(name).id</i>
- Events are, infact, surprisingly easy once the basics are known.
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement