So I wrote another long live-blog about reverse-engineering how the next visitor to your Animal Crossing town is scheduled. Let’s boil it down to the interesting bit. The visitors are seeded when you enter your town on a date after the previous visitor’s visit date. This is evaluated using the expression:
((seed + 1) + (year - month) + day + hour) % 6
month is 1-12,
day is 1-31, and
hour is 0-23. Then that value is used to index the next visitor from a list in the following order, starting from 0 and counting up: Nobody (Copper just says nothing to report and talks about some of the characters), Gracie, Crazy Redd, Wendell, Saharah, and Katrina. If the generated visitor is the same as the previous one, it merely rolls onto the next one in the list instead.
So if you’re at least moderately mathematically savvy, you can see that the account seed only matters modulo 6, meaning 0, 6, and 12 are “identical” as far as this expression is concerned, as are 1, 7, 13, and so on. So we can easily determine the seed modulo 6 by noting who visited the town last, then generating a new visitor and using the date we entered the town on to figure out our seed.
There’s a bit of a tricky case here, though, where, say our last visitor was Crazy Redd and then we get Wendell next time. We don’t know at this point whether it rolled Wendell on the first try, or if it tried to roll Crazy Redd again, failed because he was the last visitor, and then rolled onto Wendell as a fallback. However, this ambiguity is easy to resolve: we merely have to roll just one more visitor after Wendell using the same seed again.
If it rolls Crazy Redd as our third visitor, then we know that Wendell was chosen as a fallback for the second visitor. If it rolls Saharah, we know that the second visitor was rolled as Wendell fair and square and now we’re falling back to the visitor after Wendell in the list, which is Saharah.
As an example of different dates with the same seed, examine the following:
On April 21st, 2020 at 9 p.m., the seed is: (2020 – 4) + 21 + 21 = 2058.
On April 24th, 2020 at 6 p.m., the seed is: (2020 – 4) + 24 + 18 = 2058.
On April 27th, 2020 at 3 p.m., the seed is (2020 – 4) + 27 + 15 = 2058.
It’s basically just a matter of “add X days, subtract X hours” if you’re operating within the same month. For simplicity, I’ve created this page to help calculate your seed and then use it to determine when you should visit to get the visitor you want scheduled.
Just as an example usage of that page, for the save file that I was debugging with in the emulator, “nobody” was the previous visitor way back in 2011. When I logged in on April 21st, 2020 at 9 p.m., the visitor that Copper said was scheduled to come was Saharah. So I submit Nobody as the previous visitor event, hour 21, day 21, month 4, year 2020 and Saharah, and it generates a seed of 3.
Now say Saharah was going to visit my town on April 24th; if I wanted Crazy Redd to be the next visitor, I could enter April 25th, 2020 as my date and the page would tell me that I should only enter town at 3 a.m., 9 a.m., 3 p.m. or 9 p.m. that day. I tried it out on the emulator with the date set to April 25th, 2020 at 3 a.m. and…
One final cool trick that I made the generator take advantage of is the ambiguity I mentioned before. If the visitor we want to visit happens to be after the previous one in the list, we have twice as many hours in the day that we can generate them with, because we can also choose the hour that would generate the same visitor as last time, and then roll over to the next one. So for instance, if I wanted Gracie instead of Crazy Redd, I could visit town at 1 a.m., 2 a.m., 7 a.m., 8 a.m., 1 p.m., 2 p.m., 7 p.m., or 8 p.m.