WorldGen
랙 없는 월드 생성을 위한 라이브러리
시작하기에 앞서, 이 라이브러리는 UHC_System 의 월드 생성 코드를 작성하면서 WorldCreator
의 단점인 랙을 없애기 위해 만들어진 코드의 일부를 라이브러리로 공개하는 것임을 알려드립니다
WorldCreator의 랙
WorldCreator
및 기타 Bukkit API
의 코드는 메인 Thread
에서 실행 되어야하고, 이로 인해 사양이 좋지 않은 컴퓨터에서 서버를 돌릴때, 랙이 생기며, 서버가 꺼질 수 있습니다. 이의 단점을 보완하기 위해, level.dat
의 생성 만으로, Bukkit API
의 블로킹 코드 실행을 대체할 수 있는 프로그램을 제작하기 시작했습니다.
.dat 및 NBT
.dat
형식의 파일은 NBT에 대한 정보를 포함하며, UTF가 아닌 Stream
형태로 저장되어 있어 일반 텍스트 에디터로는 정보를 확인하기 어렵습니다. 따라서, 이를 parsing
해주는 기능이 필요한데, 이 라이브러리가 해주는 것이 바로 그것입니다.
WorldUtils
WorldUtils
는 level.dat
의 NBT를 수정하여 원하는 level.dat
을 생성해주는 기능입니다. minecraft-version-data
를 이용해 원하는 마인크래프트 버전의 월드를 생성해줍니다. 또한, 커스텀 seed
를 이용해 원하는 월드를 생성해줍니다.
WorldUtils 예제
fun createWorld(worldName: String, seed: Long) {
val compound = WorldUtils.generateLevelDat(
Environment.OVERWORLD,
worldName,
Bukkit.getVersion(),
Bukkit.getServer()::class.java.`package`.name,
seed
)
NBTWriter.write("target.dat", compound, true)
}
위 코드는 오버월드이고 이름
이 worldName
, seed
가 seed
인 월드의 정보을 target.dat
파일에 저장합니다. 만약 파일이 존재하지 않을 경우, 자동으로 생성합니다. 또한, 이 라이브러리는 버킷을 의존성으로 갖지 않기 때문에, 직접 버킷 버전을 위와 같이 설정해 주어야합니다.
월드
마인크래프트의 월드 내부 폴더(region
, entities
, playerdata
등)의 위치는 환경(오버월드
, 네더
, 엔드
) 마다 다릅니다. 오버월드의 경우, 월드 디렉토리의 루트에 위치됩니다. 따라서 구조는 다음과 비슷할 것입니다.
├── playerdata
│ └── xxxxx
├── region
│ └── r.0.-1.mca
│ └── xxxxx.mca
└── level.dat
네더의 경우, 내부 폴더들은 루트가 아닌 DIM-1
폴더에 저장되므로 구조는 다음과 비슷할 것입니다.
├── DIM-1
│ └── playerdata
│ └── xxxxx
│ └── region
│ └── r.0.-1.mca
│ └── xxxxx.mca
└── level.dat
그리고 엔드의 경우, 내부 폴더들은 루트가 아닌 DIM1
폴더에 저장되므로 구조는 다음과 비슷할 것입니다.
├── DIM1
│ └── playerdata
│ └── xxxxx
│ └── region
│ └── r.0.-1.mca
│ └── xxxxx.mca
└── level.dat
마무리
현재로서는 직접 서버를 처음 실행했을 때 생성되는 월드폴더를 백업해 둔후, 원할 때 클론 해서 level.dat
대체 후 로드해야합니다. 이를 자동화 해주는 코드는 나중에 구현하도록 하겠습니다