월드
월드 뷰
WorldView는 차원 하나를 나타냅니다. 콜백(이벤트, 동작, 틱)이 받은 뷰는 그 호출이 진행되는 동안에만 사용하세요.
| 영역 | 메서드 |
|---|---|
| 기본 | dimension(), isClientSide(), gameTime(), players() |
| 블록 | blockAt(pos), setBlock(pos, block), stateAt(pos), setProperty(pos, property, value), blockEntityAt(pos), emittedLight(pos) |
| 엔티티 | spawnEntity(type, x, y, z), entitiesNear(x, y, z, radius) |
| 효과 | playSound(pos, sound, volume, pitch), spawnParticles(particle, x, y, z, count, spread) |
| 게임 규칙 | gameRule(key), setGameRule(key, value) |
| 저장 | storage(id), storage(id, options) |
| 예약 | schedule(ticks, task) |
| 청크·바이옴 | setChunkForced(x, z, forced), isChunkLoaded(x, z), biomeAt(pos), naturalSpawns(pos, category) |
| 차원 | otherDimension(id) |
| 태그 | tags(), isBlockIn(pos, tag)(태그) |
world.setBlock(pos, ResourceId.minecraft("stone"));
world.spawnEntity(ResourceId.minecraft("pig"), x, y, z);
Optional<WorldView> pocket = world.otherDimension(ResourceId.of("my_mod", "pocket"));
BlockPos는 BlockPos.of(x, y, z)로 만들고, offset, above, below로 위치를 옮깁니다.
월드 저장소
mod.events().register(WorldEvents.READY, world -> {
StoredData stats = world.storage(ResourceId.of("my_mod", "stats")); // 차원별, 월드와 함께 저장
stats.data().putInt("loads", stats.data().getInt("loads", 0) + 1);
stats.markChanged();
});
- 저장소는 차원마다 따로 있고 월드와 함께 저장됩니다.
- 값을 바꾼 뒤에는
markChanged()를 호출하세요. - 버전, 마이그레이션, 클라이언트 동기화 옵션은 저장 데이터와 버전과 네트워크와 동기화에서 설명합니다.
DataTree
StoredData.data(), 블록 엔티티 데이터, 엔티티 데이터는 모두 DataTree입니다.
| 메서드 | 뜻 |
|---|---|
getInt/putInt, getLong/putLong, getDouble/putDouble, getBoolean/putBoolean, getString/putString | 값 읽기(기본값 지정)와 쓰기. put…은 이어서 호출할 수 있음 |
getBytes/putBytes | 바이트 배열 |
child(key), findChild(key) | 하위 트리(없으면 만듦 / Optional로 반환) |
has, remove, keys, clear, copy | 키 관리 |
작업 예약
world.schedule(20, () -> world.setBlock(pos, ResourceId.minecraft("stone"))); // 20틱 뒤 서버 스레드에서 실행
world.schedule(20, () -> world.playSound(pos, ResourceId.minecraft("block.note_block.bell"), 1, 1));
- 예약한 작업은 저장되지 않으므로 서버가 멈추면 사라집니다.
- 예약 작업에서 예외가 발생하면
POLY-SCHEDULE-001로 기록하고 다음 작업을 계속 실행합니다.
청크 강제 로드
world.setChunkForced(chunkX, chunkZ, true); // /forceload와 같은 동작이며 월드와 함께 저장
world.isChunkLoaded(chunkX, chunkZ);
world.biomeAt(pos);
mod.events().register(WorldEvents.CHUNK_LOADED, (w, chunkX, chunkZ) -> { /* … */ }); // CHUNK_UNLOADED도 있음
월드 이벤트
서버에서 각 차원은 서버를 시작할 때마다 LOADED → READY → SAVING(저장할 때마다) → UNLOADED를 거칩니다. LOADED, SAVING, UNLOADED는 같은 리스너 타입 WorldListener(world -> …)를 씁니다.
mod.events().register(WorldEvents.LOADED, world -> { /* 모든 차원이 생긴 뒤, 첫 틱 전 */ });
mod.events().register(WorldEvents.SAVING, world -> { /* 이때 바꾼 내용은 월드와 함께 저장됨 */ });
mod.events().register(WorldEvents.UNLOADED, world -> { /* 정지 중, 차원을 읽을 수 있는 마지막 시점 */ });
SAVING은 자동 저장,/save-all, 정지 중 저장 때 청크와 레벨 데이터를 쓰기 전에 불립니다.UNLOADED에서 바꾼 내용은 더 이상 저장되지 않습니다.
시점과 CHUNK_LOADED, CHUNK_UNLOADED 같은 다른 이벤트는 이벤트에 정리되어 있습니다.