• Godot Help
  • Organizing and Loading Spell System Efficiently in Godot

Hello everyone,

I'm working on a spell-making game in Godot and I've run into an issue regarding how to best organize and load my spells.

Current Spell Organization:
I have structured my spells using an inheritance-based system as follows:

BaseSpell

  • Proyectile
    -- FireBall
    -- AirSlash
  • Buff
    -- SpeedBuff
  • Sprite

Here's a snippet of my code:

# BaseSpell.gdt
extends Node2D
class_name BaseSpell

@export var spell_name: String = "BaseSpell"
@export var cost: int = 1
@export var srange: int = 1
@export var duration: float = 1
@export var damage: int = 10
@export var radius: int = 1
var BF
signal spell_cast

func _init():
    pass

func initialize(Battlefield):
    BF=Battlefield

func cast(target_tile:Vector2i,caster):
    return true

# proyectile.gdt
extends BaseSpell
class_name Proyectile

func _ready():
    pass

func initialize(Battlefield):
    BF=Battlefield
    
func cast(target_tile:Vector2i,caster):
    if BF.distance(target_tile,caster.tile_position)>srange:
        return false
    var target_tiles=BF.tiles_in_aoe(target_tile, radius)
    var targets = []
    for tile in target_tiles:
        targets.append(BF.get_unit_in_tile(tile))

    for target in targets:
        if target:
            effect(target)
    return true

func effect(target):
    target.take_damage(damage)

# fireball.gdt
extends Proyectile

func _ready():
    pass

func effect(target):
    target.take_damage(damage)

I load the spells using the following method:

func get_spell_by_name(spell_name: String):    
    var basespell_rsc = load("res://Scenes/Spells/Spells.tscn").instantiate()
    var spell = basespell_rsc.find_child(spell_name, true, false).duplicate()
    spell.initialize(BF)
    BF.add_child(spell)
    return spell

I want to avoid loading the entire scene with all the spells. For instance, if I call get_spell_by_name("FireBall"), I would like it to return an instance of the scene containing only the branch leading to the FireBall, not all the other spells.

Also, Is there a better way to organize and load spells to achieve this?

Any help or suggestions would be greatly appreciated!

Thank you!

    gaborit What @xyz said. You can create a "Database" resource file and load all of the scenes there and use the Database to load the scene by name/id/texture id/etc. or whatever way you want.

    The Database should have a static get method and you can just do "Database.Get(ID/Name)" and instantiate it when you cast it. This way you have a base template for the whole system.

    Sorry, I do C# and I do not know GDScript but I do hope you understood what I ment!

      PancakeGenie Thank you for the answer, but i cant seem to find the "Database" resource file.

      xyz I thought about that, but how do I avoid redundant code? if, say, fireball is the same as a thunder strike, with the only difference being the element and sprite.

        gaborit It is not a premade resource. You need to create a Database that extends the "Resource" and have a list of your PackedScenes

        gaborit I thought about that, but how do I avoid redundant code? if, say, fireball is the same as a thunder strike, with the only difference being the element and sprite.

        Use the same script, or inherit from same base class that implements common code.