Effects & Enchantments

A typical RPG/roguelike has equipment, cards, skills etc that can all provide bonuses or penalties in various statistics, primary or derived. For example, movement speed, attack speed, maximum health, etc. There are possibly lots of ways to implement them. After a few unsuccessful theoretically-efficient approaches, the current revision looks reasonable.

Temporary, permanent, recurring and conditional effects

Examples that should be possible include:

  • Potion of healing: one-off, adjust current health [permanent]
  • Potion of regeneration: every N seconds, adjust current health. Stop after N*K seconds [permanent, recurring]
  • Potion of speed: movement speed increased by 20%, for 1 minute [temporary]
  • Potion of remove blindness: one-off, sets blindness to false ONLY if the creature is not naturally blind [permanent, conditional]
  • Sword of orc slaying: +50% weapon damage (applied when we use an ability that uses the equipped weapon), only if we’re attacking orcs [temporary, conditional]
  • Boots of the desert: +50% movement speed when crossing the desert biome [conditional]

So, observing such use-cases, I made the following design choices:

  • All types of effects/modifiers can have conditions
  • Permanent effects write directly to the actual values the affect. A health potion updates the actual health value. If they have conditions, they check them once, before they apply the permanent effect.
  • Temporary effects are stored in a separate list. Every time we want to get a particular value (weapon damage, max health, etc), we need to run a system function that gets the base value and applies all effects (if any of them has conditions, it’s applied if the condition is satisfied)
  • Events are set up for recurring permanent effects
  • Events are set up for temporary effects, to remove them from the list when the effect expires.
  • Temporary effects can be applied when an item is being carried (figurine), equipped (sword) or used (potion).

A drawback of the separate list for temporary effects is that we have to maintain indirect access to all variables that could be modified by effects, so that the access function always takes into account any effects. Additionally, we can’t even cache effects as they can be conditional. So for example, we have functions like “EvaluateMaxHealth”, “EvaluateMovementSpeed” etc, that get the base maximum health, then look for any effects that target max health (and pass the conditions, if any) and generate the final value.

In the temporary effects list we have 3 types of effects, based on what they modify:

  • Numerical. +1 Skill, +50 health, +15% attack speed.
  • Boolean. Set paralyzed or not, deaf or not, able to fly or not, etc.
  • Option. Set field of vision algorithm. Probably more to come.

Overall the system should be very flexible and allow for weird effects expressed naturally by data driving, e.g. a potion of lycanthropy that only works in a full moon, over the dead body of a wolf (a date condition and a condition that there’s an item pile that contains a wolf corpse under the feet of the player). The only important rule to remember when developing effects is that any values that can be affected by temporary effects need to accessed by these evaluator functions, unless we do not want to take modifiers into account.

Here is a video that shows a few potions in action: healing, emergency healing (only when health is < 20%), alacrity (player moves at incredible speed), X-ray vision (see through walls), oracle (see entire map):

Here’s another video that shows the death particle system adjusted to go towards the direction of the hit:

Skill System Redux

Previously…

Last time I worked on the skill/stat system, I didn’t even touch active abilities, like feats in DnD. My main problems with my skill breakdown were:

  • Too many skills: around 50. Easier to navigate by using categories, but still.
  • Skill progression is difficult because of the skill breadth. Difficult to balance a jack-of-all-trades and a focused grandmaster of a few skills, with interesting skill progression/bonuses
  • The options were many, and the bad options could be many too. So, level ups would be a bit confusing and prone to mistakes and bad builds
  • Only some of these skills would enable DnD style feats, but I hadn’t thought that part out, and it would possibly be imbalanced.

So I engaged in some thinking, and some more thinking, and tried to recall bits of advice and suggestions by a variety of game/RPG design people, most importantly for what I want the core experience to be like. And the cornerstone pillars of the game’s experience is combat and exploration. But at the same time, I don’t want to ignore stealth or NPC interactions in cities/factions/elsewhere, so these exist but are of lesser importance, and this should be reflected in the system.

New approach

So, while the skills needed revamping, I like the attributes and the mastery levels. So, here are the main components of the current train of thought:

  • There are about 20 skills in 4 categories: offense, defense, arcana and misc.
  • Players can put points in each skill up to a limit of 15 skill points.
  • Players can improve their mastery of a skill given sufficient points and training from an NPC
  • Improving the mastery of a skill gives new passive bonuses (e.g. evasion chance when adding points in light armour skill). Points in a skill improves those bonuses.
  • Active abilities (think DnD feats, or ToME active skills) can be learnt from NPCs or scrolls, if player satisfies requirements in terms of skills, attributes and masteries. For example, crafting light armour would require mastery in both crafting and light armour.
  • Each level, the player can allocate 3 skill points, to a total of 90 skill points at level 30. Only one skill can be trained to grandmaster level, and thus reach the 15th point

Here’s the current list of skills:

Offense
Dual wielding
One handed
Two handed
Ranged and thrown
Defense
Light armour
Medium armour
Heavy armour
Shield
Arcana
Command magic
Alteration magic
Divination magic
Creation magic
Destruction magic
Misc
Athletics
Meditation
Lore
Stealth
Crafting and alchemy
Survival
Leadership

The idea behind this is that skills reflect play style. My goal is to make as many as possible viable play styles, mixing arcane with melee, etc.

Archetypes

Previously I had to manually author archetypes, as not all combinations of skill points would be valid. With the new approach, it should be easier to write an automatic generator of characters that does not use any predefined limits in masteries etc. If a barbarian wants to learn meditation, more power to them, it’s going to be useful still. What is required to be careful about is the related attribute. If your barbarian has very low intelligence, it’s an indicator that he/she won’t really master that skill. The goals of the archetype creation are:

  • Maximum diversity
  • Minimum bad-looking builds
  • Fully procedural builds (“make me a character”)
  • User-guided builds (“make me a grandmaster in destruction magic, with some other nice skills too”)
  • Minimum data entry / configuration effort

The new archetype generator is parameterized on a list of target skill/mastery combos to achieve (optional), and a “well-roundedness” factor, which represents how hyper-focussed or jack-of-all trades we want the character to be. It works roughly in the following way:

  • Character creation: If we have target mastery combos, roll and initialize stats to satisfy requirements as close as possible
  • Assigning attributes: Try to satisfy criteria. If done, allocate based on the well-roundedness, between completely randomly (well-rounded) and to the highest attribute (focused)
  • Assigning skills: Try to satisfy criteria. If done, allocate based on attributes and well-known combos, e.g.:
    • dual-wield + one-handed = good
    • two-handed + dual-wield / shield = bad
    • meditation + any magic = good
    • sneak + heavy armour = bad

And that’s it! Yes it’s oversimplified a bit, but the archetype generation code is less than 300 lines, and is much, much, much simpler than the old approach. So, what characters does it generate? Plotting time again!

Well-roundedness = 0, target Destruction Magic GM: What looks like a typical elemental mage, plus misc skills as he’s physically weak
Well-roundedness = 1, target Destruction Magic GM: A more well-rounded machine of destruction
Well-roundedness = 0.5, target Destruction Magic GM: Something like the above, but in-between
Well-roundedness = 0, targets Dual Wielding GM and Light Armour Expert. Adding relevant athletics and dual-wielding; we are quite agile after all. At the later levels we develop Leadership as well, since we’re high on the Charisma.

So, archetypes look like they are working as intended. For next time, instead of fast encounter resolution, like last time, I’m going to deal with HP/MP next and attempt something more concrete, like spawning a few aggressive creatures with levels, and progressing with connecting skills to active abilities.