Skip to content

Fire Registration

Crystal Spider edited this page Jul 18, 2024 · 3 revisions

Registering

To make the API aware of your custom fire you need to register it.
Registration must be done in your mod loader class to work properly.

Let's break down in small steps how registering is done:

  1. Creating a Fire:
    A Fire instance is nothing more than a representation of your fire within the API.
    You need to register one to make the API aware of your fire and handle its behaviors.

  2. Getting a Fire.Builder:
    To create a Fire instance you need a Fire.Builder.
    To get one simply call FireManager#fireBuilder() and pass your Fire Type.

  3. Tweaking the Fire:
    The Fire about to be built will be constructed using the Fire Type provided to the Fire.Builder during initialization or reset.
    However you may want to change some other properties from their default value, for example the damage. More on this below.

  4. Building the Fire:
    It's as simple as calling Fire.Builder#build().

  5. Registering the Fire:
    Once you have built your Fire instance, pass it as parameter to FireManager#registerFire(Fire).

Here is a simple example of registering two different Fires:

public final class CommonModLoader {
  /**
   * Initialize common operations across loaders.
   */
  public static void init() {
    Fire.Builder fireBuilder = FireManager.fireBuilder(new ResourceLocation(Constants.MOD_ID, "custom_fire"));
    FireManager.registerFire(fireBuilder.setLight(12).setDamage(3).build());
    fireBuilder.reset("healing_fire");
    FireManager.registerFire(fireBuilder.setDamage(-2).setInvertHealAndHarm(true).build());
  }
}

It's also possible, and suggested, to save and reuse a single FireBuilder instance if you have to register multiple fires. FireBuilder#reset() can be used to reset each value to its default. If you use the FireBuilder#reset(String) overload, like in the example, the Mod Id will not be reset.
Trying to register multiple Fires with the same Fire Id won't throw, but only the first Fire will be registered and an error will be logged for the other ones.

Fire Builder

Here's a description of each Fire.Builder method, one by one with detailed explanation and also a description of the related Fire property:

  • setLight(int):
    Related property: Fire#light, emitted light level by fire related blocks such as fire source, campfire, torch, and lantern.
    Sets the light level, defaults to 15.
    Effective only on blocks registered via Soul Fire'd API.

  • setDamage(float):
    Related property: Fire#damage, fire damage per second.
    Sets the damage, defaults to 1.0F.
    The damage can be either positive or negative. Positive hurts, negative heals, 0 does nothing.
    What just said can change when applied to undead mobs such as zombies and skeleton as explained below.

  • setInvertHealAndHarm(boolean):
    Related property: Fire#invertHealAndHarm, whether to invert harm and heal for mobs that have potion effects inverted (e.g. undead).
    Sets the flag for inverting heal and harm for undeads, defaults to false.
    Determines whether to invert heal and harm for undeads:

    Damage Flag Effect
    Positive false Hurts all entities
    Positive true Hurts normal entities, heals undead mobs
    Negative false Heals all entities
    Negative true Heals normal entities, hurts undead mobs
  • setCanRainDouse(boolean):
    Related property: Fire#canRainDouse, whether rain can douse the Fire.
    Sets the flag for allowing rain to douse the fire, defaults to false.
    Effective only on fire source blocks registered via Soul Fire'd API.

  • setOnCampfire():
    Related property: Fire#onCampfireGetter, DamageSource getter for when the entity takes damage from a campfire.
    Sets the onCampfireGetter DamageSource getter, defaults to Fire.Builder#DEFAULT_ON_CAMPFIRE_GETTER.

  • setInFire():
    Related property: Fire#inFireGetter, DamageSource getter for when the entity is in or on a block providing fire.
    Sets the inFireGetter DamageSource getter, defaults to Fire.Builder#DEFAULT_IN_FIRE_GETTER.

  • setOnFire():
    Related property: Fire#onFireGetter, DamageSource getter for when the entity is burning.
    Sets the onFireGetter DamageSource getter, defaults to Fire.Builder#DEFAULT_ON_FIRE_GETTER.

  • setComponent(Fire.Component<?, ?>, ResourceLocation) / removeComponent(Fire.Component<?, ?>):
    Related property: Fire#components, map of all Fire Components.
    Changes the value of the specified Fire Component or removes it from the Fire map.
    Read more about these in the dedicated section.

  • setBehavior(Predicate<Entity>) / setBehavior(Consumer<Entity>):
    Related property: Fire#behavior, custom behavior to apply before the entity takes damage or heals.
    Sets the custom Fire behavior, either with an explicit return or with an implicit true.
    The return value determines whether the default hurt/heal behavior should still apply.
    Read more about these in the dedicated section.

  • reset(ResourceLocation) / reset(String, String) / reset(String):
    Resets all current values in the Fire.Builder to their default.
    The reset(String) overload will not reset the Mod Id, useful if you need to register multiple fires of the same mod.

  • build():
    Returns a new Fire instance to register.

