03-item · git:20260711.586c86f · 2026-07-11 · sha256 f8fd95fba9bd439f

03-item git:20260711.586c86fA

Immutable. This exact content is served forever at /api/v1/blob/f8fd95fba9bd439f.

# 03 — 物品开发

> 适用版本:Fabric 1.14.4

---

## 约束

### 核心原则

- 物品必须在 `Registry.register(Registry.ITEM, id, item)` 中注册
- mod ID 使用 `new Identifier(MOD_ID, "name")` 构造
- **禁止**通过 `new Item()` 后不注册的方式使用
- 物品默认耐久无限(`durability` 默认 Integer.MAX_VALUE)

---

## Decision Flow

### Decision: 选择物品类型

```
IF 只是手持物品(无特殊行为)
  → new Item(new Item.Properties())

IF 是工具(剑/镐/斧/铲)
  → 使用 DiggerItem 或自定义工具类

IF 是盔甲
  → 使用 ArmorItem + ArmorMaterial

IF 是食物
  → Item + .food(FoodComponent)

IF 是可耐久工具
  → 继承 Item 并实现 repair

IF 需要自定义行为
  → 继承 Item 并重写 onItemUse()、onItemRightClick() 等方法
```

---

## 基本物品

```java
// 普通物品(无限耐久)
private static final Item MY_ITEM = Registry.register(
    Registry.ITEM,
    new Identifier(MOD_ID, "my_item"),
    new Item(new Item.Properties()
        .maxStackSize(64)
        .maxDamageIfAbsent(100))  // 耐久度(非工具类)
);
```

## 食物

```java
// 1.14.4 中的食物使用 Food 应用
private static final Item MY_APPLE = Registry.register(
    Registry.ITEM,
    new Identifier(MOD_ID, "golden_apple"),
    new Item(new Item.Properties()
        .food(new Food.Builder()
            .hunger(4)
            .saturationModifier(1.2f)
            .effect(new EffectInstance(Effects.REGENERATION, 100, 1), 1.0f)
            .alwaysEdible()      // 不消耗饱食度
            .build())
        .maxStackSize(64))
);
```

## 工具(以剑为例)

```java
// 自定义工具材质
public enum MyToolMaterial implements ToolMaterial {
    COPPER(2, 250, 6.0f, 2.0f, 15,
        () -> Items.COPPER_INGOT);  // 修复材料

    private final int maxUses;
    private final float efficiency;
    private final float attackDamage;
    private final int enchantability;
    private final Ingredient repairIngredient;

    MyToolMaterial(int maxUses, float efficiency, float attackDamage,
                   int enchantability, Ingredient repairIngredient) {
        this.maxUses = maxUses;
        this.efficiency = efficiency;
        this.attackDamage = attackDamage;
        this.enchantability = enchantability;
        this.repairIngredient = repairIngredient;
    }

    @Override public int getDurability() { return maxUses; }
    @Override public float getMiningSpeedMultiplier() { return efficiency; }
    @Override public float getAttackDamage() { return attackDamage; }
    @Override public int getMiningLevel() { return 0; }
    @Override public int getEnchantability() { return enchantability; }
    @Override public Ingredient getRepairIngredient() { return repairIngredient; }
}
```

```java
// 剑
private static final SwordItem COPPER_SWORD = Registry.register(
    Registry.ITEM,
    new Identifier(MOD_ID, "copper_sword"),
    new SwordItem(MyToolMaterial.COPPER, 3, 1.6f,
        (new Item.Properties()).defaultMaxDamage(250))
);

// 镐
private static final PickaxeItem COPPER_PICKAXE = Registry.register(
    Registry.ITEM,
    new Identifier(MOD_ID, "copper_pickaxe"),
    new PickaxeItem(MyToolMaterial.COPPER, 1, -2.8f,
        (new Item.Properties()).defaultMaxDamage(250))
);
```

## 耐久损耗

```java
@Override
public boolean hitEntity(ItemStack stack, LivingEntity target, LivingEntity attacker) {
    stack.damageItem(1, attacker, (entity) -> {
        entity.sendBreakAnimation(attacker.getActiveHand());
    });
    return true;
}
```

## 自定义物品行为

```java
public class MySpecialItem extends Item {
    public MySpecialItem(Properties settings) {
        super(settings);
    }

    @Override
    public ActionResult<ItemStack> onItemRightClick(World world, PlayerEntity player, Hand hand) {
        if (!world.isRemote) {
            // 服务端逻辑
            player.getItemStack(hand).damageItem(1, player,
                (p) -> p.sendBreakAnimation(hand));
        }
        return ActionResult.resultSuccess(player.getItemStack(hand));
    }
}
```

## 常见错误

- ❌忘记注册 `Item` — 物品不会出现在游戏中
- ❌ `BlockItem` 与 `Block` 使用不同的 registry name — 导致物品形态缺失
- ❌ 耐久物品忘记设置 `maxDamage` — 物品无法消耗耐久
- ❌ 在 `onInitialize()` 外注册 — 注册不会生效
- ❌ `Food.Builder` 中忘记 `.hunger()` — 食物不会被消耗

## 扩展点

| 配合 Skill | 协作说明 |
|------------|---------|
| `mc-registry` | 物品通过 Registry.register() 注册 |
| `mc-datagen` | 物品注册后可生成物品模型 JSON |
| `mc-block` | BlockItem 需要先有注册的 Block |
| `mc-capability` | Item 可附加 Fabric Capability |