Skip to content

bugfix(namekeys): Remove hardcoded NameKeyIDs from dummy strings for modded files#2349

Open
Caball009 wants to merge 2 commits intoTheSuperHackers:mainfrom
Caball009:fix_retail_namekey_ids
Open

bugfix(namekeys): Remove hardcoded NameKeyIDs from dummy strings for modded files#2349
Caball009 wants to merge 2 commits intoTheSuperHackers:mainfrom
Caball009:fix_retail_namekey_ids

Conversation

@Caball009
Copy link

@Caball009 Caball009 commented Feb 24, 2026

Perhaps it's best to keep the issue open because it touches on a larger issue that this PR does not fix.

#1516 adds three strings with hardcoded name key IDs. This PR fixes the following issue:

Unfortunately, hardcoding the IDs doesn't work for modded files. This became apparent after this replay started to mismatch after #1516 at 4:00: TEOD_0986_P11.zip mod files This mod expects the three strings to have IDs 265 - 267.

I've added a second commit with debug assertions for the correct name key ID with unmodded files to help us detect undesirable additions or removals of name keys.

TODO:

  • Check hash and name key ID values for Generals.
  • Replicate in Generals.

@Caball009 Caball009 added Bug Something is not working right, typically is user facing Major Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour ThisProject The issue was introduced by this project, or this task is specific to this project labels Feb 24, 2026
@Caball009 Caball009 changed the title Fix retail namekey ids bugfix(namekeys): Remove hardcoded NameKeyIDs from dummy strings for modded files Feb 24, 2026
@Caball009 Caball009 marked this pull request as ready for review February 28, 2026 15:26
@greptile-apps
Copy link

greptile-apps bot commented Feb 28, 2026

Greptile Summary

Fixes name key synchronization issue between vanilla and modded game files by replacing hardcoded file paths with generic dummy strings.

Key Changes:

  • Removed addReservedKey() function that hardcoded file paths at specific IDs (97-99)
  • Added syncNameKeyID() to create 3 generic dummy strings after TheAudio initialization
  • Added verifyNameKeyID() with debug assertions to detect unexpected name key ID deviations in unmodded files
  • Simplified nameToKey functions by removing conditional key reservation logic

Impact:

  • Modded files (like TEOD) can now have different name key sequences without causing replay mismatches
  • Maintains CRC compatibility by ensuring consistent relative ordering across all clients
  • Debug assertions help catch future initialization sequence changes that could break compatibility

Confidence Score: 5/5

  • This PR is safe to merge with no identified risks
  • The fix is well-designed and directly addresses the root cause: hardcoded IDs don't work for modded files. The new approach creates dummy strings at a consistent initialization point, ensuring all clients maintain the same relative name key ordering. Debug assertions provide safety against future regressions. Code quality is excellent with clear comments explaining the change
  • No files require special attention

Important Files Changed

Filename Overview
GeneralsMD/Code/GameEngine/Include/Common/NameKeyGenerator.h Added public methods syncNameKeyID() and verifyNameKeyID() to replace the private addReservedKey() function, improving the API design
GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp Added verification calls at strategic initialization points and synchronized name key IDs after TheAudio initialization
GeneralsMD/Code/GameEngine/Source/Common/NameKeyGenerator.cpp Replaced hardcoded file path logic with generic dummy strings, simplified name-to-key functions by removing conditional key reservation

Last reviewed commit: b8b15db

@@ -508,6 +508,10 @@ void GameEngine::init()
#endif/////////////////////////////////////////////////////////////////////////////////////////////


#if RETAIL_COMPATIBLE_CRC
if (xferCRC.getCRC() == 0xA1E7F8E6) TheNameKeyGenerator->verifyNameKeyID(1);
Copy link

Choose a reason for hiding this comment

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

Use new line.

Multiple times.

return false;
nameToKey("TSH_dummy_string_1");
nameToKey("TSH_dummy_string_2");
nameToKey("TSH_dummy_string_3");
Copy link

Choose a reason for hiding this comment

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

I suggest to preserve the original strings for context

Copy link
Author

@Caball009 Caball009 Feb 28, 2026

Choose a reason for hiding this comment

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

Yeah, I can use the strings that were added in #1516.

Those strings depend either on registry language and / or use sound track names that can be changed by mods, though.

Copy link

Choose a reason for hiding this comment

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

It is mainly about preserving the context for what these strings are for the next person to look at it.

Copy link
Author

Choose a reason for hiding this comment

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

That's fair.

#endif

return key;
return nameToLowercaseKeyImpl(name);
Copy link

Choose a reason for hiding this comment

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

This means you can merge nameToLowercaseKeyImpl into nameToLowercaseKey entirely as it was originally.

Four times.

@@ -524,6 +528,10 @@ void GameEngine::init()
if (!TheAudio->isMusicAlreadyLoaded())
setQuitting(TRUE);

#if RTS_ZEROHOUR && RETAIL_COMPATIBLE_CRC
TheNameKeyGenerator->syncNameKeyID();
Copy link

Choose a reason for hiding this comment

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

Instead of adding the syncNameKeyID function, how about just calling nameToKey 3 times here?

Copy link
Author

Choose a reason for hiding this comment

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

I wanted a better place for a TSH comment that's not in the middle of an enormous function that's not really related.

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

Labels

Bug Something is not working right, typically is user facing Gen Relates to Generals Major Severity: Minor < Major < Critical < Blocker ThisProject The issue was introduced by this project, or this task is specific to this project ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants