Opened 3 months ago

Last modified 3 weeks ago

#14886 pending defect (pending)

AGOS: Waxworks crashing at Egypt Level 3, corrupting save file

Reported by: Cobradabest Owned by: athrxx
Priority: high Component: Engine: AGOS
Version: Keywords:
Cc: Game: Waxworks

Description (last modified by Cobradabest)

I'm playing through Waxworks (GOG Version, which is English/DOS/Floppy), and when I reach the first glass on the 3rd floor in the pyramid level and beyond that point, the game crashes if I attempt to save the game and it corrupts the save file. The resulting save file is empty.

While it doesn't stop you from beating the game, it definitely impairs the gameplay since the game is very RNG heavy and full of dead ends and deaths.

I've recorded this bug, which can be seen here.

The version I'm using is Version 2.9.0git (Jan 20 2024) on Ubuntu 22.04.

Attachments (1)

waxworks-pc.002 (3.6 KB ) - added by Cobradabest 3 months ago.
Save file I've been loading from

Download all attachments as: .zip

Change History (14)

comment:1 by Cobradabest, 3 months ago

Description: modified (diff)
Priority: normalhigh

comment:2 by Cobradabest, 3 months ago

Description: modified (diff)

comment:3 by Cobradabest, 3 months ago

Description: modified (diff)
Summary: Waxworks Crashes at Egypt Level 3 (Version 2.9.0git)Waxworks Crashes at Egypt Level 3

by Cobradabest, 3 months ago

Attachment: waxworks-pc.002 added

Save file I've been loading from

comment:4 by digitall, 3 months ago

Priority: highnormal
Summary: Waxworks Crashes at Egypt Level 3AGOS: Waxworks Crashes at Egypt Level 3

Cobradabest: Please don't adjust priority as it is used by developers for setting blockers on release etc.

comment:5 by digitall, 3 months ago

The video linked shows that this is a engine abort at the save with "ERROR: itemPtrToId not found!". This error occurs when the engine tries to lookup an invalid item:
https://github.com/scummvm/scummvm/blob/master/engines/agos/items.cpp#L456

comment:6 by digitall, 3 months ago

Replicated with the attached savegame i.e. load this ("Cobra"), then walk along the corridor until you reach a glass sheet, then save with name i.e. Crash! ... the game will crash on save with the error indicated previous. This used Waxworks (Floppy/DOS/English) version. Will debug.

comment:7 by digitall, 3 months ago

Hmm. After a crash, the original savegame file used has been corrupted and will not load again so will need to get from here or backup copy to retry replication.

The fault is coming from:
https://github.com/scummvm/scummvm/blob/master/engines/agos/saveload.cpp#L1587

The issue seems to be the 4th item i.e. index 3 of the itemstore, but the use of pointers in this makes it hard to see what that item is ...

comment:8 by digitall, 3 months ago

Tracked down why this is happening. The problematic item number is 1509. _itemArrayPtr[1509] is initialized fine when loading, but that is cleared to nullptr by the Waxworks specific loadRoomItems() function when called on Room 1169:
https://github.com/scummvm/scummvm/blob/master/engines/agos/rooms.cpp#L362

The exact line clearing this is:
https://github.com/scummvm/scummvm/blob/master/engines/agos/rooms.cpp#L387

Since this then fails to lookup the mapping between item pointer and reference, the fatal error is emitted.

comment:9 by valsu, 3 months ago

Priority: normalhigh

Just encountered this bug and both my Egypt level saves got corrupted. I now need to restart the whole Egypt level. Not pretty. Setting priority to high as this bug affects basic game functionality and results in corrupted files.

Last edited 3 months ago by valsu (previous) (diff)

comment:10 by valsu, 3 months ago

Summary: AGOS: Waxworks Crashes at Egypt Level 3AGOS: Waxworks crashing at Egypt Level 3, corrupting save file

comment:11 by athrxx, 5 weeks ago

The diagnosis above seems to be correct. loadRoomItems() invalidates the current subset of items and loads a new subset. It does not update the items contained in the _itemStore array, though. That array may still hold items that have been invalidated. And when the savegame code tries to find the id of such an invalidated item it will trigger that fatal error.

Unfortunately, I haven't discovered any particular flaw in our implementation of loadRoomItems() or in our savegame code. Our code seems to be modelled very closely after the original code. The original will also not tolerate invalid items in the _itemStore array and will exit to DOS with a similar error if it encounters an invalid item.

Now, I took the savegame from here and made it loadable with the original interpreter in DOSBox. And the behavior there is exactly the same: when I walk around the corner to trigger the loadRoomItems() call and then try to save the game it will error out. So it seems that the game data already is in a broken state in that Cobra savegame. And the walk around the corner with the loadRoomItems() just finishs it off completely. Sadly, this makes it much harder to track down the exact cause of the bug...

comment:12 by athrxx, 4 weeks ago

The culprit seems to be the item in _itemStore[3]. In DOSBox plays I have a value of 217 in there, in ScummVM I have a value of 1509 (savegame uploaded here) or 1438 (one of my own tries). Both of the latter values are high enough to clash with the items exchanged by loadRoomItems().
The item in question seems to be the dead body of the last enemy killed. When the corpse comes into sight the item is copied into _itemStore[3]. The original interpreter seems to replace that value as soon as you look somewhere else. But with ScummVM, the corpse item stays.
So, the good news is: it is likely that this can be fixed in a way that the existing savegames will still be useable (we just need to understand how the original interpreter updates that array and fix that). The bad news is that currently the pyramid is not really playable. The corruption takes place after killing the first enemy, so restarting the pyramid won't help at all. It might be possible to get through that 3rd floor area without saving, but I don't know if/when saving would ever become possible again. I really recommend waiting for a fix.

comment:13 by athrxx, 3 weeks ago

Owner: set to athrxx
Resolution: pending
Status: newpending

I have now made a fix that seems to work fine with the savegame you provided here. The bug is in the savegame code and breaks the game timers. Unfortunately, each time you load a game, save again, etc. it gets broken more and more. While most of these timers don't seem to have a relevant impact on the gameplay, Waxworks has a timer that (among other things) cleans up the items chain, which prevents invalid item handles. Please test if the fix works for you.

Note: See TracTickets for help on using tickets.