Tutorial by: eyesniper2


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:

# event
on 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

  1. After setting up your base server, download the correct version of Skript from one of the sources below

  2. Put the jar into the ‘plugins’ directory of your server
  3. 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 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 doesn't support 'else if' and 'else', and doesn't start with a "if".
# There are examples about 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 "&lt;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 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

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 characters
on 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 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 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 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.

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 "&lt;light green>Successfully removed <red>%{_count}% &lt;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}%: &lt;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:

For vanilla Skript and addons

Skript Hub tutorials: https://skripthub.net/tutorials/


Did you find eyesniper2's tutorial helpful?


You must be logged in to comment

  • Sept. 16, 2020, 5:46 a.m. - 바보  

    wow this is so great!

    |     
  • Oct. 9, 2020, 5:07 p.m. - Smasher9000x  

    Nice! This really helped me create my first Scripts!

    |     
  • April 5, 2021, 1:08 p.m. - Shapely  

    This is great! It helped me understand conditionals better and have an idea on what loops can be used for, I seem to be having a problem with the second to last skript image, specifically on line 5 and potentially line 6, the server tells me that it can't understand the expression, anyway you can help?

    |     
    Nov. 10, 2021, 5:24 a.m. - ButterflyBullets  

    well ik this is a while after you posted that and idk your even active anymore but if you would send an SS and the code you used I can review it for you and help in whatever way you need :D

    |     
  • Aug. 28, 2021, 6:16 p.m. - Mr_0090  

    nice

    |     
  • Jan. 4, 2022, 7:35 p.m. - Muhv  

    Nice job!

    |     
  • July 9, 2022, 8:53 a.m. - Teceem  

    tbh it whent from bigginer lvl to hard

    |     
  • April 15, 2024, 2:06 p.m. - Nenemchocolito  

    Please make more tutorials!
    :D

    |