Whenever people talk about What I Did In 2020, I am slightly embarrassed, because I haven't come up with a socially acceptable lie to disguise the fact that my answer was reverse engineering the 1995 entry in the colonially dubious but massively selling Oregon Trail series, namely, Oregon Trail II.
The project is not finished -- I have yet to figure out how images and sound are stored, mostly because I in no way know what I'm doing there -- but I did manage to work out most of the gameplay logic. That logic is both more complicated than you might imagine, and a lot jankier. For instance: Let's talk about the bug that canonically makes your character Jesus Christ!
Oregon Trail II is basically a stateful choice-based game, except the state-tracking isn't related to character relationships or plot points but to the physical world around you. For instance, at the beginning of the game, you customize your character, including your occupation (doctor, blacksmith, teacher, journalist, etc.) and, separately, your set of skills: medical, carpentry1, farming/animals, and the like.

Some of these skills -- like, say, being a doctor -- are unsurprisingly super useful. Others are less so. Some skills become useless if you actually have them IRL -- for instance, there's a skill to auto-translate Spanish dialogue to English, which of course is pointless if you yourself are fluent in Spanish. Some skills are completely useless because the code for them just doesn't work.
Then, in a category of its own, is riverwork, which makes accidents while crossing a river less common. Many, many factors go into that: the river's difficulty (a var in river data), type of crossing, river depth, river width, precipitation level, and possibly some other factors I forgot, you get a base chance of survival. They're pretty common-sensical, mostly. If you take the ferry, you can (probably) trust the ferryman to not screw you over. If you try to ford a really deep river, you'll always get swamped.
After this come even more checks, adjusting this base chance even further. Some are flat boosts -- for instance, if you took the time to check the river conditions, you get an automatic 10% to your survival chance no matter what.2 Some are flat penalties: Taking a compensatory bulky Conestoga wagon knocks 10% off, no matter what. A few, including riverwork, are scaled adjustments using what modern games would call "fairmath," boosting your odds more if you've got a low chance of success and less if it's already high, capping it at 100%.
Anyway, I'd worked all this out, ran it through the debugger, tested it in-game, looked elsewhere in the code for anything else that touched river crossing data, and was pretty sure I'd found it all. Then someone told me I must be missing something, because they were regularly plunging into the 14-foot depths of the Missouri River and coming out just fine.
The culprit turns out to be riverwork. Here's the decompiled code3 for riverwork scaling (comments and renamed variables mine):
ecx433 = reinterpret_cast<void**>(0);
*reinterpret_cast<signed char*>(&ecx433) = *reinterpret_cast<signed char*>
(*reinterpret_cast<void***>(v33 + 0xc20) + 0x8b); // Riverwork skill flag
if (ecx433) {
__asm__("cdq ");
eax434 = 100 - successChance - edx255 >> 1;
ecx433 = reinterpret_cast<void**>(static_cast<int32_t>(successChance));
eax435 = *reinterpret_cast<int16_t*>(&eax434) +
reinterpret_cast<unsigned char>(ecx433); // 0.5x + 50
successChance = *reinterpret_cast<int16_t*>(&eax435);
}
Even after renaming/annotating the important variables, this is probably a bit hard to follow, so let's go step by step:
Line 2: The reinterpret_casts and eax___s throughout this are decompiler-code stuff. The important part for us humans is the <signed char*>, which tells us that we are checking a flag. The + 0xc20 offset here stores the game simulation data; the flags for skills start at offset 0x8a. Riverwork is the second skill, so there we go.
Lines 3 on: If we do have riverwork skill, we do some assembly math; I'll save you the trouble of algebra and just say that it comes out to 0.5x + 50, where x is the current chance of surviving the river crossing. Take a second to run some numbers through this until you see the problem.
The problem: What if we have a 0% chance of successfully crossing that river?4 Well, that chance goes up from 0% to 50%. A coin flip. Heads, common sense prevails. Tails, you walk on water. On its own this isn't super useful -- if you're crossing a river in a way that gives you 0% chance of survival, then you're doing it on purpose. But the idea of it -- especially since the game manual repeatedly stresses, to Freaky Friday levels, the importance of making good choices!!! -- amuses me.
-
no, that's not it
-
unless you took a ferry, in which case you don't get the boost but your chance of success is high anyway
-
specifically, decompiled C++ from Snowman -- I don't remember why I used this and not something more common like Ghidra, I think it was a case of going with the first thing that got me progress and then getting far enough to not want to redo it.
-
Or less than 0, which is possible