name: 1211-neoforge-modding
description: >
Minecraft 1.21.1 NeoForge Moddingに関する開発支援。Modの新規作成、Block/Item/Entityの追加、
DataGen、ネットワーク処理(Payload System)、レシピ・進捗・ルートテーブルの生成、
Capability/Data Component/Data Attachmentの実装、クラッシュ対応など。
Minecraft 1.21.1 NeoForge Moddingに関するタスクや、ModDevGradleのセットアップ、
Registry/Event/sidednessに関する質問があった際に使用する。
license: MIT
compatibility: Requires JDK 21 (JetBrains Runtime recommended), IntelliJ IDEA, Gradle, internet access for Minecraft/NeoForge artifacts
metadata:
author: code-onigiri
version: "0.2.0"
概要
このSkillは Minecraft 1.21.1 NeoForge 向けMod開発の標準パターンと落とし穴をまとめたものです。
✅ やるべきこと
- DeferredRegister + DeferredHolder(または型付きAPI)を使う —
DeferredRegister.createBlocks(MODID), DeferredRegister.createItems(MODID) などの型付きAPIが利用可能。
- DataGen を使う — 手書きJSONはミスとメンテナンスコストが爆発する。
- Parchmentでパラメータ名を補完 —
neoForge { parchment { ... } } で設定。無効でも動作するが可読性が下がる。
- すべてのDeferredRegisterをメインModクラスのコンストラクタで
modBus にregisterする — コンストラクタ引数 IEventBus modEventBus を使う。
- Block登録時はBlockItemも登録する —
DeferredRegister.Items.registerSimpleBlockItem("name", BLOCK) で簡易化可能。
ResourceLocation.fromNamespaceAndPath(MODID, "path") を使う — new ResourceLocation(...) は非推奨。
level.isClientSide() で論理サイド判定 — メソッド呼び出し形式(1.21.1以降)。
- Networkingのハンドラでは
context.enqueueWork() でメインスレッドに戻す — ネットワークスレッドでワールド変更を行うとクラッシュ。
- Capability取得は直接メソッド呼び出し —
LazyOptional は廃止。level.getCapability(...) / entity.getCapability(...) で直接取得。
- BlockEntityのデータ変更時は
setChanged() + level.sendBlockUpdated() を呼ぶ — どちらか欠けると保存/同期されない。
- Data ComponentsをItemStackのデータに使う —
persistent(Codec) + networkSynchronized(StreamCodec) の両方を提供する。
- Data AttachmentはBlockEntity/Entity/Chunk用 — ItemStackには使えない。ItemStackにはData Componentを使う。
sourceSets.main.resources { srcDir 'src/generated/resources' } を忘れない — DataGenの出力が読み込まれなくなる。
@EventBusSubscriber でbus自動検出 — bus の明示が不要になったが、特定バスに限定したい場合 bus = Bus.MOD または Bus.GAME を指定。
❌ やってはいけないこと
@OnlyIn をModコードで使わない — NeoForge内部専用。クライアント限定は @Mod(value = MODID, dist = Dist.CLIENT) または FMLClientSetupEvent で分離。
new ResourceLocation(...) を使わない — ResourceLocation.fromNamespaceAndPath() を使うこと。
- CapabilityにLazyOptionalを使わない — 1.21.1では廃止。
getCapability() は直接呼び出し。
- Data AttachmentをItemStackに使わない — ItemStackにはData Componentを使う。
mods.toml ではなく neoforge.mods.toml — ファイル名を間違えるとModが認識されない。
- ModDevGradleの
dependencies {} に minecraft や neoforge を書かない — neoForge { version = ... } ブロックで解決される。
- runClientクラッシュ後は
./gradlew --stop — Daemonがポートを占有していることがある。
- Data Componentの
Codec / StreamCodec を忘れない — ないとコンパイルエラーまたは実行時エラーになる。
開発ワークフロー(新規Mod作成時)
よく使うGradleタスク
./gradlew build # 配布用jar生成
./gradlew runClient # クライアント起動
./gradlew runServer # サーバー起動
./gradlew runData # DataGen実行
./gradlew runGameTestServer # GameTest実行
./gradlew clean # ビルドキャッシュ削除
一般的なタスクチェックリスト
Blockを追加する
DeferredRegister.Blocks → DeferredBlock<Block> を登録
- 同じ名前で
DeferredRegister.Items → BlockItem を登録(registerSimpleBlockItem で簡易化)
- BlockState JSON / Block Model / Texture(DataGen推奨)
- 必要に応じて
BlockEntity + BlockEntityType を登録
BlockTagsProvider でツール要件・採掘判定を追加
Itemを追加する
DeferredRegister.Items → DeferredItem<Item> を登録
- Item Model / Texture(DataGen推奨)
- 必要に応じて
DataComponentType を登録
LanguageProvider で表示名を追加
Entityを追加する
DeferredRegister<EntityType<?>> → DeferredHolder<EntityType<?>, EntityType<T>> を登録
EntityAttributeCreationEvent で属性(HP・移動速度など)を設定
EntityRenderersEvent.RegisterRenderers でRendererを登録(クライアント限定)
- Spawn Placements(自然スポーン条件)を設定
Recipeを追加する
RecipeProvider を継承したクラスを作成
buildRecipes(RecipeOutput) でレシピを定義
./gradlew runData を実行してJSONを生成
詳細リファレンス
Scripts
| Script |
Purpose |
scripts/check-build.sh |
JDK, Gradle, key files確認 + clean build |
scripts/validate-datapack.sh |
datapack JSON, pack.mcmeta, function tag参照の検証 |
scripts/validate-resource-pack.sh |
mod asset JSON, model/texture/sound参照の検証 |
scripts/scaffold-asset-brief.sh |
テクスチャ/プロモーションアート用Markdown brief生成 |
scripts/validate-test-layout.sh |
JUnit 5 / GameTest / MockBukkit プロジェクトレイアウト検証 |