From The Mana World
m
Line 171: Line 171:
== Prototype implementation ==
== Prototype implementation ==


Our prototype implementation hooks into the existing chat handler messaging mechanism in eAthena.  It processes all chat messages and tests whether they are identical to a given indication, then implementing the spell protocol as listed above.  For each spell, the chat handler instructs the chat system that the spell was not spam, thereby allowing quick re-casting without automatic banning.  To allow easy fine-tuning of spells, all spell requirements are read from a configuration file.
The prototype implementation hooks into the existing chat handler messaging mechanism in eAthena.  It processes all chat messages and tests whether they are identical to a given indication, then implementing the spell protocol as listed above.  For each spell, the chat handler instructs the chat system that the spell was not spam, thereby allowing quick re-casting without automatic banning.  To allow easy fine-tuning of spells, all spell requirements are read from a configuration file.


=== Spell configuration file ===
=== Spell configuration file ===
Line 194: Line 194:
** components = [ <num>, ..., <num> ] (Material components to require for the spell; these will be consumed when the spell is cast.  You can require the same item more than once to require multiple instances of that item to be consumed.)
** components = [ <num>, ..., <num> ] (Material components to require for the spell; these will be consumed when the spell is cast.  You can require the same item more than once to require multiple instances of that item to be consumed.)


Items are identified by their item IDs.  Please note that in our current implementation the default values for `mana' and `level' are very low, and neither prerequisites nor components are used, in order to simplify testing.
Items are identified by their item IDs.  Please note that in the current implementation the default values for `mana' and `level' are very low, and neither prerequisites nor components are used, in order to simplify testing.


== Improving visualisation in the client ==
== Improving visualisation in the client ==


While client visualisation should be fully functional at this point, it could use some improvement.  Our implementation sends different level-up like signals to the client, which the existing client interprets as `job level up' signals.  A refined client could map these numbers to more appropriate particle effects.
While client visualisation should be fully functional at this point, it could use some improvement.  The implementation sends different level-up like signals to the client, which the existing client interprets as `job level up' signals.  A refined client could map these numbers to more appropriate particle effects.


Furthermore, wind-based movement is currently somewhat rough, particularly for clients whose avatars are being moved.  Rough movement could be addressed by simulating smoother movement when a being is teleported only one square away from where the client expects it to be; rough scolling in turn can be addressed by scrolling rather than updating the frame position when the player's character is teleported to a very nearby location.
Furthermore, wind-based movement is currently somewhat rough, particularly for clients whose avatars are being moved.  Rough movement could be addressed by simulating smoother movement when a being is teleported only one square away from where the client expects it to be; rough scolling in turn can be addressed by scrolling rather than updating the frame position when the player's character is teleported to a very nearby location.
Line 211: Line 211:


