아이템
아이템 선언
mod.content().item("ruby", ItemDefinition.builder()
.rarity(ItemRarity.RARE)
.creativeTab(CreativeTab.INGREDIENTS)
.build());
| 빌더 메서드 | 뜻 |
|---|---|
maxStackSize(int) | 한 칸에 쌓이는 최대 개수 |
durability(int) | 내구도 |
fireResistant() | 불에 타지 않음 |
rarity(ItemRarity) | COMMON, UNCOMMON, RARE, EPIC |
food(FoodDefinition) | 음식 |
creativeTab(CreativeTab) | 게임의 창작 탭(탭 끝에 추가). 모드 전용 탭은 태그와 창작 탭에서 설명하는 mod.content().creativeTab(path, …)으로 선언 |
behavior(ItemBehavior) | 사용 콜백 |
음식
mod.content().item("star_fruit", ItemDefinition.builder()
.food(new FoodDefinition(4, 0.3f, true)) // 허기, 포화, 배부를 때도 먹을 수 있음
.creativeTab(CreativeTab.FOOD_AND_DRINKS)
.build());
사용 콜백
mod.content().item("spark", ItemDefinition.builder()
.behavior(new ItemBehavior() {
@Override
public InteractionResult onUse(ItemUse use) {
if (!use.world().isClientSide()) {
use.player().sendMessage("Spark at " + use.player().blockPos());
}
return InteractionResult.SUCCESS;
}
})
.build());
ItemUse는 world(), player(), 그리고 사용한 실제 스택을 돌려주는 stack()을 제공합니다. PASS를 반환하면 게임의 기본 동작이 그대로 실행됩니다.
아이템 데이터 컴포넌트
스택마다 값을 저장하려면 데이터 컴포넌트를 선언합니다.
ItemComponentKey<Integer> CHARGE = mod.content().itemComponent("charge", ComponentType.INTEGER);
mod.content().item("wand", ItemDefinition.builder().maxStackSize(1).behavior(new ItemBehavior() {
@Override
public InteractionResult onUse(ItemUse use) {
if (!use.world().isClientSide()) {
use.stack().set(CHARGE, use.stack().get(CHARGE).orElse(0) + 1);
}
return InteractionResult.SUCCESS;
}
}).build());
- 값 타입으로
ComponentType.INTEGER,BOOLEAN,STRING,TREE(DataTree)를 쓸 수 있습니다. - 값은 스택과 함께 저장, 복사, 동기화되며
/give <id>[<mod>:<name>=<값>]문법으로도 지정할 수 있습니다. - 값이 다른 스택끼리는 합쳐지지 않습니다.
실제 스택 참조
ItemStackRef는 실제 스택을 직접 바꿉니다. ItemUse.stack(), PlayerView.mainHandStack(), InventoryView.stackAt(slot)이 이를 돌려주며, 서버에서만 바꾸세요.
| 메서드 | 뜻 |
|---|---|
item(), count(), setCount(n), isEmpty() | 아이템과 개수 |
get(key), set(key, value), remove(key) | 데이터 컴포넌트 |
customName(), setCustomName(name) | 이름 |
damage(), maxDamage(), setDamage(n) | 내구도 |
isIn(tag) | 아이템이 아이템 태그에 들어 있는지(태그) |
snapshot() | 변하지 않는 사본(ItemStackView) |
플레이어 인벤토리
player.give(ResourceId.of("my_mod", "ruby"), 2);
int count = player.countItem(ResourceId.of("my_mod", "ruby"));
ResourceId inHand = player.mainHandItem();
InventoryView inventory = player.inventory();
툴팁
mod.events().register(ClientEvents.ITEM_TOOLTIP, (stack, lines, advanced) -> { // client 엔트리포인트
if (stack.isIn(SPARKLY)) {
lines.add(1, "§bSparkly"); // 이름 바로 아래
}
});
ClientEvents.ITEM_TOOLTIP은 게임이 아이템 툴팁을 만들 때마다 클라이언트 스레드에서, 게임이 넣는 줄 뒤에 불립니다. 툴팁이 보이는 동안 매 프레임, 창작 검색 때도 불리므로 리스너는 가볍게 유지하세요.- 게임이 툴팁을 숨기는 아이템에는 불리지 않습니다.
advanced는 고급 툴팁(F3+H)이 켜져 있는지입니다.stack은 클라이언트의 사본이니 읽기만 하고 바꾸지 마세요.
TooltipLines는 툴팁 하나의 줄 목록이며, 첫 줄이 아이템 이름입니다. 리스너가 호출되는 동안에만 유효합니다.
| 메서드 | 뜻 |
|---|---|
size() | 줄 수(이름 포함) |
get(index) | 그 줄의 글자(서식 제외) |
add(line), add(index, line) | 끝에 줄 추가, 또는 index 줄 앞에 끼워 넣기(size()면 끝에 추가) |
remove(index) | 줄 지우기 |
- 줄은 일반 텍스트입니다.
§7(회색) 같은 서식 코드는 색으로 그려집니다. - 게임이나 다른 모드가 넣은 줄은 지우지 않는 한 서식을 유지합니다.
- 범위를 벗어난 번호는
IndexOutOfBoundsException입니다. - 변환 규칙과 줄 편집은 단위 테스트로 확인했습니다. 화면에 그려진 툴팁은 창을 여는 테스트를 돌리지 않아 사람이 확인하지 않았습니다.
리소스
아이템의 모양은 assets/<mod>/items/<item>.json, models/item/…, textures/item/…에서 정하고, 이름은 lang 파일의 item.<mod>.<id> 키로 정합니다.
assets/my_mod/items/ruby.json
{"model": {"type": "minecraft:model", "model": "my_mod:item/ruby"}}
assets/my_mod/models/item/ruby.json
{"parent": "minecraft:item/generated", "textures": {"layer0": "my_mod:item/ruby"}}