04-entity · git:20260711.586c86f · 2026-07-11 · sha256 6055a162f90d9d2d
04-entity git:20260711.586c86fA
Immutable. This exact content is served forever at /api/v1/blob/6055a162f90d9d2d.
# 04 — 实体开发
> 适用版本:Fabric 1.14.4
---
## 约束
### 核心原则
- 实体必须在 `Registry.register(Registry.ENTITY_TYPE, id, type)` 中注册
- 实体渲染器在客户端单独注册(`EntityRendererRegistry`)
- 实体类继承 `Entity` 或其子类
- 实体必须有 `EntityType.Builder`
- 实体 ID 必须在 `fabric.mod.json` 的 `entrypoints` 中正确配置
---
## Decision Flow
### Decision: 选择实体类型
```
IF 静态实体(不移动、不交互)
→ EntityType.Builder.create(EntityCategory.MISC)
IF 有行为实体(动物、怪物)
→ EntityType.Builder.create(EntityCategory.CREATURE)
→ 重写 registerAttributes() 和 init() 方法
IF 需要在服务端和客户端分别初始化
→ 拆分 FabricMod 为 client/server entrypoints
IF 仅客户端渲染(如护甲、held item)
→ 不需要注册实体,使用 LayerRenderer 或 FeatureRenderer
```
---
## 基本实体注册
```java
// 1. 创建实体类
public class MyPigEntity extends CowEntity {
public MyPigEntity(EntityType<? extends MyPigEntity> type, World world) {
super(type, world);
}
}
// 2. 在 onInitialize() 中注册
public static final RegistryObject<EntityType<MyPigEntity>> MY_PIG = Registry.register(
Registry.ENTITY_TYPE,
new Identifier(MOD_ID, "my_pig"),
EntityType.Builder.<MyPigEntity>create(
MyPigEntity::new,
EntityCategory.CREATURE
)
.size(0.9f, 1.4f) // 宽, 高
.build(new Identifier(MOD_ID, "my_pig").toString())
);
```
## Entity Attributes(属性)
```java
// 在 onInitialize() 中设置属性
@Override
public void onInitialize() {
// 注册属性
((LivingEntityAttributeRegistry) (Object) this).register(MY_PIG,
LivingEntityAttributes.GENERIC_MAX_HEALTH,
20.0
);
((LivingEntityAttributeRegistry) (Object) this).register(MY_PIG,
LivingEntityAttributes.GENERIC_MOVEMENT_SPEED,
0.25
);
((LivingEntityAttributeRegistry) (Object) this).register(MY_PIG,
LivingEntityAttributes.GENERIC_ATTACK_DAMAGE,
3.0
);
// 注册实体...
Registry.register(Registry.ENTITY_TYPE, new Identifier(MOD_ID, "my_pig"), MY_PIG.get());
}
```
## Spawn Restriction(生成限制)
```java
// 使用 World spawn biomes 配置(1.14.4 方式)
// 在 EntityType 构造后,Minecraft 会自动处理基本生成
```
## 实体渲染器(客户端)
```java
// 单独的客户端入口点(推荐)
public class ExampleModClient implements ClientModInitializer {
@Override
public void onInitializeClient() {
EntityRendererRegistry.register(MY_PIG.get(), (dispatcher, context) ->
new LivingEntityRenderer<MyPigEntity>(dispatcher, new MyPigEntityModel(), 0.5f)
);
}
}
```
## fabric.mod.json 配置
```json
{
"entrypoints": {
"main": ["com.example.examplemod.ExampleMod"],
"client": ["com.example.examplemod.ExampleModClient"]
}
}
```
## 常见错误
- ❌忘记在 `fabric.mod.json` 中添加客户端 entrypoint — 实体无渲染
- ❌实体渲染器在服务端执行 — `EntityRendererRegistry` 仅在客户端有效
- ❌忘记设置 `SpawnRestriction` — 实体无法在世界中自然生成
- ❌在 `onInitialize()` 外注册 — 注册不会生效
- ❌混淆 `EntityCategory` 和 `MobCategory`(后者是 1.17+ 的名称)
## 扩展点
| 配合 Skill | 协作说明 |
|------------|---------|
| `mc-registry` | 实体通过 Registry.register() 注册 |
| `mc-item` | 实体可以掉落物品(EntityDrops 事件) |
| `mc-gui` | 实体可以打开 GUI(使用 Holder<MenuType>) |
| `mc-datagen` | 实体可以生成 loot table JSON |