Special thank you to Cuyler for assisting me and lending his knowledge for this video! I shoutout Cuyler a lot, but his efforts in datamining and decompiling the game served as the backbone of this video in particular. He's been a great friend and reference since the very beginning of this channel, so I truly appreciate his collaborations!
shoutouts to Cuyler, fraser (don't know them but I see they're also a contributor for the AC decomp project), and you for being their deeply engaging spokesperson 😉
Hi, in the Q&A I asked about fixing bugs with ACE, I know that you probably had the video planned for a long time, but I like to think that it is related. ☺️
@kasratabrizi2839 honestly the reason published devs are where they are IS BECAUSE they work like this. Prioritize shipping working code over perfect code. At the end of the day you're making a product. Even if it's for free or just for fun, you still need to ship something. That doesn't mean it's okay to be sloppy but you know bugs reproduce geometrically. Sometimes you need to pick your battles and prioritize which issues to address, given limited time.
I kind of don't blame them. If you have ever seen that "The Problem with Time & Timezones - Computerphile" video it does seem like timed stuff gets crazy. I know AC does not use time zones but I seen and worked with other timed stuff and it can get complicated fast. I would probably also use a lookup tabled back then hehe
@@pleasedontwatchthese9593 I have seen that video! And yeah, I get why they did it, but if it were me, I would’ve just had a large chain of if statements for all the possible situations, and kept the game playable forever.
god I hate it when I want to plant a tree but joe 3 miles away from me has a tree in their yard and I’m at the bottom of my acre and he’s at the top of the acre so the tree doesn’t grow. Does anyone else here relate
From my experience, right now it's really just Cuyler carrying the original Animal Crossing modding scene on his back. There are other, very talented members of this community working on their own projects, so I hope modding takes off a bit once it becomes a bit more accessible.
@@Hunter-R. once the game is decompiled and cuyler finishes his deluxe mod you should feature it on your channel. bringing attention via youtube is probably your best bet for jumpstarting the modding scene
@@Chubby_Bub but different regions for the NSO apps exist, they could technically put the different versions up on each app, or even offer to boot different ones though i wish it wasn't on NSO expansion, it sucks to have to pay for online and i dont pay the expansion because i don't even have the time to try those old games, but i'd play AC GCN for sure
@@97MiloProductions The thing is, due to technical stuff like the e-Reader and GBA connection, they'd have to make changes to any GameCube version of the game anyway. It'd probably be easiest to adjust Animal Crossing for the west and Doubutsu no Mori e+ for Japan, though I'd hope if they were going to do that, they’d give both regions the same definitive version. (Well, they could also release the N64 version, which I think can be entirely replaced with English dialogue- but that'd be rather lacking.) In any case if Nintendo ever did rerelease the first-generation AC, I'd hope they'd make it as its own game that has as many features for all regions.
@@ssl3546 I mean, the GameCube goes up to 2099 and allows you to go even further if you leave it plugged in. There is no reason why Animal Crossing should be limited aside from not wanting to calculate and hardcode a single event past 2030.
To randomize fruit The only thing you should change is what it does after the check. if it's the same as native fruit set it to oranges. If your native fruit is oranges than you will never get them in the initial roll otherwise oranges effectively replace your native fruit in the calculation. This is less complicated than creating a new table.
that makes a lot of sense, since all fruit but Peach and obviously Orange itself can't roll Orange due to the RANDOM function, setting rolling your own native fruit to be Oranges fixes both the bias for the next fruit in the list, and the lack of oranges being selected as random. And since Orange can't even roll Orange anyway, you will never have your native fruit be selected as it cannot even reach Orange in the list.
Alternatively, you could set it to check if they are greater than or equal to your native fruit then increment to the next fruit. this would mathematically be the same as removing your native fruit from the list. It's interesting if you have a brain fart and try to implement both of these solutions from scratch simultaneously, you end up with what they did.
I wanted to mention this. Basically the fix is to replace the final check if(selected_fruit == town_fruit) selected_fruit++; with either if(selected_fruit == town_fruit) selected_fruit = 4 /*orange*/; or if(selected_fruit >= town_fruit) selected_fruit++; Both methods solve the issue the same way, and they are identical assuming the original random function doesn't have a bias (otherwise the bias may be applied to different fruits)
Actually you could just throw out the whole check and do (I'll write this in python, cause I can't code C off the top of my head): def getGiftFruitId(): return (townFruitId+1+random(4))%5 That's it, 1 line no checks no nothing. Of course ideally you'd have a variable called "FruitNum" or smt to reference any time you want to know the number of fruit types but oh well.
The stupid thing is that the Japanese version of the game had code to not only set but actually calculate the lunisolar dates, correctly, but when creating the English version they turned it into that table, and somehow got the dates wrong in doing so. Doubutsu no Mori+ has another holiday on lunar 9/13 too (Jūsan'ya), and that and the Harvest Moon actually work properly. (As well as in the N64/iQue versions.) Also, I've had the same thing happen with Kapp'n's song when I tried to edit memory to make him sing a different one. K.K. Chorale is the first K.K. Slider song, so it’s usually used as a placeholder/default. It’s a bit odd that this would occur outside of the context of K.K. songs, but my guess is that the live performance of K.K. Chorale is the track the game "falls back" to when something goes wrong. And afterwards, the music won’t change anymore even when it should, subjecting you to an endless loop playing over everything.
Wait, if Animal Forest calculates it right, then does that mean that it's actually able to go as late as 2038? (The maximum date possible on 32-bit systems)
@@creampop8553 I don’t entirely understand how it works, but the code the calculation relies upon only bothered to support up to 2033. (Cuyler was able to easily extend it to 2100.) Also, 2038 is only the maximum date for the 32-bit UNIX format for time. It's evidently not used by AC, and mostly used for API stuff.
@@w花b Based on interviews, Nintendo of America fleshed out what most of the changes and additions would be, but Nintendo of Japan actually programmed them. There's one where Bill Trinen said NoA would design the furniture or come up with holidays to replace the Japanese ones, and then send them to NoJ to implement them. He also said the last thing created was the summer camping tents which was done by both teams together at E3 2002.
Some dedicated people made mods to fix the Sims 3 errors but it gets annoying. For the Sims 4, it's only this year that they actually implemented the ability to stop your Sims from washing their dishes in the bathroom sink...
Omg. I started playing this game this year for the first time and was SO annoyed by my saplings randomly dying despite having a lot of space. Good to learn that it’s a frankly very funny bug
about a year ago I remember specifically watching a video about glitches etc in the original animal crossing and wishing that there were more videos talking about animal crossing glitches and other technical details. I get so exited every time you upload
Imagine being the person who coded the lunisolar calendar, which is only used for (1) specific case, and still getting a bug anyway. You had one job and now its memorialized on the Internet, 20 years later.
That explains why I never got oranges, I started with apples. I assumed that they were introduced with WW, and didn’t learn otherwise until years after the fact.
TL;DR: I figured out why the harvest moon festival is bugged. The 2030 date cap due to restrictions in the number of dates of harvest moons available due to the fact the people gathering that data are using a calendar system for the 8th century to predict cycles of the moon, which Microsoft adapted into an algorithm which if run more than once would raise the cap. I thought I had come up with a solution to the lunisolar calendar, by tracking when a user last played, and the current date to generate the number of days since last played, as well as represent days with a full moon with a 0, which is incremented up to 28 and reset to 0, to get a 29 day lunar calendar. You could modulo the number of days since last played by 29 to get an a value, where if you add to the last days moon phase ID to that value, and then modulo by 29 to get the current cycle. This essentially the phase of the moon when assuming the last date played was a full moon, and factoring the actual last moon ID as an offset. I think this is what Nintendo did and are why the dates are wrong; you can't calculate the lunar calendar simply. The part that comes next is crazy: The developers, like me, realised that a lunar months a really hard to predict, and there are half-days involved. The duration of a lunar month changes every Gregorian month, and it doesn't align with our calendar very well. Some blokes much smarter than either of us invented the Tabular Islamic calendar. This works in 30 year cycles and repeats afterwards, much like we have leap years very 4 years unless the year was divisible by 100, but not 400; the Gregorian calendar is essentially on a 400 year cycle . Their algorithm can predict when a moon will be full with a 99.9996% success rate. The half day screws as to how full the moon will be on a full moon, and I haven't gone into the fact lunar calendars will differ depending on your timezone as the moon will be fullest at midday, so "authorities" have to decide which day will be a full moon in both calendar systems. This is because when Ramadan and Eid both start on viewing of the moon after full moons, you need to know exactly when the moons will full, in case of weather conditions meaning that you couldn't see the moon in a couple days and no one is sure whether it is waxing or waning when it does reappear. Those extra days fasting while a great festival awaits can take place can cause tension of a population. Now, when you have to find out when the next full moons are for your game in 2001 for years to come, where do you source that information? The Islamic calendar! But no one had actually really tried covert the Gregorian Calendar to the Islamic Calendar algorithmically. Microsoft developed the "Kuwaiti Algorithm", so we could easily convert dates without thinking about two calendars with different prime meridians, different days in the year and different leap years and no one is sure when each was adopted. This is where they saw the 30 year cycle and implemented it into an algorithm for Windows computer. Windows now had the capabilities to convert the date from Gregorian to Islamic, bases on 30 year intervals. So, there are the devs (either those on Animal Crossing or a service providing the next full moon to tarot readers, novelty calendar makers etc), on their Windows 2000 computers, using the calendar to find the full moons in the Islamic calendar, converting the dates using a calendar which probably only converted a single 30 year cycle from the current date (running the function more that once with the output from n-1 into n would yield more moon predictions). In 2030, the harvest moon will be on 9/11, and actually on the equinox on the 22nd of September. The algorithm counts 10,631 days (probably should of mentioned, when I said 30 year cycles, those are Islamic years), so we can get the implementation date of this feature, which is Monday, 14 August 2000 - Friday, 3 August 2001. Before, the maximum year returned when calculating the calendar would be 2029, after it is 2031. This also perfectly aligns with the development timeline of the game. So I am proposing this is why the date cap is 2030. They ran out of confirmed full moons in the method they were using. This can be fixed implementing the Kuwaiti algorithm to calculate the moon based on the last day played as a start point. As long as the algorithm feeds the data back into it if the date last played is greater than 30 years, there would be no limit other than memory/if a year past 9999 can be rendered correctly. They obviously ran into this issue but didn't implement either solution correctly, causing the bug.
Super interesting read. Thank you for doing all this research and sharing! I’ll probably return to this comment in the future and try to confirm everything if/when I look at this topic again. 🙇♂️
I was hoping at some point you would say "We have included a patch in the description to fix all of these bugs", but you never did. Great video either way, I love learning about how games tick.
The fixes are all included in the work-in-progress decomp project. The idea is that you can build the game with or without the patches applied when it’s complete. Making an entire patcher just for these silly bugs would be cool, but I don’t imagine it’d get much use. Plus, there’s always bound to be more bugs discovered as decomp progresses.
@@kameleongreen Follow the GameCube decompilation Discord server, or you can lookup the AC decompilation repo on GitHub. Linking directly to both of these is a bit troublesome and I don’t want any more issues, but finding them shouldn’t be too hard.
You truly are the "Stryder7x" of Animal Crossing. Your wealth of knowledge of Animal Crossing, down to a programming code level, is akin to his wealth of knowledge of how Paper Mario (N64) works on a programming level. I'm glad you still create content on TH-cam, he no longer does and I haven't seen word of what happened and why he no longer uploads videos
Stryder7x's ex gf accused him of SA. He said it never happened and that he was going to take a break from youtube. He never returned. Idk if he actually did it or not though - but thats why :/
^^^ this. Also, I’m pretty sure it was proven that he didn’t. But it got to the point where his reputation was tarnished so badly that there was no coming back from it.
@@selena3467 that’s what I’ve heard, and what I’ve found through some research. It’s hard to find a definitive answer, but I’m pretty sure he was innocent.
Man, the guy who coded that fruit randomizer must have either been a programming newbie, or extremely sleep deprived. Also, the guy who made the random function probably didn't explain their code all that well in their comments if it got this many mistakes. Still these mistakes are funny none the less. The tree bug has me thinking that you could theoretically plant a bunch of growable trees behind anything on the bottom border of an acre. Since it's not checking the neighbouring acre, and it's instead checking another acre miles away. Great video as always!
As a programmer, I'd like to attest that there is no coding mistake too simple to not make. You'd be surprised at just how often we screw up seemingly obvious things, however skilled.
@@blakksheep736 Oh I know that too, don't worry. I only write simple scripts, and even I facepalm at my own mistakes. I can't imagine what horrors I'd make if I did anything graphical.
@@blakksheep736 As a programmer (and programming teacher) I would tell my students not to make a random function inclusive on one end and exclusive on the other. That’s not intuitive and is definitely prone to mistakes.
@@quinton1630 That is horrible advice since almost all random functions for integers work that way. Because of how ranges work it makes sense for floats to be inclusive on both ends and ints to be exclusive on the upper end. The only times you want inclusive random for integers is when you use 1-indexed arrays.
@@quinton1630 As long as you explain why they shouldn't do this, it's fine. The students will then decide on their own to follow your advice or not, at their own risks.
I kinda like the idea of the game having a bias towards one non native fruit. It's as if there's a nearby place where some other fruit grows, or one of them being the cheaper non native option. Yeah, your town has peaches, but the town next to it might have oranges and that's why its easier to be gifted that instead of cherries or pears that have to come from somewhere farther away
probably the simplest fix for the fruit thing is to leave the randomisation as-is and make it return 4 instead of adding 1 if you land on your town fruit
@@E0O2X314FT On the other hand, if you get astronomically unlucky, your method could theoretically take an unbounded amount of time. It's generally considered bad practice to allow unlimited rerolls like that
The cherry-blossom weather is a good example why you do NOT use raw integers for that type of thing. Every language has some way to create enumerations or at least named values.
Your in-depth coverage of this games coding is so amazing, even to players like me who know nothing about coding. You describe these things so well Hunter!!
I didn't actually know the original AC had a limited calendar. It does make me wonder what future rereleases (e.g. in retro games collections) will look like. They have occassionally gone back and changed certain things in games before rereleasing them (like the sponsorships in waverace or Earthbound battle effects having a filter put over them to stop seizure enducing flashes). Eventually we'll start seeing Gamecube games appear in these retro collections, at which point I could see us getting an AC rerelease. And I doubt they'd just have these calendars double back to 2001
11:08 I think the fruit problem could actually be solved by just replacing the == in the condition with >=. That would effectively create a random selection between the 4 fruits that are not the native fruit. For example, if the native fruit was the pear (2), after calling RANDOM(4), a 0 or 1 would correspond to apple and cherry, but a 2 or 3 would be incremented and correspond to peach and orange. I wouldn't be surprised if this was the original intent.
For the fruit instead of making a new list. You can use the old list and keep the % but always offset the random by your starting fruit. If your random is offset to the fruit after yours and only picks one less the the total number of fruit it will never pick yours.
Seems a bit unorthodox, and a lot of people mentioned this last time, too. I believe the reason is because the array size is re-used as an input for randomly determining what to roll, and the function they use there ( RANDOM_F ) seemingly depends on a floating point number... 🥴
@@Hunter-R. thanks for the reply but that raises more questions haha (like why not use RANDOM for ints instead). could you ask Cuyler if this logic is somewhere in the Animal-Crossing-Decomp repo? would like to take a look at it 🙃
@@guy_th18 I simplified a bit in the video, but shell_max is actually an array itself filled with floats marking the size of the other tables, but still equally unorthodox. Anyways, you can look at the implementation here: github.com/Prakxo/ac-decomp/blob/d48e6e51096cd5c3a17cf78ae68e5c2372cded65/src/m_field_info.c#L3317
@@Hunter-R. thank you for the full details! yeah, looking into it I can't come up with a satisfying reason why they'd use floats instead of ints there (unless there's some quirk of RANDOM_F that RANDOM doesn't have that they really wanted here for some reason). dev who worked on it probably just had a weird brainfart, happens to the best of us
12:07 I think what they may have been trying to do was a rather clever approach which avoids introducing a bias while not requiring the creation of a new list. If the equality check had instead been a greater-than-or-equal-to check, then all four non-native fruit would have been obtainable. Doing this "skips" the native fruit without requiring a wraparound check.
A simpler solution to the fruit bug that has the same result as creating a new list is to leave the random parameter at 4 and add one if other_fruit >= the native fruit rather than just ==
I loooooove videos like this. It's so cool to see some of the things Cuyler and I talked about get put into action. One day we'll have a fully patched and expanded Animal Crossing experience ! I'd love to see if some of these fixes could be made into AR codes ?
For sure some of these could be fixed with AR codes! Some things aren’t though. Expanding the calendar to 2099 requires implementing the lunisolar calendar up to 2099 which isn’t easy to accomplish via AR codes due to the amount of data needed
Thank you! I also appreciate your previous collaborations with Cuyler on ACSE and the like. I know I haven’t been around the community too long, but it’s cool to finally talk to some people that I’ve heard a lot about. Also, some of the more simplistic fixes can be made into AR codes, or are already AR codes - such as the paper airplane fix. However, I imagine some of the more fundamental changes to the codebase would require a modded patch.
@@Cuyler for sure ! I saw another comment suggesting other versions have a way to calculate it on the fly; if that's true, it might be fun to implement instead. It'd be a lot of code changes though !
@@Hunter-R. Of course ! and thank YOU for showing off all these discoveries. It's been really motivating. I love how digestible your videos are, so it makes it easy to share with others things that I'm nerdy about haha :) You're doing great work !! I'd love to see some AR codes made from all this some time. It'd be cool to have a mega code that just makes a bunch of patch changes. Though maybe it'd also be worth making a custom NES ROM patch instead ? Thanks again, and good luck with future endeavours !
The solution I would use for the gift fruit bug is to do the increment every value equal OR GRATER than the native fruit while keeping the Random(4). No modulus is required, no bias.
no he can't. the guy who informs these videos and actually does decomp work for this game (Cuyler) can and does, but it's an extremely time-taking and painstaking process requiring deep computer science fundamentals that I don't believe Hunter has (he's not part of that project on GitHub)
not to nerd emoji or anything but I hope you know that's hyperbole. though Cuyler probably could (he's the guy that helps inform these videos and one of the main people working on the AC decomp project)
If I saw an error like the one in the first example at my job, my first thought would be that I'm misreading the code rather than thinking it's a bug. This video has given me more confidence when reading someone else's code.
9:53 Maybe the programmer was frustrated that the 16th journal wasn't showing up when testing, and they couldn't figure out why. So they tried to specify by adding the & 15?
There's an e'en simpler solution to the fruit bug: just change the test from == to >=. Chances are still evenly dispersed ( assuming the output o' the random function is evenly dispersed ), since the rolls that land on the town fruit & onward are just shifted rightward & there's no chance o' going beyond the bounds o' the array, since if the town fruit is the 4th fruit, the output o' random( 4 ) will ne'er be >= 4, so it will always just use the 0 - 3 roll directly.
When I played this game back in the day I was convinced oranges were a myth for years until my friend (who had peaches as her town fruit) got one as a gift.
The game play's the KK song after the Kapp'n song presumably because all the song data is stored in a single contiguous block in memory, and individual songs are referenced by an index into that block. If a song is played for longer than it's stored music, the music player probably keeps incrementing the note pointer into the next song.
omg, I thought there was a "dud spot" mechanics to explain why saplings sometimes don't grow in particular spots in an acre. That's funny to find out it's because of a coding mistake! Are you going to release a patch file for the game with the fixed codes, or is this part of the decomp project?
In the decomp project, most of the important coding bugs that have been discovered so far are marked and feature either direct fixes or workarounds. You'll be able to build with or without patches/fixes applied, which is super cool.
There’s additional intended logic for why trees die or stop growing in certain spots in an acre. Each acre has a tile attribute map and one of the attributes is how far along a tree can grow or if it should die if planted there. The bug in the game is pretty niche considering it only happens on the bottommost tiles in an acre.
Truly fascinating! I really appreciate that you not only showed bugs, but also showed how one could fix them in the game's code! I'm studying comp sci, and this was really fun to watch as a result. Big thanks to Cuyler too for the in-depth programming :D
The fruit issue AND the bias that happens when you try to fix it can be fixed with a simple trick: keep the original code, but when the result is the fruit native to your town, pick oranges. This way, every fruit that is not native to your town has an equal chance to be picked.
You’ve been having some incredible growth! It’s been only 7-8 months since I started watching you and you already have 50,000 subs! Love your content and I’ll stay for the long road to 1 million.
Imagine you are in a cutscene explaining a task to your villager but he just throws a paper airplane and leaves the scene leaving you talking to yourself like an idiot
12:25 i think you could still do this pretty elegantly without using a second list. Take the current fruit as the starting point and then add random(4)+1 to it. int gift = (current + random(4)+1) % 5; random(4)+1 will return a uniform number in [1,4]. And it will be impossible to result in your native fruit. This also removes the check.
The only issue here is that the % operator takes a performance hit if it's used with a constant that isn't a power of 2. (Since the compiler turns it into a bitwise AND in that case)
I remember changing the date as a kid and thinking what would happen after 2030. We do know nowadays, but to naturally inch towards this date feels kinda weird ngl
I love watching these technical videos. I'm a programmer and hobby modder myself and seeing these small oversights and stuff just feels so relatable and it's so interesting to me because it gives me examples of potential pitfalls I otherwise just wouldn't get
A very simple solution for the fruit at 12:00 ish: Keep it as random(4) and just replace the == with >=. This effectively simulates making a new list without having to actually do that, and thus removes the bias towards a specific fruit.
Wait, I'm confused. Why would they have all that code to keep track of the lunar calendar if they ended up just hardcoding all the dates instead? I was thinking that after 2030, they'd actually use that code to calculate the following dates, but they just left that calculation code in there without ever using it? I was also hoping you'd explain what causes the snail bug, that was very interesting! Fantastic video, honestly. Bugs and glitches always feel like the most random thing you'd never even think of, so it's incredible being able to see exactly what little slip up caused them.
Sorry if I wasn’t super clear in the video. The actual calculations in the code are apparently leftover from DnM/DnM+, and are used in AC as a failsafe. I imagine it was faster for the game to use precalculated dates and was a development decision when updating the game for the West. If you let your console roll over to the year 2030, the calculation would be used in 2031 and 2032 for the dates. After that, the holiday fails to trigger altogether. The snail bug is interesting, and we’re pretty sure the release code is just incorrectly mapped since it’s the only bug who does this. Again, this is patched in the European/Australian version, but those versions haven’t been decompiled or looked at - but looking there would tell us exactly what they changed.
im not a very tech-savvy person so please pardon any technical errors in this statement: at 18:53, when kapp’n’s song ends and is replaced by the live version of kk chorale, this may be because the code is set to return to the first song in the music list if an error occurs during kapp’n’s song, as kk chorale is the very first song in the game’s code! i discovered this glitch myself when i was playing e+ on my laggy computer, i’m not sure if it was the lag or some error that occurred while trying to skip kapp’n’s song via button mashing, but suddenly kk chorale started playing instead, only for me it was the aircheck version. very strange! i want to know how this happens very badly
I've always wondered if the game's calendar could be "fixed" to count past 2030. Guess the harvest moon would complicate that somewhat, but assuming one accounted for it, could the calendar be tweaked to be set beyond 2030 manually?
On the oranges bug, you could make a code that loops random(5) calls to the full array of fruits (including the native one) until you get a fruit that isn't your native one. This would also have the consequence of locking up your game for some time if you're INCREDIBLY unlucky and roll your native fruit several times in a row. Which makes each call to that function a lot more exciting.👀😌
Seeing all of this fervor around one of my beloved childhood games makes me want to jump in myself and see what I can do. I feel like I'd be less productive than a caveman trying to build an airplane, but being able to change/fix the various mechanics in this game seems like a fun way to make a definitive/personalized version that could be cool. Making the island reachable without peripherals, changing the logic for Nook's inventory, making villager fetch quests not require you to run between 10 villagers not in their home acres only to then get rewarded with paper, maybe even ways to influence how your village spawns, I see lots of potential.
Towards 12:25 another solution: if (other_fruit == Save_Get(fruit)) { other_fruit = (other fruit + Random(4) + 1) % 5; } This function will, if the rolled fruit is your own town fruit a Random Number between 1-4 (Random(4) generate 0-3 + 1 => 1-4) which is then modulated by 5. So in the orange Case if you roll an orange, the other_fruit value before modulo is 5-8, and after it 0-3 which would be exactly what we want and still be perfectly balanced. This has the advantage of don't occupie another block of memory and also don't have to check for tidy up when not needed anymore. Also it's just a change in a single line of code which I personally really like :D
Modulo by anything other than a power of 2 incurs a performance penalty. It's a one-liner in C but not in assembly. "x % 4" is much faster than "x % 5" since "x % 4" is converted by the compiler into "x & 3" which doesn't require a hardware multiply
Is the solution to 12:00 this: Keep the random choice of the first four fruits, but if it is the native fruit, pick the fifth fruit, the orange? That would result in an even distribution regardless of which fruit is the native fruit, right?
12:05 Or you can just make it so that if it results in your native fruit, it will give you orange(s) no matter what your native fruit is Example: Say your native fruit is pears. If you rolled a 0, 1, or 3, you get the matching fruit, but if you roll a 2, you get orange(s).
12:30 using a new list entirely seems kinda redundant, since they have most of the code already anyways. Just swap the `other_fruit++` to `other_fruit = 5` to "include" the orange in our random range whenever our home fruit is selected
The orange bug could be fixed quite elegantly: If it rolls your native fruit, return 4. The unmodified code *already* biases towards one fruit. If your native fruit is rolled, give an orange... because if you have oranges, you can't ever roll oranges to begin with, and if you don't have oranges, it essentially places oranges in the slot occupied by your native fruit
12:24 There is another solution that I'd argue is better. It allows you to avoid the construction of a new list, and minimizes the amount of code changes from the existing implementation. Simply keep the random call as "RANDOM(4)", but change the conditional from "if (other_fruit == Save_Get(fruit))" to "if (other_fruit >= Save_Get(fruit))". This fixes the issue of oranges being inaccessible given some town fruit, and prevents any bias in the result, all by only changing one conditional branch.
I’ve been binging your videos back to back to back the past few hours! Thank you for the well thought out videos that pack a knowledgeable punch! I’m such a huge fan and subscribed immediately 🎉
The slight bias at fruits makes it kinda more interesting xd - having their likelyhood differently weighted, even if its only one fruit with 2/5 chance, making the player assume it to be the primary non-native fruit
9:22 Note: The way RANDOM( x ) works in their code is not unusual and is how things often work in programming because it's more frequently useful to specify that you want 10 possibilities (instead of just specifying the upper-bound). 0-9 is 10 possible outputs, whereas 0-10 would be 11 possible outputs. It's pretty silly though that the devs of Animal Crossing apparently didn't read the docs or had skipped Probabilities & Statistics class in college.
for the whole native fruit thing you could probably just make the check re run the entire code, so that it call random again and also again checks if its the native fruit or not. its probably unlikely enough to roll the native fruit multiple times in a row to actually have an impact on the game.
instead of keeping two lists, you can also just add a random value from 0 to N-1 (where N is the number of items), then modulo that with N. as a single step that does all of this without checking, it would be (X + RANDOM(N)) % X, where X is the town fruit.
@@colly6022 It is exclusive on the upper bound, but it can also return 0, which would make it give your own fruit :-P And you moduloed on the wrong number
i am now imagining a creepypasta called "my copy of animal crossing can go past the year 2030" in it the guy finds the usual haunted game disk but in his disk the animals get access to modern technology and fashion for the year they are in and pick up behaviors that fit in line with those years and their public sentiments so they get smartphones, grow more frustrated in general, social distance, and the big climax is things are somewhat foretold as years go past the current showing things like a growing distrust of government and technology, general fear of saying the wrong thing, growing mistrust of one's neighbors, and finally around 2040 an atomic explosion reduces the area to a wasteland and kills all of the animals it would be written in proper creepypasta of the 2010-2015 fashion
OMG. I encountered the southern border tree glitch when I was younger. I remember I was trying to grow a tree in a very specific spot that happened to be on the southern border of an acre, but every sapling I planted there would die. I planted like 10 saplings, and they all kept dying. I eventually just assumed it had something to do with acre borders, so I stopped planting stuff on the borders entirely. I wasn't too far off.
12:24 A new list is actually not necessary here. Equal odds for every fruit can be achieved by changing the if statement comparison operator from "==" to ">=". This has the affect of skipping over your own fruit in the list and gives every fruit an equal chance to be picked. I used this technique in my own game.
Special thank you to Cuyler for assisting me and lending his knowledge for this video! I shoutout Cuyler a lot, but his efforts in datamining and decompiling the game served as the backbone of this video in particular. He's been a great friend and reference since the very beginning of this channel, so I truly appreciate his collaborations!
Hi😊
shoutouts to Cuyler, fraser (don't know them but I see they're also a contributor for the AC decomp project), and you for being their deeply engaging spokesperson 😉
Hi, in the Q&A I asked about fixing bugs with ACE, I know that you probably had the video planned for a long time, but I like to think that it is related. ☺️
Real recognizing real
Decompilating?! Imagine AC GCN running on a PC or a Android or IOS device, even Linux!
As an Indie Dev, seeing code with these kinds of errors made it into a full game release, makes me less anxious about my programming skills
haha same here man, I always thought that these AAA developers are gods compared to me but indeed we don't have anything to worry about.
@kasratabrizi2839 honestly the reason published devs are where they are IS BECAUSE they work like this. Prioritize shipping working code over perfect code. At the end of the day you're making a product. Even if it's for free or just for fun, you still need to ship something. That doesn't mean it's okay to be sloppy but you know bugs reproduce geometrically. Sometimes you need to pick your battles and prioritize which issues to address, given limited time.
The fact that this great game will soon no-longer be playable properly, because they hard-coded the values for a single event, is very silly.
I kind of don't blame them. If you have ever seen that "The Problem with Time & Timezones - Computerphile" video it does seem like timed stuff gets crazy. I know AC does not use time zones but I seen and worked with other timed stuff and it can get complicated fast. I would probably also use a lookup tabled back then hehe
@@pleasedontwatchthese9593 I have seen that video! And yeah, I get why they did it, but if it were me, I would’ve just had a large chain of if statements for all the possible situations, and kept the game playable forever.
@@RipVanFish09 I am lazy man and would have just locked it to a certain date after 2030. who's gonna notice? lol
we can fix it
@@pleasedontwatchthese9593 I do. Just don't add the useless harvest moon event at that point lmao
god I hate it when I want to plant a tree but joe 3 miles away from me has a tree in their yard and I’m at the bottom of my acre and he’s at the top of the acre so the tree doesn’t grow. Does anyone else here relate
God yeah I hate it when that happens
Just fix the code
You forgot the question mark.
@@JorgetePanete it's in another acre
That explains so much as to why sometimes a sapling died even though there was free space all around! Holy cow… my eyes are opened wide
I wish there was a greater modding scene for this game. It could fix bugs and add new features like the paper airplanes.
From my experience, right now it's really just Cuyler carrying the original Animal Crossing modding scene on his back. There are other, very talented members of this community working on their own projects, so I hope modding takes off a bit once it becomes a bit more accessible.
@@Hunter-R. once the game is decompiled and cuyler finishes his deluxe mod you should feature it on your channel. bringing attention via youtube is probably your best bet for jumpstarting the modding scene
@@joemkddwhat is the deluxe mod?? 🤔
Hopefully Nintendo will fix these bugs with an update
After twenty years, surely the patch is coming any day now...
Animal Crossing e+ Deluxe, coming to Nintendo Switch Online never because it would require them to reconcile the differences between regions
@@Chubby_Bub but different regions for the NSO apps exist, they could technically put the different versions up on each app, or even offer to boot different ones
though i wish it wasn't on NSO expansion, it sucks to have to pay for online and i dont pay the expansion because i don't even have the time to try those old games, but i'd play AC GCN for sure
@@97MiloProductions The thing is, due to technical stuff like the e-Reader and GBA connection, they'd have to make changes to any GameCube version of the game anyway. It'd probably be easiest to adjust Animal Crossing for the west and Doubutsu no Mori e+ for Japan, though I'd hope if they were going to do that, they’d give both regions the same definitive version. (Well, they could also release the N64 version, which I think can be entirely replaced with English dialogue- but that'd be rather lacking.) In any case if Nintendo ever did rerelease the first-generation AC, I'd hope they'd make it as its own game that has as many features for all regions.
Nintendo doesn’t care about their old games unless someone’s modding them
THAT'S why it's capped at 2030? Not because of programming stuff but likely because they couldn't calculate full moon dates for one single festival???
the game came out in 2001, 30 years is a pretty good run
Yeah that's pretty wacky
@@ssl3546 I mean, the GameCube goes up to 2099 and allows you to go even further if you leave it plugged in. There is no reason why Animal Crossing should be limited aside from not wanting to calculate and hardcode a single event past 2030.
There's also the save data only allowing an offset from the system clock by 1207 days, since it uses CPU cycles to keep track of it.
Does Cuyler have a user-appliable patch that allows AC to function through 2099?
5:13 "my people need me, i must go" _levitates away_
lol and 19:09
*Note: the villager died on the way home to his planet.*
instead of fixing the bug by playing the proper animation, it should still fly away and play a slide whistle sound effect
make it a feature
Whoa, Snail was from another planet this whole time?!
@@KyrfuffleXD
To randomize fruit The only thing you should change is what it does after the check. if it's the same as native fruit set it to oranges.
If your native fruit is oranges than you will never get them in the initial roll otherwise oranges effectively replace your native fruit in the calculation. This is less complicated than creating a new table.
Clever!
that makes a lot of sense, since all fruit but Peach and obviously Orange itself can't roll Orange due to the RANDOM function, setting rolling your own native fruit to be Oranges fixes both the bias for the next fruit in the list, and the lack of oranges being selected as random.
And since Orange can't even roll Orange anyway, you will never have your native fruit be selected as it cannot even reach Orange in the list.
Alternatively, you could set it to check
if they are greater than or equal to your native fruit then increment to the next fruit. this would mathematically be the same as removing your native fruit from the list.
It's interesting if you have a brain fart and try to implement both of these solutions from scratch simultaneously, you end up with what they did.
I wanted to mention this. Basically the fix is to replace the final check
if(selected_fruit == town_fruit) selected_fruit++;
with either
if(selected_fruit == town_fruit) selected_fruit = 4 /*orange*/;
or
if(selected_fruit >= town_fruit) selected_fruit++;
Both methods solve the issue the same way, and they are identical assuming the original random function doesn't have a bias (otherwise the bias may be applied to different fruits)
Actually you could just throw out the whole check and do (I'll write this in python, cause I can't code C off the top of my head):
def getGiftFruitId():
return (townFruitId+1+random(4))%5
That's it, 1 line no checks no nothing. Of course ideally you'd have a variable called "FruitNum" or smt to reference any time you want to know the number of fruit types but oh well.
being able to throw paper planes at people and escape social interaction is a FEATURE
The stupid thing is that the Japanese version of the game had code to not only set but actually calculate the lunisolar dates, correctly, but when creating the English version they turned it into that table, and somehow got the dates wrong in doing so. Doubutsu no Mori+ has another holiday on lunar 9/13 too (Jūsan'ya), and that and the Harvest Moon actually work properly. (As well as in the N64/iQue versions.)
Also, I've had the same thing happen with Kapp'n's song when I tried to edit memory to make him sing a different one. K.K. Chorale is the first K.K. Slider song, so it’s usually used as a placeholder/default. It’s a bit odd that this would occur outside of the context of K.K. songs, but my guess is that the live performance of K.K. Chorale is the track the game "falls back" to when something goes wrong. And afterwards, the music won’t change anymore even when it should, subjecting you to an endless loop playing over everything.
That’s very interesting. I somehow got the K.K. song to play when riding with Kapp’n before, but I forget how exactly. I wish I remembered the glitch!
Wait, if Animal Forest calculates it right, then does that mean that it's actually able to go as late as 2038? (The maximum date possible on 32-bit systems)
@@creampop8553 I don’t entirely understand how it works, but the code the calculation relies upon only bothered to support up to 2033. (Cuyler was able to easily extend it to 2100.) Also, 2038 is only the maximum date for the 32-bit UNIX format for time. It's evidently not used by AC, and mostly used for API stuff.
Who programmed the English version? Is it not the Nintendo of Japan? Was it a Nintendo of America programmer's mistake or laziness?
@@w花b Based on interviews, Nintendo of America fleshed out what most of the changes and additions would be, but Nintendo of Japan actually programmed them. There's one where Bill Trinen said NoA would design the furniture or come up with holidays to replace the Japanese ones, and then send them to NoJ to implement them. He also said the last thing created was the summer camping tents which was done by both teams together at E3 2002.
There's lots of Bugs in Animal Crossing. 40 of them, I Think.
Programming Bugs, there's probably more than that.
Just like there’s 151 monsters in Red and Blue/Green, but bugs? More than likely exceeds the current number of Pokemon today…
An Animal crossing villager wrote this
I am glad flying snails is something only in Animal Crossing.
Imagine youre driving around on a bike and suddenly one of them lands in your face.
The best thing about this video was pointing out all the errors that I've made with my own code that are so similar to these errors
@@lukemorgan6166 Mainly College and University, alongside some learning from the internet
did not expect to see a major puyo youtuber in the comment section here
@@akirbyobsessee7396 Hello! I'm glad people consider me to be "major" despite my lack of an upload schedule
I laughed so hard at the snail flying away🤣
Same! 🤣
(my people need me!)>🐌
Ultimate challenge- Fixing The Sims 4's broken code
Some dedicated people made mods to fix the Sims 3 errors but it gets annoying. For the Sims 4, it's only this year that they actually implemented the ability to stop your Sims from washing their dishes in the bathroom sink...
literally all The Sims games are severely bugged
Genuinely can't wait for the AC decompilation & modding scene to eventually take off. Loving the code deep dives, these are always so interesting!!
Omg. I started playing this game this year for the first time and was SO annoyed by my saplings randomly dying despite having a lot of space. Good to learn that it’s a frankly very funny bug
Can I ask how you are playing? I don't have a game cube but would love to play it
@@foxymummanz you can use an emulator either on computer or Android, Dolphin is one of the free available emulators that I know of.
Enjoy it while it lasts. You have about 5 more years. :P
@@RipVanFish09 Just play it with the 2001 date, it's no big deal
Babe wake up hunter R just dropped another technical dive
Hunter IS babe
Thx babe
i enjoy these so much and im not into coding
about a year ago I remember specifically watching a video about glitches etc in the original animal crossing and wishing that there were more videos talking about animal crossing glitches and other technical details. I get so exited every time you upload
Imagine being the person who coded the lunisolar calendar, which is only used for (1) specific case, and still getting a bug anyway. You had one job and now its memorialized on the Internet, 20 years later.
That explains why I never got oranges, I started with apples. I assumed that they were introduced with WW, and didn’t learn otherwise until years after the fact.
TL;DR: I figured out why the harvest moon festival is bugged. The 2030 date cap due to restrictions in the number of dates of harvest moons available due to the fact the people gathering that data are using a calendar system for the 8th century to predict cycles of the moon, which Microsoft adapted into an algorithm which if run more than once would raise the cap.
I thought I had come up with a solution to the lunisolar calendar, by tracking when a user last played, and the current date to generate the number of days since last played, as well as represent days with a full moon with a 0, which is incremented up to 28 and reset to 0, to get a 29 day lunar calendar. You could modulo the number of days since last played by 29 to get an a value, where if you add to the last days moon phase ID to that value, and then modulo by 29 to get the current cycle. This essentially the phase of the moon when assuming the last date played was a full moon, and factoring the actual last moon ID as an offset. I think this is what Nintendo did and are why the dates are wrong; you can't calculate the lunar calendar simply. The part that comes next is crazy:
The developers, like me, realised that a lunar months a really hard to predict, and there are half-days involved. The duration of a lunar month changes every Gregorian month, and it doesn't align with our calendar very well. Some blokes much smarter than either of us invented the Tabular Islamic calendar. This works in 30 year cycles and repeats afterwards, much like we have leap years very 4 years unless the year was divisible by 100, but not 400; the Gregorian calendar is essentially on a 400 year cycle . Their algorithm can predict when a moon will be full with a 99.9996% success rate. The half day screws as to how full the moon will be on a full moon, and I haven't gone into the fact lunar calendars will differ depending on your timezone as the moon will be fullest at midday, so "authorities" have to decide which day will be a full moon in both calendar systems. This is because when Ramadan and Eid both start on viewing of the moon after full moons, you need to know exactly when the moons will full, in case of weather conditions meaning that you couldn't see the moon in a couple days and no one is sure whether it is waxing or waning when it does reappear. Those extra days fasting while a great festival awaits can take place can cause tension of a population.
Now, when you have to find out when the next full moons are for your game in 2001 for years to come, where do you source that information? The Islamic calendar! But no one had actually really tried covert the Gregorian Calendar to the Islamic Calendar algorithmically. Microsoft developed the "Kuwaiti Algorithm", so we could easily convert dates without thinking about two calendars with different prime meridians, different days in the year and different leap years and no one is sure when each was adopted. This is where they saw the 30 year cycle and implemented it into an algorithm for Windows computer. Windows now had the capabilities to convert the date from Gregorian to Islamic, bases on 30 year intervals.
So, there are the devs (either those on Animal Crossing or a service providing the next full moon to tarot readers, novelty calendar makers etc), on their Windows 2000 computers, using the calendar to find the full moons in the Islamic calendar, converting the dates using a calendar which probably only converted a single 30 year cycle from the current date (running the function more that once with the output from n-1 into n would yield more moon predictions). In 2030, the harvest moon will be on 9/11, and actually on the equinox on the 22nd of September. The algorithm counts 10,631 days (probably should of mentioned, when I said 30 year cycles, those are Islamic years), so we can get the implementation date of this feature, which is Monday, 14 August 2000 - Friday, 3 August 2001. Before, the maximum year returned when calculating the calendar would be 2029, after it is 2031. This also perfectly aligns with the development timeline of the game.
So I am proposing this is why the date cap is 2030. They ran out of confirmed full moons in the method they were using. This can be fixed implementing the Kuwaiti algorithm to calculate the moon based on the last day played as a start point. As long as the algorithm feeds the data back into it if the date last played is greater than 30 years, there would be no limit other than memory/if a year past 9999 can be rendered correctly.
They obviously ran into this issue but didn't implement either solution correctly, causing the bug.
Super interesting read. Thank you for doing all this research and sharing! I’ll probably return to this comment in the future and try to confirm everything if/when I look at this topic again. 🙇♂️
8:26 I can imagine the sleep deprived programmer just ctrl+f'ing the item "bass" and copying the id without checking during crunch LOL
I was hoping at some point you would say "We have included a patch in the description to fix all of these bugs", but you never did. Great video either way, I love learning about how games tick.
The fixes are all included in the work-in-progress decomp project. The idea is that you can build the game with or without the patches applied when it’s complete. Making an entire patcher just for these silly bugs would be cool, but I don’t imagine it’d get much use. Plus, there’s always bound to be more bugs discovered as decomp progresses.
Where can we learn more about this project and its progress?@@Hunter-R.
@@kameleongreen Follow the GameCube decompilation Discord server, or you can lookup the AC decompilation repo on GitHub. Linking directly to both of these is a bit troublesome and I don’t want any more issues, but finding them shouldn’t be too hard.
@@Hunter-R. That sounds awesome, I just joined.
You truly are the "Stryder7x" of Animal Crossing. Your wealth of knowledge of Animal Crossing, down to a programming code level, is akin to his wealth of knowledge of how Paper Mario (N64) works on a programming level. I'm glad you still create content on TH-cam, he no longer does and I haven't seen word of what happened and why he no longer uploads videos
Stryder7x's ex gf accused him of SA. He said it never happened and that he was going to take a break from youtube. He never returned. Idk if he actually did it or not though - but thats why :/
^^^ this.
Also, I’m pretty sure it was proven that he didn’t. But it got to the point where his reputation was tarnished so badly that there was no coming back from it.
@@RipVanFish09 Was it though? 99% of times when people talk about Stryder they are supportive of him or are you talking about his real social circle?
@@selena3467 that’s what I’ve heard, and what I’ve found through some research. It’s hard to find a definitive answer, but I’m pretty sure he was innocent.
@@RipVanFish09 Oh sorry I was trying to ask if his reputation was really tarnished that badly.
Man, the guy who coded that fruit randomizer must have either been a programming newbie, or extremely sleep deprived.
Also, the guy who made the random function probably didn't explain their code all that well in their comments if it got this many mistakes. Still these mistakes are funny none the less.
The tree bug has me thinking that you could theoretically plant a bunch of growable trees behind anything on the bottom border of an acre. Since it's not checking the neighbouring acre, and it's instead checking another acre miles away.
Great video as always!
As a programmer, I'd like to attest that there is no coding mistake too simple to not make. You'd be surprised at just how often we screw up seemingly obvious things, however skilled.
@@blakksheep736
Oh I know that too, don't worry. I only write simple scripts, and even I facepalm at my own mistakes.
I can't imagine what horrors I'd make if I did anything graphical.
@@blakksheep736 As a programmer (and programming teacher) I would tell my students not to make a random function inclusive on one end and exclusive on the other. That’s not intuitive and is definitely prone to mistakes.
@@quinton1630 That is horrible advice since almost all random functions for integers work that way. Because of how ranges work it makes sense for floats to be inclusive on both ends and ints to be exclusive on the upper end.
The only times you want inclusive random for integers is when you use 1-indexed arrays.
@@quinton1630 As long as you explain why they shouldn't do this, it's fine. The students will then decide on their own to follow your advice or not, at their own risks.
I kinda like the idea of the game having a bias towards one non native fruit. It's as if there's a nearby place where some other fruit grows, or one of them being the cheaper non native option. Yeah, your town has peaches, but the town next to it might have oranges and that's why its easier to be gifted that instead of cherries or pears that have to come from somewhere farther away
probably the simplest fix for the fruit thing is to leave the randomisation as-is and make it return 4 instead of adding 1 if you land on your town fruit
Or simply reroll the RNG until you get a non-native fruit. RNG isn't that expensive.
@@E0O2X314FTthat’s what I was thinking. Just put it in a loop, and have it roll until you don’t get the native fruit.
@@E0O2X314FT On the other hand, if you get astronomically unlucky, your method could theoretically take an unbounded amount of time. It's generally considered bad practice to allow unlimited rerolls like that
Better yet, remove 1 fruit from the game. That way the array only has 4 elements which is easier to work with
Its crazy how many glitches have appeared due to simple miscalculations Makes you think about how many other games most likely have the same issue
12:24 Actually, the best solution would be changing == to >=
Only a single character changed, and no need to allocate/track a separate array!
I came to the same conclusion. Two comments earlier I'm comparing assembly of both methods + third with branchless version.
The cherry-blossom weather is a good example why you do NOT use raw integers for that type of thing. Every language has some way to create enumerations or at least named values.
Hell, even assembly has it!
**Sees a flying snail**
"Nature is beautiful."
Your in-depth coverage of this games coding is so amazing, even to players like me who know nothing about coding. You describe these things so well Hunter!!
Thank you brother! I hope your courses are going well and that you’re taking care of yourself. Looking forward to future videos from you as well. 🙂
I didn't actually know the original AC had a limited calendar. It does make me wonder what future rereleases (e.g. in retro games collections) will look like. They have occassionally gone back and changed certain things in games before rereleasing them (like the sponsorships in waverace or Earthbound battle effects having a filter put over them to stop seizure enducing flashes).
Eventually we'll start seeing Gamecube games appear in these retro collections, at which point I could see us getting an AC rerelease. And I doubt they'd just have these calendars double back to 2001
11:08 I think the fruit problem could actually be solved by just replacing the == in the condition with >=. That would effectively create a random selection between the 4 fruits that are not the native fruit. For example, if the native fruit was the pear (2), after calling RANDOM(4), a 0 or 1 would correspond to apple and cherry, but a 2 or 3 would be incremented and correspond to peach and orange. I wouldn't be surprised if this was the original intent.
Realized this >= thing too and was about to say basically the same thing!
Or just not have oranges in the game at all. That way you have 4 possible fruit which is far easier to work with
i found the snail flying away bug to be unnecessarily funny i'm sitting here giggling away
For the fruit instead of making a new list. You can use the old list and keep the % but always offset the random by your starting fruit. If your random is offset to the fruit after yours and only picks one less the the total number of fruit it will never pick yours.
Thought it was really interesting how you accidentally created a new bug at the end. K.K. Slider music randomly playing is pretty funny.
"Eh, i believe that when snails fly!"
"Boy do i have something to show you~!"
Everybody gangsta until the snail starts flying away
If anyone is wondering, the dummy item reads "Damii"
Yep, it's a phoenetic transliteration of "dummy"
An Animal Crossing without proper Harvest Moon dates is completely unplayable.
"Since of course it never snows in April" this does occur in Austria sometimes. Probably not the coming years, but it used to happen
8:25 Why is an array size being stored as a float?! 😨
Seems a bit unorthodox, and a lot of people mentioned this last time, too. I believe the reason is because the array size is re-used as an input for randomly determining what to roll, and the function they use there ( RANDOM_F ) seemingly depends on a floating point number... 🥴
Me and my 2.3855 column wide array
@@Hunter-R. thanks for the reply but that raises more questions haha (like why not use RANDOM for ints instead). could you ask Cuyler if this logic is somewhere in the Animal-Crossing-Decomp repo? would like to take a look at it 🙃
@@guy_th18 I simplified a bit in the video, but shell_max is actually an array itself filled with floats marking the size of the other tables, but still equally unorthodox. Anyways, you can look at the implementation here:
github.com/Prakxo/ac-decomp/blob/d48e6e51096cd5c3a17cf78ae68e5c2372cded65/src/m_field_info.c#L3317
@@Hunter-R. thank you for the full details! yeah, looking into it I can't come up with a satisfying reason why they'd use floats instead of ints there (unless there's some quirk of RANDOM_F that RANDOM doesn't have that they really wanted here for some reason). dev who worked on it probably just had a weird brainfart, happens to the best of us
12:07 I think what they may have been trying to do was a rather clever approach which avoids introducing a bias while not requiring the creation of a new list. If the equality check had instead been a greater-than-or-equal-to check, then all four non-native fruit would have been obtainable. Doing this "skips" the native fruit without requiring a wraparound check.
I wasn’t looking at the screen at the time, so i thought you were calling it a “looney solar calendar” 😂
A simpler solution to the fruit bug that has the same result as creating a new list is to leave the random parameter at 4 and add one if other_fruit >= the native fruit rather than just ==
I like to think getting a bass fish instead of an instrument was a joke the devs left in when they realized the error
I loooooove videos like this. It's so cool to see some of the things Cuyler and I talked about get put into action. One day we'll have a fully patched and expanded Animal Crossing experience !
I'd love to see if some of these fixes could be made into AR codes ?
For sure some of these could be fixed with AR codes! Some things aren’t though. Expanding the calendar to 2099 requires implementing the lunisolar calendar up to 2099 which isn’t easy to accomplish via AR codes due to the amount of data needed
Thank you! I also appreciate your previous collaborations with Cuyler on ACSE and the like. I know I haven’t been around the community too long, but it’s cool to finally talk to some people that I’ve heard a lot about.
Also, some of the more simplistic fixes can be made into AR codes, or are already AR codes - such as the paper airplane fix. However, I imagine some of the more fundamental changes to the codebase would require a modded patch.
@@Cuyler for sure ! I saw another comment suggesting other versions have a way to calculate it on the fly; if that's true, it might be fun to implement instead. It'd be a lot of code changes though !
@@Hunter-R. Of course ! and thank YOU for showing off all these discoveries. It's been really motivating. I love how digestible your videos are, so it makes it easy to share with others things that I'm nerdy about haha :) You're doing great work !!
I'd love to see some AR codes made from all this some time. It'd be cool to have a mega code that just makes a bunch of patch changes. Though maybe it'd also be worth making a custom NES ROM patch instead ?
Thanks again, and good luck with future endeavours !
The solution I would use for the gift fruit bug is to do the increment every value equal OR GRATER than the native fruit while keeping the Random(4).
No modulus is required, no bias.
at this point you could probably recreate animal crossing from scratch
no he can't. the guy who informs these videos and actually does decomp work for this game (Cuyler) can and does, but it's an extremely time-taking and painstaking process requiring deep computer science fundamentals that I don't believe Hunter has (he's not part of that project on GitHub)
Or how about in scratch? 🤔
@@DaizoDeeVonOfficial only a madman would do that
not to nerd emoji or anything but I hope you know that's hyperbole. though Cuyler probably could (he's the guy that helps inform these videos and one of the main people working on the AC decomp project)
Decomp is exactly that but in reverse
If I saw an error like the one in the first example at my job, my first thought would be that I'm misreading the code rather than thinking it's a bug. This video has given me more confidence when reading someone else's code.
9:53 Maybe the programmer was frustrated that the 16th journal wasn't showing up when testing, and they couldn't figure out why. So they tried to specify by adding the & 15?
Maybe they were tasked with fixing the journal, realized the mistake with random and decided to just go to sleep 😂
There's an e'en simpler solution to the fruit bug: just change the test from == to >=. Chances are still evenly dispersed ( assuming the output o' the random function is evenly dispersed ), since the rolls that land on the town fruit & onward are just shifted rightward & there's no chance o' going beyond the bounds o' the array, since if the town fruit is the 4th fruit, the output o' random( 4 ) will ne'er be >= 4, so it will always just use the 0 - 3 roll directly.
When I played this game back in the day I was convinced oranges were a myth for years until my friend (who had peaches as her town fruit) got one as a gift.
The game play's the KK song after the Kapp'n song presumably because all the song data is stored in a single contiguous block in memory, and individual songs are referenced by an index into that block. If a song is played for longer than it's stored music, the music player probably keeps incrementing the note pointer into the next song.
You probably could find a flying snail in Australia.
Something I haven’t seen mentioned but I really appreciate is the accessible captions! As usual these videos are amazing ❤
omg, I thought there was a "dud spot" mechanics to explain why saplings sometimes don't grow in particular spots in an acre. That's funny to find out it's because of a coding mistake! Are you going to release a patch file for the game with the fixed codes, or is this part of the decomp project?
In the decomp project, most of the important coding bugs that have been discovered so far are marked and feature either direct fixes or workarounds. You'll be able to build with or without patches/fixes applied, which is super cool.
There’s additional intended logic for why trees die or stop growing in certain spots in an acre. Each acre has a tile attribute map and one of the attributes is how far along a tree can grow or if it should die if planted there. The bug in the game is pretty niche considering it only happens on the bottommost tiles in an acre.
@@Hunter-R. How do we get these patches?
Truly fascinating! I really appreciate that you not only showed bugs, but also showed how one could fix them in the game's code! I'm studying comp sci, and this was really fun to watch as a result. Big thanks to Cuyler too for the in-depth programming :D
New Hunter R upload, I can finally eat dinner properly
The fruit issue AND the bias that happens when you try to fix it can be fixed with a simple trick: keep the original code, but when the result is the fruit native to your town, pick oranges.
This way, every fruit that is not native to your town has an equal chance to be picked.
You’ve been having some incredible growth! It’s been only 7-8 months since I started watching you and you already have 50,000 subs! Love your content and I’ll stay for the long road to 1 million.
Broken bugs? Um, I caught every bug in Animal Crossing and none of the seemed to be broken. :P
Edit: 4:47 nvm
You and Cuyler are pioneers in the GameCube Animal Crossing scene, god bless y'all
Imagine you are in a cutscene explaining a task to your villager but he just throws a paper airplane and leaves the scene leaving you talking to yourself like an idiot
12:25 i think you could still do this pretty elegantly without using a second list.
Take the current fruit as the starting point and then add random(4)+1 to it.
int gift = (current + random(4)+1) % 5;
random(4)+1 will return a uniform number in [1,4]. And it will be impossible to result in your native fruit. This also removes the check.
The only issue here is that the % operator takes a performance hit if it's used with a constant that isn't a power of 2. (Since the compiler turns it into a bitwise AND in that case)
Thank you for including closed captions on your videos!
I remember changing the date as a kid and thinking what would happen after 2030.
We do know nowadays, but to naturally inch towards this date feels kinda weird ngl
I love watching these technical videos. I'm a programmer and hobby modder myself and seeing these small oversights and stuff just feels so relatable and it's so interesting to me because it gives me examples of potential pitfalls I otherwise just wouldn't get
A very simple solution for the fruit at 12:00 ish: Keep it as random(4) and just replace the == with >=. This effectively simulates making a new list without having to actually do that, and thus removes the bias towards a specific fruit.
Wait, I'm confused. Why would they have all that code to keep track of the lunar calendar if they ended up just hardcoding all the dates instead? I was thinking that after 2030, they'd actually use that code to calculate the following dates, but they just left that calculation code in there without ever using it?
I was also hoping you'd explain what causes the snail bug, that was very interesting!
Fantastic video, honestly. Bugs and glitches always feel like the most random thing you'd never even think of, so it's incredible being able to see exactly what little slip up caused them.
Sorry if I wasn’t super clear in the video. The actual calculations in the code are apparently leftover from DnM/DnM+, and are used in AC as a failsafe. I imagine it was faster for the game to use precalculated dates and was a development decision when updating the game for the West. If you let your console roll over to the year 2030, the calculation would be used in 2031 and 2032 for the dates. After that, the holiday fails to trigger altogether.
The snail bug is interesting, and we’re pretty sure the release code is just incorrectly mapped since it’s the only bug who does this. Again, this is patched in the European/Australian version, but those versions haven’t been decompiled or looked at - but looking there would tell us exactly what they changed.
@@Hunter-R. very interesting. Thank you so much for clarifying! Absolutely love your channel! :D
This is very interesting, I didn't know there was original Animal Crossing decomp up until now.
About halfway done at this point! Forever grateful to all the contributors to that project, especially Cuyler and Prakxo.
im not a very tech-savvy person so please pardon any technical errors in this statement:
at 18:53, when kapp’n’s song ends and is replaced by the live version of kk chorale, this may be because the code is set to return to the first song in the music list if an error occurs during kapp’n’s song, as kk chorale is the very first song in the game’s code!
i discovered this glitch myself when i was playing e+ on my laggy computer, i’m not sure if it was the lag or some error that occurred while trying to skip kapp’n’s song via button mashing, but suddenly kk chorale started playing instead, only for me it was the aircheck version. very strange! i want to know how this happens very badly
I've always wondered if the game's calendar could be "fixed" to count past 2030. Guess the harvest moon would complicate that somewhat, but assuming one accounted for it, could the calendar be tweaked to be set beyond 2030 manually?
Yes, and the implementation has already been accomplished to go to 2100. You do have to mod and rebuild the game with this solution, of course.
On the oranges bug, you could make a code that loops random(5) calls to the full array of fruits (including the native one) until you get a fruit that isn't your native one.
This would also have the consequence of locking up your game for some time if you're INCREDIBLY unlucky and roll your native fruit several times in a row.
Which makes each call to that function a lot more exciting.👀😌
Seeing all of this fervor around one of my beloved childhood games makes me want to jump in myself and see what I can do.
I feel like I'd be less productive than a caveman trying to build an airplane, but being able to change/fix the various mechanics in this game seems like a fun way to make a definitive/personalized version that could be cool. Making the island reachable without peripherals, changing the logic for Nook's inventory, making villager fetch quests not require you to run between 10 villagers not in their home acres only to then get rewarded with paper, maybe even ways to influence how your village spawns, I see lots of potential.
Towards 12:25 another solution:
if (other_fruit == Save_Get(fruit)) {
other_fruit = (other fruit + Random(4) + 1) % 5;
}
This function will, if the rolled fruit is your own town fruit a Random Number between 1-4 (Random(4) generate 0-3 + 1 => 1-4) which is then modulated by 5. So in the orange Case if you roll an orange, the other_fruit value before modulo is 5-8, and after it 0-3 which would be exactly what we want and still be perfectly balanced.
This has the advantage of don't occupie another block of memory and also don't have to check for tidy up when not needed anymore. Also it's just a change in a single line of code which I personally really like :D
Modulo by anything other than a power of 2 incurs a performance penalty. It's a one-liner in C but not in assembly. "x % 4" is much faster than "x % 5" since "x % 4" is converted by the compiler into "x & 3" which doesn't require a hardware multiply
Is the solution to 12:00 this:
Keep the random choice of the first four fruits, but if it is the native fruit, pick the fifth fruit, the orange?
That would result in an even distribution regardless of which fruit is the native fruit, right?
Looking at the flat array bug at the start coming from a "how to visualize 4D hypervolumes" video is truly amazing hahaha
12:05
Or you can just make it so that if it results in your native fruit, it will give you orange(s) no matter what your native fruit is
Example: Say your native fruit is pears. If you rolled a 0, 1, or 3, you get the matching fruit, but if you roll a 2, you get orange(s).
12:30 using a new list entirely seems kinda redundant, since they have most of the code already anyways. Just swap the `other_fruit++` to `other_fruit = 5` to "include" the orange in our random range whenever our home fruit is selected
The orange bug could be fixed quite elegantly:
If it rolls your native fruit, return 4.
The unmodified code *already* biases towards one fruit.
If your native fruit is rolled, give an orange... because if you have oranges, you can't ever roll oranges to begin with, and if you don't have oranges, it essentially places oranges in the slot occupied by your native fruit
12:24 There is another solution that I'd argue is better. It allows you to avoid the construction of a new list, and minimizes the amount of code changes from the existing implementation. Simply keep the random call as "RANDOM(4)", but change the conditional from "if (other_fruit == Save_Get(fruit))" to "if (other_fruit >= Save_Get(fruit))". This fixes the issue of oranges being inaccessible given some town fruit, and prevents any bias in the result, all by only changing one conditional branch.
I’ve been binging your videos back to back to back the past few hours! Thank you for the well thought out videos that pack a knowledgeable punch! I’m such a huge fan and subscribed immediately 🎉
The slight bias at fruits makes it kinda more interesting xd - having their likelyhood differently weighted, even if its only one fruit with 2/5 chance, making the player assume it to be the primary non-native fruit
Imagine if we in the real world couldn't live past 2030 cause of a gosh darn moon being too complicated to predict....bruh
9:22 Note: The way RANDOM( x ) works in their code is not unusual and is how things often work in programming because it's more frequently useful to specify that you want 10 possibilities (instead of just specifying the upper-bound). 0-9 is 10 possible outputs, whereas 0-10 would be 11 possible outputs. It's pretty silly though that the devs of Animal Crossing apparently didn't read the docs or had skipped Probabilities & Statistics class in college.
for the whole native fruit thing you could probably just make the check re run the entire code, so that it call random again and also again checks if its the native fruit or not. its probably unlikely enough to roll the native fruit multiple times in a row to actually have an impact on the game.
I would have just removed oranges from the game entirely. That way only 4 fruit exist, which makes the calculations much easier
There's always been something magical to me about the orginal animal crossing with all these weird quirks
I feel like I haven't taken a breath since the last video
instead of keeping two lists, you can also just add a random value from 0 to N-1 (where N is the number of items), then modulo that with N. as a single step that does all of this without checking, it would be (X + RANDOM(N)) % X, where X is the town fruit.
Correction, it would have to be: (X+RANDOM(N-1)+1) % N
@@ITR it was assuming RANDOM was exclusive, but yeah.
@@colly6022 It is exclusive on the upper bound, but it can also return 0, which would make it give your own fruit :-P
And you moduloed on the wrong number
watching this right after a harvest moon happened tonight lol
i am now imagining a creepypasta called "my copy of animal crossing can go past the year 2030"
in it the guy finds the usual haunted game disk but in his disk the animals get access to modern technology and fashion for the year they are in and pick up behaviors that fit in line with those years and their public sentiments so they get smartphones, grow more frustrated in general, social distance, and the big climax is things are somewhat foretold as years go past the current showing things like a growing distrust of government and technology, general fear of saying the wrong thing, growing mistrust of one's neighbors, and finally around 2040 an atomic explosion reduces the area to a wasteland and kills all of the animals
it would be written in proper creepypasta of the 2010-2015 fashion
OMG. I encountered the southern border tree glitch when I was younger. I remember I was trying to grow a tree in a very specific spot that happened to be on the southern border of an acre, but every sapling I planted there would die. I planted like 10 saplings, and they all kept dying. I eventually just assumed it had something to do with acre borders, so I stopped planting stuff on the borders entirely. I wasn't too far off.
12:24 A new list is actually not necessary here. Equal odds for every fruit can be achieved by changing the if statement comparison operator from "==" to ">=". This has the affect of skipping over your own fruit in the list and gives every fruit an equal chance to be picked. I used this technique in my own game.
Helped work on the texture pack ages ago. Pretty fun to see some assets that I did!
People fixing bugs in old games without the developers tools make me so happy.