Note that the magic system does not require all spells to be activated at the same time: by setting a spell's invocation to "", the spell can be effectively disabled.  In this fashion, spells can be gradually added after they have survived testing.  Similarly, that have been found exploitable or broken can be disabled quickly, while spells that have become more widely known than anticipated can be re-hidden by changing (and re-seeding) their invocation.
Note that the magic system does not require all spells to be activated at the same time: by setting a spell's invocation to "", the spell can be effectively disabled.  In this fashion, spells can be gradually added after they have survived testing.  Similarly, that have been found exploitable or broken can be disabled quickly, while spells that have become more widely known than anticipated can be re-hidden by changing (and re-seeding) their invocation.
=== Future extensions and spell ideas ===
Below are some ideas for improving existing spells:
* Dying from your own offensive spell should preclude resurrection
* Range for ``Death's Door'' should be reduced.
* The effects of offensive spells should be toned down via battle_get_mdef(-).
Below are some ideas for additional spells:
* ''Magic shield:'' temporarily boost magic defence
* ''Reversal:'' any spell cast on the subject (good or bad) backfires on the caster.  For offensive spells, the computed damage backfires (making ``Death's Door'' suicidal.)  Spells the caster casts on him/herself are instead cast on a random subject in the area.  (HP draining for powering healing/offensive magic is unaffected.)  Any spell can only be turned back once in such a fashion (as in Final Fantasy).
* ''Curse of the Pink Fluffy:'' a near-indestructible pink fluffy follows the subject around, making funny noises
* ''Summon Ether Serpent:'' summons a cyan-ish snake (semi-transparent, if possible) that is significantly tougher than most monsters in the game but deals most of its damage by draining mana.  Impervious to `peace', will not (at first) attack its summoner.
* ''Banish:'' banishes a summoned creature (Ether Serpent, Pink Fluffy)
* ''Delay:'' the next spell cast by the caster will be delayed by ten seconds.  (Note that this spell can also be applied to other spellcasters via ''Reversal''...)
* ''Dispel:'' cancels any spells currently active/in range and any spells cast in the next 5 seconds
* ''Teleport:'' teleports the caster to one of a set of predetermined locations based on whatever (s)he says next
* ''Gate:'' as teleport, but creates a temporary gate to that location that other people can follow through (the gate could be visualised as an NPC).
* ''Anchor:'' creates a temporary teleport anchor (a name bound to a location).  Can only override existing bindings if the caster is more powerful than the one of the existing binding.
* ''Magic Mouth:'' creates a temporary NPC that will repeat the next sentence spoken by the caster to anyone who passes by and tries to talk to it.
* ''Bless:'' increases accuracy and slightly increases damage (eAthena might already have this one.)

Revision as of 15:00, 15 May 2008

Abstract: eAthena is not part of the medium-term development perspective for tmw. Consequently, changes to eAthena are subject to a short lifespan and little hope of re-use. As a result, there is no discernible feature development for eAthena to extend the player experience on this server. However, some enhancements that would benefit the player community (and might thereby serve to attract new testers and developers) depend on such extensions; one particular prominent example of this is magic. This document proposes a simple magic system as an addition to the eAthena system. The magic system satisfies the following requirements: (a) it is easy to implement and integrate into eAthena, (b) it can be easily configured and fine-tuned, (c) it requires no client-side extensions to function properly. This document presents the system together with fifteen spells as well as their intended behaviour and describes the system would work in regular gameplay. The document further sketches a prototype of the system [1]


Introduction

eAthena conceptually supports a magic system; however, this magic system requires client support. Furthermore, if there are bugs in the system, the generally low quality of code in eAthena would make debugging a less than pleasant experience. Since plans on the tmw side further expect eAthena to be retired soon, it seems wasteful to spend much time on a feature-rich magic system. As an alternative, tmw could adopt a simple magic system that provides the `bare-bones magic experience' as quickly as possible before eAthena support is retired: players can cast spells, but will not be required to wait for a new client to become available. As an interface, the existing chat system appears to provide sufficient expressive power to communicate many interesting spells to the server, while player location and heading can affect spell effects more or less subtly. While these interface choices are limiting, they (a) do not require players to familiarise themselves with a new interface, (b) do not require the implementation of `throw-away' interface and protocol code, and (c) (as mentioned) are already sufficient for a number of interesting spells.

In the following, the basics of the magic system are summarised, specifically the notions of `spell power' and `spell requirements'. The document then discusses a number of spells that can be expressed with the proposed interface; all of the listed spells are also implemented as part of the prototype. A high-level overview over the implementation of the prototype follows, then a description of how `spell requirements' can be configured. The document concludes with a list of possible approaches towards improving the visualisation of these spells by means of altering the client, and with observations about extensions to and applications of the system.

Basics

The proposed system is based on the idea of implementing magic by means of atomic spells, i.e., magical effects arise by triggering a particular effect-- while some spells may interact, there is no foundational mechanism that allows players to construct new spells, largely because such a mechanism would likely be hard to balance. Spells are parameterised by spell power, which is a derived attribute of each player:

spell power = experience level + intelligence

This definition of spell power (in addition to being simple) permits magic usage by established players without a (second) stat reset, while giving sufficiently significant meaning to intelligence to make it of some interest.

Each individual spell consists of the following attributes:

  • Name: The spell's name. This name need not be known to players; its principal purpose is for reference. As such, it serves as the primary key in the configuration file (see below).
  • Incantation: The spell's incantation. This phrase triggers the spell (see `casting', below). Knowing the incantation is the principal differentiator between players who can cast a given spell and players who can't.
  • Level: The spell's difficulty level. This level corresponds directly to player experience levels.
  • Cost: The spell's mana cost.
  • Prerequisites: A set of items that a player must possess in order to be able to cast the spell.
  • Material Components: A set of items that are consumed to power the spell.
  • Effect: The effect triggered by the spell.

Incantation, level, cost, prerequisites, and (material) components are together referred to as spell requirements, as they guard whether or not the spell effect will be triggered.

Casting

To cast a spell, a player must satisfy all relevant requirements:

  • Incantation: The player must type the incantation into the game's chat mechanism.
  • Level: The player's experience level must be equal to or greater than the spell level.
  • Cost: The player must have at least as many mana points as indicated by the spell cost. If the spell is successful, all of these mana points are consumed.
  • Prerequisites: The player must possess all prerequisites for the spell as inventory items.
  • Material Components: The player must also have all material components in his or her inventory. If the spell is successful, all of these components are consumed.

