API - Combat & Weapons¶
Back to API Reference · Feature guide: Gameplay Automation
Every flow function here returns { completed: false } and does nothing when its Lancer flow class is missing or the input is invalid. Check completed before chaining on a result.
Attacks¶
attackWith async → Promise<{ completed: boolean; flow?: any; reloaded?: boolean }>
attackRollWith async → Promise<{ completed: boolean; flow?: any }>
hitWith async → Promise<{ completed: boolean; flow?: any }>
damageWith async → Promise<{ completed: boolean; flow?: any }>
await api.attackWith(weapon, targets?, { reloadIfEmpty?, fxSourceToken? }) // target + start the weapon attack flow
await api.attackRollWith(weapon, targets?, { fxSourceToken?, title? }) // repeat the weapon's attack roll only
await api.hitWith(weapon, targets, damageOptions?) // declare a hit: onHit trigger + the weapon's damage flow
await api.damageWith(weapon, targets?, damageOptions?) // the weapon's damage flow alone
Params: reloadIfEmpty boolean (default false) · fxSourceToken Token (default null) · title string card title override
attackWith sets the given tokens as targets then starts the weapon's attack flow. reloadIfEmpty: true reloads instead and returns { reloaded: true } when the weapon is unloaded. fxSourceToken plays the lancer-weapon-fx effect from that token instead of the attacker (the roll stays the attacker's) - reflected shots, turrets, drones.
attackRollWith repeats the weapon's attack roll as a basic attack with the weapon's stats (tier-resolved for NPC features) and carries its damage/tags to the damage roll, but skips the weapon-fire mechanics: no loading gate, no self-heat, no item updates. Rebound pattern.
The chain is attack > hit > damage: attackWith runs all three stages, hitWith the last two (fires onHit with the upcoming damage flow as its flowState, then rolls the weapon's damage), damageWith the last one. damageOptions override the damage flow data and take the same keys as executeDamageRoll's options (defaults: the weapon's tier-resolved damage and tags).
getTier → number
tierValue → any
api.getTier(tokenOrActor) // → 1-3
api.tierValue(tokenOrActor, [t1, t2, t3]) // → value for the actor's tier
Params: tokenOrActor Token|Actor · values [any, any, any] per-tier values
tierValue(reactorToken, [4, 6, 8]) replaces tier ladders and clamped index picks.
afterFlow → boolean
Params: triggerData the trigger's data object · callback (flow, success) => any
afterFlow runs the callback once the trigger's flow completes or aborts, after its card printed - one-shot, matched to that exact flow. Use it for anything that must not interleave with the flow (follow-up attacks, moves).
executeBasicAttack async → {completed, flow}
Starts a BasicAttackFlow.
| Param | Type | Default | Description |
|---|---|---|---|
| actor | Actor |
required | The actor making the attack |
| extraData | Object |
{} |
Injected into state.la_extraData |
inside options |
|||
| targets | Token\|Token[] |
null |
Who is attacked. Avoids touching setTarget |
| tags | Array |
undefined |
Weapon tags carried onto the attack card |
| damage | Array |
undefined |
Damage list carried onto the card, so its damage button rolls pre-filled |
| fxSourceToken | Token |
null |
Play the lancer-weapon-fx effect from this token instead of the attacker |
| fxItem | Item |
null |
Item whose FX the flow should use |
| item | Item |
null |
Roots the flow on this item, so it uses the item's stats and triggers see it as weapon. Forces non-tech classification |
Those six are consumed here. Any other key is forwarded to the BasicAttackFlow constructor.
executeTechAttack async → {completed, flow}
| Param | Type | Default | Description |
|---|---|---|---|
| target | Actor\|Item |
required | The actor or item initiating the tech attack |
| extraData | Object |
{} |
Injected state data |
inside options |
|||
| targets | Token\|Token[] |
null |
Who is attacked |
| damage | Array |
undefined |
Damage list carried onto the attack card |
Any other key is forwarded to the flow constructor.
executeSkirmish async → void
| Param | Type | Default | Description |
|---|---|---|---|
| actorOrToken | Actor\|Token\|TokenDocument |
required | The actor or token performing the skirmish |
| bypassMount | Object |
null |
Mount object to skip mount selection |
| preTarget | Token |
null |
Pre-selected target token |
| weaponFilter | (weapon: Item) => boolean |
null |
Filter for available weapons |
| options | Object |
{} |
noFX: true skips the skirmish FX |
executeBarrage async → void
Runs a Barrage: attacks with either two different mounts or one superheavy mount. Prompts for the mounts unless bypassMount supplies them.
| Param | Type | Default | Description |
|---|---|---|---|
| actorOrToken | Actor\|Token\|TokenDocument |
required | The acting entity |
| bypassMount | Object\|Array |
null |
Mounts to use, skipping selection |
| preTarget | Token |
null |
Pre-targeted before each attack flow |
executeInvade async → Promise<void>
Prompts for one of the actor's invade options, then fires the tech attack flow.
Params: actorOrToken Actor|Token · bypassChoice Object optional preselected invade option, skips the picker
beginWeaponAttackFlow async → {completed, flow?}
| Param | Type | Default | Description |
|---|---|---|---|
| weapon | Item |
required | The weapon item to attack with |
| extraData | Object |
{} |
Injected state data |
inside options |
|||
| targets | Token\|Token[] |
null |
Who is attacked |
Any other key is forwarded to the flow constructor.
Pass targets rather than calling setTarget yourself.
executeDamageRoll async → {completed, flow}
| Param | Type | Default | Description |
|---|---|---|---|
| attacker | Token\|Actor |
required | The attacker |
| targets | Array<Token> |
required | Damage targets |
| damageValue | number\|string |
null |
Base damage |
| damageType | string |
null |
kinetic, energy, explosive, burn, heat, infection, variable. Case-insensitive, and anything unrecognized silently becomes Kinetic |
| title | string |
"Damage Roll" |
Roll title |
| options | Object |
{} |
Flow options (see below) |
| extraData | Object |
{} |
Injected state data |
options keys (all merged onto the DamageRollFlow's flow data, not its state. extraData is what goes to state.la_extraData):
| Key | Type | Default | Meaning |
|---|---|---|---|
| ap | boolean |
false |
Armor Piercing. |
| paracausal | boolean |
false |
Damage can't be reduced (bypasses armor and resistances). |
| overkill | boolean |
false |
Overkill - the flow rerolls 1s on the damage dice (self-heat per reroll). |
| reliable | boolean |
false |
Reliable. |
| half_damage | boolean |
false |
Halve all damage dealt. |
| add_burn | boolean |
true |
Whether Burn-type damage also accumulates on the target's burn track. |
| invade | boolean |
false |
Flags the roll as an Invade tech-attack (passed to Lancer flow). |
| has_normal_hit | boolean |
true |
At least one normal (non-crit) hit exists -> rolls normal damage. |
| has_crit_hit | boolean |
false |
At least one crit exists -> rolls crit damage. |
| tags | Array |
[] |
Weapon tags that shape the roll (Overkill/Reliable/AP...). Element: { lid, val?, name?, description? }. |
| bonus_damage | Array |
[] |
Extra damage entries added to the roll. Element: { type, val } where type is a DamageType ("Kinetic"/"Energy"/"Explosive"/"Heat"/"Burn"/"Variable") and val a formula string. |
| hit_results | Array |
[] |
Per-target hit outcomes that decide which targets take damage (chained damage rolls carry these instead of user targets). Element: { target: Token, total: string, hit: boolean, crit: boolean, usedLockOn?: boolean }. |
| targeting | Object |
- | See below. |
options.targeting { range?: number, pattern?: "target"|"blast"|"cone"|"line"|"burst", size?: number } - opens the damage HUD with the targeting picker already engaged on that shape. Without it, the picker auto-engages only on weaponless rolls that start with no target.
Checks & Saves¶
executeStatRoll async → {completed, total, roll, passed}
| Param | Type | Default | Description |
|---|---|---|---|
| actor | Actor |
required | The actor making the roll |
| stat | string |
required | "HULL", "AGI", "SYS", "ENG", "GRIT" |
| title | string |
auto | Roll title |
| target | number\|"token"\|Token\|TokenDocument |
10 |
Pass threshold or "token" for interactive choice |
| extraData | Object |
{} |
{ targetStat: "HULL" } reads that HASE stat off the target as the DC. sourceItemUuid / sourceAction attribute the roll, surfacing as item / actionName on onInitCheck and onCheck. sendToOwner routes the roll to the owning player, cardTitle / cardDescription set the card text. Every other key is merged into state.la_extraData |
extraData.accuracy / extraData.difficulty / extraData.flatModifier pre-fill the HASE HUD, the way a weapon's tags pre-fill an attack. They are added to whatever the HUD already computed and stay editable by the roller. No bonus needed for a one-off +1 Difficulty.
passed is total >= target. A number target is that number. A token target is the aggressor and resolves at roll time to its SAVE, falling back to 10. extraData.targetStat reads a HASE stat off it instead. If the flow does not complete, only { completed: false } comes back.
executeSaveVsEffect async → Array<{ target, passed, result }>
Save-or-effect over a target list: each target rolls the save (owner-routed by default, in parallel), failures get effects and/or onFail, passes get onPass.
| Param | Type | Default | Description |
|---|---|---|---|
| targets | Token\|Token[] |
required | Rollers |
inside options |
|||
| stat | string |
required | "HULL" / "AGI" / "SYS" / "ENG" / "GRIT" |
| title | string |
required | Roll title |
| origin | number\|Token |
10 |
DC, or the token forcing the save (its SAVE is the DC) |
| effects | string\|Object\|Array |
null |
Applied on fail (applyEffectsToTokens shape) |
| duration | Object |
{ label: 'indefinite' } |
Forwarded to the effect application |
| note | string |
title |
Note on the applied effects. Falls back to title |
| extraFlags | Object |
{} |
Identity flags stamped on the applied effects |
| cardTitle / cardDescription | string \| ((target: Token) => string) |
null |
Owner card text. Description can be per target |
| sendToOwner | boolean |
true |
Route each roll to its owner |
| onFail / onPass | (target: Token, result: { passed: boolean, total: number }) => void \| Promise<void> |
null |
Per-target extras |
| accuracy / difficulty / flatModifier | number \| ((target: Token) => number) |
0 |
Pre-fill each roller's HASE HUD. Pass a function for a per-target value |
| halfDamageOnSave | { value, type?, title? } |
null |
Afterwards roll this damage on ALL targets, halved for the ones that saved. Requires a Token origin |
halfDamageOnSave uses origin as the attacker of the follow-up damage roll. A numeric origin (including the default 10) leaves no attacker, so the damage roll is skipped with a warning. Pass the source token when you use it.
executeContestedCheck async → { completed, winner, loser, winnerToken, loserToken, tie, results }
| Param | Type | Default | Description |
|---|---|---|---|
| input1 | Actor\|Token |
required | First contender |
| stat1 | string |
required | "HULL" / "AGI" / "SYS" / "ENG" / "GRIT" |
| input2 | Actor\|Token |
required | Second contender |
| stat2 | string |
required | Second contender's stat |
inside options |
|||
| title | string |
"Contested Check" |
Card header |
| sendToOwner | boolean |
true |
Roll on each contender's owner client |
| accuracy1 / accuracy2 | number |
0 |
Accuracy dice pre-filled on that side's HASE HUD |
| difficulty1 / difficulty2 | number |
0 |
Difficulty dice pre-filled on that side's HASE HUD |
| flatModifier1 / flatModifier2 | number |
0 |
Flat modifier pre-filled on that side's HASE HUD |
| sourceItem | Item\|string |
null |
Item the check belongs to, surfaced as item on onInitCheck / onCheck |
| sourceAction | string |
null |
Action the check belongs to, surfaced as actionName |
| extraData | object |
null |
Extra keys merged into both rolls' la_extraData |
Rolls both stats, posts an outcome card, plays the win/loss FX. winner/loser (and their *Token) are null on a tie. results always holds both { actor, stat, total, roll }. When either roll does not complete, the result is { completed: false } with winner, loser and tie set but no winnerToken/loserToken keys at all. This is what openHaseContestCard returns.
executeForceCheck async → { completed, results }
| Param | Type | Default | Description |
|---|---|---|---|
| skill | string |
required | "HULL" / "AGI" / "SYS" / "ENG" |
| targets | Token[] |
user targets | The tokens that roll |
inside options |
|||
| saveVs | Token\|Actor |
null |
Makes it a save vs that actor's SAVE, pre-targeted in the roller's HUD |
| sendToOwner | boolean |
true |
Roll on each target's owner client |
| title | string |
"" |
Card header |
| accuracy / difficulty / flatModifier | number\|(rollerToken) => number |
0 |
Pre-filled on the roller's HASE HUD. Per-roller when given a function |
Sends each target its HASE check (owner rolls, or the GM if unowned), then posts a PASS/FAIL summary. Returned by openForceCheckCard.
Activations & Actions¶
executeItemActivation async → {completed, flow?}
Runs an item's activation flow. The item's own automation fires. activateGeneralAction is the equivalent for registry actions that belong to no item.
The flow class is picked in this order: flowName if given, then CoreActiveFlow for a frame with path: "system.core_system", then TalentFlow or ActivationFlow for a talent, then BondPowerFlow for a bond, then ActivationFlow if there is a path or the item has any actions (system.actions.0 when no path is given), then SystemFlow for a mech system, weapon mod, or non-weapon NPC feature, then WeaponAttackFlow for a weapon. If none match it errors and returns { completed: false }. This is close to triggerData.startRelatedFlow but not the same: that one tries weapons before actions, prefers a Reaction action over actions.0, has no CoreActiveFlow branch, and falls back to a simple activation card instead of erroring.
| Param | Type | Default | Description |
|---|---|---|---|
| item | Item |
required | The item to activate |
| extraData | Object |
{} |
Merged onto flow.state.la_extraData before the flow begins |
inside options |
|||
| path | string |
null |
Sets action_path, to pick one action on a multi-action item. On a talent, ranks[N] for the rank card or ranks[N].actions[M] for its action. On a bond, powers[N] |
| flowName | string |
null |
Forces a specific flow class instead of the dispatched one |
executeSimpleActivation async → {completed, flow}
| Param | Type | Default | Description |
|---|---|---|---|
| actor | Actor\|Token |
required | Acting actor, or a token to take the actor from |
| options | { title?: string, action?: { name, activation }, detail?: string, tags?: Array } |
{} |
Card fields |
| extraData | Object |
{} |
Injected state data. An item here roots the flow on that item instead of the actor |
activateGeneralAction async → {completed, flow}
Params: actorOrToken Actor|Token · name string registry action name
Triggers a general action (Brace, Boost, ...) from its registry definition: activation type and card text come from the registry, and the action's automation fires. For an item's action use executeItemActivation.
executeExtraActionCombat async → {completed, flow}
Fires an extra action's combat mode: action.laCombat === 'attack' rolls a to-hit (tech attack when activation is Invade/Quick Tech/Full Tech, else a basic attack with a full acc_diff from its weapon tags + accuracy/difficulty/attack_bonus/attack_type). 'damage' rolls action.damage with no to-hit. See the ExtraAction shape in HUD API.
| Param | Type | Default | Description |
|---|---|---|---|
| actorOrToken | Actor\|Token |
required | The attacker |
| action | ExtraAction |
required | The extra action (must have laCombat) |
| sourceItem | Item\|null |
null |
Owning item, if any (tech attacks route through it) |
inside options |
|||
| targets | Token[] |
user targets | Who is attacked, instead of the user's current targets |
| fxSourceToken | Token |
null |
Play the FX from this token. Basic-attack branch only |
| fxItem | Item |
null |
Item whose FX to use. Basic-attack branch only |
afterFx → void
Runs callback at flow end, right after lancer-weapon-fx starts its sequence (or immediately at flow end if there is no FX). Use in trigger code whose printed cards should land after the FX.
The queue only drains on the flows lancer-weapon-fx binds: WeaponAttackFlow, BasicAttackFlow, TechAttackFlow, ActivationFlow, SystemFlow, CoreActiveFlow, OverchargeFlow, FullRepairFlow, StructureFlow, SecondaryStructureFlow, OverheatFlow, CascadeFlow. Stat rolls and damage rolls are deliberately excluded, since automations nest them inside an outer flow. A callback queued from one of those runs when the outer flow ends, not when the roll does.
Meltdown & Rest¶
executeReactorMeltdown async → Promise<void>
executeReactorExplosion async → Promise<void>
executeReactorMeltdown starts the meltdown countdown, and turns skips the turn-picker dialog. executeReactorExplosion runs the explosion itself: a Burst 2 catch-confirm picker around the token, then the damage.
Params: tokenOrActor Token|Actor · turns number countdown length · token Token the exploding mech
executeRest async → Promise<void>
executeDowntime async → Promise<void>
openAddReserveDialog async → Promise<void>
await api.executeRest(token)
await api.executeDowntime()
await api.openAddReserveDialog(tokenOrActor)
The out-of-combat flows, same as their TAH entries: the Rest card, the downtime activity builder, and the add-a-reserve dialog. Feature guide: Gameplay Automation.
Params: token Token the resting mech, or a pilot token with an active mech · tokenOrActor Token|Actor the pilot's mech
Weapon & Item Details¶
Processed weapon/item info, with active actor bonuses applied (e.g. Accuracy, Threat).
getItemTags_WithBonus async → Array<Object>
Effective tag list for one item.
| Param | Type | Default | Description |
|---|---|---|---|
| item | Item |
required | The item to inspect |
| actor | Actor |
item.parent |
The actor whose bonuses should be applied |
getActorMaxThreat → number
Returns the highest Threat range across all weapons held by the actor, accounting for active bonuses. Floored at 1, so a ranged-only actor still reads 1. It is 0 only for a deployable, or an actor with no weapons at all.
| Param | Type | Description |
|---|---|---|
| actor | Actor |
The actor to inspect |
getMaxWeaponRanges_WithBonus → Record<string, number>
Max range value per range type, across every weapon in the input.
| Param | Type | Description |
|---|---|---|
| input | Actor\|Token\|Item\|Array |
The source(s) to scan for weapons |
getMaxWeaponReach_WithBonus async → number
Returns the single highest reach value across all scanned weapons. Scans Range, Threat, Line, Burst, and Cone (ignores Blast). Also accounts for the tg_thrown tag.
| Param | Type | Description |
|---|---|---|
| input | Actor\|Token\|Item\|Array |
The source(s) to scan for weapons |
getMaxItemRanges_WithBonus async → Object
Single item's max range per type, with bonuses, e.g. { Range: 10, Thrown: 5, Deploy: 8 }. Also folds in action ranges, tg_thrown (Thrown) and deployRange (Deploy).
Params: item Item · actor Actor (optional, defaults to item.parent).
getWeaponProfiles_WithBonus → Array<Object>
All profiles with bonuses merged into range/damage (base_range/base_damage keep the originals).
Params: weapon Item · actor Actor (optional, defaults to weapon.parent).
getSensorRange_WithBonus → number
Actor's effective sensor range (system.sensor_range, else 10), plus any Sensor range-type bonuses.
Params: actor Actor|Token.
hasTag async → boolean
Params: item Item · tagLid string tag LID · actor Actor (optional, defaults to item.parent) whose bonuses apply
True if the item has the tag (bonus-aware). Accepts the LID with or without tg_, so 'smart' and 'tg_smart' both work.
Simple lookups¶
| Function | Returns | Description |
|---|---|---|
getWeaponType(item) |
string |
Weapon subtype (e.g. "Superheavy Rifle", "Melee"). Synchronous, no bonuses. |
getItemType(item) |
string |
Lancer item type (e.g. "Weapon", "System", "mech_weapon"). |
getActivationIcon(actionOrActivation) |
string\|null |
Icon path or CSS class, null when nothing matches. Accepts "reaction", "quick", "full", "protocol", "free", "invade" or an action object. An action with tech_attack: true (or a "tech" activation) gets the tech icons, and an action whose name contains "grenade" gets the grenade icon. |