by Thott
2003-11-22

Overview

Spell Morphing is a major conceptual upgrade to EQ's spell handling system, without requiring a major code investment.  The concept here is to have spells change into other spells in response to spell related actions.  Every time a spell expires, it can be set to change (morph) into a different spell.  Thus if a spell fades on its own, if it fades because a rune wears out, or if it is overwritten, it can morph into something else. This is a simple sounding concept, but has many deep and interesting uses.  An entire expansion worth of spells, even a new class, could be built using just this one feature.

Examples/Ideas

New Spell Types

Druids could get a buff that puts up bark encrusted healing sap.  In game terms, this would be a tiny rune, that morphs into a heal over time when it breaks.  Pre-buffed, on-demand healing.  A totally new spell type without having to write a single line of custom code.

A super pet buff could morph into a 20k damage debuff when the duration expires or it gets dispelled, creating a super powered, but temporary, pet.

Any spell can morph into any other kind of spell as time passes with the morph system.  A spell could heal someone for several ticks, then hurt someone for several ticks.  A spell might be a renewable rune, that morphs into an empty buff when the rune is used up, and each time the duration runs out, it replaces itself with a fresh version (see the implementation details for more information on how this is possible).  This could even be an AA: hit the AA and it pops up an "infinite rune," that replenishes itself every so often by fading and morphing into itself with full duration, until the user dies.

A spell could super-buff a player, then stun them when it wears off.

A buff could build a berserker like rage on a tank by combining the Vie effect with morphing.  The spell starts off with nothing but a 1%/100hp absorb.  When it dissolves, it replaces itself with a 1%/100hp buff with additional stats.  When it fades, it replaces itself with an even better version, etc., until ultimately the full power version is in effect, and the user is at "maximum rage."  As long as the wearer keeps taking damage, the buff stays.  If he stops for a while, he calms down.  Sorry, this system can't paint him green :/.

There are truly an unlimited number of possible new spells that this system could make possible, and all for the same coding cost.

Improving Current Spells

Currently there are some buff+rune spells that fall as soon as the rune fades, which isn't always what you want (like the bard ac+spell rune song, where a tank loses AC when hit by an AE).  With this system, when the rune expires, the buff could replace itself with a new, buff only version.  The player then knows the rune is gone, but still has the buff if they want it.

Several existing hard coded features could instead be done with this system, reducing code base.  This isn't worthwhile to do for no reason, but it could be useful if rewriting some problematic code to pull that oddball code out and put it in data.  It's also illustrative of the usefulness of this system.

Invisibility, levitate and illusions all have special warning systems to tell players that the buffs are going to fade soon.  With morphing, the buff could go ahead and fade, then morph into a short duration extension buff with the same effect and an informative cast-on-you message.  No special code needed, and easily modified.

Spell Stacking Hassles

Using Pot9 is a problem right now, because it requires people to click off the Virtue a cleric already cast, then get that cleric to recast 2/3rds of Virtue on them in the form of symbol+AC buff.  Beyond this, it uses up 3 buff slots instead of 1.  With this morphing system, when Virtue overwrites Pot9 (or vice-versa), both buffs could morph into a new, combined Pot9+Virtue buff, that gives all the stats casting each spell individually would give, but in one combined buff.  This still requires both a druid and a cleric to buff that level of hp/mana regen, and it doesn't add anything it didn't add before, but it no longer requires extra hassle or triple the buff slots.

Buff Slots

As alluded to in the last example, this system can solve many buff slot problems.  I personally use 5 different click items from Plane of Time that take up a buff slot that didn't exist before (plus another item that replaces an old one).  That's 5 more buff slots I need, when I was often at the 15 buff cap before.

This is a major problem now, and will only get worse in the future.  Putting a ban on future click buffs solves this problem, but at a cost in subscribers as players get bored to tears with stat-only items that are no different from the items that came before them.

Morphing can solve this by having click buffs that are buffs by themselves, but in the presence of another buff, morph into a combined one.

For example, one of the potime click items is a 180hp buff (on Veil of the Inferno) that stacks with other hp buffs.  If Brell's Stalwart Shield is up, and I click Veil of the Inferno, it could morph both buffs into a new combined buff with 180 additional hp.  This gives us the same cool click item, that's still useful in all the situations it's useful in now, but doesn't take up an extra buff slot.