If the player types in an incantation that matches the incantation of a given spell, all of the above are checked. Only if all requirements are met is the spell effect triggered. In that case, mana points are subtracted and material components consumed as mentioned above. In all situations (no matter whether the spell requirements are fully met or not) a correct incantation results in part of the spell being starred out. Assume that a given spell has the incantation `foo'. Whenever a player types in `foo', the chat message sent to other players might be `**o' or `***' or `f**' instead. Starring out is decided individually for each character based on the obscure factor. This allows spellcasters to maintain some level of secrecy regarding the invocation.

Spell list

The list below contains a number of spells that can be handled by the proposed system within the previously described requirements. Note that the spells do not list level, cost, prerequisites or material components, as determining these is not part of the implementation of the magic system per se, but rather of applying it in practice. Invocations are listed, however, to reflect the default invocations of the prototype implementation and thereby simplify testing.

Shroud

  • short name: `shroud'
  • default invocation: `plugh'
  • visual effect: MAGIC_CAST_DEFAULT (2)
  • area of effect: self
  • duration: until logged out or cancelled

This spell obscures the player's identity: any other players observing a thusly shrouded player will not be able to determine the player's name; furthermore, any chat messages sent by the player will be anonymised.

Reveal

  • short name: `reveal'
  • default invocation: `xyzzy'
  • visual effect: MAGIC_CAST_DEFAULT (2), MAGIC_EFFECT_REVEAL (10) (on subjects)
  • area of effect: radius 2 + (power / 10) around the caster
  • duration: instantaneous

This spell cancels all shroud spells in the area of effect if the caster's spell power is at least as great as the shrouded player's level.

Detect Players

  • short name: `detect-players'
  • default invocation: `wismani'
  • visual effect: MAGIC_CAST_DEFAULT (2)
  • area of effect: radius 40 + power * 2 around the caster
  • duration: instantaneous

This spell detects all players in the area of effect and lists them to the caster. Only the current map is affected. Note: This spell will also list the correct names of shrouded players.

Wind

  • short name: `wind'
  • default invocation: `kalhur'
  • visual effect: MAGIC_CAST_DEFAULT (2)
  • area of effect: radius 4 + power / 10 around a point in front of the caster such that the caster is just barely not affected
  • duration: 5 + power cycles, where one cycle occurs every 250 ticks.

This spell creates a `wind' area immediately in front of the player. All PCs and monsters are blown in the direction the caster was facing at the time the spell was cast. By walking directly against the wind, players are able to overcome this obstacle, but only with considerable delay. A second `wind' spell near the area of the first will result in neither spell taking effect. If one of the spells finishes before the other, however, the remaining spell will take effect immediately. Note: Visualisation for this spell is less than ideal at this point, particularly for PCs that are being pushed around. See section `Improving visualisation in the client', below.

Protect

  • short name: `protect'
  • default invocation: `insanct'
  • visual effect: MAGIC_CAST_ENHANCE (3), MAGIC_EFFECT_SHIELD (11) on the subject
  • area of effect: self or single subject standing immediately in front of the caster
  • duration: (10 + power) * 500 ticks

This spell absorbs, for each attack, 25 + (power / 5) points of damage during its duration.

Haste

  • short name: `protect'
  • default invocation: `vaspor'
  • visual effect: MAGIC_CAST_ENHANCE (3), MAGIC_EFFECT_HASTE (12) on the subject
  • area of effect: self or single subject standing immediately in front of the caster
  • duration: (10 + power) * 500 ticks

This spell speeds up the subject's attacks as per a speed potion, by 30 + (power / 10).

Heal

  • short name: `heal'
  • default invocation: `vasmani'
  • visual effect: MAGIC_CAST_WHITE (4), MAGIC_EFFECT_HEAL (13) on subjects
  • area of effect: radius of 3 around the caster
  • duration: instantaneous

Heals hit points from all OTHER players within the area of effect. The caster has to pay 100-(power / 8) percent (but at least 60%) of the health given to those players from his or her own health. If this would kill the caster, the healing effect is reduced to an appropriate fraction; e.g., if a caster with 11/11 HP tries to heal a player with 20/30 HP and another with 10/110 HP at a cost of 100%, then the second player will receive one HP (-> 21/30) and the secon will receive nine (-> 19/110 HP).

Life

  • short name: `life'
  • default invocation: `kallor'
  • visual effect: MAGIC_CAST_WHITE (4), MAGIC_EFFECT_RESURRECT (16) on subjects
  • area of effect: radius of 3 around the caster
  • duration: instantaneous

