───✱*.。:。✱*.:。✧*.。✰*.:。✧*.。:。*.。✱ ───
Part 1: Research
- I’m choosing the PokeAPI. It exposes data including Pokémon species, stats, moves, abilities, types, encounters, locations, evolution chains, etc.
- The API is just a JSON REST api, so we can hit it via a HTTP GET request to
https://pokeapi.co/api/v2/pokemon/{id}
or something similar to get the JSON output - I also want to use the Smogon sets JSON to get sets given a Pokémon
https://pkmn.github.io/smogon/data/sets/gen9ou.json
Provided Data
Smogon Sets
- Per species → named sets with items, abilities, EV/IVs, nature, move slots
PokéAPI
- Pokémon details → base state, types, abilities, sprites
- Moves → power, accuracy, type, damage class
- Abilities → description and flavor text
- Types → strengths and weaknesses
- Evolutions → chains and species metadata
- Encounter data → where & how Pokémon appear
Part 2: Software Planning
Goal
- Given a seed/input Pokémon, construct a 6-Pokémon team by:
- Selecting a viable Smogon set for the seed mon
- Inferring complementary roles and desired teammate types to cover weakness & provide utility (such as a setter Pokémon)
- Find Pokémon that match those types (via PokéAPI and existing within the Smogon tier set list)
- Scoring candidates by role coverage & type synergy, iterating until the best 6 are found
- Outputting a Showdown-legal team (in the format so you can import into Pokémon Showdown)
Concepts
Roles
- Hazard setter
- Such as stealth rock or spikes
- Hazard control
- Defog or rapid skin
- Speed control
- Choice scarf or strong priority
- Defensive backbone
- At least one steel Pokémon, as well as common immunities including electric with ground, ground with flying/levitate, and general coverage where needed
- Breaker or setup win condition
- Status/Utility
- Knock off, toxic/thunder wave, taunt/encore, pivoting, etc
Flow
- Input seed Pokémon (such as “gardevoir”) and tier (such as gen9ou)
- Fetch Smogon set JSON for the tier
- Select the seed’s primary set (either the first set or the one named “Standard”)
- Compute seed needs
- Get seed types from PokeAPI and derive weaknesses/resists
- Infer role from set (moves, item, nature) to decide which roles to add
- Derive teammate targets as needs
- Typing needs:
{ kind: "typing", type: "Steel" }, { kind: "typing", type: "Ground" for Electric immunity }, { kind: "typing", type: "Water" or "Grass" to cover Fire/Ground/Rock cores }
, etc. - Role needs:
{ kind: "hazard", moveAnyOf: ["Stealth Rock", "Spikes"] }, { kind: "removal", moveAnyOf: ["Defog", "Rapid Spin"] }
, etc.
- Typing needs:
- Find candidates by desired types:
- For each type T
- PokeAPI:
GET /type/{T}
to retrieve Pokémon of that type - Normalize those names and intersect with species keys in the Smogon tier JSON so that the Pokémon are tier-legal and have competitive sets
- PokeAPI:
- Combine results of all the desired types to form a candidate pool, potentially include non-type candidates that fulfill roles
- For each type T
- Score candidates
- From the sets for each candidates, pick a representative set and score
- +2 if has hazards (stealth rock, spikes)
- +2 if has removal (defog, rapid spin)
- +1.5 if has pivoting (u-turn, volt switch, flip turn)
- +W if matches a desired typing (+1.5 for steel if requested, +1.0 for water/grass/fairy complements)
- +W if it covers the seed specific weakness (using the type chart aggregation)
- We’d want to penalize so we don’t have duplicate types or roles
- From the sets for each candidates, pick a representative set and score
- Iterative select
- Start with seed set
- Add top-scoring candidate, update needs and recompute coverage
- Continue until 6 members while ensuring at least one hazard setter, one remover, a steel or equivalent defense, speed control, and not over-stacking weaknesses
- Concrete move selection
- For each chosen set, pick one move per move slot
- Probably prefer moves that fulfill needs (such as choosing knock off if utility is unmet)
- The output would be a showdown-legal paste
Part 3: API Use Documentation
Pokémon Details
- URL: https://pokeapi.co/api/v2/pokemon/gardevoir
- JSON Excerpt:
{
"id": 282,
"name": "gardevoir",
"types": [
{
"slot": 1,
"type": { "name": "psychic", "url": "https://pokeapi.co/api/v2/type/14/" }
},
{
"slot": 2,
"type": { "name": "fairy", "url": "https://pokeapi.co/api/v2/type/18/" }
}
]
,
"abilities": [
{
"ability": {
"name": "synchronize",
"url": "https://pokeapi.co/api/v2/ability/28/"
},
"is_hidden": false,
"slot": 1
},
{
"ability": {
"name": "trace",
"url": "https://pokeapi.co/api/v2/ability/36/"
},
"is_hidden": false,
"slot": 2
},
{
"ability": { "name": "telepathy", "url": "https://pokeapi.co/api/v2/ability/140/" },
"is_hidden": true,
"slot": 3
}
],
"moves": [
{
"move": { "name": "psychic", "url": "https://pokeapi.co/api/v2/move/94/" },
"version_group_details": []
}
],
"sprites": {
"front_default": "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/282.png"
},
"stats": [
{ "base_stat": 68, "stat": { "name": "defense" } },
{ "base_stat": 125, "stat": { "name": "special-attack" } }
]
}
Type Damage Relations
- URL: https://pokeapi.co/api/v2/type/fairy
- JSON Excerpt:
{
"id": 18,
"name": "fairy",
"damage_relations": {
"double_damage_from": [
{ "name": "steel", "url": "https://pokeapi.co/api/v2/type/9/" },
{ "name": "poison", "url": "https://pokeapi.co/api/v2/type/4/" }
],
"half_damage_from": [
{ "name": "fighting", "url": "https://pokeapi.co/api/v2/type/2/" },
{ "name": "bug", "url": "https://pokeapi.co/api/v2/type/7/" },
{ "name": "dark", "url": "https://pokeapi.co/api/v2/type/17/" }
],
"no_damage_from": []
}
}
Move Details
- URL: https://pokeapi.co/api/v2/move/psychic
- JSON Excerpt:
{
"id": 94,
"name": "psychic",
"power": 90,
"pp": 10,
"accuracy": 100,
"type": { "name": "psychic", "url": "https://pokeapi.co/api/v2/type/14/" },
"damage_class": {
"name": "special",
"url": "https://pokeapi.co/api/v2/move-damage-class/3/"
},
"effect_entries": [
{
"language": { "name": "en", "url": "https://pokeapi.co/api/v2/language/9/" },
"short_effect": "May lower the target's Sp. Def by one stage."
}
]
}
Species
- URL: https://pokeapi.co/api/v2/pokemon-species/gardevoir
- JSON Excerpt:
{
"id": 282,
"name": "gardevoir",
"evolution_chain": {
"url": "https://pokeapi.co/api/v2/evolution-chain/140/"
},
"flavor_text_entries": [
{
"language": {
"name": "en",
"url": "https://pokeapi.co/api/v2/language/9/"
},
"flavor_text": "To protect its Trainer, it will expend all its psychic power."
}
],
"generation": {
"name": "generation-iii",
"url": "https://pokeapi.co/api/v2/generation/3/"
}
}
Evolution Chain
- URL: https://pokeapi.co/api/v2/evolution-chain/140
- JSON Excerpt:
{
"id": 140,
"chain": {
"species": {
"name": "ralts",
"url": "https://pokeapi.co/api/v2/pokemon-species/280/"
},
"evolves_to": [
{
"species": {
"name": "kirlia",
"url": "https://pokeapi.co/api/v2/pokemon-species/281/"
},
"evolution_details": [
{ "min_level": 20, "trigger": { "name": "level-up" } }
],
"evolves_to": [
{
"species": {
"name": "gardevoir",
"url": "https://pokeapi.co/api/v2/pokemon-species/282/"
},
"evolution_details": [
{ "min_level": 30, "trigger": { "name": "level-up" } }
],
"evolves_to": []
}
]
}
]
}
}
Pokémon by Type
- URL: https://pokeapi.co/api/v2/type/steel
- JSON Excerpt:
{
"damage_relations": {},
"game_indices": [],
"generation": {},
"id": 18,
"move_damage_class": null,
"moves": [],
"name": "fairy",
"names": [],
"past_damage_relations": [],
"pokemon": [
{
"pokemon": {
"name": "clefairy",
"url": "https://pokeapi.co/api/v2/pokemon/35/"
},
"slot": 1
},
// ... more pokémon
],
"sprites": {}
}
Smogon Sets Tier Data
- URL: https://pkmn.github.io/smogon/data/sets/gen9ou.json
- JSON Excerpt:
{
"Venusaur": {
"Sun Sweeper": {
"moves": [
"Growth",
"Giga Drain",
"Weather Ball",
[
"Sludge Bomb",
"Earth Power"
]
],
"ability": "Chlorophyll",
"item": "Life Orb",
"nature": "Timid",
"evs": {
"def": 4,
"spa": 252,
"spe": 252
},
"teratypes": [
"Fire",
"Ground"
]
}
}
// ... all pokémon in the tier
}
───✱*.。:。✱*.:。✧*.。✰*.:。✧*.。:。*.。✱ ───