Skip to content
MyLadyMalady edited this page Jun 25, 2024 · 5 revisions

Introduction

As our own minigame implementation grew more and more complicated, we saw a need to meaningfully differentiate damage sources, instead of treating it as a singular concept where all damage is just a decrease in HP.

Because of this, we've developed different damage types and appropriate resistances for each.

Damage Types

You can think of this as a "label" that is supplied mainly to damage-related skills, guns, etc. It ensures that appropriate resistances are incurred when an entity is hit with this particular type of damage source.

All damage types are prefixed with damage.

The currently available types are:

  • damage.fire

  • damage.explosion

  • damage.poison

In cases where a type isn't defined, there is a "default" source (such as what's used by mobs' melee attack) that is mainly resisted through an entity's armor.

Damage Resistances

This is slightly more complicated than labeling the incurred damage.

All damage types (excepting the default) have three kinds of resistances: .addition, .multiply_base and multiply_total; e.g. damage.fire.addition, damage.fire.multiply_base and damage.fire.multiply_total.

.addition represents a flat resistance, where the incoming damage is always reduced by the same number. For example, with a damage.fire.addition set to -2, a mob would always resist 2 of the damage, e.g. 10 is reduced to 8 and 20 is reduced to 18. This resistance defaults to 0.

.multiply_base is a scalable resistance, and the number passed to it represents a percentage change from 1 (100% damage taken). For example, with a damage.fire.multiply_base set to -0.5, the incoming damage is reduced by 50% — remember, the formula for multiply_base is original_value += original_value * supplied_value. This means that the mob would take 5 damage out of 10 incurred, 10 damage out of 20, and so on. Defaults to 0.

multiply_total is another kind of scalable resistance that works in a similar way to multiply_base. For example, with a damage.fire.multiply_total set to -0.5, 50% of the incoming damage is resisted. What makes it differ from multiply_base is the order of operations. Defaults to 0.

If you have multiple of these defined, the order of operations is:

  1. incoming damage is multiplied by the resultants of all multiply_base calls
  2. all addition is added to the damage modified by step 1
  3. incoming damage modified by step 2 is further multiplied by all multiply_total calls

The amount left after step 3 is the damage that an entity will actually receive.