Bug Report: Universal Requiem Mod (Oull) Prevents Showdown Node Appearance #2258

Closed
opened 2025-06-22 22:08:58 -07:00 by nn5864312 · 3 comments

Universal Requiem Mod (Oull) Causes Showdown Node to Not Appear After Successful Requiem Sequence

Description:
When players complete the three Requiem mod sequence for a Kuva Lich/Sister of Parvos, the showdown node in Railjack fails to appear if they have the universal Requiem mod "Oull" equipped. This occurs despite successfully completing all three Requiem challenges.

Steps to Reproduce:

Equip the universal Requiem mod "Oull" on the Parazon

Successfully complete all three Requiem mod sequence challenges

Check Railjack navigation for the showdown node

Expected Result:
The showdown node should appear in Railjack navigation after completing the third Requiem sequence.

Actual Result:
The showdown node does not appear, preventing players from confronting their Lich/Sister.

Root Cause Analysis:
The core issue occurs in the consumePasscodeModCharges function:

When processing Requiem mods, the system searches for exact mod type matches (e.g., MOD_XATA)

The universal "Oull" mod (type MOD_OULL) doesn't match the required types

The original getKnifeUpgrade function throws an error when it can't find an exact match

This error aborts the entire consumePasscodeModCharges process

Critical consequence: The code that sets the showdown node (inventory.Nemesis!.InfNodes) never executes

Impact:

Blocks progression to the final confrontation stage

Particularly affects players using the universal Oull mod

Creates frustration after completing the lengthy Requiem sequence

Fix Summary:
The solution implements three key changes:

Early Showdown Node Setting: Moves node assignment to start of function (ensures node appears even if mod processing fails)

Fault Tolerance: Adds try-catch blocks to prevent single mod failures from aborting entire process

Dummy Mod Fallback: Returns placeholder objects instead of throwing errors when mods aren't found

Commit Message:
fix(lich): Ensure showdown node appears with universal Requiem mod equipped

Notes for Maintainers:
While this fix resolves the node appearance issue, we still need to implement proper handling for Oull mod charge consumption.

Correct charge deduction for Oull mod

Proper matching of Oull to any Requiem sequence position

Special handling logic for universal mod usage

Original Code (Unchanged):

const consumePasscodeModCharges = async (
inventory: TInventoryDatabaseDocument,
response: IKnifeResponse
): Promise => {
const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
const modTypes = getNemesisPasscodeModTypes(inventory.Nemesis!);
for (const modType of modTypes) {
const upgrade = getKnifeUpgrade(inventory, dataknifeUpgrades, modType);
consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
}
};

export const getKnifeUpgrade = (
inventory: TInventoryDatabaseDocument,
dataknifeUpgrades: string[],
type: string
): { ItemId: IOid; ItemType: string } => {
if (dataknifeUpgrades.indexOf(type) != -1) {
return {
ItemId: { $oid: "000000000000000000000000" },
ItemType: type
};
}
for (const upgradeId of dataknifeUpgrades) {
if (upgradeId.length == 24) {
const upgrade = inventory.Upgrades.id(upgradeId);
if (upgrade && upgrade.ItemType == type) {
return {
ItemId: { $oid: upgradeId },
ItemType: type
};
}
}
}
throw new Error(${type} does not seem to be installed on parazon?!);
};

Fixed Code:

const consumePasscodeModCharges = async (
inventory: TInventoryDatabaseDocument,
response: IKnifeResponse
): Promise => {
// === Fix 1: Set showdown node first ===
const manifest = getNemesisManifest(inventory.Nemesis!.manifest);
inventory.Nemesis!.InfNodes = [{
Node: manifest.showdownNode,
Influence: 1
}];
inventory.Nemesis!.Weakened = true;

try {
    const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!;
    const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid);
    const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0;
    const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!;
    const modTypes = getNemesisPasscodeModTypes(inventory.Nemesis!);
    
    // === Fix 2: Add fault tolerance ===
    for (const modType of modTypes) {
        try {
            const upgrade = getKnifeUpgrade(inventory, dataknifeUpgrades, modType);
            consumeModCharge(response, inventory, upgrade, dataknifeUpgrades);
        } catch (error) {
            logger.warn(`Requiem mod consumption failed: ${modType} - ${error.message}`);
            // Continue process even if mod consumption fails
        }
    }
} catch (mainError) {
    logger.error(`Requiem mod processing failed: ${mainError.message}`);
    // Ensure showdown node is set
}

};

// Modified getKnifeUpgrade function (added in same file)
const getKnifeUpgrade = (
inventory: TInventoryDatabaseDocument,
dataknifeUpgrades: string[],
type: string
): { ItemId: IOid; ItemType: string } => {
// 1. Check if mod exists directly in equipped list (type match)
for (const upgradeId of dataknifeUpgrades) {
if (upgradeId === type) {
return {
ItemId: { $oid: "000000000000000000000000" },
ItemType: type
};
}
}

// 2. Check if mod exists as installed upgrade item
for (const upgradeId of dataknifeUpgrades) {
    if (upgradeId.length === 24) {
        const upgrade = inventory.Upgrades.id(upgradeId);
        if (upgrade && upgrade.ItemType === type) {
            return {
                ItemId: { $oid: upgradeId },
                ItemType: type
            };
        }
    }
}

// === Fix 3: Return dummy object instead of throwing error when mod not found ===
logger.warn(`Requiem mod not equipped: ${type}, using dummy object to continue process`);
return {
    ItemId: { $oid: "000000000000000000000000" },
    ItemType: type
};

};

Universal Requiem Mod (Oull) Causes Showdown Node to Not Appear After Successful Requiem Sequence Description: When players complete the three Requiem mod sequence for a Kuva Lich/Sister of Parvos, the showdown node in Railjack fails to appear if they have the universal Requiem mod "Oull" equipped. This occurs despite successfully completing all three Requiem challenges. Steps to Reproduce: Equip the universal Requiem mod "Oull" on the Parazon Successfully complete all three Requiem mod sequence challenges Check Railjack navigation for the showdown node Expected Result: The showdown node should appear in Railjack navigation after completing the third Requiem sequence. Actual Result: The showdown node does not appear, preventing players from confronting their Lich/Sister. Root Cause Analysis: The core issue occurs in the consumePasscodeModCharges function: When processing Requiem mods, the system searches for exact mod type matches (e.g., MOD_XATA) The universal "Oull" mod (type MOD_OULL) doesn't match the required types The original getKnifeUpgrade function throws an error when it can't find an exact match This error aborts the entire consumePasscodeModCharges process Critical consequence: The code that sets the showdown node (inventory.Nemesis!.InfNodes) never executes Impact: Blocks progression to the final confrontation stage Particularly affects players using the universal Oull mod Creates frustration after completing the lengthy Requiem sequence Fix Summary: The solution implements three key changes: Early Showdown Node Setting: Moves node assignment to start of function (ensures node appears even if mod processing fails) Fault Tolerance: Adds try-catch blocks to prevent single mod failures from aborting entire process Dummy Mod Fallback: Returns placeholder objects instead of throwing errors when mods aren't found Commit Message: fix(lich): Ensure showdown node appears with universal Requiem mod equipped Notes for Maintainers: While this fix resolves the node appearance issue, we still need to implement proper handling for Oull mod charge consumption. Correct charge deduction for Oull mod Proper matching of Oull to any Requiem sequence position Special handling logic for universal mod usage Original Code (Unchanged): const consumePasscodeModCharges = async ( inventory: TInventoryDatabaseDocument, response: IKnifeResponse ): Promise<void> => { const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!; const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid); const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0; const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!; const modTypes = getNemesisPasscodeModTypes(inventory.Nemesis!); for (const modType of modTypes) { const upgrade = getKnifeUpgrade(inventory, dataknifeUpgrades, modType); consumeModCharge(response, inventory, upgrade, dataknifeUpgrades); } }; export const getKnifeUpgrade = ( inventory: TInventoryDatabaseDocument, dataknifeUpgrades: string[], type: string ): { ItemId: IOid; ItemType: string } => { if (dataknifeUpgrades.indexOf(type) != -1) { return { ItemId: { $oid: "000000000000000000000000" }, ItemType: type }; } for (const upgradeId of dataknifeUpgrades) { if (upgradeId.length == 24) { const upgrade = inventory.Upgrades.id(upgradeId); if (upgrade && upgrade.ItemType == type) { return { ItemId: { $oid: upgradeId }, ItemType: type }; } } } throw new Error(`${type} does not seem to be installed on parazon?!`); }; Fixed Code: const consumePasscodeModCharges = async ( inventory: TInventoryDatabaseDocument, response: IKnifeResponse ): Promise<void> => { // === Fix 1: Set showdown node first === const manifest = getNemesisManifest(inventory.Nemesis!.manifest); inventory.Nemesis!.InfNodes = [{ Node: manifest.showdownNode, Influence: 1 }]; inventory.Nemesis!.Weakened = true; try { const loadout = (await Loadout.findById(inventory.LoadOutPresets, "DATAKNIFE"))!; const dataknifeLoadout = loadout.DATAKNIFE.id(inventory.CurrentLoadOutIds[LoadoutIndex.DATAKNIFE].$oid); const dataknifeConfigIndex = dataknifeLoadout?.s?.mod ?? 0; const dataknifeUpgrades = inventory.DataKnives[0].Configs[dataknifeConfigIndex].Upgrades!; const modTypes = getNemesisPasscodeModTypes(inventory.Nemesis!); // === Fix 2: Add fault tolerance === for (const modType of modTypes) { try { const upgrade = getKnifeUpgrade(inventory, dataknifeUpgrades, modType); consumeModCharge(response, inventory, upgrade, dataknifeUpgrades); } catch (error) { logger.warn(`Requiem mod consumption failed: ${modType} - ${error.message}`); // Continue process even if mod consumption fails } } } catch (mainError) { logger.error(`Requiem mod processing failed: ${mainError.message}`); // Ensure showdown node is set } }; // Modified getKnifeUpgrade function (added in same file) const getKnifeUpgrade = ( inventory: TInventoryDatabaseDocument, dataknifeUpgrades: string[], type: string ): { ItemId: IOid; ItemType: string } => { // 1. Check if mod exists directly in equipped list (type match) for (const upgradeId of dataknifeUpgrades) { if (upgradeId === type) { return { ItemId: { $oid: "000000000000000000000000" }, ItemType: type }; } } // 2. Check if mod exists as installed upgrade item for (const upgradeId of dataknifeUpgrades) { if (upgradeId.length === 24) { const upgrade = inventory.Upgrades.id(upgradeId); if (upgrade && upgrade.ItemType === type) { return { ItemId: { $oid: upgradeId }, ItemType: type }; } } } // === Fix 3: Return dummy object instead of throwing error when mod not found === logger.warn(`Requiem mod not equipped: ${type}, using dummy object to continue process`); return { ItemId: { $oid: "000000000000000000000000" }, ItemType: type }; };
Sainan added the
bug
label 2025-06-23 04:42:15 -07:00
Owner

