[Paper 플러그인 실전 제작기 #01] Java 21 + Maven으로 첫 플러그인 만들기

2026. 2. 20. 20:32Java/마인크래프트

Paper 플러그인 실전 제작기 1편입니다.
이번 편 목표는 딱 3가지입니다.

  1. Java 21 + Maven + Paper 개발 환경 준비
  2. 플러그인이 서버에서 로딩되는지 확인
  3. /ping 명령어를 실제로 동작시키기

1) 준비물

  • Java 21
  • IDE (IntelliJ 권장)
  • 테스트용 Paper 서버 (1.21.x 이상 권장)
  • Maven 프로젝트

2) Maven 프로젝트 생성

프로젝트를 만든 뒤 pom.xml을 아래처럼 설정합니다.

<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>com.example</groupId>
    <artifactId>skullvillage-core</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <name>SkullVillageCore</name>

    <properties>
        <maven.compiler.source>21</maven.compiler.source>
        <maven.compiler.target>21</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>

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

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

3) plugin.yml 작성

src/main/resources/plugin.yml

name: SkullVillageCore
version: 1.0.0
main: com.example.skullvillage.SkullVillageCore
api-version: '1.21'
commands:
  ping:
    description: 서버 응답 확인
    usage: /ping

4) 메인 클래스 작성

src/main/java/com/example/skullvillage/SkullVillageCore.java

package com.example.skullvillage;

import org.bukkit.command.Command;
import org.bukkit.command.CommandSender;
import org.bukkit.plugin.java.JavaPlugin;

public class SkullVillageCore extends JavaPlugin {

    @Override
    public void onEnable() {
        getLogger().info("SkullVillageCore enabled");
    }

    @Override
    public void onDisable() {
        getLogger().info("SkullVillageCore disabled");
    }

    @Override
    public boolean onCommand(CommandSender sender, Command command, String label, String[] args) {
        if (command.getName().equalsIgnoreCase("ping")) {
            sender.sendMessage("Pong!");
            return true;
        }
        return false;
    }
}

5) 빌드 및 서버 적용

  1. 프로젝트 루트에서 빌드
mvn clean package
  1. target/ 폴더의 jar 파일을 서버 plugins/ 폴더로 복사
  2. 서버 실행
  3. 게임에서 /ping 입력
  4. Pong! 출력 확인

6) 자주 막히는 포인트

  • plugin.ymlmain 경로와 실제 패키지 경로가 다르면 로딩 실패
  • Java 버전이 서버/IDE/Maven에서 서로 다르면 빌드 또는 실행 오류
  • API 의존성은 provided 스코프로 두는 것이 기본

마무리

1편에서는 가장 작은 단위의 “동작하는 플러그인”을 만들었습니다.
다음 편에서는 /heal 명령어를 기준으로 권한, 인자 파싱, 탭완성까지 실전 구조로 확장해보겠습니다.