1. Welcome to skUnity!

    Welcome to skUnity! This is a forum where members of the Skript community can communicate and interact. Skript Resource Creators can post their Resources for all to see and use.

    If you haven't done so already, feel free to join our official Discord server to expand your level of interaction with the comminuty!

    Now, what are you waiting for? Join the community now!

Dismiss Notice
This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Advanced Skript Tutorial

Feb 21, 2019
Advanced Skript Tutorial
  • Hello and welcome to this tutorial!

    You've taken a look at Skript, you've made some cool Commands, and you generally know what you're doing (if you don't, check this out!), and you're ready to upgrade your scripting game.
    In this tutorial, I'll be showing you some advanced Skript tactics, code efficiency, and some more useful stuff that you might not have known.

    Chapter 1 - Changers

    Most expressions can be changed, and you probably recognize these changers: set, add, remove, delete and clear. They're used for changing expressions, such as
    Code (Skript):
    1. add 1 to {list::*}
    But what if I told you some are faster than others? You probably wouldn't believe me, but I'm not lying. Currently, the 'set' changer is faster than 'add' and 'remove'. So code like this,
    Code (Skript):
    1. add 1 to {_list::*}
    could be made more efficient by replacing it with e.g.
    Code (Skript):
    1. set {_list::1} to 1
    This has been proven by a test (made my @KingAlterIV) which contained the following code:
    Code (Skript):
    1. command /Variables:
    2.     trigger:
    3.         delete {test::*} # resets the values
    4.         set {_n} to now
    5.         loop 10000 times:
    6.             add loop-number to {test::*} # here the 'add' changer is used
    7.         delete {test::*} # resets the values
    8.         set {_now} to difference between {_n} and now
    9.         set {_n2} to now
    10.         loop 10000 times:
    11.             set {test::%loop-number%} to loop-number # here the 'set' changer is used
    12.         set {_now2} to difference between {_n2} and now
    13.         message ""
    14.         message "&e&l10000 &rvariables adding: %{_now}%"
    15.         message "&a&l10000 &rvariables setting: %{_now2}%"
    16.         message ""
    17.         delete {test::*}
    The results were pretty conclusive:
    Code (Text):
    1. 10000 Variables adding: 55.08 seconds
    2. 10000 Variables setting: 5.01 seconds
    The 'set' changer was in this test a whapping 1099.4% faster.
    In conclusion: you should use the 'set' changer above all changers (except delete and clear)

    Chapter 2 - Loops

    Loops are being used all the time. They're a great way for sorting information 1 by 1, and you've probably used them before. You might think the most optimal Loops look something like this:

    Code (Skript):
    1. loop all players:
    2.     if player is in world "Lobby":
    3.         send "Like this tutorial!!" to loop-player
    Code (Skript):
    1. set {_loop index} to 0
    2. loop {players::*}:
    3.     set slot {_loop index} of player's current inventory to loop-value
    4.     add 1 to {_loop index}
    But the most efficient code for these 2 examples actually looks something like this:
    Code (Skript):
    1. send "Like this tutorial!!" to all players in world "Lobby"
    Code (Skript):
    1. loop {players::*}:
    2.     set slot (loop-index parsed as int - 1) of player's current inventory to loop-value
    Most effects accept multiple players, and that's why you can use 'all players..'
    Some shortcuts:

    The expression loop-index is the index where the loop currently is, e.g.:
    Code (Skript):
    1. set {_index} to 1
    2. loop {values::*}:
    3.     # some code..
    4.     set {_index} to {_index} + 1
    This code can be simplified by just using
    Code (Skript):
    1. loop {values::*}:
    2.     # some code
    Here you can replace the variable {_index} with loop-index, so you don't have to create another variable.

    If you want indices to start, for example, at 0 (maybe for GUIs) you can achieve this with some simple math:

    Code (Skript):
    1. loop ..:
    2.     broadcast "%loop-index parsed as int - 1%"
    Being equal to
    Code (Skript):
    1. set {_index} to 0
    2. loop ..:
    3.     broadcast "%{_index}%"
    4.     set {_index} to {_index} + 1
    All players
    This expression is basically just all players. You can use this expression instead of looping all players, for example:
    Code (Skript):
    1. loop all players in world "world":
    2.     teleport loop-player to {my location}
    could be
    Code (Skript):
    1. teleport all players in world "world" to {my location}
    Every expression in vanilla Skript (the default syntax in Skript without any addons) currently supports multiple players, so you can always use it.

    Chapter 3 - Packets

    Packets.. for most people one of the hardest things to understand in Skript. But it's actually easier than you thought, thanks to some websites. Here, I'll be showing you how to use the protocol wiki from http://wiki.vg/Protocol

    You'll want to use MundoSK for packets, this addon currently supports packets the best.

    For this tutorial I'll be showing you how to modify the basics, and I'm gonna be using the packet below.

    As you can see, the packet above will spawn an experience orb only for specific players.
    You can see that it's a client packet ('Bound To' section) and to the right you can see the fields you will need to change. The Entity ID, the location, and the count. In the 'Field Type' section you can see what things you need to modify.

    These 'Field Types' will make your life easier, since they literally tell you what things you need to change.
    The current changers are these:
    Code (Skript):
    1. %type% pinfo %number% of %packet%
    2. %type% array pinfo %number% of %packet%
    3. %string% pinfo %number% of %packet%
    4. %world% pentity %number% of %packet%
    5. byte pnum %number% of %packet%
    6. short pnum %number% of %packet%
    7. int pnum %number% of %packet%
    8. long pnum %number% of %packet%
    9. float pnum %number% of %packet%
    10. double pnum %number% of %packet%
    11. byte array pnum %number% of %packet%
    12. int array pnum %number% of %packet%
    13. %string% pjson %number% of %packet%
    14. %string% array pjson %number% of %packet%
    15. %string% penum %number% of %packet%
    If you look at the picture again, you see that the 'Entity ID' needs a 'VarInt' changer, which correlates to an integer, which you can change using
    Code (Skript):
    1. set int pnum %number% of %packet% to %integer%
    If you haven't figured it out already, the 'Field Types' contain the changer. You can see that 'VarInt' contains 'int', so you'll have to use the expression
    Code (Skript):
    1. int pnum %number% of %packet%
    The X, Y and Z fields are Doubles, so you will have to use
    Code (Skript):
    1. double pnum %number% of %packet%
    And you can use this for every packet: you can look what expression you need to use that has the field type in it.

    You may have figured out that in every syntax of modifying a packet, there's a %number% expression, and this is for keeping values apart. These count from 0, and you just have to follow the order the wiki lists them in.

    So now I'll show you an example of the picture above with notes, to make it more clear.
    Code (Skript):
    1. command /I want an experience orb:
    2.     trigger:
    3.         # create a new packet, most of the times it looks like this: play_(client/server)_(packet name)
    4.         set {_packet} to new play_server_spawn_entity_experience_orb
    5.         # it's the first VarInt in the list, so use number 0
    6.         set int pnum 0 of {_packet} to 1 # sets the Entity ID of the exp orb
    7.         # this is the first Double in the list, so use number 0
    8.         set double pnum 0 of {_packet} to player's x coordinate # sets the x coordinate of where the orb will be spawned to the player's x coordinate
    9.         # this is the second Double in the list, so use 1
    10.         set double pnum 1 of {_packet} to player's y coordinate + 1 # sets the y coordinate of the orb to player's y coord + 1
    11.         # this is the third Double in the list, so use 2
    12.         set double pnum 2 of {_packet} to player's z coordinate # sets the z coordinate of the orb to player's z coord
    13.         # this is the first Short in the list, so use 0
    14.         set short pnum 0 of {_packet} to 30 # spawn 30 exp orbs
    15.         # now send the packet to the player
    16.         send player packet {_packet}
    For all packets names, you can take a look here for a list of up-to-date packets.
    For more information take a look at this tutorial