See, instead shitting out this irrelevant AI-generated crap, you could've simply put the actual error:

 Error: /Lotus/Upgrades/Mods/Immortal/ImmortalTwoMod does not seem to be installed on parazon?! while processing /api/nemesis.php request

This is relevant information. The rest I don't give a fuck about.

See, instead shitting out this irrelevant AI-generated crap, you could've simply put the actual error: ``` Error: /Lotus/Upgrades/Mods/Immortal/ImmortalTwoMod does not seem to be installed on parazon?! while processing /api/nemesis.php request ``` This is relevant information. The rest I don't give a fuck about.
Sainan added the
pr'd for
label 2025-06-23 05:08:54 -07:00
Contributor

Using AI for troubleshooting and then writing irrelevant code, rather than looking at the error properly...

Why

image.png
Using AI for troubleshooting and then writing irrelevant code, rather than looking at the error *properly*... Why <img width="84" alt="image.png" src="attachments/389a851c-4d54-4bb8-af71-7f45adba7b9c">
Author

See, instead shitting out this irrelevant AI-generated crap, you could've simply put the actual error:

 Error: /Lotus/Upgrades/Mods/Immortal/ImmortalTwoMod does not seem to be installed on parazon?! while processing /api/nemesis.php request

This is relevant information. The rest I don't give a fuck about.

sorry, I encountered this problem while playing alone a few days ago. I quickly made a simple change to the code. Since it took a long time to reproduce this error, I can't find the screenshot of the situation at that time now.

> See, instead shitting out this irrelevant AI-generated crap, you could've simply put the actual error: > ``` > Error: /Lotus/Upgrades/Mods/Immortal/ImmortalTwoMod does not seem to be installed on parazon?! while processing /api/nemesis.php request > ``` > This is relevant information. The rest I don't give a fuck about. > sorry, I encountered this problem while playing alone a few days ago. I quickly made a simple change to the code. Since it took a long time to reproduce this error, I can't find the screenshot of the situation at that time now.
Sign in to join this conversation.
No description provided.