NeoForge 26에서 AttachmentTypes는 플레이어, 엔티티, 청크, 블록 엔티티에 임의의 데이터를 "붙이는" 가장 현대적인 방법입니다. 구식 Capabilities API를 대체하며, DeferredRegister + Codec으로 등록·직렬화를 통일했습니다.
AttachmentType.builder(defaultValueSupplier)로 빌더를 만들고, 체이닝으로 옵션을 추가한 뒤 .build()합니다.
// examplemod-template-26.1.2/src/main/java/com/example/examplemod/ExampleMod.javapublic static final Supplier<AttachmentType<Integer>> MANA = ATTACHMENT_TYPES.register( "mana", () -> AttachmentType.builder(() -> 100) // 기본값 100 .serialize(Codec.INT.fieldOf("mana")) // NBT 저장 (필드명 "mana") .copyOnDeath() // 사망 시 보존 .build());
getData, setData, hasData, removeData 네 메서드로 모든 접근을 처리합니다. 메서드는 IAttachmentHolder 인터페이스에 정의되어 있으며, Player, Entity, BlockEntity, Chunk가 모두 구현합니다.
// 읽기 — 값이 없으면 기본값(100) 반환int mana = player.getData(ExampleMod.MANA.get());// 쓰기player.setData(ExampleMod.MANA.get(), 50);// 부착 여부 확인 (기본값과 구분 필요 시 활용)boolean has = player.hasData(ExampleMod.MANA.get());// 제거 — 기본값으로 리셋player.removeData(ExampleMod.MANA.get());
// 예시 이벤트 핸들러 — @EventBusSubscriber(modid = "examplemod") 패턴은// examplemod-template-26.1.2/.../events/ParticleHandlers.java 와 동일하다.@EventBusSubscriber(modid = "examplemod")public class ManaHandler { @SubscribeEvent public static void onPlayerRightClick(PlayerInteractEvent.RightClickItem event) { Player player = event.getEntity(); int mana = player.getData(ExampleMod.MANA.get()); if (mana >= 10) { player.setData(ExampleMod.MANA.get(), mana - 10); } }}