Before 1.21

Before Minecraft 1.21, enchantments were created via code rather than being data driven.
For this reason, Fire.Builder included the following methods:

  • setFireAspectConfig(Function<FireAspectBuilder, FireAspectBuilder>):
    Related property: Fire#fireAspect, FireTypedFireAspectEnchantment (fire aspect) for the fire.
    Sets the Fire Aspect enchantment configuration to use to build the enchantment, defaults to the default configuration.
    See Tweaking enchantments for details on how to tweak the enchantment configuration.

  • removeFireAspect():
    Related property: Fire#fireAspect, FireTypedFireAspectEnchantment (fire aspect) for the fire.
    Prevents the generation of the Fire Aspect enchantment for the fire, to be used if you never want the enchantment to exist.
    If you wish instead to make the enchantment available depending on your mod configuration, see Tweaking enchantments.

  • setFlameConfig(Function<FlameBuilder, FlameBuilder>):
    Related property: Fire#flame, FireTypedFlameEnchantment (flame) for the fire.
    Sets the Flame enchantment configuration to use to build the enchantment, defaults to the default configuration.
    See Tweaking enchantments for details on how to tweak the enchantment configuration.

  • removeFlame():
    Related property: Fire#flame, FireTypedFlameEnchantment (flame) for the fire.
    Prevents the generation of the Flame enchantment for the fire, to be used if you never want the enchantment to exist.
    If you wish instead to make the enchantment available depending on your mod configuration, see Tweaking enchantments.

Furthermore, there was no specific DamageSource for campfire, so the method setOnCampfire() and the related property didn't exist.

Before 1.19.4

Before Minecraft 1.19.4, the DamageSource was drastically different.
It had hardcoded static references for all the damage sources, instead of being more data driven and allowing for damage type tags.
For this reason, before 1.19.4, Fires had direct references to their damage source instead of getters (Function<Entity, DamageSource>).

Tweaking enchantments

Since 1.21

Since Minecraft 1.21, enchantments are now exclusively data driven.
For this reason, all classes related to building and registering Fire enchantments via code have been removed, and it's now needed to create the enchantments via JSON files.
Of course, Soul Fire'd provides an enchantment effect for this.
Read more about custom Fire data driven enchantments in the dedicated wiki section.

Before 1.21

Each registered Fire comes by default with its own Fire Aspect and Flame enchantments, each with its own configuration.
To remove an enchantment altogether, just call its remove method when building your Fire.
To instead tweak the configuration of an enchantment you need to call its set config method when building your Fire and using the provided FireEnchantmentBuilder instance to change what you'd like to change.
For example, suppose you have a couple of configuration options to set whether the enchantments are treasure:

// When building and registering a Fire.
.setFireAspectConfig(builder -> builder.setEnabled(ModConfig::getCustomFireAspectIsTreasure))
.setFlameConfig(builder -> builder.setEnabled(ModConfig::getCustomFlameIsTreasure))

This way whether the enchantments are considered treasure, the same way as Mending, depends on the value read from the mod configuration.
Another example may be calling FireEnchantmentBuilder#setRarity(Rarity) to change the rarity of the enchantment.

Each FireEnchantmentBuilder method has an overload that, instead of taking directly the value, it takes a Supplier of that value, to allow a dynamic configuration for enchantments.
The only exceptions to this are FireEnchantmentBuilder#setEnabled(Supplier<Boolean>), FireEnchantmentBuilder#setCompatibility(Function<Enchantment, Boolean>) and FireEnchantmentBuilder#setRarity(Rarity) that only have the mentioned signatures.

It's also possible to tweak the applied fire duration by setting the duration property when building the enchantment.
Like most other properties, it can either take a supplier (actually a TriFunction giving access to the attacker, target, and default duration) or a raw value. It defaults to Vanilla Fire Aspect and Flame durations.
If you need the enchantment level when calculating the duration for a Fire Aspect, you can just divide by 4 the default duration.

Registering another mod's fire

Once registering is done, everything is set for the Fire to work properly.
This means you can also register another mod's fire and it will work as well!
However, make sure all the Client and Server resources are there, possibly adding the missing ones.

If your mod's aim is only to register other mods Fires, you might consider using Data Driven Fires.