Skript: podstawy skryptowania dla adminów serwerów Minecraft (2026)
Skript pozwala dorzucić logikę do serwera bez ani jednej linii Javy. Piszesz prawie po angielsku do pliku .sk, wrzucasz do plugins/Skript/scripts/, robisz /sk reload i działa. Dla admina, który chce dodać powitanie na wejściu, własny /heal, licznik killi albo małą ekonomię bez szukania javowca, to najszybsza droga od pomysłu do działającej mechaniki.
W 2026 aktywna gałąź to Skript 2.9.x i wyżej od ekipy SkriptLang (github.com/SkriptLang/Skript), wspiera Paper 1.21+, Folia tylko w eksperymentalnych branchach. Niżej: instalacja, układ pliku .sk, składnia, dodatki (skBee, skript-yaml, skript-reflect, skquery) i typowe pułapki wydajnościowe.
Czym Skript jest naprawdę i komu się przyda
Skript to plugin-interpreter. Czyta pliki .sk, parsuje je jako DSL wyglądający jak angielski i przekłada na eventy, komendy i efekty Bukkit/Paper. Dla admina to znaczy: mechanikę, na którą inaczej trzeba by szukać programisty, składasz w jeden wieczór.
Komu się to faktycznie opłaca:
- Admin małego SMP, który potrzebuje 3 do 5 własnych komend i kilku triggerów.
- Admin publicznego serwera, który chce szybko wystawiać eventy (podwójny XP w weekend, killstreaki, easter eggi).
- Programista prototypujący pomysł, zanim wejdzie pełen plugin w Javie.
Komu nie: budowniczy systemów walki MMORPG z tysiącami graczy jednocześnie i ciężką logiką per tick. Skript wytrzymuje typowe SMP i minigry, ale gorące ścieżki należy potem przepisać do Javy.
Instalacja i pierwsze /sk reload
Najnowszą wersję bierzesz z GitHub releases na github.com/SkriptLang/Skript/releases albo z Modrintha na modrinth.com/plugin/skript. W 2026 mówimy o Skript 2.9.x na Paper 1.21+.
JAR do plugins/, raz odpalasz serwer, plugin tworzy swój folder. Layout po pierwszym starcie:
plugins/Skript/
├── config.sk # globalna konfiguracja
├── aliases-english.sk # nazwy itemów
├── scripts/
│ ├── -disabled-script.sk # myślnik z przodu = wyłączony
│ └── examples/
└── lang/
Pierwszy plik plugins/Skript/scripts/welcome.sk:
on join:
send "&aWelcome %player% to the server!" to player
add 1 to {joins::%player's uuid%}
W konsoli albo w grze z permem skript.admin:
/sk reload welcome
Skript powie ile triggerów wczytał i czy były błędy. Wchodzisz na serwer, widzisz zielone powitanie. To twój pierwszy działający skrypt.
Struktura pliku .sk: events, commands, functions
Plik .sk to stos bloków na top-levelu. Każdy blok zaczyna się w kolumnie 0, wszystko w środku ma wcięcie dokładnie 4 spacje albo 1 tab. Skript jest w tym bezlitosny: mieszanie tabów i spacji w jednym pliku daje inconsistent indentation i plik się nie ładuje.
Trzy typy bloków:
1. Event handler. Reaguje na event serwera.
on death of a player:
broadcast "&c%victim% died at %location of victim%"
2. Command. Rejestruje własną komendę.
command /fly [<player>]:
permission: server.fly
permission message: &cYou cannot fly here.
trigger:
if arg-1 is set:
set {_target} to arg-1
else:
set {_target} to player
if {_target} is flying:
set flight mode of {_target} to false
send "&7Flight disabled for &e%{_target}%" to player
else:
set flight mode of {_target} to true
send "&aFlight enabled for &e%{_target}%" to player
3. Function. Logika do reużycia, czyli procedura.
function welcomeMessage(p: player):
send "&aWelcome back, %{_p}%!" to {_p}
if difference between {lastSeen::%{_p}'s uuid%} and now is greater than 7 days:
send "&7You were gone for a while. Server is on Paper 1.21.4 now." to {_p}
set {lastSeen::%{_p}'s uuid%} to now
on join:
welcomeMessage(player)
Nazwa pliku nie wpływa na zachowanie, tylko na ergonomię /sk reload <file>. Myślnik z przodu wyłącza skrypt bez kasowania.
Typy danych: player, item, location, block, vector, number, text
Skript jest typowany, ale inferencja robi większość roboty. Podstawy:
| Typ | Przykład | Gdzie się pojawia |
|---|---|---|
player | player, arg-1, victim | event handlery, cele komend |
item | 1 diamond, player's tool | inventory, dropy |
location | location of player, block's location | teleport, spawn moba |
block | targeted block, event-block | placement, break |
vector | vector(0, 1, 0) | velocity, knockback |
number | 42, player's health | liczniki, koordynaty |
text | "hello", "&a%player%" | wiadomości, nazwy |
entity | attacker, loop-entity | moby, NPC |
world | world "world_nether" | sprawdzanie świata |
timespan | 5 seconds, 2 minutes | opóźnienia, cooldowny |
chatcolor | red, &c | formatowanie |
Konwersje robią wyrażenia typu block at location, location of entity, name of item. Jawne castowanie nie jest potrzebne.
Realny handler on join
Powitanie z wykryciem pierwszego wejścia, wariantem VIP i trackowaniem online:
on first join:
broadcast "&6%player% &ejoined for the first time! Welcome!"
give 1 stone pickaxe of efficiency 1 to player
give 16 cooked beef to player
teleport player to {spawn}
on join:
if player has permission "server.vip":
send "&6&l[VIP] &eWelcome back, %player%" to player
else:
send "&aWelcome back, %player%" to player
add 1 to {stats::joins::%player's uuid%}
set {stats::lastjoin::%player's uuid%} to now
wait 2 ticks
set tab list header "&aServer Online" and footer "&7Players: %size of all players%" for player
on quit:
set {stats::lastquit::%player's uuid%} to now
first join odpala raz na UUID, join przy każdym wejściu. Nie kolidują, oba lecą dla nowego gracza.
Własne komendy: /heal z permami i argumentami
Skript rejestruje komendy automatycznie przy ładowaniu skryptu, plugin.yml zostawiasz w spokoju.
command /heal [<player>] [<integer>]:
description: Heals a player to full or to a specific amount
aliases: /h
permission: server.heal
permission message: &cMissing permission &7server.heal
cooldown: 30 seconds
cooldown message: &cWait %remaining time% before using /heal again.
cooldown bypass: server.heal.bypass
trigger:
if arg-1 is set:
if sender does not have permission "server.heal.others":
send "&cYou cannot heal others." to sender
stop
set {_target} to arg-1
else:
if sender is not a player:
send "&cConsole must specify a player." to sender
stop
set {_target} to sender
if arg-2 is set:
set health of {_target} to arg-2
else:
heal {_target}
feed {_target}
send "&aHealed %{_target}%" to sender
if {_target} is not sender:
send "&aYou were healed by &e%sender%" to {_target}
Co ważne: cooldown jest wbudowany, permission message pokazuje się przy braku perma, aliases daje /h, stop przerywa trigger. Argumenty przez arg-1, arg-2.
Zmienne: lokalne, listy, persystentne
Trzy rodzaje:
Lokalna ({_name}) żyje tylko w bieżącym triggerze albo funkcji:
on damage:
set {_dmg} to damage
set {_attacker} to attacker
if {_dmg} is greater than 10:
send "Big hit by %{_attacker}%" to victim
Globalna ({name}) jest persystowana do variables.csv i przeżywa restarty:
set {spawn} to location of player
set {server.motd} to "&aPaper 1.21.4"
Listowa/indeksowana ({name::%key%} albo {name::*}) działa jak słownik:
add 1 to {kills::%attacker's uuid%}
loop {kills::*}:
send "%loop-index%: %loop-value%" to player
clear {kills::%player's uuid%}
delete {kills::%player's uuid%}
Twardy nawyk: zawsze klucz po uuid, nigdy po nicku. Gracz zmieni nick i tracisz dane. Ciężkich obiektów typu pełen inventory nie pakuj do persystentnych zmiennych bez powodu, plik puchnie.
W poważnych projektach przenieś stan persystentny do SQL przez skript-db albo do YAML przez skript-yaml. CSV wytrzyma 50 do 100 tysięcy wpisów, dalej ładowanie boli.
Przydatne dodatki: skBee, skript-yaml, skript-reflect, skquery
Goły Skript pokrywa może 70% potrzeb. Reszta to dodatki.
| Dodatek | Do czego | Link |
|---|---|---|
| skBee | NBT, scoreboardy, world border, recipes, fastboards, particle | github.com/ShaneBeee/skBee |
| skript-yaml | Czytanie i zapis YAML | github.com/SkriptLang/skript-yaml |
| skript-reflect | Refleksja Javy (surowe Bukkit API) | github.com/TPGamesNL/skript-reflect |
| skquery | Stare rozszerzenia, częściowo pokryte przez skBee | github.com/Tuke-Nuke/SkQuery |
| skript-placeholders | Most do PlaceholderAPI | github.com/APickledWalrus/skript-placeholders |
| skript-db | MySQL/SQLite | github.com/btk5h/skript-db |
W 2026 skBee 3.x zastępuje większość tego, co kiedyś robił skquery, plus nowoczesne API Papera. Tylko jeden dodatek? Niech to będzie skBee.
Scoreboard ze skBee:
on join:
create new scoreboard named "stats_%player's uuid%"
set line 1 of player's scoreboard to "&7&m-----------"
set line 2 of player's scoreboard to "&aKills: &f%{kills::%player's uuid%} ? 0%"
set line 3 of player's scoreboard to "&cDeaths: &f%{deaths::%player's uuid%} ? 0%"
set line 4 of player's scoreboard to "&7&m-----------"
set title of player's scoreboard to "&6Server Stats"
set player's displayed scoreboard to player's scoreboard
Typowe wzorce: licznik killi, mała ekonomia, welcome
Licznik killi z topką.
on death of a player:
if attacker is a player:
add 1 to {kills::%attacker's uuid%}
add 1 to {deaths::%victim's uuid%}
send "&a+1 kill &7(total: %{kills::%attacker's uuid%}%)" to attacker
command /killtop:
trigger:
send "&6&l=== Top 10 Killers ===" to player
set {_sorted::*} to sorted indexes of {kills::*} in descending order
loop {_sorted::*}:
if loop-iteration > 10:
stop loop
set {_uuid} to loop-value
set {_name} to name of offline player from uuid {_uuid}
send "&e%loop-iteration%. &f%{_name}% &7- &c%{kills::%{_uuid}%}% kills" to player
Ekonomia bez Vault.
on join:
if {money::%player's uuid%} is not set:
set {money::%player's uuid%} to 100
command /balance [<player>]:
aliases: /bal, /money
trigger:
if arg-1 is set:
set {_t} to arg-1
else:
set {_t} to player
send "&aBalance of &e%{_t}%&a: &6%{money::%{_t}'s uuid%} ? 0%$" to player
command /pay <player> <integer>:
trigger:
if arg-1 is sender:
send "&cYou cannot pay yourself." to sender
stop
if arg-2 is less than 1:
send "&cAmount must be positive." to sender
stop
if {money::%sender's uuid%} is less than arg-2:
send "&cNot enough money." to sender
stop
remove arg-2 from {money::%sender's uuid%}
add arg-2 to {money::%arg-1's uuid%}
send "&aPaid &6%arg-2%$ &ato &e%arg-1%" to sender
send "&aReceived &6%arg-2%$ &afrom &e%sender%" to arg-1
Wydajność i pułapki
Skript jest mocny, ale naiwny kod kładzie TPS. Twarde reguły:
1. Nie loopuj wszystkich graczy co tick.
Źle:
every tick:
loop all players:
set action bar of loop-player to "&aServer"
Dobrze:
every 5 seconds:
loop all players:
set action bar of loop-player to "&aServer"
Tick to 20 razy na sekundę. Action bar przy 2 do 4 Hz wygląda tak samo i kosztuje rząd wielkości mniej.
2. Async, kiedy się da.
Ciężkie rzeczy (HTTP, duże YAML, SQL) lecą w async:
command /lookup <text>:
trigger:
send "&7Looking up..." to player
set {_p} to player
execute async:
set {_data} to text from "https://api.example.com/lookup/%arg-1%"
execute sync:
send "&aResult: &f%{_data}%" to {_p}
Bez async serwer zamarza na cały czas requestu.
3. Itemów i inventory nie wciskaj do persystentnych zmiennych bez potrzeby. Serializacja jest droga, variables.csv puchnie. Lootboksy trzymaj jako recepturę (typ plus ilość plus meta), nie żywy ItemStack.
4. wait zamiast zagnieżdżonych every. Źle: every 1 second: w on join:. Dobrze: wait 1 second albo timer na zmiennej.
5. Profilowanie przez spark. /spark profiler --thread server pokazuje, czy Skript zjada tick. Dużo Trigger.execute w stacku oznacza ciężki event handler, prawie zawsze every tick albo gruby on damage.
Debugowanie: /sk reload, /sk debug
Komendy admina, perm skript.admin:
/sk reload allprzeładowuje wszystkie skrypty./sk reload <name>ładuje jeden plik (bez.sk)./sk reload configprzeczytujeconfig.skbez restartu plugina./sk disable <name>dokleja myślnik i wyładowuje./sk enable <name>cofa./sk infopokazuje wersję i listę dodatków./sk update checksprawdza aktualizacje.
Jeśli skrypt się nie ładuje, błędy lecą do konsoli z numerem linii. Klasyki: zmieszane wcięcie, literówka w nazwie eventu, brak dodatku do składni z forum.
Przy głębszym debugu rzucasz telemetrię:
on damage:
broadcast "DEBUG: %attacker% hit %victim% for %damage% (final: %final damage%)"
if attacker is a player:
broadcast "DEBUG: weapon = %attacker's tool%, projectile = %projectile%"
W produkcji broadcast zamień na send to console albo skasuj. Jest też skUnity Parser do sprawdzenia składni bez ruszania serwera.
FAQ
Czy Skript nadaje się na duży publiczny serwer?
Na typowe PvP/SMP/minigry przy 100 do 300 jednocześnie spokojnie, jeśli trzymasz reguły wydajności. Przy 1000+ jednocześnie z tysiącami eventów na sekundę gorące ścieżki przepisujesz do Javy, a Skript zostaje na rzadkie eventy i własne komendy.
Gdzie szukać gotowych skryptów?
skUnity Forums, SkriptHub, GitHub. Przed deployem czytaj kod. Forum często zawiera ukryty every tick po wszystkich graczach, który zabija TPS.
Czemu Skript krzyczy inconsistent indentation?
Masz mieszane taby i spacje. Otwórz plik w edytorze z włączonym pokazem białych znaków (VS Code: View > Render Whitespace) i wybierz jeden styl. 4 spacje to bezpieczny domyślny.
Co ze zmiennymi po hard crashu?
Skript flushuje variables.csv cyklicznie, domyślnie co 5 minut (save interval w config.sk). 1 minutę da się ustawić, kosztem IO. Naprawdę krytyczny stan przepuść przez skript-db do SQL albo rsynkuj CSV co 10 minut.
Czy Skript działa na Folii?
Stan na 2026: mainline SkriptLang/Skript nie wspiera Folii w pełni, tylko branche eksperymentalne. Serwery region-aware idą z ograniczeniami (brak dostępu cross-region bez właściwego schedulera). Przed migracją sprawdź github.com/SkriptLang/Skript/issues.
Jak chronić serwer ze Skriptem przed DDoS?
Skript pracuje na warstwie eventów gry i z floodami L4 nic nie zrobi. Przed serwer wstaw filtr sieciowy, np. MineGuard. Skript to logika ingame, nie hydraulika pakietowa.
Skript pozostaje najszybszym sposobem zamiany pomysłu w działającą mechanikę bez startu projektu Java. Zainstaluj, napisz pierwszy welcome.sk, potem /heal, potem licznik killi i po tygodniu masz stos własnej logiki dopasowanej do twojego serwera. Tylko trzymaj every tick z dala od ciężkich loopów i nie zapominaj o async, kiedy w grę wchodzi dysk albo sieć.
Chroń swój serwer przed atakami DDoS
Darmowa ochrona z konfiguracją w 5 minut. 1 TB ruchu w zestawie.
Wypróbuj za darmoPowiązane artykuły
Mój serwer Minecraft jest pod DDoS: co robić teraz
Plan działań krok po kroku, jeśli twój serwer Minecraft właśnie jest pod atakiem DDoS. Jak rozpoznać typ ataku, co zrobić w pierwszych minutach i jak się zabezpieczyć, żeby to się nie powtórzyło.
DiscordSRV: konfiguracja bota Discord dla serwera Minecraft
Pelny przewodnik DiscordSRV: instalacja pluginu, tworzenie bota w Developer Portal, konfiguracja mostu czatu, synchronizacja rol i wiazanie kont. Z typowymi bledami.
Slimefun: kompletny przewodnik po pluginie dla serwera Minecraft 2026
Slimefun4 na Paper 1.21: instalacja, GuideBook, badania, sieć cargo, energia, dodatki ExoticGarden i InfinityExpansion oraz jak nie zabić TPS.