Effect Condition Catalog
Built-in condition types used by the effect engine. Effects (from artifacts, ship passives, and mod abilities) attach an array of ConditionDef entries; the engine evaluates them in array order and bails on first failure. ALL must pass for the effect’s actions to fire. Each entry has shape { type: string, params: Record<string, number | string> } and dispatches through CONDITION_MAP in engine/effects/conditions.ts.
This catalog backs the ConditionDef.type field documented in engine/effects/types.ts. All params support $value placeholders resolved from EffectInstance.values via resolve-params.ts (numeric params through resolveNumber, strings through resolveString).
Conditions are pure reads — they never modify state. Evaluation order matters: list cheapest (signal/random) first, ship-state next, registry lookups last.
Signal-context (cheapest)
These fire against the SignalSnapshot carried by the triggering event. If the trigger has no snapshot (e.g. run_start), most snapshot-based conditions short-circuit.
| Type | What it checks | Params |
|---|---|---|
random | Roll a uniform 0–1 random < chance. Independent per evaluation. | chance (0..1, default 1) |
signal_str1_eq | The triggering signal’s str1 field equals an expected value. Returns false if no snapshot. | value (string, default '') |
signal_str1_neq | The triggering signal’s str1 field does NOT equal a value. Returns true if no snapshot (vacuously). | value (string, default '') |
signal_num1_gte | The triggering signal’s num1 field is at least a threshold. Returns false if no snapshot. | value (number, default 0) |
damage_tag_eq | Convenience alias over signal_str1_eq — checks damage tag carried in str1. Used to gate hit/kill procs by damage type (fire, kinetic, etc.). | tag (string, default '') |
Ship state
Read against the active ShipState.
| Type | What it checks | Params |
|---|---|---|
hp_below | ship.hp / hpMax is below a fraction. | threshold (0..1, default 0.5) |
hp_above | ship.hp / hpMax is above a fraction. | threshold (0..1, default 0.5) |
shield_active | Ship has any shield remaining (shield > 0). | none |
shield_broken | Ship shield is fully gone (shield <= 0). | none |
shield_empty | Alias for shield_broken — semantically distinct gating keyword for content authors. | none |
heat_above | Ship heat gauge is at or above a threshold. | threshold (number, default 50) |
speed_above | Ship’s current velocity magnitude (sqrt(vx²+vy²)) is at or above a threshold. | threshold (number, default 100) |
speed_below | Ship’s current velocity magnitude is strictly below a threshold. Used for “stationary” procs. | threshold (number, default 10) |
has_buff | At least one modifier with the given source tag is currently active on this ship (read via Modifiers._modsByTarget). | source (string, default '') |
Inventory / progression
Read against GameState.
| Type | What it checks | Params |
|---|---|---|
has_artifact | The player has an artifact with the given id in game.artifacts. | artifactId (string) |
has_upgrade | game.upgradeCounts[upgradeId] is at least minLevel. | upgradeId (string), minLevel (number, default 1) |
Run state / time
| Type | What it checks | Params |
|---|---|---|
kill_streak_above | game.killStreak is at or above a threshold. | threshold (number, default 0) |
elapsed_above | game.time (run-elapsed seconds) is at or above a threshold. Use to gate late-run effects. | seconds (number, default 0) |
elapsed_below | game.time is strictly below a threshold. Use for early-run-only effects. | seconds (number, default 999999) |
tier_at_least | Current level/tier (_currentLevel) is at or above a number. | tier (number, default 1) |
Boss
| Type | What it checks | Params |
|---|---|---|
boss_active | A boss arena is currently active (game.bossArena !== null). | none |
boss_phase_gte | Reserved — currently a stub that always returns false. Placeholder for future boss-phase gating. | (TBD) |
Authoring notes
- Order matters. Put
random/ signal checks first, ship-state second, registry lookups (has_artifact,has_upgrade,has_buff) last. - AND-only. There’s no OR or NOT at the condition level. Use multiple effects with different condition arrays to express alternates.
- No snapshot → undefined. Snapshot-based conditions return
falsewhen there’s no signal (the_neqvariant returnstrue). Trigger types likerun_start,timer, or polling auras have no snapshot, so don’t attach signal conditions to them. - Param resolution. Numeric and string params accept
$keyreferences resolved againstEffectInstance.valuesat evaluation time, so a single effect template can be reused across stat tiers. - Adding a new type. Implement a
ConditionFn, register it inCONDITION_MAPat the bottom ofengine/effects/conditions.ts. Unknown types throw — there is no silent fallback.
Related
engine/effects/types.ts—ConditionDef,EffectInstance,EffectDefshapes.engine/effects/effect-engine.ts— trigger dispatch + condition orchestration.engine/effects/resolve-params.ts—$keyplaceholder resolution.engine/effects/actions.ts— what runs when all conditions pass.- Companion concept: trigger types, action catalog, signal-snapshot fields.