Core Concepts of Skript - LucFr1746/Minecraft-Coding GitHub Wiki
Events are called when something happens. So when a player clicks on something, takes damage, dies, when a mob does something, or even when the environment does something else completely independent of entity interaction. This will allow you to make something happen when something else happens. For example:
on explode:
cancel event
Note the spacing. Every time there is a colon (:), then the next line down is indented one more. You can either use a tab or spaces as an indentation. The length of the indentation doesn't matter, but an event must use the same indentation on each line. I prefer to use the tab key because I only need to hit it once per indent. The actual code is pretty simple. When an explosion happens, it gets canceled. This would be useful if you don't want TNT, creepers, or even the Ender Dragon to destroy stuff on your server. Keep in mind that this cancels the actual explosion event, meaning that players will not get hurt either. So when an explosion happens, it stops it from happening. You can easily change the outcome to be whatever you want. Another example could be as dramatic as killing all players on the server.
Conditionals are an essential part of any script. They are pieces of code that check to see if a condition is met before executing the rest of the script/trigger.
The structure of conditionals is as follows:
if <condition>:
# this section will run if the condition is positive
else if <condition>:
# this section will run if the first condition is negative and the second condition is positive
else if <condition>:
# this section will run if the first two conditions are negative and the third condition is positive
else:
# this section will run if none of the conditions above are positive
# Skript also supports in-line conditions which don't support 'else if' and 'else', and doesn't start with an "if".
# There are examples of this below
else ifs
and else
are optional.
You can add as many else if as you want.
An example with permissions is below:
on right click:
if player has permission "Skript.boom":
create explosion with force 3 at targeted block
#or
on right click:
player has permission "Skript.boom"
create explosion with force 3 at targeted block
This will create an explosion that is slightly smaller than TNT, but it will only do so if the player has the correct permission. Conditionals can also be used to check things like if the player has an item in his/her inventory, or what a line on a sign says. You can even use multiple conditionals so that an event has to meet all of them before moving on.
on right click:
block is a sign
line 1 of sign is "[Shop]"
player has permission "Skript.shop"
player has 2 gold nuggets
remove 2 gold nuggets from player
give player 1 bread
message "<light green>You bought a bread."
In this script, the player must right-click on a sign with the first line of "[Shop]", have the correct permission, and 2 gold nuggets. Then the effects occur. In this case, the player will lose 2 gold nuggets and receive some bread.
You can create commands with ease in Skript. Check out this tutorial: https://skripthub.net/tutorials/10 We will use some commands in the next examples.
Loops can be used to complete repetitive tasks that would otherwise be much more complicated. For example, if you wanted to see if there was a chest near you, you would need to check every block in a certain distance to see if it was a chest. This can be done easily using a loop:
command /chest:
trigger:
loop blocks in radius 3 around player:
if loop-block is a chest:
message "There is a chest at %location of loop-block%"
The percent signs indicate that there is a value that will replace that part of the text. In this case, there will be an x, y, and z value instead of %location of loop-block%
. The loop-block part of the code refers to whatever block the loop is checking. The loop will look at every block within a 3-block radius of the player and then run the code we have indented under it. And because we are using a command to trigger the loop, we can add arguments and allow the player to choose how far the loop will search.
command /chest <integer=3>:
trigger:
loop blocks in radius argument around player:
if loop-block is a chest:
message "There is a chest at %location of loop-block%"
Here we also set a default value for the command, just in case the player didn't enter one. In the loop expression we see the number has been replaced with an "argument" This means that whatever number you typed in the command will be put here instead. If a number was not entered in this command, then 3 will be used because it was set to be the default value. If you would like to see exactly how far a radius value is, then you can use this script to make a sphere out of blocks so you can visibly see the size.
command /sphere <integer=3>:
trigger:
loop blocks in radius argument around player:
if loop-block is an air:
set loop-block to stone
set {clear location} to location of player
set {clear radius} to argument
command /clear:
trigger:
loop blocks in radius {clear radius} around {clear location}:
if loop-block is stone:
delete loop-block
# deleting a block means setting it to an air block
The /clear command is so that you can easily delete the sphere that you made. Also because you will be at the center of the sphere, you will need a way to teleport yourself out. These Commands may cause a small amount of damage to your server if used close to the ground. Please use them while flying to get the full effect.
The parts of code with the curly brackets { } are called variables. You will learn about them in the next section.
While loops are loops that run the code as long as a specified condition is positive:
while <condition>:
# code
Please note that while loops don't have a delay, so they are faster than a tick and will crash the server if you are using Minecraft stuff (like blocks) without at least a tick delay: wait a tick Example usage:
# append a dot to the text until it hits 10 characters
on load:
set {_text} to "test"
while length of {_text} is smaller than 10:
set {_text} to "%{_text}%."
broadcast {_text} # test......
Variables are used to store information under a name. Think of it like a box with a label on it. When you want to get the info you put in that box, you just go look for the one with the right label on it. Skript does the same thing with Variables, which are the computer equivalent of a box. You save information like this:
set {variable name goes here} to true
The reason for this is so that we can get this information later. So maybe we want to check if a command was performed by this player before. We would do it like so:
command /sethome:
trigger:
set {home} to location of player
command /home:
trigger:
teleport player to {home}
Every time a variable is used in a script you must must put it in curly brackets { } to tell Skript that you are using a variable. Above is a very simple home script. We store the location of the player in a variable called {home} When the player types a different command like "/home" we go back to that variable to get the location out so we know where to teleport the player to. This does not clear the value out of the variable, it's more like reading it, then putting it back. When programming, you always need to think about what the user/player could do wrong. For example the player thought that they sethome back in their base, but forgot to do so. What happens if they try and use /home and there is no where to teleport them to? That is when you use an if statement. This statement checks if something is the way it is supposed to be, and if it's not, then it will do something different than the rest of the script. There is no default error messages that will be sent to the player, so you will need to make your own.
command /sethome:
trigger:
set {home} to location of player
command /home:
trigger:
if {home} is not set:
message "<red>You don't have a home!"
message "<gray>Use <orange>/sethome <gray>to set your home."
stop trigger
teleport player to {home}
Now if a player tries to do /home they will get an error message and then the rest of the trigger will stop. If you forget to stop the trigger, then the rest of the events not indented under the if statement will continue as normal. Also if the if statement is false, then none of the code indented under it will be read and the player will not get an error message.
The main problem with our current script is that if one person sets their home location under the {home} variable, then anyone who uses /home will be sent to that person's home, and if someone sets their home after another player, it will override the other location and only save the newest one. The way to fix this is to use expressions in variable names. In the case of the command event, it is whoever typed the command. So in order to set a different home per player we can actually put the player's name in the variable itself.
Also, we should use "list variables" here. List variables are a much cleaner way of storing values, especially variables that are unique to something, the player in this case. List variables can be looped, deleted all at once, and make a variable organization. To make list variables, we simply add ::
to the variable name: {home::%player's uuid%}
This makes a variable in the home list, using UUID of the player as the variable name (index).
In the end, it looks like this: list variable with expressions in variable names
command /sethome:
trigger:
set {home::%player's uuid%} to location of player
command /home:
trigger:
if {home::%player's uuid%} is not set:
message "<red>You don't have a home!"
message "<gray>Use <orange>/sethome <gray>to set your home."
stop # does the same thing with 'stop trigger'
teleport player to {home::%player's uuid%}
Now the player's name who set their home is in the variable. For example when it checks if the variable is set, it will check {home::069a79f4-44e9-4726-a5be-fca90e38aaf5}
for the Notch player (in online servers). With this script, every player will have their own home location.
Let's make some admin commands for our home system, using some benefits of list variables:
command /resethomes:
aliases: reset-homes, clearhomes, clear-homes
permission: skhomes.admin
trigger:
set {_count} to the size of {home::*}
clear {home::*}
send "<light green>Successfully removed <red>%{_count}% <light green>homes."
{home::*}
(with an asterisk for the variable index) will return all values in the home
list. We can get the amount of these variables using the Amount expression.
{_count}
(with an underscore prefix) makes the variable local to the event. Local variables can't be accessed from other events and will be deleted at end of the current event.
command /listhomes:
aliases: list-homes, homes
permission: skhomes.admin
trigger:
loop {home::*}:
# converts the UUID to a player and puts it to the _player variable
set {_player} to loop-index parsed as an offline player
send "<orange>Home of %{_player}%: <light blue>%loop-value%"
When looping a list variable, loop-value will be value and loop-index will be index of the currently looped variable. In this case the index is a player UUID, the value is a location.