1. 개요
Paper API는 PaperMC의 마인크래프트 자바 에디션 서버 구현체인 Paper에서 제공하는 플러그인 개발용 API이다. Bukkit API 및 Spigot API와의 호환성을 바탕으로 하면서, Paper에서 추가한 기능과 최신 마인크래프트 서버 구조에 맞춘 기능을 제공한다.2. Bukkit API, Spigot API와의 관계
Paper는 오랫동안 Spigot을 기반으로 개발되었기 때문에 Paper API 역시 Bukkit API와 Spigot API의 영향을 강하게 받았다. 일반적인 플러그인 개발 방식도 Bukkit 계열과 비슷하다. 플러그인의 메인 클래스는 보통 JavaPlugin을 상속하며, 이벤트 리스너, 명령어, 권한, 설정 파일 등을 이용해 서버 기능을 확장한다.기존 Bukkit 또는 Spigot 플러그인은 Paper 서버에서 대체로 사용할 수 있다. 그러나 반대로 Paper API에만 존재하는 기능을 사용한 플러그인은 Spigot에서 사용할 수 없거나, 별도의 호환 처리가 필요하다. 특히 Paper가 1.21.4부터 Spigot의 향후 변경 사항에 종속되지 않는 하드포크를 진행하면서, 장기적으로는 Paper API와 Spigot API 사이의 차이가 더 커질 가능성이 있다.
PaperMC 측은 플러그인 개발자에게 Paper 서버를 대상으로 개발할 경우 Spigot API가 아니라 Paper API 의존성을 기준으로 컴파일할 것을 권장한다.
3. 개발 환경
Paper 플러그인은 일반적으로 Java와 Gradle을 사용해 개발한다. PaperMC 공식 문서는 Gradle Kotlin DSL을 기준으로 개발 환경을 설명하고 있으며, Paper API는 PaperMC의 Maven 저장소에서 compileOnly 의존성으로 추가한다.repositories {
maven {
name = "papermc"
url = uri("https://repo.papermc.io/repository/maven-public/")
}
}
dependencies {
compileOnly("io.papermc.paper:paper-api:버전")
}
compileOnly 를 사용하는 이유는 Paper API가 서버 자체에 포함되어 있으므로, 플러그인 JAR 안에 API를 함께 넣을 필요가 없기 때문이다.
플러그인의 기본 구조는 Bukkit 계열 플러그인과 유사하다. src/main/java에는 Java 소스 코드를, src/main/resources에는 plugin.yml 또는 paper-plugin.yml같은 리소스 파일을 둔다.
4. plugin.yml
기존 Bukkit 방식의 플러그인은 plugin.yml 파일을 사용한다. 이 파일에는 플러그인의 이름, 버전, 메인 클래스, 설명, 제작자, API 버전, 명령어, 권한, 의존 플러그인 등의 정보가 들어간다.예시는 다음과 같다.
name: ExamplePlugin
version: 1.0.0
main: io.github.example.ExamplePlugin
description: Example Paper plugin
author: Example
api-version: '1.21'
api-version 은 플러그인이 대상으로 하는 API 버전을 나타낸다. 서버 버전이 플러그인이 요구하는 버전보다 낮으면 플러그인이 로드되지 않을 수 있다.
5. Paper 플러그인
Paper는 기존 plugin.yml 방식과 별개로 paper-plugin.yml을 사용하는 Paper 전용 플러그인 구조를 제공한다.Paper 플러그인은 부트스트래퍼와 로더를 선언할 수 있다. 부트스트래퍼는 서버가 완전히 시작되기 전 단계에서 플러그인이 필요한 작업을 수행할 수 있게 하며, 로더는 외부 라이브러리 추가 등 플러그인의 클래스패스 구성을 제어하는 데 사용된다.
paper-plugin.yml 에서는 의존성도 bootstrap과 server 단계로 나누어 선언할 수 있다. 이는 플러그인이 어느 시점에 다른 플러그인에 의존하는지를 더 명확하게 지정하기 위한 구조이다.
다만 Paper 플러그인 구조는 기존 Bukkit 플러그인 방식과 차이가 있으며, 모든 플러그인이 반드시 이 방식을 사용해야 하는 것은 아니다. 일반적인 플러그인은 여전히 plugin.yml 기반으로 개발할 수 있다.
6. 주요 기능
6.1. Adventure
Paper API는 메시지와 텍스트 처리를 위해 Adventure 라이브러리를 적극적으로 사용한다. Adventure는 색상, 클릭 이벤트, 호버 이벤트, 번역 가능한 텍스트 등을 컴포넌트 기반으로 표현하는 라이브러리이다. 기존 Bukkit 계열에서 흔히 사용되던 문자열 기반 색상 코드보다 구조화된 방식으로 채팅 메시지, 타이틀, 액션바 등을 다룰 수 있다.6.2. 이벤트와 스케줄러
Paper API는 Bukkit API와 마찬가지로 이벤트 기반 구조를 사용한다. 플레이어 접속, 블록 설치, 엔티티 피해, 명령어 실행 등 서버에서 발생하는 동작을 이벤트로 감지하고 처리할 수 있다. 또한 BukkitScheduler를 통해 특정 작업을 일정 시간 뒤에 실행하거나 반복 실행할 수 있다.6.3. 레지스트리 API
Paper는 마인크래프트의 레지스트리를 다루기 위한 API를 제공한다. 레지스트리는 아이템, 생물 군계, 마법 부여 등 같은 종류의 항목을 키로 관리하는 구조이다. Paper의 레지스트리 API를 사용하면 플러그인이 서버의 레지스트리 값을 조회하거나, 일부 레지스트리에 항목을 추가,수정할 수 있다.이 기능은 데이터 팩과 유사하게 서버가 클라이언트에 전달하는 데이터 기반 요소를 다루는 데 중요하다. 예를 들어 커스텀 마법 부여나 생물 군계 같은 기능은 레지스트리 API와 밀접하게 관련된다.
6.4. 명령어 API
기존 Bukkit 플러그인은 plugin.yml 에 명령어를 선언한 뒤 명령어 실행기를 등록하는 방식을 주로 사용했다. Paper는 Brigadier 기반 명령어 API도 제공한다. Brigadier는 마인크래프트 본편의 명령어 시스템에 사용되는 라이브러리로, 명령어 인수 구조와 자동 완성, 파싱 등을 더 세밀하게 다룰 수 있다.Paper 플러그인에서는 paper-plugin.yml의 commands 필드를 사용하지 않고 Brigadier Command API를 통해 명령어를 등록하는 방식이 사용된다.
6.5. paperweight-userdev
Paper API만으로는 접근할 수 없는 서버 내부 코드, 이른바 NMS를 사용해야 하는 경우에는 paperweight-userdev가 사용된다. 이는 PaperMC의 Gradle 플러그인으로, 개발 환경에서 마인크래프트 서버 내부 코드에 접근할 수 있도록 해 준다.PaperMC는 서버 JAR을 직접 의존성으로 사용하는 방식을 권장하지 않는다. paperweight-userdev는 개발 중에는 디옵퓨스케이트된 이름을 사용할 수 있게 하고, 필요한 경우 플러그인 빌드 과정에서 런타임 환경에 맞게 다시 매핑하는 역할을 한다.
다만 NMS 사용은 버전 변경에 취약하므로, 가능하면 Paper API로 제공되는 기능을 우선 사용하는 편이 좋다.
7. 하드포크 이후
Paper는 1.21.4부터 Spigot의 향후 변경 사항에 종속되지 않는 방향으로 하드포크를 진행했다. 이전에도 Paper는 Spigot 위에 다수의 패치를 추가한 형태였지만, 하드포크 이후에는 Paper 자체의 API와 내부 구조를 더 자유롭게 발전시킬 수 있게 되었다.이 변화는 Paper API의 중요성을 높였다. 기존에는 Bukkit,Spigot API와의 호환성이 Paper API의 중심에 가까웠다면, 이후에는 Paper가 자체적으로 필요한 API를 추가하고 정리하는 비중이 커질 수 있다. PaperMC는 하드포크 이후에도 기존 설정과 플러그인 호환성을 갑자기 제거하지는 않겠다고 밝혔지만, 장기적으로는 Paper 전용 API와 Spigot API 사이의 차이가 누적될 가능성이 있다.
8. 호환성
Paper API를 사용하는 플러그인은 Paper 서버를 기준으로 개발된다. Bukkit API 또는 Spigot API만 사용하는 플러그인은 Paper에서 대부분 동작하지만, Paper API 전용 기능을 사용하는 플러그인은 Spigot에서 동작하지 않을 수 있다.플러그인 개발자는 대상 서버를 명확히 정해야 한다. 단순한 기능을 제공하고 넓은 호환성이 필요하다면 Bukkit 또는 Spigot API 범위 안에서 개발할 수 있다. 반대로 Paper의 성능 개선, Adventure 지원, 레지스트리 API, Paper 전용 로딩 구조 등을 활용하려면 Paper API를 기준으로 개발하는 것이 적절하다.