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. Mantis entry for this proposal.
(The following discussion applies to the updated v4 version of the patch)
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', `magic defence', `magic absorption' 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. Intelligence also affects one of the two defensive properties for magic:
magic absorption = experience level / 8 + intelligence
`magic absorption' describes how many points of magical damage to subtract each time magical damage is dealt to a character-- this derived stat therefore works similarly to vitality. A third stat, `magic defence', is already present in eAthena and describes (as a percentage) how much magical damage is absorbed. `magic defence' is applied first, then `magic absorption'.
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 / 25 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.
Barrier
- short name: `barrier'
- default invocation: `anort'
- visual effect: MAGIC_CAST_ENHANCE (3), MAGIC_EFFECT_BARRIER (20) on subjects
- area of effect: self or player standing immediately in front of the caster
- duration: (10 + power) * 100 ticks
During the duration of this spell, magic defence is raised to 100 (as per the default eAthena implementation of `barrier'), thereby absorbing all damage from offensive spells such as the three previous ones.
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.
A corresponding experimental patch that addresses some further minor issues is available Visualisation improvements.
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
Below are some ideas for additional spells:
- 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.)
- Floating Backpack: temporarily eliminates the `no regeneration' penalty for being burdened. (Note: suggested by Vink)
- Blink: short-range teleport in the direction the caster is facing; does not pass through walls but may pass through monsters/players.
- Boost: temporarily increases the caster's spell power.