【MOD開発】鉱石の生成を削除する方法

シェアする:
【MOD開発】鉱石の生成を削除する方法

注意!!

この記事の内容はMinecraft Ver.1.20.1、Forge Ver.47.3.0上で確認した内容になっています。

バージョンが異なると仕様やレシピが変更されている場合があります。

MOD開発のお話なので、プレイオンリーの人には興味のない話です。 すいません。

今回はデフォルトの鉱石生成を止める話。

なんでそんなことをしようと思ったかというと、

1.18の頃から採掘がつまらなくないですか?

Y座標が-64まで拡張され、Y0付近から深層岩が出るようになって、それに伴って深層岩の鉱石が追加されて、バランス調整をかねて既存の鉱石分布も大きく見直されました。

その結果、ダイヤ狙いだとあんまり鉄が掘れず、石炭は全く掘れないという状態になったので、Y-55付近とY15付近で2層のブランチマイニングをしないといけなくなりました。

層が分かれたことで何かしらの鉱石にあたる頻度が下がり、深層岩が硬いわ、鉱石は見つからんわでイライラしながら採掘してる人もいるでしょう。

そう、オレだ!

そんなわけで、デフォルトの鉱石生成をとめて、従来型の鉱石を配置するLegacy Oresなるmodを開発しようと思ったわけです。

ここでは鉱石削除のみの説明で、鉱石生成の追加はまた別の機会にやります。

ChatGPTやネットで調べた鉱石削除事情

まずChatGPTくんに聞いてみたら「BiomeLoadingEventで鉱石生成イベントを削除できるよー」ってコードがだらだら出て来ました。 調べてたらOre Removerだったかな、実際にBiomeLoadingEventで鉱石削除をしてそうなmodのソースも見つかりました。

ところがコイツ、1.19の時点で削除されてしまったらしく、当然1.20でも使えません。

ほな、1.20ではどないすんねん。

と調べてたらForge wikiなるものでBiomeModifierなる方法を見つけました。

僕はJAVAもmod開発もサッパリなので書いてあることは全然理解できなかったんですが、Remove Featuresという項目でJSONでやれそうなことが書いてあります。 もうちょっと上に戻ると「data/modid/forge/biome_modifier/」に置けばいいよと書いてあったので、ChatGPTくんのサポートしてもらってこんな↓JSONを書いて設置してみました。


{
  "type": "forge:remove_features",
  "biomes": "#minecraft:overworld",
  "features": "minecraft:iron_ore",
  "steps": "underground_ores"
}

クラッシュしました…。

「overworld」を「is_overworld」に変えたりとかいろいろ試したんですがぜーーーーーーーーーーーんぶクラッシュ。

しょうがないので、別の方法を探します。

DataGeneratorで鉱石削除JSONを出力する

この手のJSONってDataGeneratorを使って正しいものを出力することが出来るんです。

まぁ、今回はそれについては解説しないんですが。

最終的にDatapackBuiltinEntriesProviderで鉱石生成を追加するのと似たような方法でできました。

というのもですね、鉱石生成の時にForgeBiomeModifiers.AddFeaturesBiomeModifier()という関数を使うんですが、この「AddFeatures」ってどう見てもさっきのremoveの逆じゃないですか。 じゃーこのクラスにRemoveFeaturesという関数があるに違いないと思って、実際にありました。

ChatGPTくんに教えてもらってこんな↓感じ。


private static final RegistrySetBuilder BUILDER = new RegistrySetBuilder()
  .add(ForgeRegistries.Keys.BIOME_MODIFIERS, ctx -> {
    ctx.register(
      ResourceKey.create(ForgeRegistries.Keys.BIOME_MODIFIERS, new ResourceLocation(LegacyOres.MODID, "remove_overworld_ore")),
      new ForgeBiomeModifiers.RemoveFeaturesBiomeModifier(
        ctx.lookup(Registries.BIOME).getOrThrow(BiomeTags.IS_OVERWORLD),
          HolderSet.direct(
            ctx.lookup(Registries.PLACED_FEATURE).getOrThrow(ResourceKey.create(Registries.PLACED_FEATURE, new ResourceLocation("minecraft", "ore_diamond")))
        ),
        EnumSet.of(GenerationStep.Decoration.UNDERGROUND_ORES)
      )
    );
  }
);

「ore_diamond」の部分が削除する鉱石になる部分です。 これは鉱石のブロックIDではなくてPLACED_FEATUREという鉱石生成を定義している部分のIDです。 マイクラのJARファイルを開いて「data\minecraft\worldgen\placed_feature」にあるJSONの名前がそれに該当します。

鉄の場合はこの↓3つ。

  • ore_iron_middle
  • ore_iron_small
  • ore_iron_upper

金の場合はこの2つ。

  • ore_gold
  • ore_gold_lower

ore_gold_deltasとore_gold_netherはネザーの金です。 ore_gold_extraはメサのやつだと思います。

で、これで実際にJSONを出力してみると…

DataGeneratorが出力したJSON

まず出力フォルダは「data/modid/forge/biome_modifier/」で問題ないようでした。

出力されたJSONはこんな↓内容でした。


{
  "type": "forge:remove_features",
  "biomes": "#minecraft:is_overworld",
  "features": [
    "minecraft:ore_iron_middle",
    "minecraft:ore_iron_small",
    "minecraft:ore_iron_upper"
  ],
  "steps": "underground_ores"
}

バイオームの指定は「overworld」ではなく「is_overworld」でした。

「features」のところがブロックIDだと思ってたのが失敗で、「data\minecraft\worldgen\placed_feature」にあるJSONの名前のIDです。 そこさえ合ってたらJSONのままいけてたんですねー。

石炭や金、ダイヤなども加えてマイクラを起動すると、何の鉱石も生成されてないワールドになりました。 X-RAYで確認してます。

追加の課題

上記方法で間違いなく鉱石生成を止めることが出来たんですが、ちょっと問題もあって。

その状態でJustEnoughResourcesを入れてみて鉱石の生成率を見たんですが反映されてない↓んですよ。

modのロード順の問題なのかとmods.tomlをいじったりしてみたんですけど、これmodというよりデータパックみたいなもんだしなーと、フォルダ名変えたりしたんですが反映できず。

もうちょっと知識増えないと分かんない。

[DEV-TOC]

PR お手軽にマルチサーバでプレイしませんか?

処理性能No.1!快適なゲーム環境なら「Xserver for Game」

月額1000円くらいでオンラインにサーバを置いてMinecraftをマルチプレイできます。 統合版、Java版、Forgeに対応。

いやー僕はオンラインサーバって試したことなくて。

プレイ期間は24時間PC起動してたんですけど、電気代考えると1000円ならオンラインに置いた方が快適なのでは…?

過去のサーバデータを見たら1.12未満では500MB未満、1.12~1.18で1.5~2.0GB、1.19で3.0~3.5GBくらいだったので最安プランで問題なさそう。 スペック的にもマイクラは大丈夫みたいです。

僕も興味を持ったのでどういうサーバにするか考えた上でレビューしたいと思います。 マイクラ以外にもARK、テラリア、7 Days to Dieとかもいけるみたい。

シェアする: