Toată documentația
Toate ghidurile

Învață programare

Primul tău plugin Minecraft cu Paper

Creezi un plugin Java pentru un server Paper, cu o comandă și un eveniment de intrare, îl compilezi și îl pui pe server.

Un plugin este un program mic scris în Java, pe care serverul de Minecraft îl încarcă la pornire. Cu un plugin poți adăuga comenzi, mesaje, reguli și mecanici noi, fără să modifici jocul în sine. În acest ghid faci un plugin care salută jucătorii și are o comandă proprie.

Presupunem că ai citit „Ce este programarea” și ai pregătit calculatorul cu „Mediu de lucru pe Windows”. Nu trebuie să știi Java: îți arătăm doar ce ai nevoie.

Ce este Paper și ce este un plugin

Paper este un server de Minecraft Java, rapid și compatibil cu pluginurile din familia Bukkit și Spigot. Pluginurile se scriu împotriva unui API (un set de clase puse la dispoziție de Paper), apoi se împachetează într-un fișier .jar și se copiază în folderul plugins al serverului.

Un plugin are trei piese minime: un fișier plugin.yml care îl descrie, o clasă principală care pornește, și restul codului tău (comenzi, evenimente).

Java în cinci minute. Doar atât îți trebuie ca să citești codul de mai jos.

  • Clasa (class) este un șablon de cod. Fiecare fișier .java conține o clasă cu același nume ca fișierul.
  • Metoda este o funcție din clasă. Ea are tip de întoarcere, nume și parametri: void onEnable() nu întoarce nimic.
  • import aduce o clasă din altă parte, ca să o poți folosi. package spune în ce folder logic se află clasa ta.
  • extends înseamnă „moștenește”: clasa ta primește tot ce are clasa de bază. implements înseamnă „respect un contract”.
  • @Override și @EventHandler sunt adnotări: etichete care spun compilatorului sau serverului ce rol are metoda.
  • Textul se scrie între ghilimele și se lipește cu plus: "Salut, " + nume.

Pregătirea mediului

  1. Instalează un JDK (kitul de dezvoltare Java). O sursă comună este adoptium.net. Ia versiunea cerută de versiunea de Paper pentru care scrii; o găsești în documentația Paper.
  2. Alege un editor care știe Java: IntelliJ IDEA sau VS Code cu extensiile pentru Java sunt amândouă potrivite. Alege-l pe cel cu care te simți bine.
  3. Instalează Maven (sau lasă editorul să-l aducă). Maven este unealta care descarcă bibliotecile și construiește fișierul .jar.
  4. Verifică în terminal: java -version și mvn -version trebuie să afișeze versiuni, nu erori.
  5. Pregătește un server Paper de test pe care îl poți reporni fără grijă, nu serverul cu jucători reali.

Nu scriem aici un număr de versiune de Minecraft sau de Paper, pentru că se schimbă des. Ia versiunea curentă și cerința de Java din documentația oficială Paper (docs.papermc.io) și folosește-o peste tot unde vezi VERSIUNE_PAPER, VERSIUNE_API și VERSIUNE_JAVA mai jos.

Structura proiectului. Proiectul Maven are un aspect standard. Numele pachetului (ro.exemplu.salut) îl poți schimba cu al tău.

structuratext
salutplugin/
  pom.xml
  src/main/java/ro/exemplu/salut/
    SalutPlugin.java
    SalutCommand.java
    JoinListener.java
  src/main/resources/
    plugin.yml

Fișierul pom.xml

pom.xml spune lui Maven de ce are nevoie proiectul. Fragmentul este un schelet: înlocuiește VERSIUNE_PAPER și VERSIUNE_JAVA și, la nevoie, copiază blocul exact pentru dependență din documentația Paper, care este sursa corectă și actualizată.

