General Skript Tutorial

A very helpful tutorial that helped me learn Skript. This was all written by Demon on the DBO forums before they got removed. I modified some of it to be more grammatically correct or to update to present methods. (If something should be changed let me know)

Hello and welcome to Skript! Here you can find everything you need to get coding and begin your first script!


Skript 2.2 by Njol is the latest version that supports 1.7 or

Recommended (dev36): Works on 1.8, but not supported. If link doesn't work you can find dev36 at the github link below.

Recommended (SkriptLang forks):

Extra Info
Note that all versions of Skript not by Njol are unofficial and their issues should be reported to their respective issue trackers.

The original goal of Skript was to make a simple way for non-programmers to make their own mini plugins (called scripts). I feel that this purpose has been lost due to the lack of understanding of how to script. This tutorial will teach even the newest person to Skript, how to make this wonderful plugin work on his or her server.

Step 1: Read over the documentation
Njolbrim's website and Skunity have all of the expressions, conditions, effects and events that you will ever need on your server. I am not here to go over every single one of these but I will reference them in talking about commands and variables. It is also very helpful when you are programing on your own, so that you know the limitations of what you can do, as well as the syntax needed to get your task accomplished. Links can be found below; (updated Fork of Skript)

Variables, Loops, Commands, Conditionals and Events
During your time scripting for your server, you will undoubtedly use at least one, if not all, of the five types mentioned above. Below I have outlined what each can do, as well as how and when to use them.

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 (4 or 8) spaces. You cannot use tabs and spaces to indent different lines of a script. I prefer to use the tab key because I only need to hit it once per indent. The actual event in the 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 enderdragon 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 this script is very simple 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. An example with permissions is below:

on rightclick:
player has permission "skript.boom"
create explosion with force 3 at targeted block
on rightclick:
if 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 rightclick:
block is a sign
line 1 of sign is "[Shop]"
player has permission ""
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. To learn more visit the website above.

Every server admin knows about commands, its the way you run your server. Skript allows you to make your own custom commands. These commands are very similar to events, except that you get to define the event. The simple version of this is that the event is activated whenever a player types in the command that you define on the event line. To get a better idea of what I'm talking about, look to the example below:

command /hi:
permission: skript.hi
message "hi"

This simple command sends a message to the player who typed the command. The first line is the "event" line. First we say that we want to define a command. then we say what that command is. Then we give it things like a permission and usage. Finally, we add the trigger, which is what we want the command to do assuming the player has permission to do so. You can check the website mentioned above for more info on defining parts of a command like the usage. You can also make more complex commands that can get information, like who you want this command to affect and so forth. Look to the example below to see what I mean:

command /hi <player>:
permission: skript.hi
send "hi" to argument

This command will send the same message as before, but this time allows the player typing the command to send it to someone else as well. The reason we use the send effect this time is because the message effect only sends the message to the player in the event, i.e. the player who typed the command. With the send effect we can send a message to someone. The argument is whatever was entered in the command. So if you typed "/hi demon_penguin" then the effect would be replaced with "send "hi" to demon_penguin" thus sending the "hi" message to me. Again you can look to the website to find out more about commands.

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 very easily using a loop:

command /chest:
loop blocks in radius 3 around player:
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>:
loop blocks in radius argument around player:
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 "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>:
loop blocks in radius argument around player:
loop-block is air
set loop-block to stone
set {clear.block} to location of player
set {clear.radius} to argument

command /clear:
loop blocks in radius {clear.radius} around {clear.block}:
loop-block is stone
set loop-block to air

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. If you want to learn more about loops you can check the website that was mentioned above.

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 {} to true

Values for variables can be true/false, a location (x,y,z) or a plain old number. 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:
set {home} to location of player

command /home:
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 box 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 too. This does not clear the value out of the box, 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 though 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:
set {home} to location of player

command /home:
if {home} is not set:
message "<red>You need to set a home first!"
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 Skript 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 use expressions. These are things that will be inserted depending on who is triggering the event. 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. It looks like this:

command /sethome:
set {home.%player%} to location of player

