pkmn / ps

Modular Pokémon Showdown
MIT License
107 stars 15 forks source link

Questions about learnset data #4

Closed zacharybussey closed 4 years ago

zacharybussey commented 4 years ago

Hello,

I'm trying to put together a damage calculator/team builder tool. I'd like to be able to only show valid moves that can be learned for a particular gen. But, I'm not familiar with the format of data that the learnset returns.

      expect((await gens.get(8).learnsets.get('bulbasaur'))!.learnset!.leafstorm)
        .toEqual(['8M', '7E', '6E', '5E', '4E']);

I'm thinking the number is a Gen number, but it doesn't seem to match up with if the move is valid or not. For example, Gengar lists astonish: ["6S4"] but, this is an egg move from Gen 3 to Gen 8.

Also, what does the letter mean? My deduction is that is probably Egg move, TM, TR and so on, but what are all of the codes used?

scheibo commented 4 years ago

Hi! https://github.com/pkmn/ps/blob/master/sim/sim/global-types.ts#L69-L90 is where PS documents its learnset encoding scheme. ['6S4'] means astonish is the 5th event move from Gengar in Gen 6 (thanks @KrisXV for confirming).

It might be worth adding some wrappers around PS's Learnset to expose these in a more friendly way (which is the point of the @pkmn/data library). I haven't worked with learnsets that much yet so I don't have a good intuition for what such an API might look like, but if you have suggestions I'd love to hear them!

zacharybussey commented 4 years ago

Great, thanks for the quick response.

I'd expect though that it would include ['8E', '7E', ...] and so on in the list as well. https://www.serebii.net/pokedex-swsh/gengar/ Although, I realize not many people would care to use Astonish competitively, so it could be a data quality issue.

I think it would probably make sense to limit what is returned based on the gen you are working in. Essentially, calling this from the Gen8 dex.

      expect((await gens.get(8).learnsets.get('bulbasaur'))!.learnset![0])
        .toEqual({
          name: 'Leaf Storm',
          source: MoveSource.TM,
        });

And, probably you are going to cross-reference this with the moves list anyways, so including the type, power, accuracy, and description might be reasonable. Probably depends on what you are building if that is useful or not.

scheibo commented 4 years ago

Although, I realize not many people would care to use Astonish competitively, so it could be a data quality issue.

I would be surprised by that, because AIUI the Learnset data is actually ripped directly from the data files mined from the games, but @Marty-D or @Lusamine may be able to tell you if that's the case. :)

I think it would probably make sense to limit what is returned based on the gen you are working in.

Now that I'm thinking about it a little more, I think I'm remembering why I left it returning all of the data - for validation purposes, the provenance of the move across each gen is important, as it becomes relevant when figuring out complex scenarios like which moves can be bred onto another Pokémon etc. I think (one again, not a pro at learnsets) the presence of a move in the Learnset.learnset returned currently represents the superset of moves a given Pokémon might have, but the interplay of the exact MoveSource values is relevant for determining which combination of moves are legal on a mon?

I like the idea of changing the relatively inscrutable '8M'code to a more structured response though

Marty-D commented 4 years ago

Hello! By default, the learnset scheme doesn't include egg moves for evolutions that can't hatch from eggs themselves. So while Gengar can get Astonish from that event, it can also get it by evolving from a hatched Gastly using some inheritance logic which is handled in the validator along with other complex legality rules: https://github.com/pkmn/ps/blob/master/sim/sim/team-validator.ts

zacharybussey commented 4 years ago

Great! Thank you. I think everything there makes sense now.

scheibo commented 4 years ago

Nice! I'm going to leave this open to remind myself to take a look at seeing if I can't smooth out the API a little, but I probably won't get to this for a little while. :)

scheibo commented 4 years ago

And, probably you are going to cross-reference this with the moves list anyways, so including the type, power, accuracy, and description might be reasonable. Probably depends on what you are building if that is useful or not.

I don't disagree that this would certainly be useful, but currently this is out of scope for the @pkmn/data package. Like Pokémon Showdown it does not 'materialize' ID references, primarily for performance and practicality reasons. It should be possible to implement such a data layer without performance concerns, but attempting to do so while serving as a wrapper on top of Pokémon Showdown's Dex becomes difficult. I believe https://github.com/smogon/data (used to power Smogon's dex) handles this (or plans to), and may be worth taking a look at :)

It might be worth adding some wrappers around PS's Learnset to expose these in a more friendly way

I looked into doing this - I think to transform something like '8E' into {gen: 8, source: 'Egg'} would require wrapping, transforming, and caching returning Learnset object and I'm not sure it's worth the effort given the Learnset data is still going to be intrinsically complicated and require special knowledge (like Marty explained above) to be able to use anyway. I would probably merge a PR that adds such a transformation, but I don't think it's going to end up being valuable enough to spend cycles on myself.

Thanks for the question and for the suggestions! Good luck with your damage calculator (have you seen the @smogon/calc package?)/team builder tool.

zacharybussey commented 4 years ago

Thanks, yeah, I've been looking at the calc package already. Haven't gotten that far along though.

There is an exportLearnsets function in smogon/data that might do this. But, I think the scope of this project is much wider than what I really need as far as learnsets go. I'm building something small just for me to start with, and just for Gen 8 VGC rules, which seem much easier to implement since moves are a "clean slate" approach when a Pokemon comes from an old gen.

Thanks again for taking the time to answer questions. Very its been very helpful.