java.lang.Object
com.binaris.wizardry.api.content.spell.Spell
Direct Known Subclasses:
AreaEffectSpell, ArrowSpell, BetterFlight, Blink, BlockWithSurprise, BuffSpell, Charge, ConjureItemSpell, ConstructSpell, DragonFireball, Evade, Fangs, FlamingWeapon, Flight, FrostBarrier, GrowthAura, ImbueWeapon, InvokeWeather, Leap, Levitation, LightningPulse, MinionSpell, NoneSpell, PhaseStep, PocketFurnace, PocketWorkbench, ProjectileSpell, RaySpell, ShulkerBullet, SpeedTime, VanishingBox, WitherSkullSpell

public abstract class Spell extends Object
Abstract blueprint for every spell in the mod.

Spell is the high-level contract that all concrete spell classes must follow. It defines the casting entry points, a small sound helper API, and access to data-driven properties that configure a spell's behavior. Implementations usually override one or more cast(...) methods and the properties() factory to provide defaults and custom behavior.
Responsibilities:

- Provide cast(...) entry points for player, entity or location-based casts.

- Expose configurable data via SpellProperties and the helper property(...).

- Resolve name/description/icon from the registry using Services.REGISTRY_UTIL.

- Offer simple sound helpers for one-shot and continuous sounds.


Recommended implementation pattern:

1) Override properties() to set defaults (cost, cooldown, element, tier, ...).

2) Override the appropriate cast(...) method for your source (player/entity/location). If entities or locations are valid casters, enable them via canCastByEntity() / canCastByLocation().

3) Use playSound(...) or playSoundLoop(...) for audio. Continuous spells should use playSoundLoop(...) to start the client-side loop at the first tick.

4) For small behaviors, consider using existing abstract helpers such as RaySpell or ArrowSpell instead of a custom class.


Client/server notes:

By default, spells are processed on the server and mirrored to clients when requiresPacket() returns true. Keep requiresPacket() as true if your spell spawns particles or relies on client-side effects. Override only as an optimization when logic is purely server-side.


Edge cases and notes:

- Equality is based on the registered ResourceLocation; two spell instances with the same registry key are considered equal.

- Default continuous sound names are derived from the spell path. The standard loop expects three sounds: spell...start, .loop and .end.

- Properties are assigned from properties() in the constructor, but can be replaced at runtime with assignProperties(...) for dynamic or test variants.

  • Field Summary

    Fields
    Modifier and Type
    Field
    Description
    protected float
    The pitch of the sound played by this spell, relative to 1.
    protected float
    The random variation in the pitch of the sound played by this spell.
    protected float
    The volume of the sound played by this spell, relative to 1.
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    final Spell
    Helper method when you're creating spells that doesn't need a custom class (like ArrowSpell or ProjectileSpell spells), allowing you to set the properties of the spell in a more concise way.
    boolean
    Whether this spell can be cast by an entity source (e.g.
    boolean
    Whether this spell can be cast by a non-entity source (e.g.
    boolean
    This cast method is meant to be used for spells that are cast by an entity source, like a mob.
    boolean
    This cast method is meant to be used for spells that are not cast by an entity, but rather by a non-entity source, like a command block or a dispenser.
    abstract boolean
    This cast method is meant to be used for spells that are cast by a player source.
    void
    Called when the spell finishes casting, in case you want to make any special behavior happen when the spell finishes casting, like applying a buff to the player or something.
    boolean
     
    Gets the action of this spell.
    int
    Gets the charge-up time of this spell in ticks.
    int
    Gets the cooldown of this spell in ticks.
    int
    Gets the cost of this spell in spell points.
    net.minecraft.network.chat.Component
    Gets the description for this spell.
    net.minecraft.network.chat.Component
    Gets the formatted description for this spell (e.g.
    Will return the description ID for the spell (e.g.
    Gets the element of this spell.
    net.minecraft.resources.ResourceLocation
    Gets the icon for this spell.
    net.minecraft.resources.ResourceLocation
    Will return the location for the spell (e.g.
    protected net.minecraft.sounds.SoundEvent[]
    Helper method that you could change if you want to add/change the names of the 3 sound events that are used for the standard continuous spell sound loop.
    protected String
    Will return the description ID for the spell (e.g.
    protected net.minecraft.resources.ResourceLocation
    Will return the location for the spell (e.g.
    float
    Gets the pitch for this spell.
    float
    Gets the pitch variation for this spell.
    This is just for internal use mostly, used to load the properties from the data files and vice versa.
    Gets the tier of this spell.
    Gets the type of this spell.
    float
    Gets the volume for this spell.
    boolean
    Checks if this spell is enabled in the given context.
    boolean
    Whether this spell is instant or not.
    void
    Deprecated.
    protected void
    playSound(net.minecraft.world.level.Level world, double x, double y, double z, int ticksInUse, int duration)
    Plays this spell's sounds at the given position in the given world.
    protected void
    playSound(net.minecraft.world.level.Level world, net.minecraft.world.entity.LivingEntity entity, int castTicks, int duration)
    Plays this spell's sound at the given entity in the given world.
    protected void
    playSound(net.minecraft.world.level.Level world, net.minecraft.world.phys.Vec3 pos, int castTicks, int duration)
    Plays this spell's sound at the given position in the given world.
    protected final void
    playSoundLoop(net.minecraft.world.level.Level world, double x, double y, double z, int ticksInUse, int duration)
    Start the standard continuous spell sound loop at the given position on the first cast tick.
    protected final void
    playSoundLoop(net.minecraft.world.level.Level world, net.minecraft.world.entity.LivingEntity entity, int ticksInUse)
    Start the standard continuous spell sound loop on the given entity at the first cast tick.
    protected abstract @NotNull SpellProperties
    This method is where you should set the default properties for your spell when creating a new spell class.
    final <T> T
    property(SpellProperty<T> property)
    Gets the value of the given property for this spell.
    boolean
    Whether this spell requires a packet to be sent on client when it is cast.
    soundValues(float volume, float pitch, float pitchVariation)
    Sets the sound parameters for this spell.
     

    Methods inherited from class java.lang.Object

    clone, finalize, getClass, hashCode, notify, notifyAll, wait, wait, wait
  • Field Details

    • volume

      protected float volume
      The volume of the sound played by this spell, relative to 1.
    • pitch

      protected float pitch
      The pitch of the sound played by this spell, relative to 1.
    • pitchVariation

      protected float pitchVariation
      The random variation in the pitch of the sound played by this spell.
  • Constructor Details

    • Spell

      public Spell()
  • Method Details

    • cast

      public abstract boolean cast(PlayerCastContext ctx)
      This cast method is meant to be used for spells that are cast by a player source. This is useful for spells that are meant to be cast by players, as it provides more information about the caster and the context of the cast.

      Override this method to implement the casting behavior for spells that are meant to be cast by players.

      Parameters:
      ctx - The context of the spell cast, containing information about the world, caster, hand used, modifiers, etc.
      Returns:
      true if the spell was successfully cast, false otherwise. If this returns false, the spell will not be considered as having been cast, so no cooldown will be applied.
    • cast

      public boolean cast(EntityCastContext ctx)
      This cast method is meant to be used for spells that are cast by an entity source, like a mob. This is useful for spells that are meant to be cast by entities, as it provides more information about the caster and the context of the cast.

      Override this method to implement the casting behavior for spells that are meant to be cast by entities.

      Parameters:
      ctx - The context of the spell cast, containing information about the world, caster, modifiers, etc.
      Returns:
      true if the spell was successfully cast, false otherwise. If this returns false, the spell will not be considered as having been cast, so no cooldown will be applied.
    • cast

      public boolean cast(LocationCastContext ctx)
      This cast method is meant to be used for spells that are not cast by an entity, but rather by a non-entity source, like a command block or a dispenser. This is useful for spells that are meant to be cast in a specific location without needing an entity to cast them. By default, this returns false, as most spells are meant to be cast by entities. You can override this to return true if your spell is meant to be cast by non-entity sources and to implement the casting behavior for that case.
      Parameters:
      ctx - The context of the spell cast, containing information about the world, location, modifiers, etc.
      Returns:
      true if the spell was successfully cast, false otherwise. If this returns false, the spell will not be considered as having been cast, so no cooldown will be applied.
    • endCast

      public void endCast(CastContext cxt)
      Called when the spell finishes casting, in case you want to make any special behavior happen when the spell finishes casting, like applying a buff to the player or something. This is called regardless of whether the spell is instant or not, so it will be called at the end of the cast() method for instant spells, and at the end of the last tick of casting for non-instant spells.
      Parameters:
      cxt - The context of the spell cast, containing information about the world, caster (if any), location (if any), modifiers, etc.
    • onCharge

      @Deprecated public void onCharge(CastContext ctx)
      Deprecated.
      Called when the spell is on charge time, this is meant to be used for spells that have a charge-up time, allowing you to implement the behavior of the spell during the charge-up time.
      Parameters:
      ctx - The context of the spell cast, containing information about the world, caster (if any), location (if any), modifiers, etc.
    • isInstantCast

      public boolean isInstantCast()
      Whether this spell is instant or not. An instant spell is a spell that is cast in a single tick, (it could have cooldown and/or charge-up time) and does not have a duration. By default, this returns true, as most spells are instant, but you can override this to return false if your spell is meant to have a duration and be cast over multiple ticks.
      Returns:
      true if this spell is instant, false otherwise.
    • canCastByEntity

      public boolean canCastByEntity()
      Whether this spell can be cast by an entity source (e.g. a player or a mob). By default, this returns false, as some spells may be designed to only be cast by non-entity sources, but you can override this to return true if your spell is meant to be cast by entities.
      Returns:
      true if this spell can be cast by an entity source, false otherwise.
    • canCastByLocation

      public boolean canCastByLocation()
      Whether this spell can be cast by a non-entity source (e.g. a command block or a dispenser). By default, this returns false, as most spells are meant to be cast by entities, but you can override this to return true if your spell is designed to be cast by non-entity sources.
      Returns:
      true if this spell can be cast by a non-entity source, false otherwise.
    • requiresPacket

      public boolean requiresPacket()
      Whether this spell requires a packet to be sent on client when it is cast. Returns true by default, but can be overridden to return false if the spell's cast() method does not use any code that must be executed client-side (i.e. particle spawning).

      If in doubt, leave this method as is; it is purely an optimization.

      Returns:
      true if the spell code should be run on the server and all clients in the dimension, false if the spell code should only be run on the server and the client of the player casting it.
    • getDescriptionFormatted

      public net.minecraft.network.chat.Component getDescriptionFormatted()
      Gets the formatted description for this spell (e.g. Fireball with dark red color). By default, this is a translatable component with the key "spell.[namespace].[path]", where [namespace] and [path] are the namespace and path of this spell's location, respectively, and with the color of this spell's element.
    • getOrCreateDescriptionId

      protected String getOrCreateDescriptionId()
      Will return the description ID for the spell (e.g. "spell.ebwizardry.fireball"), in case it hasn't been set yet, it will attempt to get it from the registry using the spell instance. This is used to avoid needing to set the description ID manually for every spell, as it can be easily obtained from the registry and formatted.
      Returns:
      The description ID for this spell, used for formatting and translations. By default, this is "spell.[namespace].[path]", where [namespace] and [path] are the namespace and path of this spell's location, respectively.
    • getDescriptionId

      public String getDescriptionId()
      Will return the description ID for the spell (e.g. "spell.ebwizardry.fireball") if you want the location instead, use getLocation()
      Returns:
      The description ID for this spell, used for formatting and translations. By default, this is "spell.[namespace].[path]", where [namespace] and [path] are the namespace and path of this spell's location, respectively.
    • getOrCreateLocation

      protected net.minecraft.resources.ResourceLocation getOrCreateLocation()
      Will return the location for the spell (e.g. "ebwizardry:fireball"), in case it hasn't been set yet, it will attempt to get it from the registry using the spell instance. This is used to avoid needing to set the location manually for every spell, as it can be easily obtained from the registry.
      Returns:
      The ResourceLocation where this spell is registered.
    • getLocation

      public net.minecraft.resources.ResourceLocation getLocation()
      Will return the location for the spell (e.g. "ebwizardry:fireball") if you want the description ID (formatted name) instead, use getDescriptionId().
      Returns:
      The ResourceLocation where this spell is registered.
    • getDesc

      public net.minecraft.network.chat.Component getDesc()
      Gets the description for this spell. By default, this is a translatable component with the key "spell.[namespace].[path].desc", where [namespace] and [path] are the namespace and path of this spell's location, respectively. You can override this method to provide a custom description for your spell in a different way.
      Returns:
      The description for this spell.
    • getIcon

      public net.minecraft.resources.ResourceLocation getIcon()
      Gets the icon for this spell. By default, this is "textures/spells/[namespace]/[path].png", where [namespace] and [path] are the namespace and path of this spell's location, respectively. You can override this method to provide a custom icon for your spell in a different way.
      Returns:
      The ResourceLocation of the icon for this spell.
    • getProperties

      public final SpellProperties getProperties()
      This is just for internal use mostly, used to load the properties from the data files and vice versa. You should use the property(SpellProperty<T>) method to get the value of a specific property.
      Returns:
      The SpellProperties object containing all properties for this spell.
    • properties

      @NotNull protected abstract @NotNull SpellProperties properties()
      This method is where you should set the default properties for your spell when creating a new spell class. This method is called in the constructor of the Spell class, and the properties returned by this method are assigned to the spell's properties field.
      Returns:
      A SpellProperties object with the default properties for your spell.
    • assignProperties

      public final Spell assignProperties(SpellProperties properties)
      Helper method when you're creating spells that doesn't need a custom class (like ArrowSpell or ProjectileSpell spells), allowing you to set the properties of the spell in a more concise way.
      Parameters:
      properties - The properties to set for this spell.
      Returns:
      The spell instance, allowing this method to be chained onto the constructor.
    • property

      public final <T> T property(SpellProperty<T> property)
      Gets the value of the given property for this spell. This is a shortcut for getProperties().get(property). You should always use this method instead of directly calling getProperties().get(property) for better readability.
      Type Parameters:
      T - The type of the property value.
      Parameters:
      property - The property to get the value of.
      Returns:
      The value of the given property for this spell.
    • getChargeUp

      public int getChargeUp()
      Gets the charge-up time of this spell in ticks. By default, this is 0, meaning the spell is instant and has no charge-up time.
      Returns:
      The charge-up time of this spell in ticks.
    • getType

      public SpellType getType()
      Gets the type of this spell. By default, this is SpellType.UTILITY.
      Returns:
      The type of this spell.
    • getAction

      public SpellAction getAction()
      Gets the action of this spell. By default, this is SpellAction.POINT.
      Returns:
      The action of this spell.
    • getElement

      public Element getElement()
      Gets the element of this spell. By default, this is Elements.MAGIC.
      Returns:
      The element of this spell.
    • getTier

      public SpellTier getTier()
      Gets the tier of this spell. By default, this is SpellTiers.NOVICE.
      Returns:
      The tier of this spell.
    • getCost

      public int getCost()
      Gets the cost of this spell in spell points. By default, this is 0, meaning the spell is free to cast. (You shouldn't leave this on 0 for most spells)
      Returns:
      The cost of this spell in spell points.
    • getCooldown

      public int getCooldown()
      Gets the cooldown of this spell in ticks. By default, this is 0, meaning the spell has no cooldown.
      Returns:
      The cooldown of this spell in ticks.
    • isEnabled

      public boolean isEnabled(SpellContext context)
      Checks if this spell is enabled in the given context. By default, all contexts are enabled, it's the user's responsibility to disable the contexts in the mod config.
      Parameters:
      context - The context to check.
      Returns:
      true if this spell is enabled in the given context, false otherwise.
    • toString

      public String toString()
      Overrides:
      toString in class Object
    • equals

      public boolean equals(Object obj)
      Overrides:
      equals in class Object
    • soundValues

      public Spell soundValues(float volume, float pitch, float pitchVariation)
      Sets the sound parameters for this spell.
      Parameters:
      volume - The volume of the sound played by this spell, relative to 1.
      pitch - The pitch of the sound played by this spell, relative to 1.
      pitchVariation - The random variation in the pitch of the sound played by this spell. The pitch at which the sound is played will be randomly chosen from the range: pitch +/- pitchVariation.
      Returns:
      The spell instance, allowing this method to be chained onto the constructor.
    • getVolume

      public float getVolume()
      Gets the volume for this spell.
      Returns:
      The volume of the sound played by this spell, relative to 1.
    • getPitch

      public float getPitch()
      Gets the pitch for this spell. The pitch at which the sound is played will be randomly chosen from the range: getPitch() +/- getPitchVariation().
      Returns:
      The base pitch of the sound played by this spell.
    • getPitchVariation

      public float getPitchVariation()
      Gets the pitch variation for this spell. The pitch at which the sound is played will be randomly chosen from the range: getPitch() +/- getPitchVariation().
      Returns:
      The random variation in the pitch of the sound played by this spell.
    • playSound

      protected void playSound(net.minecraft.world.level.Level world, net.minecraft.world.entity.LivingEntity entity, int castTicks, int duration)
      Plays this spell's sound at the given entity in the given world. This calls playSound(Level, double, double, double, int, int), passing in the given entity's position as the xyz coordinates. Also checks if the given entity is silent, and if so, does not play the sound.

      You should override this is you're trying to implement a custom sound loop, check FrostRaySpell as an example.

      Parameters:
      world - The world to play the sound in.
      entity - The entity to play the sound at, provided it is not silent.
      castTicks - The number of ticks this spell has already been cast for, passed in from the cast(...) methods. Not used in the base method, but included for use by subclasses overriding this method.
      duration - The number of ticks this spell will be cast for, passed in from the cast(...) methods. Not used in the base method, but included for use by subclasses overriding this method.
    • playSound

      protected void playSound(net.minecraft.world.level.Level world, net.minecraft.world.phys.Vec3 pos, int castTicks, int duration)
      Plays this spell's sound at the given position in the given world. This is a vector-based wrapper for playSound(Level, double, double, double, int, int).

      This is not called automatically by the Spell class; subclasses should call it at the appropriate point(s) in the cast methods. If you're using any standard subclass of Spell (e.g. RaySpell ArrowSpell) you won't need to handle the sound system by yourself, as these classes will call the playSound in the right moment for you.

      Parameters:
      world - The world to play the sound in.
      pos - A vector representing the position to play the sound at.
      castTicks - The number of ticks this spell has already been cast for, passed in from the cast(...) methods. Not used in the base method, but included for use by subclasses overriding this method.
      duration - The number of ticks this spell will be cast for, passed in from the cast(...) methods. Not used in the base method, but included for use by subclasses overriding this method.
    • playSound

      protected void playSound(net.minecraft.world.level.Level world, double x, double y, double z, int ticksInUse, int duration)
      Plays this spell's sounds at the given position in the given world. This is not called automatically by the Spell class; subclasses should call it at the appropriate point(s) in the cast methods. You can also override this method if you want to implement a sound loop (normally for continuous spells), check FrostRaySpell as an example.

      In case you're using any standard subclass of Spell (e.g. RaySpell ArrowSpell) you won't need to handle the sound system by yourself, as these classes will call the playSound in the right moment for you.

      Parameters:
      world - The world to play the sound in.
      x - The x position to play the sound at.
      y - The y position to play the sound at.
      z - The z position to play the sound at.
      ticksInUse - The number of ticks this spell has already been cast for, passed in from the cast(...) methods.
      duration - The number of ticks this spell will be cast for, passed in from the cast(...) methods. Not used in the base method, but included for use by subclasses overriding this method.
    • playSoundLoop

      protected final void playSoundLoop(net.minecraft.world.level.Level world, net.minecraft.world.entity.LivingEntity entity, int ticksInUse)
      Start the standard continuous spell sound loop on the given entity at the first cast tick. This is likely happening with a player or some living-entity-based casting logic, so the sound loop will be played at the given entity's position and will follow the entity as it moves. The sound loop will only be started if the given entity is not silent, and if this is the first tick of casting (i.e. ticksInUse is 0), so that the sound loop starts on the first tick of casting and does not start at all if the entity is silent.
      Parameters:
      world - The world to play the sound in.
      entity - The entity to play the sound at, provided it is not silent
      ticksInUse - The number of ticks this spell has already been cast for, passed in from the cast(...) methods. This method will only play the sound loop if this is 0, so that the sound loop starts on the first tick of casting.
    • playSoundLoop

      protected final void playSoundLoop(net.minecraft.world.level.Level world, double x, double y, double z, int ticksInUse, int duration)
      Start the standard continuous spell sound loop at the given position on the first cast tick. This is likely happening with a dispenser or some static casting logic (like casting a spell from a command) so the sound loop will be played at the given position.
      Parameters:
      world - The world to play the sound in.
      x - The x position to play the sound at.
      y - The y position to play the sound at.
      z - The z position to play the sound at.
      ticksInUse - The number of ticks this spell has already been cast for, passed in from the cast(...) methods. This method will only play the sound loop if this is 0, so that the sound loop starts on the first tick of casting.
      duration - The number of ticks this spell will be cast for, passed in from the cast(...) methods. This is used to determine how long the sound loop should last; if this is -1, the sound loop will last until the spell ends, otherwise it will last for the given number of ticks.
    • getLoopSounds

      protected net.minecraft.sounds.SoundEvent[] getLoopSounds()
      Helper method that you could change if you want to add/change the names of the 3 sound events that are used for the standard continuous spell sound loop. Keep in mind that if you want to add more than 3 sound events, you will need to make your own implementation to handle the extra sound events.

      By default, this method assumes that the sound events are named "spell.[namespace].[path].start", "spell.[namespace].[path].loop", and "spell.[namespace].[path].end", where [namespace] and [path] are the namespace and path of this spell's location, respectively.

      Returns:
      By default, an array of 3 sound events, in the order of start, loop, and end sounds.