Skip to content

Check Egg Move combinations for a valid father #4444

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 14 commits into
base: master
Choose a base branch
from

Conversation

abcboy101
Copy link
Contributor

Closes #4426

  • Both legality checks and generated encounters with requested moves are verified through this class. Repeated lookups are cached.
  • When called, the method constructs a graph, and uses a breadth-first search to look for a chain of fathers that can collectively learn the needed moves by level up, and pass them down as Egg Moves all the way to the Egg.
    • If that doesn't work, it then checks encounter data for each father for any transfers, static encounters, etc. that can learn all of the needed moves.
    • If no matching encounter is found, the combination is deemed impossible.
  • Currently, the chain is only logged to the console during debug, but it might be nice to display it in the detailed legality info.

One of the existing test cases appears to have an invalid combination based on this check. This Gen2 Oddish has Flail/Razor Leaf/Swords Dance/Synthesis.

  • The only father who can pass Flail to Oddish is the Chikorita line, so the father must be a member of the Chikorita line with Flail/Razor Leaf/Swords Dance/Synthesis.
  • For Chikorita to have Flail, it must be chain bred via the Squirtle line as the direct father. But, Chikorita can only get Swords Dance as an Egg Move, and the Squirtle line can't learn it. Therefore, the combination is impossible.

abcboy101 and others added 7 commits February 3, 2025 23:13
For a given father, the needed moves might be different for another child, so we need to keep multiple paths
Will post comment reply with observations
@kwsch
Copy link
Owner

kwsch commented Feb 8, 2025

Potential observations/insights:

  1. Form appears to be irrelevant, as form-specific movesets/eggmoves didn't become a "thing" until Gen7 with Alolan forms. Can remove it from all bits of the code? The only exception could be Wormadam, but Burmy has no egg moves.
  2. Female-only breeds should consider inherited father moves (level-up, TM) as if they were egg moves. Genderless/Male-only cannot inherit level-up moves, as they must breed from Ditto (and are already be flagged by existing verifier).
  3. Count==1 should be a special case similar to count==0. Is always valid unless it's a female-only breed, as we've already removed any impossible egg moves. This can skip a lot of computation for even more cases, but I guess we can have a setting bool to "be detailed" and check anyway (to find which father would source).
  4. API signatures: should be possible to define a method to search for a chain with only species, moves[], version. Useful for unit testing. IsPossible already satisfies this (sans Form), but is private.
  5. Smeargle: Can know any move. The API doesn't need to check if it's a sketch-able move, because in Gen2-5, all egg/levelup moves to be checked can be sketched (Struggle will always be flagged, and Chatter is always legal on Chatot via two Chatot parents and thus won't ever be needed to check).
  6. Smeargle: An eager check at the beginning can skip all the work if the egg group is Field.
  7. More often than not, egg move inheritance will not require a complex/deep verification. There is a LOT of setting up being done for every time the verifier is called. Is there opportunity for general precomputation (pkl)? The encounter database is "complete", so a leaf-node list of "special" moves & species that learn them could be useful. (move, species[])[]. When a chain search fails to find the next depth, we can search for all remaining moves to see if any single species can be specially obtained with all. For multiple exclusive moves, maybe have a separate database w/ species-moveset -- should be a super short list.
  8. Result data structure: With above mentioned distillations, it appears that a chain node can be expressed as a 16-bit value comprised of 4 move bitflags and the lower bits for species. For a 4-move inheritance, we can store this in a single ulong struct, and thus be allocation free without needing any allocation or stack data structure.
  9. Could recursion (to mutate the ulong) be a better approach? Bitflags to indicate the un-appended indexes of the span.
  10. Wouldn't need to clear the dirtied portions of a ulong when exiting recursion, as a complete validation will be clean, and an incomplete validation shouldn't be referenced (false). If species is 10-bit [0,1023], we can use 4 bits for moves chained. If really wanted, the last 2 bits can indicate validity at that depth.
  11. There are differences in learnsets/eggmoves between versions of the same context; I don't know if there's any "unlocked via crossover" possibilities that aren't considered in this version-specific approach.

Historically, the egg-chain theorycrafting was done by dumping a list of Move->species[]. This approach might be useful, if we also want to precompute seedpoke[species] (baby eggs from current species) and (group1, group2)[species]. We're already doing the work when the node list is built... so if we only have to do some of the work once and keep a global copy...

Maybe a rent on MovesPassable u1-Populated-u4Level-u4Egg[species] can give us some lazy computation with recursion, as the recursion will update a ulong struct until bits are all cleared or the search ends. No need to allocate aside from the initial setup for each context (2,3,4,5). The above mentioned leaf node list could be context specific, and point backwards to previous contexts to search for any leaf parent possible on the current context.

kwsch and others added 6 commits February 8, 2025 01:56
In Gen 2-5, no species has a different gender ratio or Egg Groups between forms.

Only Wormadam has a different learnset between forms, but it can't be a father to pass on any moves it learns and Burmy has no Egg Moves.
The Egg Move lists are supposed to only include possible Egg Moves

Remove impossible Egg Moves in GS:
- Bulbasaur, Oddish, Snorlax (Charm)
- Staryu (Aurora Beam, Barrier, Supersonic)
- Smoochum (Lovely Kiss)
Expose IsPossible for unit tests
@abcboy101
Copy link
Contributor Author

1-3 and 6 should be addressed for now, the rest I'll try to get to another day.

For 2, I'll note that only inherited level-up moves are currently considered, since it's only directly checking movesets in the current generation anyway (past-gen TMs are handled through attempted encounter generation for now).

For 3, there were some impossible Egg Moves in GS that needed to be removed:

  • Bulbasaur, Oddish, Snorlax (Charm)
  • Staryu (Aurora Beam, Barrier, Supersonic)
  • Smoochum (Lovely Kiss)

For 5, Bulbapedia and Showdown claim that depending on the game, certain moves (Mirror Move, Sleep Talk, Transform, Metronome, Mimic, Self-Destruct and Explosion) also can't be Sketched. They don't agree on whether Mirror Move or Sleep Talk can't be Sketched or not in Gen 3-5 though (Bulbapedia claims they can't, Showdown claims they can).

stackalloc, rearrange early checks
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.

Gen 2-5 Allow Combinations of Egg Moves
2 participants