The Beginning of The End 2 (Progress Report)

Good morning/afternoon/evening. With saves implemented and most warnings dealt with we’re one step closer to the final stage. The game is should be mostly playable at the moment, but the only way to verify that is to actually test it.

Debug Commands

In order to facilitate our endeavors, it is useful to create lots of debug commands (I’ve explained how to implement them in the last post).

Here is the full list of commands added so far:

// Input: <None>. Kills the center actor
bool cmdKillProtag(int argc, const char **argv);

// Input: <Actor ID>. Kills an actor
bool cmdKill(int argc, const char **argv);

// Input: <Object ID>. Prints an object's name
bool cmdObjName(int argc, const char **argv);

// Input: <Name Index>. Prints an ObjectID corresponding to the name index.
bool cmdObjNameIndexToID(int argc, const char **argv);

// Input: <Object Name>. Prints a list of objects containing the string in their name
bool cmdSearchObj(int argc, const char **argv);

// Input: <Object ID>. Adds the object to the center actor's inventory.
bool cmdAddObj(int argc, const char **argv);

// Input: <1/0>. Sets godmode
bool cmdGodmode(int argc, const char **argv);

// Input: <1/0>. Sets whether the position coordinates show
bool cmdPosition(int argc, const char **argv);

// Input: <1/0>. Sets whether an item's stats show when holding it
bool cmdStats(int argc, const char **argv);

// Input: <1/0>. Sets whether you can teleport by clicking on the screen
bool cmdTeleportOnClick(int argc, const char **argv);

// Input: <u> <v> <z>. Teleports the center character to the given position
bool cmdTeleport(int argc, const char **argv);

// Input: <Actor ID>. Teleports the character to the npc
bool cmdTeleportToNPC(int argc, const char **argv);

// Input: <Actor ID> <u> <v> <z>. Teleports the npc to the given coordinate
bool cmdTeleportNPC(int argc, const char **argv);

// Input: <Actor ID>. Teleports the npc to the center actor
bool cmdTeleportNPCHere(int argc, const char **argv);

// Input: <None>. Saves the current location in a variable
bool cmdSaveLoc(int argc, const char **argv);

// Input: <None>. Teleports the center actor to the saved location
bool cmdLoadLoc(int argc, const char **argv);

// Input: <Place ID>. Teleports to the given place
bool cmdGotoPlace(int argc, const char **argv);

// Input: <None>. Lists all of the place names along with their IDs
bool cmdListPlaces(int argc, const char **argv);

// Input: <Map Scale Multiplier>. Dumps the map into a png.
bool cmdDumpMap(int argc, const char **argv);


I’ve used the playlist by Sinatar as a basis of what a normal gameplay would look like (also helps me keep track of the normal course of the story). With that open, I proceed along the gameplay with ScummVM and if there’s something specific I wish to check, I open DOSBox and compare the two. Having backwards compatible saves here helps a lot.

One of the first things I wished to check was whether I could reach an ending. I did some research and took notice that I needed three Golden Apples to open the passage to the underworld.

Opening the passage to the Underworld.

Once there we can teleport the final boss, Sariloth to us with teleport_npc_here 32977.

The final fight?

Defeating Sariloth on DOSBox caused one of the endings to play, but here on ScummVM it only made the New Game dialog pop up.

Comparing the source code for playing the endings we can see that some code got lost in the reformatting.

void setLostroMode(void) {
	allPlayerActorsDead = false;
	if (GameMode::newmodeFlag)

	if (!abortFlag) {
void setLostroMode( void )
	waitForVideoFile( "INTRO.SMK");
	allPlayerActorsDead = FALSE;
	if (GameMode::newmodeFlag)

	if (!abortFlag)

abortFlag is set to false inside of waitForVideoFile, so we fix that by adding a abortFlag = false; at the top of setLostroMode (this code is candidate for some more code reformatting, though).

We got one of the bad endings… Spoiler warning?


Other than that, by following the walkthrough I took notice of some lesser bugs as well. Here is a list of the bugs I’ve annotated so far:

BugSteps to reproduceExplanation
Speech is too quiet (compared to music/sound effects)
Music does not loop when it finishesIt loops periodically on the original
Music does not disappear completely when volume is set to zeroSet the music to zeroYou can hear it faintly even when the slider is fully on the left
Music does not restartAfter setting the music to zero, raise it once againIt should restart on the original
Music Volume not reflected to what is on the config when the game startsSet the volume to 0, restart gameThe volume will be at 0 in the options but music will be blasting at full volume
Arrow sprite not changing when reading scrollOpen the scroll in the Padavis InnThe arrow sprite should change to an up arrow when hovering on the upper part and vice-versa for the lower part on the original
Close parchment button not workingOpen the parchments on the notices board in Padavis InnThe close button does not work (although clicking outside the parchment closes it)
Speech not finishing before dialog to buy beer startsPavilion Bar – buy beer with RiddenbutterOn the original, the buy dialog should appear after the speech ends
Crash on reading Kaidar’s bookcmd: add_obj 274 and read book in chestThe book is readable on the original
Crash on saving/loading when spells are presentGo to the Underworld and save when the Wraiths are casting spells, then load the save
Crash on Credits (options menu)Click on the credits button
Fade-in not working when loading a world with WorldID > 0 from the launcherLoad a save from the Underworld from the launcherThe screen flickers and the fade-in does work properly

From now on the development will consist mostly of playtesting and solving bugs. After that I suspect refactoring, solving warnings on other platforms and creating documentation may become of more importance. Thankfully I only have two weeks of school left, so in the worst case scenario I still have plenty of time after that. Let’s hope this project ends in success!

Leave a Reply

Your email address will not be published. Required fields are marked *