pom.xmlxml
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>

  <groupId>ro.exemplu</groupId>
  <artifactId>salutplugin</artifactId>
  <version>1.0.0</version>
  <packaging>jar</packaging>

  <properties>
    <maven.compiler.release>VERSIUNE_JAVA</maven.compiler.release>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

  <repositories>
    <repository>
      <id>papermc</id>
      <url>https://repo.papermc.io/repository/maven-public/</url>
    </repository>
  </repositories>

  <dependencies>
    <dependency>
      <groupId>io.papermc.paper</groupId>
      <artifactId>paper-api</artifactId>
      <version>VERSIUNE_PAPER-R0.1-SNAPSHOT</version>
      <scope>provided</scope>
    </dependency>
  </dependencies>
</project>

scope provided înseamnă că API-ul există deja pe server, deci nu se pune în jar. Dacă preferi Gradle, aceeași dependență se declară în fișierul build, cu repository-ul Paper și paper-api; documentația Paper are ambele variante.

Fișierul plugin.yml. Acesta merge în src/main/resources. Fără el serverul refuză pluginul. Pentru început folosim plugin.yml clasic; Paper are și un format mai nou, dar nu ai nevoie de el acum.

plugin.ymlyaml
name: SalutPlugin
version: '1.0.0'
main: ro.exemplu.salut.SalutPlugin
api-version: 'VERSIUNE_API'
description: Salută jucătorii
commands:
  salut:
    description: Îți trimite un salut
    usage: /salut
  • name este numele pluginului, așa cum apare în listă.
  • main este calea completă a clasei principale: pachet plus nume de clasă. O greșeală aici blochează încărcarea.
  • api-version trebuie să corespundă versiunii de Minecraft pe care o țintești, în formatul din documentația Paper.
  • commands declară comenzile; fără declarare, comanda nu există pentru server.

Clasa principală

onEnable rulează când pluginul pornește, onDisable când se oprește. Acolo înregistrăm comanda și evenimentele.

SalutPlugin.javajava
package ro.exemplu.salut;

import org.bukkit.plugin.java.JavaPlugin;

public class SalutPlugin extends JavaPlugin {

    @Override
    public void onEnable() {
        getLogger().info("SalutPlugin a pornit!");
        getCommand("salut").setExecutor(new SalutCommand());
        getServer().getPluginManager().registerEvents(new JoinListener(), this);
    }

    @Override
    public void onDisable() {
        getLogger().info("SalutPlugin s-a oprit.");
    }
}

getLogger().info scrie un mesaj în consola serverului, cu prefixul pluginului. Este prima ta unealtă de depanare.

Comanda /salut. O comandă este o clasă care implementează CommandExecutor. Metoda onCommand primește cine a scris comanda (sender), numele și argumentele. Întoarce true dacă ai tratat comanda; false ar afișa mesajul „usage” din plugin.yml.

SalutCommand.javajava
package ro.exemplu.salut;

import org.bukkit.command.Command;
import org.bukkit.command.CommandExecutor;
import org.bukkit.command.CommandSender;
import org.bukkit.entity.Player;

public class SalutCommand implements CommandExecutor {

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (!(sender instanceof Player)) {
            sender.sendMessage("Comanda poate fi folosită doar de un jucător.");
            return true;
        }
        Player player = (Player) sender;
        player.sendMessage("Salut, " + player.getName() + "!");
        return true;
    }
}

Comanda poate fi lansată și din consola serverului, unde nu există un jucător. De aceea verificăm cu instanceof înainte să o tratăm ca jucător.

Paper preferă mesaje construite cu biblioteca Adventure (obiecte Component), care permit culori și text clicabil. Dacă IDE-ul marchează sendMessage cu un text simplu ca depășit, treci la Component; tutorialul din documentația Paper arată cum. Pentru primul plugin, textul simplu este suficient pentru înțelegere.

Evenimentul de intrare. Un eveniment este ceva ce se întâmplă în joc: un jucător intră, sparge un bloc, vorbește. Scrii o clasă Listener cu o metodă marcată @EventHandler, al cărei parametru arată ce eveniment asculți. Am înregistrat-o deja în onEnable.

JoinListener.javajava
package ro.exemplu.salut;

import org.bukkit.entity.Player;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerJoinEvent;

public class JoinListener implements Listener {

