add-move
Add new moves to the battle system. Use when implementing attack, status, or support moves for Pokemon.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
メニュー
Add new moves to the battle system. Use when implementing attack, status, or support moves for Pokemon.
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
Add a Pokemon (real or fake) to src/config/pokemonConfig.js with its moves, abilities, rarity, and evolution data. Use when the user asks to add, register, implement, or create a new Pokemon, Pokemon form, or fake/custom Pokemon in the battle system.
Find a Pokemon's Discord emoji string — canonical (e.g. `<:25:1100282072003772457>`) from `pokestar-pk-{n}`, form variants (e.g. `<:483origin:1404654211324448848>`) from `pokestar-forms-1`, or fakemon (e.g. `<:ashpikachu:1109522092283658250>`) from `pokestar-pk-extra` — via Playwright CLI. Use when the user asks for a Pokemon's emoji, emoji ID, form emoji, fakemon emoji, or needs an `<:name:snowflake>` string.
Create an implementation plan before adding one or more Pokemon via the `add-pokemon` skill. Builds Pokemon, moves, and abilities tables with all required inputs, flags unimplemented moves/abilities, and produces step-by-step implementation instructions. Use when the user asks to plan adding a Pokemon, plan a Pokemon batch, or invokes this skill before `add-pokemon`.
Verify Discord bot changes by running the bot and testing commands in Discord via Playwright CLI. Use when the user asks to test, verify, or check bot commands in Discord.
Verify a Pokemon's configuration in pokemonConfig.js by testing its moves and abilities in Discord via Playwright CLI. Use when validating a Pokemon's battle behavior after configuration changes.
Add Pokemon abilities to the battle system. Use when implementing passive abilities that trigger on events.
SOC 職業分類に基づく
| name | add-move |
| description | Add new moves to the battle system. Use when implementing attack, status, or support moves for Pokemon. |
Files to modify:
src/enums/battleEnums.js - Add moveIdEnum.YOUR_MOVE entry (ONLY if not exists)src/battle/data/moves.js - Add the move implementation as a new entry in the movesToRegisterRaw object (NOT sketchMoves or the frozen movesToRegister re-export)DO NOT modify other moves or battleConfig.js unless explicitly asked.
The move name and tier should be provided as inputs to this skill. For all other fields, they are optional, and if unprovided, you can infer them yourself.
[moveIdEnum.MOVE_NAME]: new Move({
id: moveIdEnum.MOVE_NAME,
name: "Move Name",
type: pokemonTypes.TYPE, // FIRE, WATER, GRASS, etc.
power: 80, // Base damage (null for non-damaging)
accuracy: 100, // Hit chance % (null = always hits)
cooldown: 3, // Turns before reusable
targetType: targetTypes.ENEMY, // ENEMY, ALLY, ANY
targetPosition: targetPositions.FRONT, // FRONT, BACK, ANY, SELF, NON_SELF
targetPattern: targetPatterns.SINGLE, // See references/target-patterns.md
tier: moveTiers.POWER, // BASIC, POWER, ULTIMATE
damageType: damageTypes.PHYSICAL, // PHYSICAL, SPECIAL, OTHER
description: "Move description",
execute() { /* implementation */ },
}),
NOTE: The execute function binds this to the MoveInstance.js MoveInstance class, with properties such as:
Example Properties:
this.source - User of the movethis.primaryTarget - Main target selectedthis.allTargets - All affected targets (based on pattern)this.missedTargets - Targets that were missedthis.battle - Battle instancethis.power, this.type, this.id - Move propertiesAll generic methods are available in MoveInstance.js. These are some common examples:
// Deal damage to all targets
this.genericDealAllDamage();
// Returns { damageInstances: {targetId: damage}, totalDamageDealt: number }
// Custom damage calculation
this.genericDealAllDamage({
calculateDamageFunction: (args) =>
this.source.calculateMoveDamage(args) * 1.5,
offTargetDamageMultiplier: 0.5,
backTargetDamageMultiplier: 0.7,
attackOverride: this.source.getStat("def"),
});
// Apply status (BURN, PARALYSIS, FROZEN, SLEEP, POISON)
this.genericApplyAllStatus({
statusId: statusConditions.BURN,
probability: 0.3,
});
// Apply effect (see references/effects.md)
this.genericApplyAllEffects({
effectId: "atkUp",
duration: 3,
probability: 0.5,
});
// Single target effect
this.genericApplySingleEffect({
target: this.primaryTarget,
effectId: "shield",
duration: 3,
initialArgs: { shield: 100 },
});
// Combat readiness
this.genericChangeAllCombatReadiness({ amount: 25, action: "boost" }); // or "reduce"
// Healing
this.genericHealAllTargets({ healPercent: 25 });
this.genericHealSingleTarget({ target, healAmount: 100 });
Optional tags array for ability interactions:
"punch" - Boosted by Iron Fist ability"slice" - Boosted by Sharpness ability"charge" - Two-turn moveUse overrideFields to change properties based on context:
overrideFields: (options) => {
if (options.source?.speciesId === pokemonIdEnum.SPECIAL_FORM) {
return { power: 120, description: "Enhanced version" };
}
},
pokemon.getStat("atk") - Get effective statpokemon.hasType(pokemonTypes.FIRE) - Check typepokemon.applyEffect(id, duration, source, initialArgs)pokemon.dispellEffect(effectId) - Remove effectpokemon.removeStatus() - Clear status conditionpokemon.dealDamage(amount, target, info) - Deal damagepokemon.giveHeal(amount, target, info) - Healpokemon.boostCombatReadiness(source, amount)pokemon.getPartyPokemon() - Get ally arraypokemon.isFainted - Check if faintedAfter implementing a move, run the move test suite to validate the implementation:
npm test -- src/battle/data/__tests__/moves.test.js
This runs an e2e test that verifies all moves can execute without throwing errors. If your new move causes a test failure, fix the implementation and re-run until tests pass.
Default: write at least one assertion test for the move. The e2e test in moves.test.js only verifies that execute() does not throw — a move with the wrong damage, wrong target, missing status application, or silently-broken side effect will pass the e2e test but still be wrong. So unless the move is purely a thin wrapper around a single generic method, write a focused test.
Skip move-specific tests only when ALL of these are true:
execute() body is one (or zero) generic method calls (genericDealAllDamage, genericApplyAllEffects, genericApplyAllStatus, genericHealAllTargets, genericChangeAllCombatReadiness, etc.) with no extra logic before or after.if, ternary, &&/|| short-circuits used for control flow).overrideFields, no tags interactions you want to verify, and no charge/two-turn behavior.If any non-generic call appears in execute() (a custom damage calculation, a manual pokemon.applyEffect, a pokemon.dealDamage, a pokemon.removeStatus, a custom target loop, etc.), or any of the conditions above is false, write at least one assertion test. Examples of what counts as "non-generic" and warrants a test:
execute()calculateDamageFunction, custom multipliers)describeStatusProbability / describeEffectProbabilityBattlePokemon methods (applyEffect, dispellEffect, dealDamage, giveHeal, boostCombatReadiness, etc.) outside of the generic helperstags you want to confirm interact correctly with abilities (e.g. "punch" + Iron Fist)The bar is "non-generic call → one assertion test", not "complex logic → one assertion test". Prefer one short, focused test that asserts the unique behavior over no test at all.
Add tests to src/battle/data/__tests__/moves.test.js. See the test-move skill for the full testing infrastructure, including custom matchers, test utilities, and test patterns.
references/target-patterns.md - Visual guide to target patternsreferences/effects.md - List of all buff/debuff effect IDsreferences/pattern-*.md - Code examples for common move types