Page 1 of 1
Spells!!!!
PostPosted: Thu Aug 13, 2009 3:09 pm
by tobz
So this isn't so much some big problem that I see, but just an attempt to generate meaningful discussion about the current state of the spell system and updates that could be made.
Anyways, spells! Sometimes we love them, sometimes we hate them.
A couple problems/ideas I've always seen:
- bonus handling -> bonus handling as in how DOL manages bonus values and changes. Currently, if I'm not mistaken, there are property calculators and then a lot of hard-coded checks in spell handlers, etc. It seems like there might be some room for improvement by switching entirely to a system much like the property calculators. Ideally, I'd make it cache values and regenerate only when spells/items are applied/removed. For example, if a spell modifies dexterity, there might be a map for spell type to some enum that represents the bonus(es) being changed, and then you call something like BonusCache.Update(SpellBonusType.Dexterity) and it'd recalculate total dexterity, and maybe recalculate block chance or something if block chance is based on dexterity. This is still sort of hard-coded, only giving the benefit of centralized bonus value calculations and taking out things like RA checks in spell handlers, etc. This is where a true scripting language would be really cool. That, or runtime compilation from DynamicMethods or something. That is for a totally different post, though.
The main point is that you're caching values, and regenerating when changes happen. It may not even be more performant, but I think it could have the potential to be cleaner and more streamlined.
Class is about to be over, so I'll edit this with more stuff when I get home.
Re: Spells!!!!
PostPosted: Thu Aug 13, 2009 4:43 pm
by Dinberg
SpellHandler in general is a bit messy. There's alot of class checks hard coded, not just realm abilities and the like. I'd be up for any improvements, heck I'd even do it myself if I had the time