command /home:
if {home.%player%} is not set:
message "<red>You need to set a home first!"
stop trigger
teleport player to {home.%player%}

Now the player's name who set their home is in the variable. So when it checks if the variable is set, it will check {home.demon_penguin} for me and {home.whateveryouruseernameis} for everyone else. With this script every player will have their own home location.

Closing Notes:
Remember that all of the stuff you learned under command section about if statements and stuff like that can be used in any trigger. This includes any event. And as a final reminder if you wan to learn more about what effects you can do and things like that, check out the documentation website above.

If you have any questions about what I have said here, or have any kind of issue with a script, to ask on the help forum.

- Demon

Variables are little names we give to store some information in. Remember solving for 'x' in your math class? Variables are just like that, but the computer does the solving!

I like to think of variables as boxes with a label. So I'm going to put the number 5 in a box labeled {box} When I look at the contents of the box later, I'm going to find the number 5. I don't need to remember what is inside, as the computer does all of that. All I need to do is say what to do depending on the value of the variable (otherwise known as the contents of the box). For example I could say "If the contents of {box} is 5 then kill all the players"

Now that you know what variables in general are, let's talk about what they can do in Skript!

Variables in Skript
In most programming languages, variables need to be declared, and can only be one type. (ie only a number or text ect) In Skript you can use a variable name anywhere you want, and if it doesn't exist, Skript will create one of the type needed.

All variables in Skript have curly brackets around them "{}" Then on the inside you put whatever you want to call the variable (again its the same as putting a label on a box). Usually you will put a dot between the name as such {} However it is not required and you could use spaces or whatever you would like except for '%' They have their own special purpose.

Nest Variables
Nest variables are when you put the value of an expression inside the variable name. An example could be :


