Why do certain FNames get capitalized in packaged builds?

I have the following code:

  FName happy = FName(TEXT("happy"));
  UE_LOG(LogTemp, Log, TEXT("%s"), *happy.ToString())
  FName h = FName(TEXT("h"));
  UE_LOG(LogTemp, Log, TEXT("%s"), *h.ToString())
  FName index = FName(TEXT("index"));
  UE_LOG(LogTemp, Log, TEXT("%s"), *index.ToString())
  FName i = FName(TEXT("i"));
  UE_LOG(LogTemp, Log, TEXT("%s"), *i.ToString())
  FName joy = FName(TEXT("joy"));
  UE_LOG(LogTemp, Log, TEXT("%s"), *joy.ToString())
  FName j = FName(TEXT("j"));
  UE_LOG(LogTemp, Log, TEXT("%s"), *j.ToString())

In the editor I see expected output:

LogTemp: happy
LogTemp: h
LogTemp: index
LogTemp: i
LogTemp: joy
LogTemp: j

But in packaged builds I find certain names unexpectedly capitalized:

[2018.02.23-21.08.07:946][  0]LogTemp: happy
[2018.02.23-21.08.07:946][  0]LogTemp: H
[2018.02.23-21.08.07:946][  0]LogTemp: Index
[2018.02.23-21.08.07:946][  0]LogTemp: I
[2018.02.23-21.08.07:946][  0]LogTemp: joy
[2018.02.23-21.08.07:946][  0]LogTemp: J

This is causing me trouble in other projects where I convert FNames to char* for comparison purposes. I know that FNames are case insensitive, so is there something unsafe about using them in this manor?

You can find the project that generates this output here.

Update 5/1/2018: Removed project hosting.

The case of an FName depends on the first instance that is created with that unique (case-insensitive) string. If you create the FName for “x” and other packages (or code) uses the FName “X”, whether the x is uppercase or lowercase will depend upon which of those is encountered first by the engine. You can not change this behavior so make sure that all uses of the string treat the FName as case-insensitive.

Thanks for your response. That makes sense. It’s interesting that this behavior changes between the editor and packaged builds. Are there modules that get loaded in packaged builds that aren’t present when running in the editor?

Yes. Running a commandlet to cook or package the game takes a different code path than running the editor or game. If you want to know what code is causing an FName to get added with a specific case, you can set a breakpoint in the FName::FName constructors in UnrealNames.cpp and do a strcmp() looking for a specific case being used.