| name | add-effect |
| description | Add battle effects (buffs, debuffs, shields) to the battle system. Use when creating temporary status modifiers. |
Adding Effects to Pokestar
Quick Reference
Files to modify:
src/enums/battleEnums.js - Add effectIdEnum.YOUR_EFFECT entry (ONLY if not exists)
src/battle/data/effects.js - Add the effect implementation
DO NOT modify other effects or battleConfig.js unless explicitly asked.
Effect Structure
[effectIdEnum.EFFECT_NAME]: new Effect({
id: effectIdEnum.EFFECT_NAME,
name: "Effect Name",
description: "Description of the effect",
type: effectTypes.BUFF,
dispellable: true,
effectAdd({ battle, target, source, initialArgs }) {
return {
};
},
effectRemove({ battle, target, source, properties, initialArgs }) {
},
tags: [],
}),
Properties Pattern
The most important pattern is the properties pattern - return state from effectAdd that you'll need in effectRemove:
effectAdd({ battle, target, source, initialArgs }) {
return {
listenerId: battle.registerListenerFunction({...}),
originalValue: target.getStat("atk"),
counter: 0,
};
},
effectRemove({ battle, target, properties }) {
battle.unregisterListener(properties.listenerId);
}
Event Listener Registration
Use battle.registerListenerFunction for effects (effects don't have a class-level helper):
effectAdd({ battle, target }) {
return {
listenerId: battle.registerListenerFunction({
eventName: battleEventEnum.BEFORE_DAMAGE,
callback: (args) => {
return { damage: Math.floor(args.damage * 0.5) };
},
conditionCallback: getIsTargetPokemonCallback(target),
}),
};
},
effectRemove({ battle, properties }) {
battle.unregisterListener(properties.listenerId);
}
Effect Types
| Type | Description |
|---|
effectTypes.BUFF | Positive effect, can be dispelled by debuff-removing abilities |
effectTypes.DEBUFF | Negative effect, can be dispelled by buff-removing abilities |
effectTypes.NEUTRAL | Neither buff nor debuff, special handling |
Using initialArgs
Effects can receive arguments when applied. Access them in both add and remove:
effectAdd({ battle, target, initialArgs }) {
const { shield } = initialArgs;
battle.addToLog(`${target.name} is shielded for ${shield} damage!`);
return { shieldAmount: shield };
},
effectRemove({ battle, target, initialArgs }) {
const { shield } = initialArgs;
}
Common Gotchas
-
Always Clean Up Listeners: Failing to unregister listeners causes memory leaks and incorrect behavior.
-
Event Argument Modification: Return modified values from callbacks to change event behavior:
callback: (args) => {
return { damage: Math.floor(args.damage * 0.5) };
};
-
State Management: Properties can be mutated during runtime - be careful with shared references.
-
Dispellable Flag: Set dispellable: false for effects that should persist through dispell abilities.
Validation
After implementing an effect, run the effect test suite to validate the implementation:
npm test -- src/battle/data/__tests__/effects.test.js
This runs an e2e test that verifies all effects can be applied and removed without throwing errors. If your new effect causes a test failure, fix the implementation and re-run until tests pass.
See the unit-test skill for more details on testing.
References
references/pattern-*.md - Common effect implementation patterns
add-event-listener skill - Common event types and condition callbacks