Formulas

Formulas are the math engine behind Spark's number crunching. They are used for damage calculations, healing calculations, stat scaling, stat bonuses, and anywhere else a custom calculation is needed. Formulas are not limited to combat — any system that needs a calculated value can reference a formula.

Spark uses nCalc, a powerful open-source expression evaluator for .NET, as its formula engine. This means formulas support a full range of mathematical operations, conditional logic, and built-in functions.

Creating a Formula

Open the Spark Editor, go to Combat > Formulas and click Create New.

Each formula entry has:

Field
Description

Formula Expression

The nCalc math expression (e.g., BaseDamage + [AttackPower] * 2.5 - [Armor] * 0.5).

Variable Mappings

Maps variable names in the expression to stat values from the caster or target.

Variable Mappings

Each variable mapping connects a name used in the formula to an actual stat value at runtime:

Field
Description

Variable Name

The name used in the expression (e.g., "AttackPower").

Stat

Which stat entry to read the value from.

Property ID

Which property of the stat: value (for value stats), current or maximum (for resource stats). Default: value.

Source

Whether to read from the Caster or the Target entity.

Built-in Variables

These variables are automatically available in every formula without needing a mapping:

Variable
Description

BaseDamage

The base damage value from the damage effect.

BaseHealing

The base healing value from the healing effect.

StackMultiplier

The current stack count of the status applying this effect.

Random

A random value between 0 and 1, generated fresh each evaluation.

nCalc Expression Reference

Spark's formula system supports the full nCalc expression language. Below is a reference of everything you can use in formula expressions.

Arithmetic Operators

Operator
Description
Example

+

Addition

BaseDamage + 10

-

Subtraction

[MaxHP] - [CurrentHP]

*

Multiplication

[AttackPower] * 2.5

/

Division

[Damage] / 2

%

Modulus (remainder)

[Level] % 10

**

Exponentiation

[Level] ** 2

Comparison Operators

Operator
Description
Example

= or ==

Equal

[Level] = 10

!= or <>

Not equal

[Class] != 0

<

Less than

[CurrentHP] < 100

>

Greater than

[Armor] > 50

<=

Less than or equal

[Mana] <= 0

>=

Greater than or equal

[Level] >= 5

Logical Operators

Operator
Description
Example

and or &&

Logical AND

[Level] > 5 and [HasBuff] = 1

or or ||

Logical OR

[IsBoss] = 1 or [IsElite] = 1

not

Logical NOT

not ([IsDead] = 1)

Conditional Functions

Function
Description
Example

if(condition, trueValue, falseValue)

Returns one of two values based on a condition.

if([CurrentHP] < [MaxHP] * 0.3, BaseDamage * 1.5, BaseDamage)

switch(condition1, result1, ..., default)

Returns a value from a list based on the first matching condition.

switch([Element] = 1, 'Fire', [Element] = 2, 'Ice', 'Normal')

in(value, set...)

Checks if a value is in a set.

in([DamageType], 1, 3, 5)

Built-in Math Functions

nCalc provides all standard math functions from .NET's System.Math:

Function
Description
Example

Abs(x)

Absolute value

Abs([Armor] - [Penetration])

Ceiling(x)

Round up to nearest integer

Ceiling(BaseDamage * 1.3)

Floor(x)

Round down to nearest integer

Floor([CritMultiplier] * BaseDamage)

Round(x)

Round to nearest integer

Round([AttackPower] * 0.7)

Round(x, decimals)

Round to specified decimal places

Round([DPS], 2)

Truncate(x)

Remove decimal portion

Truncate([RawDamage])

Max(x, y)

Return the larger value

Max(1, BaseDamage - [Armor])

Min(x, y)

Return the smaller value

Min([CurrentHP], [MaxHP])

Pow(x, y)

Raise x to the power of y

Pow([Level], 1.5) * 10

Sqrt(x)

Square root

Sqrt([Intelligence]) * 5

Log(x)

Natural logarithm

Log([Level] + 1) * 50

Log10(x)

Base-10 logarithm

Log10([Experience])

Log(x, base)

Logarithm with custom base

Log([Value], 2)

Exp(x)

e raised to the power of x

Exp(-0.1 * [Armor])

Sign(x)

Returns -1, 0, or 1

Sign([Direction])

Sin(x)

Sine (radians)

Sin([Angle])

Cos(x)

Cosine (radians)

Cos([Angle])

Tan(x)

Tangent (radians)

Tan([Angle])

Asin(x)

Arc sine

Asin([Value])

Acos(x)

Arc cosine

Acos([Value])

Atan(x)

Arc tangent

Atan([Value])

Atan2(y, x)

Arc tangent of y/x

Atan2([DeltaY], [DeltaX])

IEEERemainder(x, y)

IEEE remainder

IEEERemainder([Value], 360)

Formula Examples

Here are some practical formula examples for common game mechanics:

Simple damage with armor reduction:

Critical hit with random chance:

Percentage-based healing:

Level-scaled damage with diminishing returns:

Conditional damage bonus (execute-style, bonus damage on low HP targets):

Where Formulas Are Used

Formulas appear in several places throughout Spark:

  • Damage effects: Custom damage calculation replacing the default BaseDamage.

  • Healing effects: Custom healing calculation.

  • Stat scaling: Stats can scale damage/healing types using a formula instead of flat/percentage.

  • Stat bonuses: Stat-to-stat bonuses can use formulas for complex scaling relationships.

Because formulas are database entries, the same formula can be reused across multiple abilities, stats, and effects.

Performance

Spark caches compiled formula expressions and uses version tracking to invalidate the cache only when a formula changes. This means formula evaluation is fast at runtime even with complex expressions. The result is always clamped to a minimum of 0 to prevent negative values.

Last updated

Was this helpful?