An entire series of click buff items in an expansion could be designed such that if someone collects them all, they combine into a more powerful, long duration version.  They would actually combine in pairs - collect two similar ones to get the upgraded buff they both create.  Collect two pairs and get an even better buff.  Thus each buff doesn't have to be strong and powerful on its own, because the end result buff will be.  This adds a level of item progression that currently doesn't exist.

Multiple Casters

Some games have complex hard-coded systems to try to combine casting from multiple casters.  This system does it with ease.  The method is this:

  1. Create a buff/debuff that has no effect and shorter duration than recast time.
  2. Mark this buff/debuff such that it will overwrite itself, and when it does, it morphs into a new buff/debuff.
When a caster casts the buff, it does nothing.  He can't overwrite it himself because the recast delay is longer than the duration.  But if another caster casts that same buff, it overwrites the first buff, which then morphs into the real buff, that actually does something.

This can easily be extended to three casters by having an intermediate buff2 created by the first two casters that does nothing until the first buff hits it again.  The only trick here is the recast has to be long enough relative to the duration so that the first caster can't be one of the later casters...but then again, that may be exactly what you want.

Examples
To create a short duration super pet, several necromancers may cast the same buff on the same necromancer pet over and over again.  The first two morph into buff2, then the next two do not overwrite buff2 but instead stack to start, and when overwritten creates a new buff2 that overwrites the first and creates a buff3 (this is illustrated below).

Further castings of buff1 then create a new buff2, then a second new buff2 that overwrites the first and creates a new buff3, that overwrites the first buff3 and hugely buffs the pet, or whatever special effect is desired.

After a minute or so, that super pet buff would fade.  Again using the morphing system, that buff could morph when it fades into a 20k hp debuff - killing the pet.

A similar spell could buff a necromancer directly, turning him into a melee killing machine, by having the final buff be a huge skeleton/spectre illusion combined with massive melee buffs with built in silence.  Naturally I suggest having that same 20k debuff at the end.  Necromancers enjoy death, right?

Disclaimer: the actual technique to use more than 2 casters may vary based on the actual implementation.  I.e. buff1+buff1=buff2, but does that buff2 replace a buff1, or does it get applied as a new spell?  If it replaces buff1, then there needs to be a buff1, 2, 3, 4, 5, etc., one for every expected cast.  If instead the buff is re-applied, then a pyramid building format can accomplish the same thing in log2(N) spells, with N being the number of casts, as described above.  Better example:

Start: [no buffs]
Cast buff1: buff1
Cast buff1: buff1+buff1 = buff2
Cast buff1: buff2+buff1
Cast buff1: buff2+buff1+buff1 = buff2+buff2 = buff3
Cast buff1: buff3+buff1
Cast buff1: buff3+buff1+buff1 = buff3+buff2
Cast buff1: buff3+buff2+buff1
Cast buff1: buff3+buff2+buff1+buff1 = buff3+buff2+buff2 = buff3+buff3 = buff4
etc.

There's no special reason that these buffs all come from the same class either.  Just like the Virtue+Pot9 buff above, two (or more) different classes could create a new buff/debuff when working together.  This could not only add flavor, it could help make sub-optimal combinations viable, or make additional members of any class desired on raids.

Aggro Control

Using multiple casters, or multiple casts, could provide a unique way of dealing with current aggro problems.  For example, two enchanters may be able to cast a weaker, no aggro tash, that when combined create the full power version...but without the hate.  Shamans could do the same thing with slow.  Thus instead of debuffer deaths on every raid, debuffers work together to debuff without generating all that hate, while still maintaining the single group risk for debuffers that needs to be there.  This too can make additional debuffers more useful than they are right now.

Level Cap