Resurrects a dead player. The player's level must not be greater than the caster's power.

Aggravate

  • short name: `aggravate'
  • default invocation: `iten plz'
  • visual effect: MAGIC_CAST_DEFAULT (2), MAGIC_EFFECT_AGGRAVATE (18) on subjects
  • area of effect: radius of 3 + (power / 10) around the caster
  • duration: instantaneous

Aggravates all monsters in range. Each monster tries to attack the caster.

Peace

  • short name: `peace'
  • default invocation: `erana sent me'
  • visual effect: MAGIC_CAST_DEFAULT (2), MAGIC_EFFECT_PEACE (17) on subjects
  • area of effect: radius of 3 + (power / 10) around the caster
  • duration: instantaneous

All monsters in range may become peaceful, stopping their current attacks and no longer auto-attacking (the latter effect is permanent for the given monster). This effect is only guaranteed if the player's power is greater than or equal to the subject's monster level; otherwise the spell may or may not take effect (whether the spell takes effect is determined solely by who the caster is and who the monster is, i.e., re-casting the spell will not change the outcome). The spell will never take effect against monsters whose level is more than twice the caster's power.

Delayed Teleport

  • short name: `delayed-teleport'
  • default invocation: `relkalpor'
  • visual effect: MAGIC_CAST_DEFAULT (2), MAGIC_EFFECT_TELEPORT (19) after the delay completes
  • area of effect: self
  • duration: 5000 ticks

After the duration has expired, the caster is teleported back to the location he/she was at when casting the spell.

Happy

  • short name: `happy'
  • default invocation: `happy happy joy joy'
  • visual effect: MAGIC_CAST_DEFAULT (2)
  • area of effect: self or subject standing immediately in front of the caster
  • duration: 500 * power ticks

During the duration of the spell, the subject will constantly emote a happy grin. Note: Based on a suggestion by Vink.

Kill

  • short name: `kill'
  • default invocation: `kalcorp'
  • visual effect: MAGIC_CAST_BLACK (5), MAGIC_EFFECT_EVIL (15) on subjects
  • area of effect: all subjects standing immediately in front of the caster
  • duration: instantaneous

Deals up to 13 * power damage to each monster standing immediately in front of the caster. The caster loses (80 - power / 3) (but at least 20) percent of the total damage dealt and may die. If the caster dies, his/her hair turns white. Note: Based on a suggestion by Vink. Note 2: Combined with Life, this spell can be used to rather great effect by a pair of sorcerers. One possible way to combat such abuse would be to require expensive material components for either; another would be to alter Life in such a way that it cannot resurrect those who were slain by their own dark magic.

Dragon Slave

  • short name: `dragon-slave'
  • default invocation: `kalgravhur'
  • visual effect: MAGIC_CAST_BLACK (5), MAGIC_EFFECT_INJURE (14) on subjects
  • area of effect: radius of 2 * round around the player
  • duration: power / 30 rounds of 500 ticks each

Deals damage to the caster's surroundings in multiple rounds. During the first round (radius 2), the spell deals up to power * 4 damage, then power * 2 (radius 4), power * 4/3 (radius 6), power * 1 (radius 8), etc. Monsters/pvp players nearby may be hit multiple times, once for each round. The caster must pay 50 - power/5 percent (but at least 20%) of the damage dealt. If dealing this damage would kill the caster, the damage is reduced proportionally (as per the `heal' spell). If the caster gets very close to dying, his/her hair will turn white.

Death's Door

  • short name: `deaths-door'
  • default invocation: `kalbetcorp'
  • visual effect: MAGIC_CAST_BLACK (5), MAGIC_EFFECT_EVIL (15) on subjects
  • area of effect: Radius of power / 10 around the caster
  • duration: instantaneous

The health of all player characters and monsters in the specified area of effect is set to one. Note: This spell is the only means for injuring another player outside of a pvp zone. It is possible to abuse this spell to aid monsters in killing other players. Furthermore this spell may deal a significant amount of damage for a comparatively small cost.

Prototype implementation

The prototype implementation hooks into the existing chat handler messaging mechanism in eAthena. It processes all chat messages and tests whether they are identical to a given indication, then implementing the spell protocol as listed above. For each spell, the chat handler instructs the chat system that the spell was not spam, thereby allowing quick re-casting without automatic banning. To allow easy fine-tuning of spells, all spell requirements are read from a configuration file.

Spell configuration file

The spell configuration file (spell.conf) contains two kinds of declarations:

  • obscure = <int>

