Hello and welcome to Skript!
This is a general "How to Skript" guide that will hopefully give you everything you need to get setup and begin writing your first script! This tutorial includes parts originally written by Demon on the original DBO forums and LimeGlass. This tutorial will assume that you are familiar with making a Bukkit servers, but not with programing. So lets get into it!
What is Skript?
Skript is a plugin for Bukkit/Spigot, a popular Minecraft server mod, that allows server admins to easily modify how Minecraft works without programming anything.
— Peter "Njolbrim" Güttinger
Skript was created by Peter Güttinger, also know as Njolbrim or Njol, and first released on Feb 16, 2012. The goal of Skript is to provide a simple way for non-programmers to make their own mini plugins (called scripts). Skript is designed as an event driven language.
This is achieved with triggers, whereof each is a collection of conditions and effects. Each time a trigger is called all conditions are checked, and if all are met, the effects are executed.
— Peter "Njolbrim" Güttinger
This means for any of your code to be run, something in the game or your server must happen. This is call an event or a trigger. These can include things like commands, a passage of time, or the actions of a player (mining a block or jumping). After something has happened, then the series of conditions and effects is run through for things to actually happen based on that event. A condition is a yes or no question your code asks the server. This can include things like: is the player online, is the player holding a pickaxe. An effect is then something that happens, these can include giving the player an item or moving the player. These building blocks combined with other elements you will learn later can be combined to produce powerful features for your server very quickly. These features will be discussed in depth later in this tutorial.
Scripts are written in text files that end in .sk
. As such you can use any text editor such as VS Code, Sublime Text, NotePad++, Atom or many others out there. However, using Microsoft Word or Google Drive will not work.
There is also a Skript IDE called SkIDE which offers a lot of nice features such as autocomplete and code highlighting.
A very basic example of a Skript can be found below:
# eventon join: # effect broadcast "Welcome to Skript!"
Please note that #s are used for comments and will not do something
The script above sends the message "Welcome to Skript" to everyone on the server every time someone joins the server. You might notice that the script is very easy to understand, this is because scripts are meant to be very readable, English and easy to understand.
Setting up Skript
After setting up your base server, download the correct version of Skript from one of the sources below
Minecraft 1.9.4 to 1.14.x: bensku's fork, 2.4x versions: https://github.com/SkriptLang/Skript/releases
- Minecraft 1.8.x
bensku's fork, 2.2-dev36 (Recommended): https://github.com/SkriptLang/Skript/releases/tag/dev36
⚠ This version is for 1.9, but should work on 1.8 too, but is not supported.Mirreski's fork, 2.2 fixes v8b: https://www.dropbox.com/sh/qubix8i86u216rs/AAATz1mjgYH6ySeUSr0NPYH-a / (GitHub Repository)
Minecraft 1.7.10 and older: 2.1.2 by Njol: https://dev.bukkit.org/projects/skript/files
- Put the jar into the ‘plugins’ directory of your server
- Restart the server once to generate the config files and some example scripts
Notes
- bensku's fork does not support CraftBukkit. It will work fine with Spigot, but Paper is recommended, as it has more features and Skript supports some of them, especially timings v2.
- All versions of Skript not by Njol are unofficial and their issues should be reported to their respective issue trackers.
- Issue tracker for bensku's fork: https://github.com/SkriptLang/Skript/issues
- Mirreski's fork is not active.
How to make a Script?
As mentioned earlier, scripts are written in text files that end in .sk
. These scripts live in the plugins\Skript\scripts
folder. You will notice several example scripts generated when you first start up Skript. These files will have a -
prefix in their name, scripts with this prefix are disabled and will not be loaded. Removing the -
prefix will allow for the script to be loaded and run.
Now lets make your first script file!
Using a text editor, make a text file that is named "hello.sk" and save it to your plugins\Skript\scripts
folder. Keep in mind that Skript will also load scripts in folders inside the "scripts" folder such as plugins\Skript\scripts\subFolder\test.sk
. Now add the text below:
on join: broadcast "Welcome to Skript!"
and save the file!
Congrats you have just written your first script! How lets talk about loading it on the server.
How to load a Script?
Scripts are not loaded when you save their sk files. Instead they are loaded on the server startup or when you use the /sk reload
command:
/sk reload hello # loads the script with name "hello"/sk reload subFolder/hello.sk # loads the script with name "test", in 'scripts/subFolder/'/sk reload subFolder/ # loads all scripts in 'scripts/subFolder/'/sk reload scripts # loads all scripts
Go on try it! Now when joining your server "Welcome to Skript!" will be broadcast to all users!
Any errors with your script will be either shown in the chat to the user who typed the reload command or the server console. Unlike plugins, with scripts you don't need to restart your server to add or update features. It can all happen through the reload command. However be careful as this can also cause a small freeze on your server that your players might experience when loading large scripts.
Now that you can create and load scripts, lets get into the core concepts of Skript!
Core Concepts of Skript
Events
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 next line down is indented one more. You can either use a tab or spaces as indentation. 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 cancelled. 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
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.
Structure of conditionals is as follows:
if <condition>: # this section will run if the condition is positiveelse if <condition>: # this section will run if the first condition is negative and the second condition is positiveelse if <condition>: # this section will run if the first two conditions are negative and the third condition is positiveelse: # this section will run if none of the conditions above are positive# Skript also supports in-line conditions which doesn't support 'else if' and 'else', and doesn't start with a "if".# There are examples about this below
else if
s 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#oron 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 loose 2 gold nuggets and receive some bread.
Commands
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
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 argumentcommand /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
While loops are loops that runs 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 characterson load: set {_text} to "test" while length of {_text} is smaller than 10: set {_text} to "%{_text}%." broadcast {_text} # test......
Variables
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 computers 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 playercommand /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 playercommand /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 persons 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 whomever 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 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) .
At the end, it looks like this:
list variable with expressions in variable names
command /sethome: trigger: set {home::%player's uuid%} to location of playercommand /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.
Lets 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 amount of these variables using the Amount expression.{_count}
(with a 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.
Functions
Functions are an useful way to make reusable sections of code. If you have a bunch of code that is often repeated, instead of copying and pasting the code in many places you can just put it in a function then call the function when you need to run the code.
Check this tutorial: https://skripthub.net/tutorials/9
Addons
Addons are separate plugins written by other developers to add more functionality to Skript. Addons are a massive part of the Skript community and you will see them discussed everywhere. For example you can use databases, make Discord bots, send web requests, manage other plugins like Citizens and WorldGuard, play various particle effects and much more with the addons. To use an addon, all you have to do is add the addon to your server's ‘plugins’ directory with any addition plugins they might need. Then you can use their syntax in your scripts after you restart the server.
Where to find documentation/resources
Depending on your version of Skript, Njol's website or Bensku's website will have all the up to date "vanilla" syntax. However, other websites such as Skript Hub host not just Skripts documentation, but all of the addons documentation in one place! This means you can search every expression, condition, effect or event in one place. Links for both can be found below:
For vanilla Skript:
- Docs for bensku's fork of Skript: https://skriptlang.github.io/Skript/
- Original Skript docs: http://njol.ch/projects/skript/doc
For vanilla Skript and addons
- Recommended and up to date: https://skripthub.net/docs/
- Older: https://docs.skunity.com/
Skript Hub tutorials: https://skripthub.net/tutorials/