Re: Spells!!!!
PostPosted: Thu Aug 13, 2009 8:50 pm
by Graveen
hardcoded class checks, hardcoded subspells id.... there is a lot of work in the spell system :s
Re: Spells!!!!
PostPosted: Tue Sep 01, 2009 8:14 pm
by Luhz
My suggestion:
Split Spell into SpellXEffect and Effect.
The Spell Database would have ID, ClientEffect, Icon, Name, EffectList, MergeStyle.
The Effect database would be similar to the existing Spell database, but it would remove ID, ClientEffect, Icon, Name, SubSpellID, and Type.
Basically, this change leads to a whole bunch of other necessary changes, and has a number of effects.
1. Effect no longer contains SubSpellID - Spells themselves contain an EffectList of 1..n Effects, meaning any spell is made up from a list of spell effects. Subspells are no longer needed because having a subspell is equivalent to having a Spell with two effects. The bonus here is that you can cleanly create spells with more than two effects.
My primary idea here was to remove redundancy in things like SingleStatBuff, DualStatBuff, AllStatBuff - why have three spell handlers for stat buffs? With and EffectList, cut the code down to SingleStatBuff, and use multiple effects to achieve the same effect.
2. MergeStyle is a new field (or fields if design requires) which dictates how multiple Effects are incorporated together. This would handle things like whether the mana cost of the effects is summed, whether the range of the spell is limited to the range of the shortest-range effect, etc.
The simplest two examples would be "Free Mix", where each effect retains whatever values it has, and casting the spell is effectively like casting all of the effects at once (eg. different effects could have different maximum ranges, mana cost for each effect could be distinct, etc), and "Strict Mix" where the effects are mixed to ensure that the spell still acts like a single spell does in DAoC.
Optionally, the Spell database could retain a few duplicate fields which could act as "master" values. This way you could have a spell with 4 effects, but have a "master" ClientEffect so that only one effect is triggered for the whole spell. This could also be left out of the database and could be handled through a form of MergeStyle.
3. Most significant, removing Type requires a redesign of how spells are written in the code and in the database. The idea here is that the removal of Type specification requires two things: SpellHandlers be merged into one; Effect database be expanded with sufficient values to identify every aspect of an effect. The point is that the database becomes generic enough to create any spell through selection of the correct values, rather than through selection of spell handler.
The reason this ultimately "simplifies" things is that the current system makes it difficult to merge and mix different aspects of spells. For example, there is a BoltSpellHandler which inherits from SpellHandler. If you then want to make a bolt spell that does lifedrain return you need to create another spellhandler to mix aspects of the lifedrain spellhandler and the bolt spellhandler. If the appropriate fields were instead stored in the database, you would only need to create an effect that does damage, returns life, and is flagged as "Bolt".
How many fields would the new table need? I'm guessing about the number that are in the existing table, plus at least one new field for each spell handler that exists. That's about 440. Just for reference, MySQL has a table column limit of 4096, and a row size limit of 65535bytes, which shouldn't be an issue with this design unless someone throws in lots of text/unicode columns.
This would probably be reduced by removing a good deal of redundancy, but by how much I'm not sure. However, the database would be much more powerful as a result, and performance shouldn't be an issue here so long as effects are pre-loaded when the server loads.
I think this kind of system is what DOL was originally designed for when the Spell database and SpellHandler were written, but the desire to keep the code clean overrode this and we ended up with a new spellhandler every time something needed tweaking, as opposed to keeping flexibility in the database and everything in one big mess in SpellHandler.cs. Moreover, I think that DOL would benefit from the flexibility in having a general "Effects" system, rather than a mishmash of spells, abilities, realm abilities, etc. Every one of those could simply make use of the same Effects backend.
I hope this book actually gets my idea across.
Re: Spells!!!!
PostPosted: Tue Sep 01, 2009 9:31 pm
by Graveen
I see your points. Interesting.
Ofc, a table with 400+ fields is unmaintainable and uneditable. I understand many fields shold be empty.
But the concept of adding layers, and managing the way theses layers are acting (priority) is an interesting system.
And yes, it is an amount of job.
Re: Spells!!!!
PostPosted: Tue Sep 01, 2009 10:16 pm
by bluraven
I think someone mentioned it before, but is maybe worth mentioning it again here, as it still comes to mind on the topic of spells. An idea that makes a lot of sense is to re-use columns in the database for spell values. For instance, having a number of columns for things that every spell has (an effect ID, a client ID, a name, a level, a power cost, etc.) and then having extra columns that are re-usable from spell to spell (Value 1, Value 2, Value 3, etc). That way you don't end up with one-off uses of columns like resurrection power (only applies to rez spells), etc. And in the spell handler is where it is decided what each Value field is used for. Like the Resurrection spell handler could decide that Value 1 is the Resurrection power amount, Value 2 is the Resurrection health amount, etc. But then the problem is that you would need some sort of outside tool to be able to make changes to spells and know which each Value box really is holding for each spell.
Re: Spells!!!!
PostPosted: Tue Sep 01, 2009 10:39 pm
by Graveen
this is traditionnally where and why serialisation takes place: allowing a non determined number of features. But i think the spellxvalue table is better, because the value can be developped and extended,ibstead of serialisation.
Re: Spells!!!!
PostPosted: Thu Sep 03, 2009 2:58 pm
by tobz
This is where I say a flat-file system could be better utilized.
I like Luhz' idea of simplying defining outcomes of a spell, rather than defining the spells rigidly. This not only makes it easier to customize but it makes it trivial to extend and cope with changes in the future. I'm not sure the interdependence of subspells to their parent spells. It may be super simple, there may be cases that the sub-spell depends on the above spells level of something. It could be clean, it could get messy. This is simply a matter of exploring the existing system in its entirety and making sure to account for all of the possible problems in the design phase rather than the implementation phase. This is best suited for public discussion because regardless of programming experience, anybody who has played DAOC will be able to say "hey, wait a minute, those spell mechanics aren't right!" and I'm convinced that will prove to the be the most valuable part of a development of any new spell system.
Again, when it comes to storing spells in the database, I think you're constraining yourself because you're always thinking of limiting columns or table interdependencies. Switch to XML for the design phase, and you can completely ignore those DB limitations. Since spells are loaded at start-up, performance is almost entirely irrelevant.
This is where I wish something like Lua was given attention with the DLR like IronPython/IronRuby got. It would be easily embeddable as CDATA in XML and could allow spells to be entirely dynamic at run-time. Coupled with a new system that doesn't rely on strongly-typed handlers in the code, it could allow for entirely runtime-based adding, updating, and removing of spells. Pretty cool if you think about it, given that most likely no other emulator, regardless of game, has any sort of system like that.
Even apart from embedding the spell behavior in the XML files, you could still use something like IronPython and have separate files.