02-block · git:20260711.586c86f · 2026-07-11 · sha256 423ab8498fe62755
02-block git:20260711.586c86fA
Immutable. This exact content is served forever at /api/v1/blob/423ab8498fe62755.
# 02 — 方块开发
> 适用版本:Fabric 1.14.4
---
## 约束
### 核心原则
- 方块必须在 `Registry.register(Registry.BLOCK, id, block)` 中注册
- 如需方块物品形态,在 `Registry.ITEM` 中注册同名 `BlockItem`
- 方块类继承 `Block` 或其子类
- 使用 `Block.Properties` 配置方块属性
- **禁止**在服务端直接创建客户端专用对象
---
## Decision Flow
### Decision: 选择方块类型
```
IF 简单静态方块
→ new Block(Block.Properties.create(Material.STONE))
IF 可配置方块(如可交互、可放置)
→ 自定义 Block 子类
IF 方块需要存储数据(inventory、energy 等)
→ 方块实现 BlockEntityProvider + 注册 BlockEntityType
IF 需要自定义渲染
→ 注册自定义 BlockRenderType 或使用 BlockEntity + custom renderer
```
---
## Block.Properties
```java
// 基础配置
Block.Properties.create(Material.STONE)
.hardnessAndResistance(1.5f) // 硬度和抗爆性
.hardnessAndResistance(1.5f, 6.0f) // hardness, resistance
.breakByTool(ToolType.PICKAXE) // 需要镐挖掘(Fabric API)
.requiresTool() // 需要工具
.breakByHand(false) // 不能空手破坏
.dropsFrom(Blocks.STONE) // 掉落物同另一个方块(Fabric API)
.mapColor(MapColor.STONE) // 地图颜色
.noCollission() // 无碰撞箱(注意:1.14 中是 noCollission)
.slipperiness(0.98f) // 摩擦力
.velocityMultiplier(0.98f) // 速度倍率
.jumpVelocityMultiplier(0.95f) // 跳跃倍率
```
## 常用方块创建
```java
// 普通方块
private static final Block MY_STONE = Registry.register(
Registry.BLOCK,
new Identifier(MOD_ID, "my_stone"),
new Block(Block.Properties.create(Material.STONE).hardnessAndResistance(1.5f))
);
// 注册同名 BlockItem
private static final Item MY_STONE_ITEM = Registry.register(
Registry.ITEM,
new Identifier(MOD_ID, "my_stone"),
new BlockItem(MY_STONE, new Item.Properties())
);
// 无碰撞方块(如草、花)
private static final Block MY_PLANT = Registry.register(
Registry.BLOCK,
new Identifier(MOD_ID, "my_plant"),
new Block(Block.Properties.create(Material.PLANTS).doesNotBlockMovement())
);
// 可配置方块
public class MySlabBlock extends Block {
public MySlabBlock(Properties properties) {
super(properties);
}
@Override
public BlockRenderType getRenderType(BlockState state) {
return BlockRenderType.MODEL;
}
}
```
## BlockItem 注册
```java
// ✅ 正确:BlockItem 与 Block 使用完全相同的 Identifier
Registry.register(Registry.ITEM, new Identifier(MOD_ID, "my_block"),
new BlockItem(MY_BLOCK, new Item.Properties()));
// ❌ 错误:BlockItem 使用不同的 registry name
Registry.register(Registry.ITEM, new Identifier(MOD_ID, "my_block_item"), // 错误!
new BlockItem(MY_BLOCK, new Item.Properties()));
```
## BlockEntity(带数据存储的方块)
```java
// 1. 创建 BlockEntity 类
public class MyChestBlockEntity extends BlockEntity {
private NonNullList<ItemStack> inventory;
public MyChestBlockEntity(TileEntityType<?> type) {
super(type);
this.inventory = NonNullList.withSize(27, ItemStack.EMPTY);
}
// ... read/write 方法
}
// 2. 方块实现 BlockEntityProvider
public class MyChestBlock extends Block implements BlockEntityProvider {
@Override
public BlockEntity createBlockEntity(BlockBlockEntityType<?> type) {
return type.create(MyBlockEntities.MY_CHEST);
}
@Override
public BlockState getStateForPlacement(BlockItemUseContext context) {
return this.getDefaultState();
}
}
// 3. 注册 BlockEntityType
public static final RegistryObject<BlockEntityType<MyChestBlockEntity>> MY_CHEST =
Registry.register(Registry.BLOCK_ENTITY_TYPE,
new Identifier(MOD_ID, "my_chest"),
BlockEntityType.Builder.create(MyChestBlockEntity::new, MY_CHEST_BLOCK)
.build(null));
```
## 常见错误
- ❌ `BlockItem` 与 `Block` 使用不同的 registry name — 物品会显示为缺失
- ❌忘记注册 `BlockItem` — 方块在世界中存在但无法放入物品栏
- ❌ 在 `onInitialize()` 外注册 — 注册不会生效
- ❌ 在服务端创建 `BlockRenderType` — 渲染相关只能在客户端
## 扩展点
| 配合 Skill | 协作说明 |
|------------|---------|
| `mc-registry` | 方块通过 Registry.register() 注册,BlockItem 需要同名注册 |
| `mc-datagen` | 方块注册后可生成方块模型 JSON |
| `mc-gui` | BlockEntity 用于 GUI 交互(如箱子) |
| `mc-item` | BlockItem 关联方块和物品 |