원클릭으로
pasterdream-entity-api
PasterDream模组实体注册专用API,提供Facade+Builder模式一键注册自定义实体。在需要创建新实体、配置实体属性/AI/碰撞箱/追踪范围/生物技能、动画系统或注册渲染器时调用。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
PasterDream模组实体注册专用API,提供Facade+Builder模式一键注册自定义实体。在需要创建新实体、配置实体属性/AI/碰撞箱/追踪范围/生物技能、动画系统或注册渲染器时调用。
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Guides API-Split multi-module architecture decisions for NeoPasterDream (NeoForge 1.21.1). Invoke when deciding where to place new code (PasterDreamAPI vs PasterDream), creating Builder/Facade/Result/Config classes, or designing new registration systems.
PasterDream模组药水效果注册专用API,提供Facade+Builder模式一键注册自定义MobEffect。在需要创建新状态效果、配置效果属性/着色器/粒子/回调/药水酿造时调用。
PasterDream NeoForge 1.21.1 模组开发指南。提供项目结构、注册系统、实体系统、物品系统等的开发规范,以及常见崩溃问题的解决方案。Invoke when developing or modifying PasterDream mod features, creating new items/blocks/entities, fixing crashes, or when needing to understand the mod's architecture.
PasterDream 物品移植 API —— 用于将原 FixPasterDream 模组(MCreator 生成)中的物品系统化移植到 NeoForge 1.21.1。提供 Builder 模式、批量注册、迁移追踪、配方生成、战利品表生成、方块数据生成、创造标签页生成、语言文件生成及超级快速导入器等一站式工具链。Invoke when needing to port items from the old FixPasterDream mod, register new items in PDItems.java, batch-create items with consistent patterns, generate recipes/loot tables/block tags, or create creative tab registration code.
Minecraft NeoForge 1.21.1 方块掉落问题诊断与修复指南。Invoke when user encounters block drop issues, missing loot drops, or needs to implement custom block drops. Covers getDrops() override, BlockItem registration, and loot table JSON troubleshooting.
PasterDream模组维度注册专用API,提供Facade+Builder模式一键注册自定义维度。在需要创建新维度、配置维度类型/生物群系/背景音乐或生成维度JSON时调用。
| name | pasterdream-entity-api |
| description | PasterDream模组实体注册专用API,提供Facade+Builder模式一键注册自定义实体。在需要创建新实体、配置实体属性/AI/碰撞箱/追踪范围/生物技能、动画系统或注册渲染器时调用。 |
本 Skill 提供 PasterDream 模组实体注册专用 API 的使用指南,采用 Facade + Builder 模式(与 BlockAPI / DimensionAPI 风格一致),通过链式调用即可完成实体的注册、属性配置、渲染器注册和生成蛋颜色管理。
// ====== 1. 在 PDEntities.java 中注册实体 ======
EntityResult<ShadowGolemEntity> shadowGolem = EntityAPI.createEntity("shadow_golem")
.category(MobCategory.MONSTER) // 实体分类
.size(2.2f, 3.5f) // 碰撞箱尺寸
.trackingRange(64) // 追踪范围
.updateInterval(3) // 更新间隔
.velocityUpdates(true) // 启用速度同步
.entityClass(ShadowGolemEntity.class) // 实体类
.attributes(ShadowGolemEntity::createAttributes) // AI 属性
.spawnEgg(0x333333, 0xFF4444) // 生成蛋颜色
.build();
// ====== 2. 在 ClientSetup.java 中注册渲染器 ======
@SubscribeEvent
public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) {
EntityAPI.registerRenderer(event, shadowGolem, ShadowGolemRenderer::new);
}
// ====== 3. 在 PDEntityEvents.java 中注册属性 ======
@SubscribeEvent
public static void registerAttributes(EntityAttributeCreationEvent event) {
EntityAPI.registerAttributes(event, shadowGolem);
}
// ====== 4. 在代码中生成实体 ======
EntityType<ShadowGolemEntity> type = shadowGolem.entityType();
ShadowGolemEntity golem = type.create(level);
golem.setPos(x, y, z);
level.addFreshEntity(golem);
在 PasterDreamMod 构造函数中注册 EntityAPI 的 REGISTRY:
public PasterDreamMod(IEventBus modEventBus) {
// ... 其他注册器 ...
EntityAPI.REGISTRY.register(modEventBus);
}
EntityAPI ← Facade 门面
├── createEntity(name) ← 工厂方法 → EntityBuilder
├── registerRenderer(event, result, provider) ← 渲染器注册
├── registerRenderer(event, name, provider) ← 按名称注册渲染器
├── registerAttributes(event, result) ← 属性注册(缓存)
├── registerAttributes(event, result, supplier) ← 属性注册(显式)
├── registerAttributes(event, name) ← 按名称注册属性
├── createSpawnEggItem(registry, name, supplier) ← 刷怪蛋物品注册
├── setSpawnEggModelsOutputDir(path) ← 刷怪蛋模型输出目录
├── cacheSpawnEgg(name, bg, hl) ← 缓存刷怪蛋颜色
├── getSpawnEggColors(name) ← 查询刷怪蛋颜色
├── getEntityType(name) ← 查询 EntityType
├── getEntityResult(name) ← 查询 EntityResult
└── getRegisteredEntities() ← 所有已注册实体
EntityBuilder<T> ← Builder 构建器
├── category(MobCategory) ← 实体分类(必要)
├── size(float, float) ← 碰撞箱尺寸(必要)
├── entityClass(Class<T>) ← 实体类(必要)
├── trackingRange(int) ← 追踪范围(默认 64)
├── updateInterval(int) ← 更新间隔(默认 3)
├── velocityUpdates(boolean) ← 速度同步(默认 true)
├── attributes(Supplier<Builder>) ← AI 属性(AttributeSupplier.Builder)
├── attributesBuilt(Supplier) ← AI 属性(预构建)
├── spawnEgg(int, int) ← 刷怪蛋颜色 [底色, 高光色]
└── build() ← 注册 → EntityResult<T>
EntityResult<T> ← Record 结果
├── name() → String(实体注册名)
├── entityTypeSupplier() → Supplier<EntityType<T>>
├── entityClass() → Class<T>
├── entityType() → EntityType<T>(便捷获取)
└── deferredHolder() → DeferredHolder
| 方法 | 参数 | 说明 | 必需 |
|---|---|---|---|
category(MobCategory) | 实体分类 | 决定生物容量和生成行为 | ✅ |
size(float, float) | 宽度, 高度 | 碰撞箱尺寸 | ✅ |
entityClass(Class) | 实体 Class | 实体 Java 类(需有 (EntityType, Level) 构造) | ✅ |
trackingRange(int) | 格数 | 客户端同步距离(默认 64) | ❌ |
updateInterval(int) | tick 数 | 位置同步频率(默认 3) | ❌ |
velocityUpdates(boolean) | bool | 是否接收速度更新(默认 true) | ❌ |
attributes(Supplier) | AttributeSupplier.Builder | AI 属性配置 | ❌ |
attributesBuilt(Supplier) | AttributeSupplier | 预构建的属性 | ❌ |
spawnEgg(int, int) | 底色, 高光色 | 生成蛋颜色(16 进制) | ❌ |
| 分类 | 说明 |
|---|---|
MobCategory.MONSTER | 敌对生物(容量 70) |
MobCategory.CREATURE | 友好动物(容量 10) |
MobCategory.AMBIENT | 环境生物(如蝙蝠,容量 15) |
MobCategory.WATER_CREATURE | 水生生物(容量 5) |
MobCategory.WATER_AMBIENT | 水下环境生物(如鱼,容量 20) |
MobCategory.MISC | 其他(如掉落物、箭矢) |
API 提供了 EntityAttributesGenerator 工具类,包含多种预设属性模板,可直接通过方法引用传入 Builder:
| 方法 | 适用 | 预设值 |
|---|---|---|
createMonsterAttributes() | 怪物 | 攻击 3.0, 盔甲 2.0, 追踪 32 |
createCreatureAttributes() | 动物 | 生命 10.0, 速度 0.2, 追踪 16 |
createFlyingAttributes() | 飞行生物 | 生命 10.0, 速度 0.2, 飞行 0.4, 追踪 24 |
createWaterCreatureAttributes() | 水生生物 | 生命 15.0, 速度 0.3, 追踪 16 |
// 注册
EntityResult<ShadowGolemEntity> golem = EntityAPI.createEntity("shadow_golem")
.category(MobCategory.MONSTER)
.size(2.2f, 3.5f)
.trackingRange(64)
.entityClass(ShadowGolemEntity.class)
.attributes(() -> Mob.createMobAttributes()
.add(Attributes.MAX_HEALTH, 80.0)
.add(Attributes.ATTACK_DAMAGE, 12.0)
.add(Attributes.ARMOR, 8.0)
.add(Attributes.MOVEMENT_SPEED, 0.25)
.add(Attributes.FOLLOW_RANGE, 48))
.spawnEgg(0x2C2C2C, 0x6B3FAF)
.build();
// 渲染器
EntityAPI.registerRenderer(event, golem, ShadowGolemRenderer::new);
// 属性
EntityAPI.registerAttributes(event, golem);
EntityResult<ForestSpiritEntity> spirit = EntityAPI.createEntity("forest_spirit")
.category(MobCategory.CREATURE)
.size(0.6f, 1.8f)
.entityClass(ForestSpiritEntity.class)
.attributes(EntityAttributesGenerator::createCreatureAttributes)
.spawnEgg(0x4CAF50, 0x81C784)
.build();
EntityResult<NightmareBatEntity> bat = EntityAPI.createEntity("nightmare_bat")
.category(MobCategory.AMBIENT)
.size(0.8f, 0.8f)
.entityClass(NightmareBatEntity.class)
.attributes(EntityAttributesGenerator::createFlyingAttributes)
.updateInterval(1) // 飞行生物需要更频繁同步
.spawnEgg(0x1A1A2E, 0xE94560)
.build();
// 在任意位置,只要知道实体名称就可以查询和注册
@SubscribeEvent
public static void registerAttributes(EntityAttributeCreationEvent event) {
// 自动查找已缓存的 shadow_golem 实体和属性
EntityAPI.registerAttributes(event, "shadow_golem");
}
@SubscribeEvent
public static void registerRenderers(EntityRenderersEvent.RegisterRenderers event) {
EntityAPI.registerRenderer(event, "shadow_golem", ShadowGolemRenderer::new);
}
Entity API 提供了一个完整的刷怪蛋解决方案,包括颜色配置、自动物品注册和模型文件自动生成。
在 EntityBuilder 的链式调用中通过 .spawnEgg() 配置颜色:
EntityResult<ShadowGolemEntity> golem = EntityAPI.createEntity("shadow_golem")
.category(MobCategory.MONSTER)
.size(2.2f, 3.5f)
.entityClass(ShadowGolemEntity.class)
.attributes(ShadowGolemEntity::createAttributes)
.spawnEgg(0x2C2C2C, 0x6B3FAF) // 底色, 高光色
.build();
颜色值以 16 进制 RGB 格式传入,Builder 在 build() 时自动缓存颜色。
在 PDItems.java 中使用 EntityAPI.createSpawnEggItem() 统一注册刷怪蛋物品,无需手动指定颜色:
// 所有刷怪蛋颜色由 PDEntities 中的 .spawnEgg() 统一管理
public static final DeferredItem<Item> SHADOW_GOLEM_SPAWN_EGG =
EntityAPI.createSpawnEggItem(ITEMS, "shadow_golem", PDEntities.SHADOW_GOLEM);
原理:createSpawnEggItem() 会从 PDEntities 中 .spawnEgg() 缓存的颜色数组中自动读取,生成 SpawnEggItem。
当 EntityBuilder 的 .build() 执行时,如果已配置模型输出目录,会自动在对应路径生成 {name}_spawn_egg.json 模型文件(内容固定为 {"parent": "minecraft:item/template_spawn_egg"})。
配置方式:在 PasterDreamMod.java 构造函数中设置输出目录:
public PasterDreamMod(IEventBus modEventBus, ModContainer modContainer) {
// ... 其他注册器 ...
// 配置刷怪蛋模型自动生成输出目录
EntityAPI.setSpawnEggModelsOutputDir(
Path.of("PasterDream", "src", "main", "resources", "assets",
PasterDreamMod.MOD_ID, "models", "item"));
// ... 后续初始化 ...
}
// ====== PDEntities.java ======
private static final EntityResult<ShadowGolemEntity> SHADOW_GOLEM_RESULT =
EntityAPI.createEntity("shadow_golem")
.category(MobCategory.MONSTER).size(2.2f, 3.5f)
.entityClass(ShadowGolemEntity.class)
.attributes(ShadowGolemEntity::createAttributes)
.spawnEgg(0x191926, 0xA7A5B1) // ← 颜色在此配置
.build();
// 向后兼容常量
public static final Supplier<EntityType<ShadowGolemEntity>> SHADOW_GOLEM =
SHADOW_GOLEM_RESULT.entityTypeSupplier();
// ====== PDItems.java ======
public static final DeferredItem<Item> SHADOW_GOLEM_SPAWN_EGG =
EntityAPI.createSpawnEggItem(ITEMS, "shadow_golem", PDEntities.SHADOW_GOLEM);
// ====== PasterDreamMod.java ======
public PasterDreamMod(IEventBus modEventBus, ModContainer modContainer) {
// ... 注册器 ...
EntityAPI.setSpawnEggModelsOutputDir(
Path.of("PasterDream", "src", "main", "resources", "assets",
"pasterdream", "models", "item"));
// ...
}
| 步骤 | 操作 | 位置 |
|---|---|---|
| 1 | 在 .spawnEgg() 中配置颜色 | PDEntities.java |
| 2 | 用 EntityAPI.createSpawnEggItem() 注册刷怪蛋物品 | PDItems.java |
| 3 | 调用 EntityAPI.setSpawnEggModelsOutputDir() 配置输出目录 | PasterDreamMod.java |
| 4 | 确保实体有向后兼容常量(public static final Supplier<EntityType<T>>) | PDEntities.java |
⚠️ 若未配置
.spawnEgg()但调用了createSpawnEggItem(),会在运行时抛出IllegalStateException,提示 "未配置生成蛋颜色"。
实体类必须包含 (EntityType, Level) 构造方法:
public class ShadowGolemEntity extends Monster {
public ShadowGolemEntity(EntityType<? extends ShadowGolemEntity> type, Level level) {
super(type, level);
}
}
Entity API 提供了一套完整的 procedure 动画播放系统,用于播放由服务端触发的一次性动画(如技能释放、咆哮、受击等)。
服务端 客户端
│ │
├─ setAnimation("roar") ──────► ├─ 同步数据到达
│ (更新 entityData.set) │
│ ├─ ProcedureAnimationHandler.predicate()
│ │ ├─ 检测新动画 → 通过 GeckoLib 播放一次
│ │ ├─ 动画播放中 → 返回 CONTINUE
│ │ └─ 动画播完 → 自动重置为 "empty"
│ │
│ └─ movementPredicate()
│ ├─ procedure 动画进行中 → STOP
│ └─ procedure 为空 → 播放 idle/walk/death
// 在实体类字段中:
/** 客户端 procedure 动画处理器 */
private final ProcedureAnimationHandler procAnim = new ProcedureAnimationHandler();
private PlayState procedurePredicate(AnimationState<MyEntity> state) {
return procAnim.predicate(state,
level().isClientSide(),
this::getSyncedAnimation,
() -> setAnimation("empty"));
}
参数说明:
state — GeckoLib 动画状态(传入原生 AnimationState)level().isClientSide() — 是否在客户端侧(服务端不播动画)this::getSyncedAnimation — 同步动画数据的 getter() -> setAnimation("empty") — 动画播完后重置的回调private PlayState movementPredicate(AnimationState<MyEntity> state) {
// 必须使用 getSyncedAnimation() 而非 this.animationprocedure
if (this.getSyncedAnimation().equals("empty")) {
if ((state.isMoving() || !(state.getLimbSwingAmount() > -0.15F && state.getLimbSwingAmount() < 0.15F))) {
return state.setAndContinue(RawAnimation.begin().thenLoop("walk"));
}
if (this.isDeadOrDying()) {
return state.setAndContinue(RawAnimation.begin().thenPlay("death"));
}
return state.setAndContinue(RawAnimation.begin().thenLoop("idle"));
}
return PlayState.STOP;
}
关键规则:movementPredicate 必须检查 getSyncedAnimation()(同步数据),不能检查 this.animationprocedure(本地字段)。
@Override
public void registerControllers(AnimatableManager.ControllerRegistrar controllers) {
controllers.add(new AnimationController<>(this, "movement", 4, this::movementPredicate));
controllers.add(new AnimationController<>(this, "procedure", 4, this::procedurePredicate));
}
注意:procedure 控制器的 transition length 建议与 movement 一致(通常 4 tick)。
// 在 hurt()、技能逻辑、或其他需要触发动画的地方:
this.setAnimation("roar"); // 服务端同步数据 → 客户端自动播放
| 错误模式 | 后果 |
|---|---|
movementPredicate 使用 this.animationprocedure 判断 | procedure 动画被 movementPredicate 覆盖,永远播不出 |
procedurePredicate 不检查 level().isClientSide() | 服务端和客户端争抢控制,动画行为不可预测 |
procedurePredicate 没有 currentlyPlaying 追踪 | 每帧重复触发动画,导致卡顿或循环 |
| 直接在 procedurePredicate 里写完整逻辑 | 每个实体重复同样的代码,容易出错 |
| 方法 | 说明 |
|---|---|
predicate(state, isClientSide, syncedAnimSupplier, setEmptyAnim) | 标准 procedure 动画回调 |
reset() | 重置处理器状态(实体死亡时调用) |
getCurrentlyPlaying() | 获取当前正在播放的动画名称 |
EntitySkillManager 是更高级的技能管理系统,内置了动画同步机制:
// 实体类中
private final EntitySkillManager skillManager = new EntitySkillManager(this);
// 构造方法中注册技能
public MyEntity(EntityType<? extends Monster> type, Level level) {
super(type, level);
skillManager.registerSkill(EntitySkill.builder("roar")
.animationName("roar")
.damage(12.0f).range(5.0f).cooldownTicks(200)
.particleName("explosion")
.soundId("pasterdream:terrorbeak_roar")
.build());
}
// baseTick 中更新
@Override
public void baseTick() {
super.baseTick();
skillManager.tick();
}
// 触发技能
skillManager.tryTriggerSkill("roar", target);
EntitySkillManager 会自动处理: