The mod adds a system where the player can find books of spells and cast them using mana/fuel stored in items. The system has been designed to be easily extensible (both within the mod and by other mods that want to reuse the system), have data-driven components for ease of user modification in-game, and allow arbitrary items to be sources of fuel for spells, or hold spells themselves for casting. Here are some notes on the architecture.
Casting spells requires spell fuel. Fuel is represented as a SpellFuelQuantity record, made up of an integer quantity and a SpellFuelType. Mods can add fuel types with SpellFuelTypes#createSpellFuelType(String id, ChatFormatting colour).
Spell fuel can be stored on any item with an attached SpellBatteryComponent, using the vanilla data component system. The component can store either a specific fuel type or a universal colourless type, and uses the id abyssal:spell_fuel_store.
SpellBatteryComponent items can be refueled by items with a SpellRefuelComponent and a RestoreFuelConsumeEffect. The consume effect gives the item right-click behaviour and performs the refuel, while the component defines the SpellFuelQuantity being restored. Player-held batteries can also be refueled directly by calling quantity.topUp(player) on a FuelQuantity.
Spells are assigned to spellbook items, or any other item in principle, with the SpellComponent under the id abyssal:spellbook. This stores the Identifier for the spell and can optionally store another Identifier for an alternate cast.
Spells can be cast by holding any ItemStack whose Item extends SpellStaff, or by calling spell.cast(level, player, staff, book, ap) directly. In that call, staff is the spellcasting focus ItemStack, book is the ItemStack which is the source of the spell, and ap is the applicable ability power modifier, usually from the player's attribute.
The spell casting logic lives in Spell. New spell behaviour is implemented by extending that class and overriding cast, with an optional secondary implementation for altBookCast.
Adding Spells
Other mods can add spells through the public spell map. This is currently an experimental API: it is not yet a NeoForge registry, has no registration event, and may change between releases.
public final class ExampleSpells {
public static final Spell REVEAL = Spells.createSpell(
new Spell(
Identifier.fromNamespaceAndPath("examplemod", "reveal"),
new SpellFuelQuantity(SpellFuelTypes.FUEL_LIGHT, 10)
) {
@Override
public InteractionResult cast(Level level, Player player,
ItemStack staff, ItemStack book, double abilityPower) {
if (!level.isClientSide()) {
// Perform authoritative world/entity changes.
}
return InteractionResult.SUCCESS;
}
}
);
public static void init() {
// Calling this method forces class initialization and registration.
}
}
Call ExampleSpells.init() during common mod initialisation on both physical sides. Registration must occur before items containing that spell are decoded or displayed.
The spell tooltip can be localised with the language key spell.mod_id.spell_id.