Skip to content

Many more abilities and items, and searchable pickers for both - #10

Merged
TechLuddite merged 1 commit into
mainfrom
claude/abilities-items-availability-a1dpww
Aug 6, 2026
Merged

TechLuddite merged 1 commit into
mainfrom
claude/abilities-items-availability-a1dpww

Conversation

@TechLuddite

Copy link
Copy Markdown
Owner

Closes #9.

Joseph pointed out that not all abilities or items were available. He was right, and by a wide margin.

What was actually wrong

  • Abilities: 25 modeled, 312 in the dex. Most Pokémon opened the picker to find every option greyed out as "not in sim yet". Static (38 Pokémon), Swift Swim (48), Chlorophyll (39), Sheer Force (37), Lightning Rod (37), Pressure (36) — all doing nothing.
  • Items: 11, hand-written. There was no item dataset at all. No type-boosting items, no berries beyond Sitrus, no Rocky Helmet, Flame Orb, Heavy-Duty Boots, Weakness Policy or weather rocks.
  • Neither dropdown had search, unlike the Pokémon and move pickers.

The blocker, and how it got cleared

The single biggest group of missing abilities was contact-triggered — Static, Flame Body, Rough Skin, Iron Barbs, Poison Point, Effect Spore, Tough Claws — plus Rocky Helmet and the punish riders on Spiky Shield, King's Shield and Baneful Bunker. ROADMAP.md had them all filed under one blocker: PokéAPI's /move endpoint carries no flags block, so the sim had no way to know whether a move touched.

Those flags are published elsewhere, so they now get baked the same way the dex does. npm run refresh-flags runs scripts/build-move-flags.mjs once, offline, and writes src/data/move-flags.json; data/index.js attaches them to every move object. Nothing new is fetched at runtime. Ten flags are baked — contact, punch, bite, sound, powder, bullet, pulse, slicing, wind, heal — and each one has an ability or item reading it.

What's in now

ABILITIES 25 → ~130, ITEMS 11 → ~75, under the standing rule: modeled and hand-tested, or not offered.

Abilities, by group: weather (Swift Swim, Chlorophyll, Sand Rush, Slush Rush, Sand Veil, Snow Cloak, Sand Force, Solar Power, Rain Dish, Ice Body, Dry Skin, Leaf Guard, Hydration, Air Lock, Cloud Nine); damage (Sheer Force, Tinted Lens, Iron Fist, Strong Jaw, Tough Claws, Sharpness, Mega Launcher, Punk Rock, Reckless, Rock Head, Analytic, Sniper, Super Luck, Serene Grace, Skill Link, Hustle, Compound Eyes, No Guard, Scrappy, Infiltrator, Mold Breaker, Unaware, Defeatist); defence (Fur Coat, Ice Scales, Solid Rock, Filter, Multiscale, Heatproof, Water Bubble, Fluffy, Marvel Scale, Shell Armor, Shield Dust, Wonder Guard); immunities (Lightning Rod, Storm Drain, Motor Drive, Sap Sipper, Earth Eater, Well-Baked Body, Soundproof, Bulletproof, Overcoat); status (Immunity, Limber, Insomnia, Water Veil, Magma Armor, Oblivious, Natural Cure, Shed Skin, Early Bird, Poison Heal, Quick Feet, Unburden); contact (Static, Flame Body, Poison Point, Effect Spore, Rough Skin, Iron Barbs, Aftermath, Gooey, Cursed Body, Poison Touch, Stench); reactions (Moxie, Beast Boost, Defiant, Competitive, Weak Armor, Steadfast, Anger Point, Justified, Rattled, Stamina, Berserk, Download); stat guards (Clear Body, Hyper Cutter, Big Pecks, Keen Eye, Contrary, Simple); turn order (Prankster, Gale Wings, Triage, Stall, Pressure, Unnerve).

Items: all eighteen type-boosting items, all eighteen type-resist berries, plus Muscle Band, Wise Glasses, Scope Lens, Razor Claw, King's Rock, Metronome, Big Root, Rocky Helmet, Heavy-Duty Boots, Bright Powder, Safety Goggles, Weakness Policy, White Herb, Mental Herb, Flame Orb, Toxic Orb, Light Clay, Quick Claw, Black Sludge, Lum Berry, Oran Berry, Shell Bell and the four weather rocks.

