Skip to content

Conversation

@SilasD
Copy link
Contributor

@SilasD SilasD commented Jan 2, 2026

missing nemesis2

In the past month, two people on the DFHack Discord have reported game-worlds with missing nemesis records, and a third person provided a savegame that proved to have missing nemesis records.

On 12/13/25, Gladius reported a savegame that crashes on retire with a report of "Unit X has IS_NEMESIS flag, but no nemesis record found; save is corrupted." as well as some issues with armor disappearing from units returning from missions. A brief analysis showed that 60 nemesis records were missing from this savegame.

On 12/22/25, Bumber reported a savegame diagnosed as Update: His nemesis record has gone completely AWOL. Oof. The savegame is also is noted as logging "save is corrupted" in the errorlog.txt, as well has having warnings about missing/corrupted unit files. Bumber also reported " My world has been slowly losing unit files."

On 12/23/25, The Dadinator uploaded a savegame for an unrelated armor issue. The provided savegame is missing 36 nemesis records, 13 of which are for active citizens.


Checking for missing nemesis records is trivial; it should not materially slow down the game. The warning could spare players a lot of wasted time trying to play a corrupt savegame. I think adding a test is justified.

The specific text of the warning message could stand to be improved. I am open to suggestions.

missing nemesis

local citizens = {}
for _, unit in ipairs(dfhack.units.getCitizens(true)) do
if dfhack.units.getGeneralRef(unit, df.general_ref_type.IS_NEMESIS) then
local nid = dfhack.units.getGeneralRef(unit, df.general_ref_type.IS_NEMESIS).nemesis_id
Copy link
Member

@quietust quietust Jan 2, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rather than calling getGeneralRef twice, call it once (outside of the if statement) and save the result. Additionally, you can call the getNemesis() vmethod on it to let the game find it.

    for _, unit in ipairs(dfhack.units.getCitizens(true)) do
        local nem = dfhack.units.getGeneralRef(unit, df.general_ref_type.IS_NEMESIS)
        if nem ~= nil and nem:getNemesis() == nil then
            table.insert(citizens, '  ' .. dfhack.units.getReadableName(unit))
        end
    end

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants