Jump to content

[SOLVED] (1.19) Configuring Per-Biome Spawn Weight for Entities using TOML Configs


Mikul

Recommended Posts

I'm currently updating my mod from 1.18, which previously allowed players to define the spawn weight of my custom entity for any biome via .TOML config files. This was done by subscribing to BiomeLoadingEvent and adding to the spawn list. That event has now been removed in favor of the new data-driven system, which I am still trying to fully grasp.

My current idea is to hook into GatherDataEvent and iterate through the list of user-defined biomes from the config, but the issue is that the configs aren't loaded at this stage, and runData crashes because the ForgeConfigSpec isn't initialized yet.

Here's what I currently have:

@SubscribeEvent
    public static void gatherData(GatherDataEvent event)
    {
        DataGenerator generator = event.getGenerator();
        ExistingFileHelper helper = event.getExistingFileHelper();
        RegistryOps<JsonElement> registryOps = RegistryOps.create(JsonOps.INSTANCE, RegistryAccess.builtinCopy());

		<...>          
          
        EntityType<ChameleonEntity> chameleon = EntityInit.CHAMELEON.get();
        ConfigSettings.CHAMELEON_BIOMES.get().forEach((biomeID, weight) ->
        {
            ForgeRegistries.BIOMES.getHolder(biomeID).ifPresent(biomeHolder ->
            {
                modifiers.put(new ResourceLocation(ColdSweat.MOD_ID, "chameleon_spawns_" + biomeID.getNamespace() + "_" + biomeID.getPath()),
                              ForgeBiomeModifiers.AddSpawnsBiomeModifier.singleSpawn(HolderSet.direct(biomeHolder), new MobSpawnSettings.SpawnerData(chameleon, weight, 1, 1)));
            });
        });

        JsonCodecProvider<BiomeModifier> jsonCodecProvider = JsonCodecProvider.forDatapackRegistry(generator, helper, ColdSweat.MOD_ID, registryOps, ForgeRegistries.Keys.BIOME_MODIFIERS, modifiers);
        generator.addProvider(event.includeServer(), jsonCodecProvider);
    }

And here's the code on GitHub: https://github.com/Momo-Studios/Cold-Sweat/blob/1.19.x-FG/src/main/java/dev/momostudios/coldsweat/data/ColdSweatData.java

Is there a way to access the configs at this stage, or should I be using another way? I'd highly prefer using the configs since they're simpler to edit for users.

Edited by Mikul
Solved
Link to comment
Share on other sites

13 hours ago, Mikul said:

I'm currently updating my mod from 1.18, which previously allowed players to define the spawn weight of my custom entity for any biome via .TOML config files.

You should just let people change this via a datapack. That's literally the point since they can replace the values themselves.

Link to comment
Share on other sites

1 hour ago, ChampionAsh5357 said:

You should just let people change this via a datapack. That's literally the point since they can replace the values themselves.

I understand that it's their intended purpose, and they're definitely much more versatile, but I find them more cumbersome to use than the configs I had set up before, and I think most of my user base would agree.

Plus, what I'm attempting to do wouldn't prevent anyone from using a data pack if they want, to my knowledge.

Link to comment
Share on other sites

  • Mikul changed the title to (1.19) Configuring Per-Biome Spawn Weight for Entities using Configs

I think I've misunderstood how data generation works. I thought GatherDataEvent was called at runtime, but I've found that it's only used for generating static JSON files when runData is executed, which are shipped with the mod. It seems to me that it's now impossible to do this in the way that I originally had.

And I now have another concern about these data-driven biome modifiers. How is inter-mod compatibility implemented? Say I wanted my entity to spawn in rainforests from Biomes O' Plenty (optional dependency). If I make a file adding the mob to "biomesoplenty:rainforest", datapack loading now fails unless the "biomesoplenty" is loaded. I cannot find any way to make this an "optional" biome modifier, similar to how tags can be optional. Am I missing something?

Edited by Mikul
Link to comment
Share on other sites

  • Mikul changed the title to (1.19) Configuring Per-Biome Spawn Weight for Entities using TOML Configs
13 hours ago, Mikul said:

It seems to me that it's now impossible to do this in the way that I originally had.

You can technically screw with it using a biome modifier to force the config check yourself; however, I still recommend against it.

13 hours ago, Mikul said:

I cannot find any way to make this an "optional" biome modifier, similar to how tags can be optional. Am I missing something?

You can make an optional biome modifier. Create your own that checks if the mod is loaded first, and don't do anything if it isn't.

Link to comment
Share on other sites

35 minutes ago, ChampionAsh5357 said:

You can technically screw with it using a biome modifier to force the config check yourself; however, I still recommend against it.

You can make an optional biome modifier. Create your own that checks if the mod is loaded first, and don't do anything if it isn't.

Alright, then I'll look into making my own. Thank you for the suggestion. If biome modifiers are a Forge construct then I might suggest that optionality be added To the built-in ones.

Link to comment
Share on other sites

Making a custom biome modifier worked. I just need a dummy JSON file for the modifier to be loaded, then it injects the spawns according to the config settings. I also added an option to disable this, if the user wanted to define the spawns the normal way. It looks something like this:

// This is a generic version of my implementation, without all the stuff specific to my mod
@Override
public void modify(Holder<Biome> biome, Phase phase, ModifiableBiomeInfo.BiomeInfo.Builder builder)
{
    // Ensure proper phase and user is using configs
    if (phase == Phase.ADD && useConfigs)
    {   // Null check for optional ResourceKey
        biome.unwrapKey().ifPresent(biomeKey ->
        {   
            ResourceLocation biomeID = biomeKey.location();
            // I have a static map of the user's configured spawn weights parsed from the config
            Integer weight = MAP_OF_ENTITY_WEIGHTS.get(biomeID);
            // Weight is null if undefined
            if (weight != null)
            {   builder.getMobSpawnSettings().addSpawn(MobCategory.CREATURE, new MobSpawnSettings.SpawnerData(MyEntity, weight, 1, 1));
            }
        });
    }
}

This also has no problems with other mods' biomes being present or not, since it's only called for existing biomes in the registry.

Thanks for pointing me in the right direction. I needed to take a second look at custom biome modifiers to see how to do this.

Edited by Mikul
Link to comment
Share on other sites

  • Mikul changed the title to [SOLVED] (1.19) Configuring Per-Biome Spawn Weight for Entities using TOML Configs

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.