Windows Base game bug that errors with certain modded furniture lists

Esca

Farmhand
Version: Stardew Valley 1.6.15 build 24356 on Microsoft Windows 11 Pro
Language: English

In rare cases, the game can encounter errors when using the "ALL_ITEMS" game state query condition. It seems to depend on the number of furniture items in the game, as well as their internal IDs, due to a bug in the sorting code. This primarily affects mods when players happen to download certain sets of furniture, but can technically happen in the base game, if any future updates add furniture.

The problematic code in Stardew is here, in the Utility class:

public static int SortAllFurnitures(Furniture a, Furniture b)
{
string leftId = a.QualifiedItemId;
string rightId = b.QualifiedItemId;
if (leftId != rightId)
{
if (leftId == "(F)1226" || leftId == "(F)1308")
{
return -1;
}
if (rightId == "(F)1226" || rightId == "(F)1308")
{
return 1;
}


When furniture items 1226 and 1308 are compared to each other, it produces inconsistent results and sometimes throws an error. (For any specific list of furniture, the result is always the same; with only the base game's current furniture set, it doesn't throw an error.)

Those IDs should return specific results when compared to each other (e.g. "return 0"), regardless of the comparison order (i.e. which furniture item happens to be "a" or "b").

I've attached a SMAPI log where a mod user is encountering the bug consistently.

The code below can reproduce the error. In a basic SMAPI C# mod, call "DemonstrateSortingError()" at any time after the game has launched. The code is similar to that used by the "ALL_ITEMS" game state query condition, but this shuffles the furniture list before sorting it, which makes the error far more likely to happen.

private void DemonstrateSortingError()
{
Random random = new();
List<Furniture> furniture = new List<Furniture>();
IItemDataDefinition itemDataDefinition = ItemRegistry.GetTypeDefinition(ItemRegistry.type_furniture);
foreach (ParsedItemData data in itemDataDefinition.GetAllData())
{
Furniture item = ItemRegistry.Create<Furniture>(data.QualifiedItemId);
furniture.Add(item);
}
for (int x = 0; x < 1000; x++)
{
ShuffleList<Furniture>(furniture, random);
furniture.Sort(Utility.SortAllFurnitures);
}
}

private void ShuffleList<T>(List<T> list, Random random)
{
for (int current = list.Count - 1; current > 0; current--)
{
int num = random.Next(current + 1);
T temp = list[num];
list[num] = list[current];
list[current] = temp;
}
}
 

Attachments

Top