Abilities that genuinely do nothing in a one-on-one battle — Pickup, Run Away, Telepathy, the doubles-only ones — are listed with noop: true and grouped as "No effect one-on-one". That's an honest entry, not a stub: it's the difference between a Pokémon whose ability does nothing and one whose ability the sim never heard of.

Mechanics worth a second look in review

  • seenAbility(attacker, defender) is how anything reads the defender's ability, so Mold Breaker can switch it off. The abilities that punish a move after it lands — Static, Rough Skin, Aftermath — deliberately read foe.ability directly, because Mold Breaker doesn't stop those.
  • The end-of-turn order gained weather healing and chip, Shed Skin, Hydration and the two orbs. It's still written out in one place at the top of endOfTurn and still load-bearing.
  • Substitute is checked against the original sign of a stat change, then Contrary flips it or Simple doubles it, and only then do Clear Body and friends look at what's left. A Contrary'd "drop" is a rise, and Clear Body has no quarrel with a rise.
  • Sheer Force cancels the Life Orb recoil too. That's the real rule, not a rounding error.
  • Effect Spore uses the published 9/10/11 split inside the 30% that fired.

The pickers

Item and ability dropdowns now use the same search-at-the-top component as Pokémon and moves, grouped, with each entry's description shown beside its name and searchable — typing "burn" finds the Flame Orb. The closed button shows the short name and clips; the open list wraps.

Tests

npm run test:run and npm run build both green. 310 tests, up from 177 — 133 new ones in sim.test.js, every expected number derived by hand from the formulas, plus move-flags.test.js guarding against a bake that quietly writes an empty file (which would switch Static off without anything else failing).

Changelog entry added, credited to Joseph. ROADMAP's "still not modeled" list rewritten to say what's actually left.


Generated by Claude Code

Joseph pointed out that most Pokémon had an ability the sim had never
heard of, and that there were only eleven items to pick from. Verified:
25 of the 312 ability slugs in the dex were modeled, and ITEMS was a
hand-written list of 11 with no dataset behind it at all. Closes #9.

The blocker on the biggest group was move flags. PokéAPI's /move endpoint
has no flags block, so the sim had no way to know whether a move made
contact — which is why ROADMAP listed Static, Flame Body, Rough Skin,
Rocky Helmet and the Spiky Shield / King's Shield riders as all blocked
together. Those flags are published elsewhere, so they get baked the same
way the dex is: `npm run refresh-flags` writes src/data/move-flags.json
once, offline, and data/index.js attaches them to every move object.
Nothing new is fetched at runtime.

ABILITIES goes from 25 to ~130 and ITEMS from 11 to ~75, under the
standing rule: modeled and hand-tested, or not offered. Abilities that
genuinely do nothing one-on-one (Pickup, Run Away, Telepathy) are listed
with noop: true and grouped as such, which is honest rather than a stub.

Mechanics worth flagging for the next person in here:

- seenAbility(attacker, defender) is how anything reads the DEFENDER's
  ability, so Mold Breaker can switch it off. The abilities that punish a
  move AFTER it lands read foe.ability directly, because Mold Breaker
  doesn't stop those.
- The end-of-turn order gained weather healing/chip, Shed Skin, Hydration
  and the two orbs. It is still written out in one place and still
  load-bearing.
- Substitute is checked against the ORIGINAL sign of a stat change, then
  Contrary flips it, then the guard abilities look at what's left.

The item and ability pickers now use the same search-at-the-top dropdown
as Pokémon and moves, grouped, with each entry's description shown next
to it and searchable — typing "burn" finds the Flame Orb.

sim.test.js gains 133 tests, every expected number derived by hand.
move-flags.test.js guards against a bake that quietly writes an empty
file, which would switch Static off without anything else failing.
@TechLuddite
TechLuddite merged commit 47cf0c1 into main Aug 6, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Battle sim: most abilities and held items still can't be picked

2 participants