This optionsets the `obscure percentage', an int. This defines how likely it is that an individual character in a spell incantation will be starred out (preventing casual listeners to figure out precisely what the proper incantation is). Note that the effectiveness of this measure also depends on the length of the incantation.

  • spell "<str>" : <options>

configures the specified spell (see below for a list of spells). The <options> adjust various spell properties; any option left open will be left at some unreasonable defualt. The options are below:

    • level = <int> (spell level. Minimum int+lvl a character must have to cast it.)
    • effect = <int> (spell casting graphical effect index number. Default is mostly 2.)
    • mana = <int> (mana points that must be expended to cast the spell)
    • incantation = "<str>" (The incantation to use to invoke the spell.)
    • prerequisites = [ <num>, ..., <num> ] (Prerequisite items to cast the spell; these will NOT be consumed.)
    • components = [ <num>, ..., <num> ] (Material components to require for the spell; these will be consumed when the spell is cast. You can require the same item more than once to require multiple instances of that item to be consumed.)

Items are identified by their item IDs. Please note that in the current implementation the default values for `mana' and `level' are very low, and neither prerequisites nor components are used, in order to simplify testing.

Improving visualisation in the client

While client visualisation should be fully functional at this point, it could use some improvement. The implementation sends different level-up like signals to the client, which the existing client interprets as `job level up' signals. A refined client could map these numbers to more appropriate particle effects.

Furthermore, wind-based movement is currently somewhat rough, particularly for clients whose avatars are being moved. Rough movement could be addressed by simulating smoother movement when a being is teleported only one square away from where the client expects it to be; rough scolling in turn can be addressed by scrolling rather than updating the frame position when the player's character is teleported to a very nearby location.

Finally, the existing client does not properly draw the mana bar, instead opting always to display it as full. This inconvenience can be fixed trivially in src/gui/ministatus.cpp by uncommenting the line

     // mMpBar->setProgress((float) player_node->mMp / player_node->mMaxMp);

Conclusions and Future Work

This document presents a magic system that is simple to use and easy to integrate with the existing infrastructure but offers players additional, `magical' operations. While not all of the spells presented herein are balanced in and by themselves, they can be balanced by adding appropriate material component requirements. This in turn creates new opportunities for money sinks and player-driven markets. Finally, the use of invocations as part of the spellcasting process allows spells to be guarded and/or propagated by social means rather than by developer-driven quests; depending on how the invocations are seeded, this may have interesting effects on existing and new social structures within the game.

Note that the magic system does not require all spells to be activated at the same time: by setting a spell's invocation to "", the spell can be effectively disabled. In this fashion, spells can be gradually added after they have survived testing. Similarly, that have been found exploitable or broken can be disabled quickly, while spells that have become more widely known than anticipated can be re-hidden by changing (and re-seeding) their invocation.

Future extensions and spell ideas

Below are some ideas for improving existing spells:

  • Dying from your own offensive spell should preclude resurrection
  • Range for ``Death's Door should be reduced.
  • The effects of offensive spells should be toned down via battle_get_mdef(-).

Below are some ideas for additional spells:

  • Magic shield: temporarily boost magic defence
  • Reversal: any spell cast on the subject (good or bad) backfires on the caster. For offensive spells, the computed damage backfires (making ``Death's Door suicidal.) Spells the caster casts on him/herself are instead cast on a random subject in the area. (HP draining for powering healing/offensive magic is unaffected.) Any spell can only be turned back once in such a fashion (as in Final Fantasy).
  • Curse of the Pink Fluffy: a near-indestructible pink fluffy follows the subject around, making funny noises
  • Summon Ether Serpent: summons a cyan-ish snake (semi-transparent, if possible) that is significantly tougher than most monsters in the game but deals most of its damage by draining mana. Impervious to `peace', will not (at first) attack its summoner.
  • Banish: banishes a summoned creature (Ether Serpent, Pink Fluffy)
  • Delay: the next spell cast by the caster will be delayed by ten seconds. (Note that this spell can also be applied to other spellcasters via Reversal...)
  • Dispel: cancels any spells currently active/in range and any spells cast in the next 5 seconds
  • Teleport: teleports the caster to one of a set of predetermined locations based on whatever (s)he says next
  • Gate: as teleport, but creates a temporary gate to that location that other people can follow through (the gate could be visualised as an NPC).
  • Anchor: creates a temporary teleport anchor (a name bound to a location). Can only override existing bindings if the caster is more powerful than the one of the existing binding.
  • Magic Mouth: creates a temporary NPC that will repeat the next sentence spoken by the caster to anyone who passes by and tries to talk to it.
  • Bless: increases accuracy and slightly increases damage (eAthena might already have this one.)