Currently there is a level cap on many forms of CC that makes sense for a single group, but doesn't make much sense on raids, where we're supposed to be fighting higher level mobs.  Through morphing, two enchanters could both debuff the same mob with a special high level spell, that when combined, morphs into a much higher (or unlimited) level cap mez (assuming of course the target isn't immune).  The same could be done with a team of enchanters charming a higher level mob.

Augmenting Existing Buffs

Clerics could get a right click buff that morphs virtue into virtue+100hp on any target, improving their buffing capability.  Enchanters could get a click buff that morphs vallon's into vallon's+20atk, etc.

Expansion spells could do the same thing, augmenting existing buffs without replacing them.  In LDoN for example, a better virtue couldn't be given because hand of virtue is already level 65.  Another level 65 spell that does the same thing only better wouldn't make sense.  But a level 65 spell that augments virtue would.

New Class

A new casting class could be built around this feature.  Instead of using regular buffs/debuffs, this class could use repeated castings to ramp up its spellcasting power.  This is like being able to select if you want to spend a little amount of mana on a little buff, or a lot of mana on a big buff.

For example this class might have a group damage increase buff of some kind (haste, atk, whatever).  The first cast gives +10%.  The second increases it to +20%.  The third, +30%, etc., until it reaches some maximum, at which point it could be kept going with only occasional casts (each cast morphing the top buff into itself at full duration).  If the casts stop, then the buff falls.  It could even go through the same progression as it wears out.

Or perhaps the class is melee oriented, but uses proc buffs.  Every proc could build power.  For example, the player may proc an atk debuff.  If he procs it again, the debuff is increased.  Every proc makes the debuff stronger.  Another proc buff may buff the party in the same way, if the player procs a lot, the party is super buffed, if he doesn't, the buffs drop down in power as they wear out, until eventually they dissipate.

To the player, these are essentially new play styles, as if a new bard-like extension to the spell system were added, but the actual implementation is just this morph system plus data entry.

Implementation Details

Data Storage

The first thing is data storage.  Where to put all this morphing information?  There are three obvious options:
  1. Include it in the spell database by extending the number of columns.  Thus there may be 8-12 morphing records added to each spell entry.
  2. Include it in the spell database, but not by adding a lot of columns.  Instead, each morphing spell has single field that contains another spell ID number (or 0 if it's not a morphing spell).  That spell record space would be used up by morph format records instead of containing a real spell (which should really confuse spell readers for a while).
  3. Place all the morph information in a separate database.  Just like #2, all each morphing spell needs is an index into a database, the difference being, which database it's an index to.

When to Morph

Just saying what to morph into isn't enough, it's also important to know when to morph.  Some spells will only morph when overwritten by other specific spells.  Some spells will only morph when they run their full duration and end.  Each morph record will need to have a field for when that rule should be used.  In actual implementation, this field will likely contain a single number.  If that number is over 5 or so, it's the spell that causes the morph.  If it's under 5, it's one of the below special cases.
  1. When it is overwritten by [spell X]
    This will probably be the most common type.  When spell X overwrites the current spell, morph into spell Y.
  2. When it fades naturally
    This probably won't be as common as the others, but it has its uses.  For example, a buff could decay in usefulness over time.  Each time its duration runs out, it replaces itself with a weaker version.  If you really wanted to be complete you could stop buffs from blinking that have this morph option.
  3. When it fades early, but not voluntarily
    This is primarily for runes, but can apply to any spell effect that causes itself to fade.  Note that this doesn't apply to buffs that are clicked off manually or dispelled.  From the last example, a buff could decay over time, but it could also grow over time.  If a player could click it off to force advancement then that could bypass a needed limitation.  Thus fading early means a rune wears out, or other special effect failure, i.e. invis.

    Early EQ invis broke early and immediately disappeared.  Later, this was changed through special code to mean a change to 1 tick of remaining duration.  The morph system can do the same thing with this duration rule.  Invis fades, and when it does, it morphs into a 1 tick duration invis, with a cast-on-you message of "Your invisibility is about to fade."

  4. When it is clicked off early or dispelled
    This likely wouldn't be used much by itself, but it is needed to ensure a negative effect does indeed take hold after a positive one wears off.  For example, a buff could give a huge amount of atk/haste/etc. for 60 seconds, and then fade, morphing into a 20 second stun.  If the buff is clicked off early, it should still do the stun.  This rule makes it so.  Using #2 (fades naturally) alone wouldn't work, because #2 doesn't get triggered if the buff is clicked off early.  For this buff spell there would be two rules, each causing a morph to the same stun, but with different requirements (#2 and #3).

    Dispel is included here instead of as a separate rule because players can dispel themselves.  Because of this, the two have to be treated as one and the same conceptually.

This is not just a list of types to store in the morph record, this is also a list of the places that need morphing hooks.

Duration Formulas

  1. Keep current duration
    When a spell morphs into something else, the new spell has the duration of the one it morphed from.  For example: rune+buff spells.  The spell shouldn't get extended duration if the rune wears out late.
  2. Take new duration
    Use whatever duration the new spell has.  Example: two enchanters combining to create some super-buff.  The duration of the spells the enchanters cast has to be shorter than the recast on the spell, or one enchanter could do it himself.  It wouldn't do to have a 72 minute duration buff require a 73 minute recast to work.  Thus the new spell needs a long duration, while the pre-spell that's cast by each enchanter needs a short duration.  The solution is to use the duration of the new buff.
  3. Weighted average of combining buff durations The mana weighted duration of the two source buffs is combined.  Example: Virtue+Pot9.  Virtue is 1000 mana for 1500 ticks duration.  Pot9 is 725 mana for 1000 ticks.  If Virtue is active already, and has 900 ticks left, and Pot9 is cast, then the two will morph into a new Virtue+Pot9 buff (assuming it's set up to do so).  The duration would be the average of the two, weighted by mana, i.e.:
    (max_duration1+max_duration2)   (current_duration1*mana1 + current_duration2*mana2) 
    ----------------------------- * ---------------------------------------------------
    	     2		            (max_duration1*mana1 + max_duration2*mana2)
    
    Which seems complex, but isn't too bad if you think about it.  It starts with the average duration:
    Average duration: (max_duration1 + max_duration2)
                      -------------------------------
    		                2
    
    If mana costs were the same, you'd then multiply this by the average of what duration is left on each one:
    Duration remaining (ratio): (current_duration1 + current_duration2)
                                ---------------------------------------
    			       (max_duration1 + max_duration2)
    
    Except that we care how much each one cost, so we weight the whole thing with mana, then multiply that weighted remaining duration ratio times the original average to get our new value.

    In this case, we have:

    Buff1: Virtue
    current_duration1 = 900
    max_duration1 = 1500
    mana1: 1000
    
    Buff2: Pot9
    current_duration2: 1000
    max_duration2: 1000
    mana2: 725
    
    (max_duration1+max_duration2)   (current_duration1*mana1 + current_duration2*mana2) 
    ----------------------------- * ---------------------------------------------------
    	     2		            (max_duration1*mana1 + max_duration2*mana2)
    
    (1500+1000)   (900*1000 + 1000*725) 
    ----------- * ---------------------- = 912.9 = 912 or 913 ticks
         2	      (1500*1000 + 1000*725)
    
    There are two caveats here: first, there needs to be a check to see if both spells cost zero mana, and if so, use 1 for mana cost throughout the formulas.  The second is group spells, and is fairly minor.  Mana cost for group spells should probably be cut to 1/3 for use in these duration formulas.

Morph Record

We now know what kind of data we need to store for a morph record:
  1. Type of morph (natural fade, early fade, clicked off/dispelled, overwritten by X)
  2. Duration (from existing, from new, weighted average)
  3. Spell to morph into

That's it!

Conclusion

The spell morph system is relatively easy to implement, compared to other recent system additions.  It solves the 15 buff problem in a sideways fashion, by reducing the number of actual buff slots used.  It requires no changes to the player record, nor does it noticeably increase memory footprint.  It adds a tiny increase in processing time when a buff is removed, but this is negligible; other fairly recent changes to the buff system probably added much more.  Increasing the buff limit would almost certainly increase processing time more.

The benefits extend beyond the 15 buff limit: adding new types of character advancement, opening the door for new character classes and special abilities, and greatly increasing the options available to designers when creating any form of new content in a way that requires no additional code.

The cost to implement this system is less than any recently added system I can think of.  The benefits, especially in the long term, are far greater.

License

While I don't think I have any special rights to any implementations of this idea, just to be completely clear: I hereby release this idea into the public domain.  It can be utilized in any software product without cost or attribution.  It can be copied freely.