When Skript reads the variable, it will replace %player% with the name of the player. If you were to look in the variables.csv file (You should probably never look in there just in case something gets messed up, but for the sake of the example, I'm going to tell you what you might find) you would see


Skript would fill in the name of the player. In this case it was Demon_Penguin. This will essentially make a separate variable per player, which is used in most scripts. You can also put the value of another variable inside a variable name like this:


If {color} was set to green, then you would see {}.

There may also be situations where you need multiple expressions to refer to the same player. For example, in a loop, you may need to refer to loop-player to get the correct player for a variable.

Local Variables
Local variables are used when you only want to use a variable for a little bit and don't want/need to save it. There can also exist multiple local variables of the same name at the same time. This is useful for things like log in events. While the code is executing for one player, another player may log in and need their own variable. In order to tell Skript you want this variable to be a local variable all you need to do is prefix the variable name with an _ Looks like this {_local} (Note that you may see it used as '*' in older posts, however in newer versions of Skript the underscore _ is used)

Option Variables
Option variables are a bit different from other variables. Any time they are used in code, they are replaced by their value. They also cannot be modified by the code in any way. Option variable (unlike other variables in Skript) need to be declared. There is a section you can add (usually at the top of the script) that declares the options and what their values are. They work almost like a little config file, which is what most scripters use them for.

Name: value

In order to tell Skript that you are using an option variable (outside of the options section) you prefix the name with the @ symbol. Looks like this {@Name}

List Variables
List variables are very special and complicated variables. They can hold an entire list of values, and not all of them need to be the same type. Their usage usually looks like {list::*}

Following my box example, I will compare a list variable to a room full of boxes. The room is called by the name of the list variable, and the name of a box in the room is the stuff after the two colons. Whenever you use the base name of the variable (for example {list::*}) you are referencing the whole room. The different parts of list variables are explained below:

WARNING: List variables are by far the most complicated of all the variable types. Only attempt using them if you feel you have a good understanding of the other variable types.

List variables have two parts to them: Their name (The name of the room) and the Index (The name of a box in that room). All list variables (rooms) start off empty. So lets start by learning how to put a box in that room.

add the player to {list::*}

What this does is creates a box that holds the player in the event. You may notice that we didn't tell Skript what to name the box. All we told it to do was put it in the room we call {list::*}. Skript names these boxes by numbers. It starts at 1 and works its way up to infinity. So the actual name of the variable that is holding our player is "{list::1}" This works well when we really don't care what the box is called, but only the fact that it is in the room. For example, if we had a variable that held all of the mods on the server, it doesn't matter if they are mod 1 or mod 2, just that they are on the moderator list. However, in many cases, you will want to be able to name every box in the room so we know right where to get it when we want to access it.

All you need to do is set the name (The part after the colons) in the variable. You can write it out, or you can even use expressions to set it for you:

set {list::mod} to 7
set {list::%player%} to true

Notice that we no longer use the 'add' effect? This is because we are not simply adding a box to the room (Which would give us the default number system), but we are adding a box with a specific name. So we need to set that box's name to something, and give it a value. You can also use this method to access a specific box in the room (One value out of a list variable) at any time in your code. This makes them work very similar to nested variables.

This technique allows for the quick deletion of a list of variables. Rather than setting nested variables to a value, you can do the same thing with a list variable, but it will be set up in such a way to be able to easily delete the entire list:

set {mod.%player%} to true # Old method
set {mod.list::%player%} to true #New method

delete {mod.list::*} #When you use the * as the index it refers to the entire room, rather than a specific box

To start a loop of a list variable you start it off with:

loop {list::*}:

What this does is check all the different boxes in that room, one by one.

Now you have a few values to deal with.
  • The loop-value is the value of the variable. Whatever is in that box.
  • The loop-index is what ever is after the colons for this particular box (ie the name of that box)

Then you can deal with each value one by one as it loops through each box.

If you need help of any kind you should search through the help forum. If you can't find what you are looking for, then feel free to make your own post.

- Demon

Syntax is the way that code is read. Skript will look for certain things to figure out how to read the code. It is important that you know how this works so that all of your scripts will work the way they are supposed to. Different aspects of Skript's syntax are show below.

on rightclick:
block is a sign
line 1 of clicked block is "[Checkpoint]"
set {checkpoint.%player%} to location of player
message "Progress saved!"

on respawn:
if {checkpoint.%player%} is not set:
stop trigger
wait 3 seconds
teleport player to {checkpoint.%player%}

All indents tell Skript when to do something. 'On rightclick:' is an event that triggers when a player right clicks, and then runs all the code indented under it. An indent is either one tab or a fixed amount of spaces. You can only use one or the other for the entire script. You can however use tabs in one script and spaces in another, they just have to be different files. I prefer to use tabs, because they are quicker and only require 1 tap of the key per indent. Also note that when you copy paste scripts it will paste them as spaces. So if you copy part of your script and typed te rest with tabs, you will have to change them to all tabs or spaces. Examples of when to indent and how many there should be are below:

command /commandname <args>:
description: This is an example command
permission: skript.permission
usage: /commandname <args>
effects and conditionals go here

When you start any event, you start with no indents. Every time after that you will usually indent every time after you use a colon. Commands are the only exception. At the end of your command and arguments you put in a colon to signify that you are done with that line and can continue on. You indent after the colon like normal. Then you add things like description, permission and usage to the command. Even though these have a colon after them, you do not indent. When you have added all that you would like to your commands here and are ready to add its effects, you type "trigger:" Now you are past the only irregularity and can indent after each colon, which includes the one you just put after 'trigger'. Now you can add effects and conditionals.

Any time you use a conditional you can put a colon at the end of it. This will require you to indent, but allow you to separate out the effects. An example is shown below:

on rightclick:
if player has permission "skript.example":
strike lightning at targeted block
strike lightning effect at targeted block

If the player has the correct permission, the code under the conditional will be executed, in this case, striking lighting at the block the player is looking at. The else, means that if the previous conditional that used a colon was false, then do this instead. NOTE: You can have conditionals inside of other conditionals indenting one more each time.

When you are done with a section then indent one less to return to the previous grouping.

Remember if you have any questions, to search the help forum as it may have already been answered!

- Demon

Specific Tutorials: These will give a more in depth understanding of more specific parts of Skript:

Creating Custom Commands
Custom commands can be some of the trickiest things to create. They can also be some of the most powerful. In this tutorial I am going to show everything about commands, and how to use them. Let's start by defining what we want the user to type when they execute this command:

command /test:

We now have set up a command called /test. But what if we want the user to enter in more information? Things like a player name or a number. That is where we use arguments. Arguments are a lot like variables, but only have one value that changes each time a command is executed. They are completely dependent on what the player types in. In order to add them to a command you enclose the type of argument with < and >

command /test <player>:
#And for multiple arguments
command /test <player> <number> <text>:

You may also want to make an argument optional. That way the user doesn't have to type it in if they don't want or need that argument for the command. For example, if you made a command that teleported you to spawn 1, spawn 2, or spawn 3, and the user just wanted to type in /spawn to get them to spawn 1. Rather than making them type /spawn 1 you can just make it optional, and default to 1. Here's an example of what I'm talking about

command /spawn [<number=1>]:

The [ and ] around the argument make it optional (the user doesn't have to type it in) and then we also give it a default value so that we know what to do if the user doesn't type it in. Also know that if you use an optional text argument, that the default value should be in "

command /test [<text="Example">]:

This first line of defining a command ends with a : Because of that (and because it acts as our event) all subsequent lines need to be indented. The next few lines are all about the options that our command will have. Things like a description, permission, and usage message.

command /test:
description: Description of what the command does
usage: The message that comes up if the user types the command in wrong
permission: The permission required to use this command
permission message: The message that appears if the user doesn't have the correct permission
executable by: Who can use this command? Players, console, or both?
aliases: Other names or shortcuts to this command

If you read the tutorial on indentation, then you will know that I mentioned that the only exception to the indent after colon rule was commands. Well here it is. Each of these options ends with a colon, but only the trigger gets an indent. The only one of these options that is required is the trigger (it holds what the command actually does) The rest aren't necessary, but can be useful in controlling aspects of the command. Now let's go one by one, and get into more detail on each of these options

- Description

What does this command do? What is it's purpose? It is mostly for in code documentation, but it's good to add anyway

- Usage

How should the command look? This message will come up when someone types a command in wrong. For example, if the command wanted a number, but the user typed in "Rabbit" this message would come up. It defaults to the arguments that you defined on the first line. It is used to make the command a little bit more readable. Instead of "/pay <player> <number>" you could put "/pay <player> <amount>"

- Permission

This allows you to define a permission for the command. By default there is no permission for these commands, so anyone can use them.

- Permission message

Here you define what the message should be if the user doesn't have the permission you set earlier. There is a default message that will show if you don't include this option

- Executable by

Who can use this command? The options are "players" "console" "console and players" Defaults to console and players

- Aliases

Make some shortcuts to your commands! You can add multiple aliases by separating them with commas "/h, /help, /helpmeout"

- Trigger

The most important part of any command, and the only option here that is required. Nothing else goes on this line, but all the next lines need to be indented again. This block of code will define what the command should do when executed. Here is a completed example:

command /help [<number=1>]:
description: Shows the help menus
usage: /help [page]
permission: help.permission
permission message: &cYou don't have the help permission!
executable by: players and console
aliases: /h, /helpmerightnow
message "This is a help command!"

Now we know how to set up a command, and where to add the effects, but how do we use the arguments (the data that the player entered in) in the trigger? If there is only one type of an argument you can reference it by using "arg <type>"

arg player
arg number
arg text

Alternatively you can use the number of the argument. This is determined by what order the arguments come in the command.

command /test <number> <player> <text>:
message "%arg 1%"
message "%arg 2%"
message "%arg 3%"

This command will display the arguments in order 1, 2, and then 3. The number, the player, and then the text. Next is a list of all the argument types and a bit about how they are used

  • biome - Things like SWAMPLAND or FOREST. Note that when entering this into a command the biome names will need to be in all caps +
  • block - Dirt, sand, cobblestone. Any type of block alias or ID will work here +
  • boolean - true/on/yes or false/off/no
  • colour - Any of the colors you can use in Minecraft. Can also be able to be spelled color
  • enchantment - Protection, sharpness, unbreaking Any of the enchantments in Minecraft +
  • enchantment type - Works the same as enchantment, but has a level (sharpness 3) +
  • entity - Creeper, zombie, player Anything that moves/walks around
  • game mode - Survival/creative/adventure +
  • integer - A number without a decimal such as 1, 3, or 87
  • item - Any item in the game. Could also be a block in item form (You can also use 'material' instead of 'item')
  • living entity - Same as entity but without projectiles and primed tnt. Something living
  • money - Some amount of money. Note that the name of the currency must be included when executing this command (You should probably use number instead for this)
  • number - A number with a decimal like 2.5
  • offlineplayer - A player that is possibly offline. Requires the player's exact name
  • player - A player that is online. Requires only part of the player's name to be valid (like using 'demon' instead of 'demon_penguin')
  • potion effect type - Any kind of potion effect. Strength, slowness, haste, ect. +
  • projectile - Arrow, snowball, or thrown potion +
  • text - Any kind of text. The exactness of whatever the player typed in. Could be anything
  • time - The Minecraft time. Anywhere between 00:00 to 23:59 +
  • timperiod - Same as time, but can use 'night' 'day' 'dusk' and 'dawn' +
  • timespan - Some amount of time like "3 seconds" "8 ticks" or "5 hours" Note that the unit must be typed when executing the command
  • treetype - Any type of tree or giant mushroom "giant red mushroom" "redwood tree" +
  • weather type - The type of weather "clear/sun/sunny, rain/rainy/raining, and thunder/thundering/thunderstorm" +
  • world - The name of a world

+ means that it is a valid type, but I have not tested to make sure that it works as a command argument. If anyone has tested some of these you can pm me and I'll update the list

Post in the help forum with any questions, and on the tutorials forum if you have any improvements or suggestions for this tutorial

- Demon

This tutorial is mostly for those of you who do not do any programming outside of Skript. It explains the concept of loops, as well as examples of how the syntax looks in Skript.

What Loops Are
A loop is a bit of code that keeps repeating itself (aka looping) until a certain condition is false. See this image For a visual representation of how this works.

The condition isn't very obvious in most of the loops Skript provides.

loop 10 times:
broadcast "Hi"

This code simply runs (or loops) 10 times. So where's the condition? There is an expression called loop-number that holds the number of times the loop has run (starts with 1) The condition is: if loop-number is greater than 10. After the loop runs for the tenth time, loop-number becomes 11 and the condition becomes false, and so the code moves on past the loop.

Loops simply repeat the code they are given. However, there can be slight differences each time. For example, the loop-number expression is a different number each iteration (an iteration is one time of running the loop code. The previous example would have 10 iterations). So what would happen if we broadcasted that number?

loop 10 times:
broadcast "%loop-number%"

The output would be:


As you can see, the loop did something slightly different in each of it's iterations. Now let's have an example with players:

loop all players:
if {var::%loop-player%} is true:
send "You are true!" to loop-player
send "You are not true!" to loop-player

For this example, let's say there are 3 players: player1, player2, and player3. The loop starts with player1, checks the variable, and sends a message depending on the outcome. Then it does the same with player2 and player3. Now the loop is out of players, and continues on with any code after the loop. If {var.player1} was true and {var.player2} was false, player1 would get the true message and player2 would get the false message. This is the main advantage of loops. They allow you to handle each object separately instead of all exactly the same.

Looping List Variables
List variables have the capability to hold many values. This means that you can loop through them! This is explained a bit more above in the Variable explanation.

While Loops
While loops look much closer to that diagram I posted above. While other kinds of loops go through a specified amount of objects before running out, a while loop could potentially run on forever. Just like other loops, this will keep iterating until the condition is false. Make sure to add a wait 1 tick into the code or else the server will crash from the constant while loop.

while {var} is true:
strike lightning at player
chance of 10%:
set {var} to false

In this case the loop will keep running and striking the player with lightning with only a 10% chance of stopping each time. Any condition you can use with an if statement, you can use for a while loop.

Hopefully this clears up some of the confusion around loops in Skript. You can post in the help forum, or send me a PM (LimeGlass) if you have any questions, or need some more explanation about loops.

- Demon

Functions tutorial:

If you have any questions you can post in the help thread on Skunity or private message me about anything. (Create conversation)