Effect Types
Buff effects define what happens when a buff triggers. All effects extend the BaseBuff interface and can have optional conditions and trigger keys.
Base Effect Properties
condition
Optional condition that must be met for the effect to trigger.
triggerKey
Optional key used for triggered effects system.
Damage Effects
damage
Deals damage to the enemy.
{
kind: 'damage',
amount: { value: 1.0, stat: 'power' },
hits?: { value: 3, stat: undefined }, // Optional multiple hits
damageType?: 'true' | 'corrupt' | 'disruption' // Optional special damage
}
Example from game:
// From a celestial technique
{
kind: 'damage',
amount: { value: 0.8, stat: 'power' },
damageType: 'true'
}
damageSelf
Deals damage to yourself.
{
kind: 'damageSelf',
amount: { value: 0.03, stat: 'maxhp' },
damageType?: 'true' | 'corrupt' | 'disruption'
}
Example from Profane Exchange:
// Intercept effect that converts corruption into self-damage
{
kind: 'damageSelf',
amount: { value: 0.03, stat: 'maxhp', upgradeKey: 'hpCost' },
damageType: 'true'
}
Healing and Protection
heal
Restores health.
{
kind: 'heal',
amount: { value: 0.25, stat: 'power' },
hits?: { value: 2, stat: undefined } // Optional multiple heals
}
Example from Restoring Fragrance:
// After-technique healing
{
kind: 'heal',
amount: { value: 0.25, stat: 'power', upgradeKey: 'power' }
}
barrier
Grants barrier (damage absorption).
{
kind: 'barrier',
amount: { value: 0.9, stat: 'power' },
hits?: { value: 1, stat: undefined }
}
Example from Advancing Fist:
{
kind: 'barrier',
amount: { value: 0.9, stat: 'power', upgradeKey: 'barrier' }
}
repair
Restores health to barrier-type buffs that have taken damage.
{
kind: 'repair',
amount: { value: 0.5, stat: 'power' },
group: 'shield',
rule: 'lowestHealth'
}
Parameters:
group— Selects which buffs to repair. Matched against the buff’sname,buffType, or any flag set on it (same matching rules asmodifyBuffGroup).rule—'all'repairs every matching buff;'lowestHealth'targets the most damaged one;'highestHealth'targets the least damaged.
Example — repair the most damaged shield buff:
{
kind: 'repair',
amount: { value: 0.3, stat: 'power' },
group: 'shield',
rule: 'lowestHealth'
}
Buff Management
buffSelf
Grants a buff to yourself.
{
kind: 'buffSelf',
amount: { value: 2, stat: undefined },
buff: targetBuff,
instances?: { value: number, stat?: string }, // Number of separate buff instances to create (supports Scaling)
silent?: true, // Don't show application message
hideBuff?: true // Don't show buff in tooltips
}
consumeSelf
Removes a buff from yourself.
{
kind: 'consumeSelf',
amount: { value: 1, stat: undefined },
buff: targetBuff // Can be Buff object or string name
}
buffTarget
Gives a buff to the enemy.
{
kind: 'buffTarget',
amount: { value: 3, stat: undefined },
buff: debuffBuff
}
consumeTarget
Removes a buff from the enemy.
{
kind: 'consumeTarget',
amount: { value: 2, stat: undefined },
buff: enemyBuff
}
Stack Manipulation
add
Adds or removes stacks from the current buff.
{
kind: 'add',
amount: { value: -1, stat: undefined } // Remove 1 stack
}
Example from Moonchill:
// Consume 1 stack after each technique
{
kind: 'add',
amount: { value: -1, stat: undefined }
}
multiply
Multiplies the current stack count.
{
kind: 'multiply',
amount: { value: 2 } // Double stacks (multiply by 2)
}
negate
Removes all stacks of the current buff.
{
kind: 'negate';
}
mergeSelf
Combines multiple stacks from one buff into fewer stacks of another buff. Unlike convertSelf which transfers stacks one-for-one, mergeSelf condenses a ratio of source stacks into target stacks.
{
kind: 'mergeSelf',
source?: sourceBuff, // If omitted, uses the current buff
sourceStacks: { value: 2, stat: undefined },
target: targetBuff,
targetStacks: { value: 1, stat: undefined }
}
Example — condense 2 source stacks into 1 target stack:
{
kind: 'mergeSelf',
sourceStacks: { value: 2, stat: undefined },
target: condensingBuff,
targetStacks: { value: 1, stat: undefined }
}
Use case: Efficiency mechanics where lower-tier resource buffs are consolidated into higher-tier forms. For example, a technique that generates multiple weak stacks which should be merged into a single stronger stack rather than accumulating separately.
Advanced Effects
convertSelf
Converts stacks of one buff into stacks of another buff, one-for-one. Unlike mergeSelf, this transfers all available stacks at the point of execution rather than merging by a ratio.
{
kind: 'convertSelf',
source: sourceBuff, // Buff to take stacks from
target: targetBuff, // Buff to add stacks to
amount: { value: 1, stat: undefined } // Stacks to convert per application
}
Example — inscription upgrade chain (used in onRoundEffects):
{
kind: 'convertSelf',
source: baseInscription,
target: forbiddenInscription,
amount: { value: 1, stat: undefined },
}
Use case: Escalating resource mechanics where lower-tier buffs automatically promote to higher-tier versions at the end of each round.
setState
Sets or increments a named state variable that persists for the duration of combat. State variables can be read in conditions using their key name.
{
kind: 'setState',
key: 'variableName', // Arbitrary string key
value: { value: 1, stat: undefined },
mode?: 'set' | 'add' // 'set' overwrites, 'add' increments (default: 'set')
}
Example — counting triggers this technique:
// In triggeredBuffEffects — increment counter each time a trigger fires
{
kind: 'setState',
key: 'triggersThisTechnique',
value: { value: 1, stat: undefined },
mode: 'add',
}
// Reset counter after processing
{
kind: 'setState',
key: 'triggersThisTechnique',
value: { value: 0, stat: undefined },
mode: 'set',
}
Reading the variable in a condition:
condition: {
kind: 'condition',
condition: 'triggersThisTechnique > 0',
}
Use case: Tracking counts or flags within a single combat session that drive conditional effects, such as “if this buff triggered more than twice this technique, deal bonus damage.”
trigger
Triggers custom events for other systems.
{
kind: 'trigger',
triggerKey: 'customEvent',
amount: { value: 1, stat: undefined },
triggerTooltip?: 'Explanation of what this trigger does'
}
cleanseToxicity
Removes or adds toxicity.
{
kind: 'cleanseToxicity',
amount: { value: 10, stat: undefined } // Positive removes, negative adds
}
modifyBuffGroup
Modifies all buffs of a specific group.
{
kind: 'modifyBuffGroup',
group: 'celestial',
amount: { value: 1, stat: undefined }
}
consumeInventoryItem
Consumes an item from the player’s inventory. The effect silently does nothing if the item is not present.
{
kind: 'consumeInventoryItem',
itemName: 'Qi Replenishing Pill', // Exact display name of the item
amount: { value: 1, stat: undefined }
}
Use case: Equipment or mount effects that deplete consumable items as part of their activation (for example, a mount that burns a special pill each round to provide its bonus).
permanentStatChange
Permanently modifies a physical or social statistic on the player. The change takes effect after combat ends. The amount is floored to an integer.
Only applies when the technique is used by the player — enemy techniques with this effect kind are ignored.
{
kind: 'permanentStatChange',
stat: 'muscles', // Any PhysicalStatistic or SocialStatistic
amount: { value: 5, stat: undefined }
}
Valid stat values:
Physical statistics:
'flesh'— Max Health and Barrier Effectiveness'muscles'— Power and Qi Intensity'meridians'— Qi Control and Artefact Power'dantian'— Max Barrier, Max Qi Pool, and Qi Absorption'digestion'— Toxicity Resistance and Item Effectiveness'eyes'— Critical Chance and Critical Multiplier
Social statistics:
'charisma'— Presence and shop prices'battlesense'— Stance count and stance-switch power bonus'craftskill'— Qi Control and Qi Intensity bonus'artefactslots'— Number of equippable artefacts'talismanslots'— Number of equippable talismans'condenseEfficiency'— Qi to Qi Droplet conversion rate'pillsPerRound'— Items usable per combat round'age'— Current age'lifespan'— Maximum lifespan
Use case: Combat consumables that permanently enhance the player’s physical or social attributes when used during a fight.
Example — a pill that permanently boosts muscles by 1:
{
kind: 'permanentStatChange',
stat: 'muscles',
amount: { value: 1, stat: undefined }
}
Scaling System
All effects use the Scaling interface for amount calculations:
interface Scaling {
value: number; // Base value
stat?: CombatStatistic; // Stat to scale from
scaling?: string; // Custom scaling variable (e.g. 'stacks', a buff name)
eqn?: string; // Expression multiplied onto the result
additiveEqn?: string; // Expression added to the result (after eqn multiplication)
max?: Scaling; // Maximum value cap
upgradeKey?: string; // Reference for upgrades
}
The eqn field enables complex calculations within the scaling value itself. For example, the Meteor buff uses eqn to scale its damage with the meteor’s current mass:
{
kind: 'damage',
amount: {
value: 3,
stat: 'power',
eqn: '1 + (state.mass * 0.2)', // Base 3x power, plus 20% per mass
},
}
See the Scaling docs for the full formula and all available scaling patterns.
Common Scaling Patterns
Power Scaling:
amount: { value: 1.2, stat: 'power' }
Stack Scaling:
amount: { value: 0.1, stat: 'power', scaling: 'stacks' }
Percentage of Max HP:
amount: { value: 0.05, stat: 'maxhp' }
Capped Scaling:
amount: {
value: 0.05,
stat: 'power',
scaling: 'stacks',
max: { value: 1, stat: 'power' }
}
Element Resistance and Amplification
When a technique has one or more element types, the target’s resistance for each element is checked. The highest resistance value (positive or negative) is selected and applied to the damage:
- Positive resistance reduces incoming damage, capped at 90% reduction. For example, 50% resistance multiplies damage by 0.5.
- Negative resistance amplifies incoming damage with no lower cap. For example, -20% resistance multiplies damage by 1.2.
The system selects the single most impactful resistance value, so mixing positive and negative values picks whichever helps or hurts the target most.
// Example: target has 30% Blossom resistance
// A Blossom technique dealing 100 damage would deal 70 damage
// Example: target has -15% Blood resistance (vulnerable to blood)
// A Blood technique dealing 100 damage would deal 115 damage
This applies only when the technique has element types set. Techniques with no element type skip resistance checks entirely.
Damage Types
Special damage types bypass certain protections:
'true'
Ignores both barrier and defense.
'corrupt'
Ignores defense but not barrier.
'disruption'
Only affects barrier, not health.
Condition Examples
Multiple Hits with Scaling
{
kind: 'damage',
amount: { value: 0.3, stat: 'power' },
hits: {
value: 0.5, // 1 hit per 2 stacks
scaling: 'bloodCorruption',
max: { value: 3, stat: undefined } // Max 3 hits
}
}
Conditional Effects
{
kind: 'heal',
amount: { value: 0.2, stat: 'power' },
condition: {
kind: 'hp',
percentage: 50,
mode: 'less'
}
}
Chance-Based Effects
{
kind: 'buffSelf',
buff: shieldBuff,
amount: { value: 1, stat: undefined },
condition: {
kind: 'chance',
percentage: 25
}
}