The Move That Quartered Crits — JavaScript Bug Hunt
Modelled on the Focus Energy bug in Pokémon Red and Blue (1996).
- Language: JavaScript
- Layer: Frontend
- Difficulty: Easy
- Concepts: Game Logic, Bitwise
- Modelled on: Pokémon Red/Blue · 1996
- Visible tests: an unfocused attacker uses half its base speed; Focus Energy raises the threshold
- Reward: 50 XP for a complete fix
Briefing
Modelled on the Focus Energy bug in Pokémon Red and Blue (1996). The move was meant to raise the user's chance of landing a critical hit, but the game code shifted the critical-hit value the wrong way, so using it actually made critical hits less likely. The bug shipped in the Generation I games.
This battle engine computes a critical-hit threshold from the attacker's base speed. Its Focus Energy branch shifts in the wrong direction.
Fix critThreshold so Focus Energy raises the threshold.
Bug report
BUG-FOCUS · Priority: Medium · Reported by: competitive players
critThreshold(baseSpeed, focused):
- the threshold starts at floor(baseSpeed / 2)
- Focus Energy (focused = true) multiplies it by 4 (shift LEFT by rules.FOCUS_SHIFT)
- the result is capped at rules.MAX_THRESHOLD (255)
isCritical(baseSpeed, focused, roll) is true when roll (0-255) < threshold.
Observed: a base-speed-100 attacker has threshold 50 normally but 12 after using Focus Energy.
Logs
[battle] crit threshold speed=100 focused=false -> 50
[battle] crit threshold speed=100 focused=true -> 12The code as shipped
src/battle/critical.js (editable)
var rules = require("./rules");
exports.critThreshold = function (baseSpeed, focused) {
var threshold = Math.floor(baseSpeed / 2);
if (focused) threshold = threshold >> rules.FOCUS_SHIFT;
return Math.min(threshold, rules.MAX_THRESHOLD);
};
exports.isCritical = function (baseSpeed, focused, roll) {
return roll < exports.critThreshold(baseSpeed, focused);
};
Read-only context: src/battle/rules.js.
Open the hunt to edit the files, run the visible tests and submit against the hidden ones. More JavaScript bug hunts.