name: 1201-forge-modding
description: >
Minecraft 1.20.1 Forge Moddingに関する開発支援。Modの新規作成、Block/Item/Entityの追加、
DataGen、ネットワーク処理、レシピ・進捗・ルートテーブルの生成、Capabilityの実装、
クラッシュ対応など。Minecraft 1.20.1 Moddingに関するタスクや、Gradle/MDKのセットアップ、
Registry/Event/sidednessに関する質問があった際に使用する。
license: MIT
compatibility: Requires JDK 17+, IntelliJ IDEA, Gradle, internet access for Minecraft/Forge artifacts
metadata:
author: code-onigiri
version: "0.4.0"
概要
このSkillは Minecraft 1.20.1 Forge 向けMod開発の標準パターンと落とし穴をまとめたものです。
✅ やるべきこと
- DeferredRegister + RegistryObject を使う — 旧来の
RegistryEvent ベースの登録は非推奨。
- DataGen を使う — 手書きJSONはミスとメンテナンスコストが爆発する。
- Mojang Mappings(official)が標準 — Parchmentでパラメータ名を補完する。
- すべてのDeferredRegisterをModBusにregisterする — コンストラクタで
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus(); を取得し、各 register(modEventBus) を呼ぶ。
- Block登録時はBlockItemも登録する — Blockだけではインベントリに出ない。
level.isClientSide で論理サイド判定 — 物理サイドではなく論理サイドで分岐。
- Networkingのハンドラでは
ctx.enqueueWork() でメインスレッドに戻す — ネットワークスレッドでワールド変更を行うとクラッシュ。
- Capability取得時は
LazyOptional を使う — isPresent() / ifPresent() で安全にアクセス。invalidateCaps() も必ず実装する。
- BlockEntityのデータ変更時は
setChanged() + level.sendBlockUpdated() を呼ぶ — どちらか欠けると保存/同期されない。
sourceSets.main.resources { srcDir 'src/generated/resources' } を忘れない — DataGenの出力が読み込まれなくなる。
❌ やってはいけないこと
@OnlyIn をModコードで使わない — Forge内部専用。使うとマルチプレイでクラッシュ。クライアント限定コードは @Mod.EventBusSubscriber(value = Dist.CLIENT) または FMLClientSetupEvent で分離する。
ResourceLocation に大文字・ハイフンを使わない — 小文字と _ / . / / のみ。
- ContainerDataの各スロットは16bit — 32bit整数(エネルギー量など)は2スロットに分割すること。
- PacketのID(int)を重複させない — SimpleChannelのregisterMessageでID衝突は通信破損。
- Capabilityを通常のBlockに直接付けない — BlockEntityが必要。
- runClientクラッシュ後は
./gradlew --stop — Daemonがポートを占有していることがある。
開発ワークフロー(新規Mod作成時)
よく使うGradleタスク
./gradlew build # 配布用jar生成
./gradlew runClient # クライアント起動
./gradlew runServer # サーバー起動
./gradlew runData # DataGen実行
./gradlew runGameTestServer # GameTest実行
./gradlew clean # ビルドキャッシュ削除
一般的なタスクチェックリスト
Blockを追加する
DeferredRegister<Block> → RegistryObject<Block> を登録
- 同じ名前で
DeferredRegister<Item> → RegistryObject<BlockItem> を登録
- BlockState JSON / Block Model / Texture(DataGen推奨)
- 必要に応じて
BlockEntity + BlockEntityType を登録
BlockTagsProvider でツール要件・採掘判定を追加
Itemを追加する
DeferredRegister<Item> → RegistryObject<Item> を登録
- Item Model / Texture(DataGen推奨)
- 必要に応じて
LanguageProvider で表示名を追加
Entityを追加する
DeferredRegister<EntityType<?>> → RegistryObject<EntityType<T>> を登録
EntityAttributeCreationEvent で属性(HP・移動速度など)を設定
EntityRenderersEvent.RegisterRenderers でRendererを登録(クライアント限定)
- Spawn Placements(自然スポーン条件)を設定
Recipeを追加する
RecipeProvider を継承したクラスを作成
buildRecipes(Consumer<FinishedRecipe>) でレシピを定義
./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 プロジェクトレイアウト検証 |