For the complete documentation index, see llms.txt. This page is also available as Markdown.

Rules

This page covers the Rules plugin architecture and how to create custom condition and effect types.

Rule Architecture

The Rules system uses two interfaces:

  • ISparkCondition: A condition that evaluates to true or false given a context.

  • ISparkEffect: An action that executes given a context.

A rule pairs conditions with effects: if all conditions pass, all effects execute.

Context System

Conditions and effects receive context objects that provide information about the evaluation:

public class ConditionContext
{
    public SparkEntity Source { get; }     // The entity being evaluated
    public SparkEntity Target { get; }     // Optional target entity
    public object CustomData { get; }      // Plugin-specific data
}

public class EffectContext
{
    public SparkEntity Source { get; }
    public SparkEntity Target { get; }
    public object CustomData { get; }
}

Creating Custom Conditions

Implement ISparkCondition:

For conditions with configurable parameters, use serialized fields:

Creating Custom Effects

Implement ISparkEffect:

Built-in Condition Categories

Spark and its plugins include conditions across these domains:

  • Inventory: Has item, item count checks

  • Stats: Stat value comparisons

  • Character: Class, race, profession checks

  • Combat: In combat, health thresholds, has buff/debuff

  • World: Time of day, zone, weather (if implemented)

  • Quest: Quest state checks

Built-in Effect Categories

  • Inventory: Give/remove items

  • Stats: Modify stats, apply buffs/debuffs

  • Character: Change class, grant profession

  • Combat: Deal damage, heal, apply status effects

  • World: Change scene, spawn objects, play effects

  • Quest: Accept/complete quests

Integration Examples

Rules are used by many systems:

Best Practices

  • Keep conditions pure (no side effects). They should only read state, never modify it.

  • Keep effects focused on a single action.

  • Use ComparisonType for numeric conditions. Don't hardcode comparison logic.

  • Always null-check entities and components in both conditions and effects.

  • Make conditions and effects reusable across different contexts (quests, NPCs, interactables).

  • Use serialized fields and Spark attributes so designers can configure them in the editor.

Last updated

Was this helpful?