Add Pokemon abilities to the battle system. Use when implementing passive abilities that trigger on events.
Files to modify:
src/enums/battleEnums.js - Add abilityIdEnum.YOUR_ABILITY entry (ONLY if not exists)src/battle/data/abilities.js - Add the ability implementationDO NOT modify other abilities or battleConfig.js unless explicitly asked.
[abilityIdEnum.ABILITY_NAME]: new Ability({
id: abilityIdEnum.ABILITY_NAME,
name: "Ability Name",
description: "Description of what the ability does",
abilityAdd({ battle, target }) {
// Called when ability is applied (battle start)
return {
// Properties to store for later use in abilityRemove
listenerId: this.registerListenerFunction({...}),
};
},
abilityRemove({ battle, target, properties }) {
// Called when ability is removed
battle.unregisterListener(properties.listenerId);
},
}),
Return state from abilityAdd that you'll need in abilityRemove:
abilityAdd({ battle, target }) {
return {
listenerId: this.registerListenerFunction({...}),
originalValue: target.getStat("atk"),
triggered: false,
};
},
abilityRemove({ battle, target, properties }) {
battle.unregisterListener(properties.listenerId);
}
Abilities have a class-level registerListenerFunction method that automatically includes the ability instance:
abilityAdd({ battle, target }) {
return {
listenerId: this.registerListenerFunction({
battle,
target,
eventName: battleEventEnum.AFTER_DAMAGE_DEALT,
callback: ({ damage, abilityInstance }) => {
// abilityInstance.data contains the properties
// Perform ability logic
},
conditionCallback: getIsSourcePokemonCallback(target),
}),
};
},
Refer to references/pattern-* for common ability implementations.
Always Clean Up Listeners: Failing to unregister listeners causes memory leaks.
Event Argument Modification: Return modified values from callbacks:
callback: (args) => {
return { damage: Math.floor(args.damage * 0.5) };
};
abilityInstance: Access stored properties via abilityInstance.data in callbacks.
Source vs Target: Use the right condition callback:
getIsSourcePokemonCallback - when this Pokemon is dealing damage/using movesgetIsTargetPokemonCallback - when this Pokemon is receiving damage/effectsAfter implementing an ability, run the ability test suite to validate the implementation:
npm test -- src/battle/data/__tests__/abilities.test.js
This runs an e2e test that verifies all abilities can be applied and removed without throwing errors. If your new ability causes a test failure, fix the implementation and re-run until tests pass.
See the unit-test skill for more details on testing.
add-event-listener skill - Common event types and condition callbacksreferences/pattern-* - Common ability implementation patterns