    @EventHandler
    public void onJoin(PlayerJoinEvent event) {
        Player player = event.getPlayer();
        player.sendMessage("Bun venit pe server, " + player.getName() + "!");
    }
}

Construirea fișierului jar

  1. Deschide un terminal în folderul salutplugin (cel cu pom.xml).
  2. Rulează mvn package. Prima dată Maven descarcă biblioteci, deci durează.
  3. La final vezi BUILD SUCCESS. Fișierul gata de folosit este target/salutplugin-1.0.0.jar.
  4. Dacă vezi BUILD FAILURE, citește prima linie ERROR: de obicei arată fișierul și linia cu problema.

Acest ghid nu a putut compila codul pe un JDK în momentul scrierii. Clasele sunt scrise cu API-ul clasic Bukkit, dar compilează-le tu cu mvn package și testează-le pe un server Paper înainte să le folosești. Dacă o clasă nu e găsită, verifică versiunea din dependență.

Instalarea pe server

Pe orice server Paper pașii sunt aceiași: copiezi fișierul în folderul plugins și repornești serverul.

  1. Oprește serverul de test sau fii pregătit să-l reiei.
  2. Copiază target/salutplugin-1.0.0.jar în folderul plugins al serverului.
  3. Pornește sau repornește serverul. Evită comanda /reload pentru pluginuri: poate lăsa serverul într-o stare ciudată. O repornire completă e mai sigură.
  4. Urmărește consola: ar trebui să vezi mesajul SalutPlugin a pornit! și pluginul în lista din comanda plugins.
  5. Intră în joc, scrie /salut și verifică răspunsul. La intrare primești și mesajul de bun venit.

Pe un server din GamePanel

GamePanel poate crea un server Minecraft cu Paper (alegi framework-ul Paper în pagina de creare). Din panou poți porni, opri și reporni serverul, iar consola live îți arată jurnalul în timp real, deci acolo cauți mesajul pluginului tău. Managerul de fișiere al panoului listează, citește, salvează, șterge și descarcă fișierele serverului.

Pagina Mods a panoului arată, pentru Minecraft, că pluginurile se pun în folderul plugins (sau mods pentru modificările de tip Forge sau Fabric), în format .jar. Pentru a copia fișierul .jar propriu-zis pe server folosește metoda pe care ți-o oferă găzduirea ta; după copiere, repornește serverul din panou.

Dacă ai un server public, încearcă mai întâi pluginul pe un server de test. Un plugin cu greșeli poate bloca serverul sau poate șterge date.

Citirea consolei și depanarea

  • Could not load plugins/...jar: serverul nu a putut citi pluginul. Cauze frecvente: lipsește plugin.yml sau are o greșeală de scriere.
  • Invalid plugin.yml sau cannot find main class: valoarea main nu se potrivește cu pachetul și numele clasei.
  • Unsupported API version: api-version din plugin.yml nu corespunde serverului. Ia formatul din documentația Paper.
  • UnsupportedClassVersionError: ai compilat cu o versiune de Java mai nouă decât cea de pe server. Scade VERSIUNE_JAVA sau urcă Java pe server.
  • release version N not supported (la Maven) înseamnă că JDK-ul instalat este mai vechi decât valoarea maven.compiler.release din pom.xml; instalează un JDK cel puțin la fel de nou.
  • NullPointerException la getCommand: comanda nu e declarată în plugin.yml sau numele diferă.
  • Adaugă getLogger().info(...) în punctele suspecte și vezi în consolă până unde ajunge programul.

Pașii următori

  • Citește un fișier config.yml și lasă proprietarul serverului să schimbe mesajul de bun venit.
  • Adaugă argumente la comandă și verifică permisiuni cu hasPermission.
  • Învață evenimente noi: blocuri sparte, mesaje de chat, moartea unui jucător.
  • Treci la mesaje cu Adventure și la comenzi cu sugestii de completare (tab complete).
  • Dacă îți place programarea în Java, citește o carte gratuită de bază și rezolvă mici exerciții în afara Minecraft.