After finishing a couple small Hugo projects earlier this year, I decided to go back to the task of adapting Robb's Fallacy of Dawn to use my Roodylib library. I had previously done this with Necrotic Drift (and possibly Cryptozooker, I can't even fully remember), but FoD is a bit of a larger undertaking that took more preparation to tackle. Anyhow, none of these Roodylib-ized versions were made for public consumption. The main point of doing them is to see if the Roodylib-ized versions function, and if they function, if they are configurable enough to keep all formatting and such the same. Other people's games are really the best way for me to discover shortcomings in Roodylib.
I've had a version of FoD-with-Roodylib that could compile for a long time now. Testing it is the thing that I've really been putting off. So, I made compiled versions of each with normalized random numbers so the same commands should get all of the same responses. Then I made a recording file that went as far as a third (or possibly a quarter) into Robb's original. The walkthrough I was using (it has been a long time since I've played through FoD) didn't have individual commands, and I didn't have the game map handy so I got lost in the city and decided to stop there.
When I used playback on the Roodylib version, it didn't take very long for the recording to go off the rails. My lovely dinner at the local sushi restaurant never got interrupted by an uninvited guest, which is required for the game to proceed, so FoD's protagonist was forced to spend the rest of the recording (and his life) trapped in that sushi restaurant.
Using Hugofix's script monitor, it turned out that the assailant was waiting at a point where he should have been barging in. In retrospect, I should have instantly realized that the end of his script had been overwritten by the beginning of a script for the character, Clara (which is started at the same point in the game).
The Hugo Book implies that a "step" is actually two elements in the setscript array, but the code behaved like it was one. The assailant's script had 19 steps but would go off the rails after step 16. Since the Hugo Book and the constant declared MAX_SCRIPT_STEPS as 32, it really felt like, "gee, maybe there is one element to a step after all."
So, first I got the assailant's script working by splitting it up into two scripts, adding this code to his object:
Code: Select all
after
{
actor CharMove
{
if parent(self) = BoggitStreet3
{
CancelScript(self)
dapper_script2
return true
}
else
return false
}
}
I once fixed a math error in Hugo's score ranking system, and I thought that maybe something like that was going on here, too. To figure out exactly how things were supposed to be, I broke it down logically. setscript[] is the array that holds all of the character routines and the possible object being used by the routine (example: &CharMove, n_obj). setscript[] is defined with 1024 elements. The MAX_SCRIPTS constant is how many scripts can run simultaneously. It's defined as 16, so dividing 1024 by 16, we get 64. Since MAX_SCRIPT_STEPS is 32, this is the proof that a "step" is two elements (the character routine and the object), not one.
So I then looked over the Script and RunScripts routine to find places that were using the wrong logic. The Script routine is used to return a number where a new character script should start in the setscripts[] array. Hugolib has this line.
Code: Select all
return o * MAX_SCRIPTS * 2
Code: Select all
return o * MAX_SCRIPT_STEPS * 2
Code: Select all
! action
routine = setscript[a * MAX_SCRIPT_STEPS + step * 2]
! object being acted upon
b = setscript[a * MAX_SCRIPT_STEPS + step * 2 + 1]
Code: Select all
! action
routine = setscript[(a * MAX_SCRIPT_STEPS + step) * 2]
! object being acted upon
b = setscript[(a * MAX_SCRIPT_STEPS + step) * 2 + 1]
Not that so many games are written in general, but it's even rarer to have ones with multiple characters moving around with scripts longer than 16 steps where this kind of bug came up. Still, it's surprisingly satisfying to solve an issue that is nearly 20 years old already.
My most recent Roodylib release had a little bug in it, so it's nice to have a bigger reason to get a new update out there sooner!