Efficient spell system/too many scripts

Hey guys,

I’m trying to make an ability system similar to games like League of Legends, WoW, or Diablo. I want to have a bunch of spells across a number of playable characters. The problem I’m running into is implementing spells that are unique; I’m not trying to make a game full of fireball copies or really similar spells.

I came up with my own system of designing an ability (I haven’t implemented it yet) that involves choosing a base script for the spell that gives it a certain targeting type, then adding components to that script to make the spell unique; dealing damage, bouncing to other enemies, etc. however, I’m worried that this will still not be able to handle certain spells that we had in mind.

Ideally, I would like to be able to program each individual spell as its own class. After doing some research, I haven’t been able to find out if having that many spell prefabs or scripts will affect the game’s performance. In the actual scene, there will not be much more than 4 or 5 spell instances attached to the player. It seems like having a lot of prefabs in the project would just make a bigger file size for the game, but I’m not totally sure. So if someone could let me know if programming each spell is a viable option or of you have your own spell system that you’re willing to share, that would be awesome

Seems like a good idea. I don’t think having a few more scripts will impact performance. Another thing you could do is Enum & delegates; you could have a public Enum targetingType{target, aoe, none} and then a matching delegate so that way you could do it all in one script. Ideally a base script that all spells would inherit from. Because each spell will have some common features, right? Like mana cost, targeting type, cooldown, etc.

I recently posted a playable example project with code that works along the lines you described.

Skill casting method and secondary effects

It’s data-driven and component-based. By data-driven, I mean that the scripts provide a general-purpose method for defining spells. But the actual spells are designed in the inspector by composing different parts (casting prerequisites, aiming, firing, etc.) and optionally saved as prefab. To add a new spell, you just use the inspector. You don’t have to modify code.

You generally want to avoid designs that require you to go back and modify existing code, since it’s easy to break existing functionality. For example, avoid enums and switch statements unless you’re absolutely sure you won’t ever add any new spells or skills. Otherwise you’ll have to go in and edit the code with those enum and switch statements. This is a very common source of bugs.

The example code I posted uses a handful of general-purpose, reusable scripts for each spell, and it uses SendMessage. Someone asked if this design has any impact on performance. In practice, no. If you’re unsure about that, just profile it. Few of the scripts have Update() methods, so they don’t do anything on a regular interval. And if you’re concerned about SendMessage (though you shouldn’t be, since it’s only called once when the character casts a spell, so it has no performance impact), you could always use C# delegates like @ suggests. But in this scenario it’s not worth the extra complexity.

2 Likes

Yes! I did something very similar for a camera system. I really really dislike those all purpose scripts some people make. Good advice here.

Also, OP, no point worrying too much about performance/optimisation at this point. Just get it working. Otherwise, over engineering will be a big problem and therefore code complexity will probably increase.

Thanks everybody for the responses, they’re all very helpful.TonyLi, the system you described in that thread is almost exactly what I had in mind.
I think Im going to make one base spell class with common attributes and spell functions, including targeting type, and then add extra classes that make the spell unique

If I may make a suggestion: Don’t make subclasses. Deep inheritance trees will bite you in this situation. Skim over my post in that other thread and consider composition. You won’t have a single base class with common attributes. Instead, each attribute is a separate script.

Yeah, when i said extra classes i just meant separate scripts that make the spell behave certain ways, not subclasses. And for the base class, I was just gonna include stuff like mana cost and cooldowns that every spell has, like supremegrandruler suggested.

Sounds like a plan!