| name | add-ability |
| description | Add Pokemon abilities to the battle system. Use when implementing passive abilities that trigger on events. |
Adding Abilities to Pokestar
Quick Reference
Files to modify:
src/enums/battleEnums.js - Add abilityIdEnum.YOUR_ABILITY entry (ONLY if not exists)
src/battle/data/abilities.js - Add the ability implementation
DO NOT modify other abilities or battleConfig.js unless explicitly asked.
Ability Structure
[abilityIdEnum.ABILITY_NAME]: new Ability({
id: abilityIdEnum.ABILITY_NAME,
name: "Ability Name",
description: "Description of what the ability does",
abilityAdd({ battle, target }) {
return {
listenerId: this.registerListenerFunction({...}),
};
},
abilityRemove({ battle, target, properties }) {
battle.unregisterListener(properties.listenerId);
},
}),
Properties Pattern
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);
}
Event Listener Registration
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 }) => {
},
conditionCallback: getIsSourcePokemonCallback(target),
}),
};
},
Common Patterns
Refer to references/pattern-* for common ability implementations.
Common Gotchas
-
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 moves
getIsTargetPokemonCallback - when this Pokemon is receiving damage/effects
Validation
After 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.
References
add-event-listener skill - Common event types and condition callbacks
references/pattern-* - Common ability implementation patterns