Issue #29148: WorkshopParentScript.ResetWorkshop() can double-count population
So, WorkshopParentScript listens for OnLocationChange events on the player.
If a location that's switched to is a workshop, it will run ResetWorkshop on the workbench at that location (line 1050 in the vanilla version of the script).
ResetWorkshop() (line 2998) loops over all the actors at the settlement (3137), calling AddActorToWorkshop on most of them (3143).
Toward the end of AddActorToWorkshop(), we'll find this chunk of code (2008):
if !workshopRef.RecalculateWorkshopResources() wsTrace(" RecalculateWorkshopResources returned false - add population manually") ; add population manually if couldn't recalc ModifyResourceData(WorkshopRatings[WorkshopRatingPopulation].resourceValue, workshopRef, 1) endif
What this is doing is trying to run RecalculateWorkshopResources() on the local workshop to record the actor in the local WorkshopRatingPopulation AV.
If this succeeds, which it will if the player is at the workshop (see also #23496), it will run the native RecalculateResources() function on the workshop, which uses some engine-level code to quickly record local resources and save the resulting actor values to the local workbench.
If the player is not at the workshop, RecalculateWorkshopResources() will return false, and AddActorToWorkshop() will instead manually modify the WorkshopRatingPopulation on the workbench.
The issue here is that, when RecalculateWorkshopResources() succeeds, it records the full population of the settlement—or, at least the ones that are loaded. But, AddActorToWorkshop() is a long function, and it takes a while to call it on every settler at the settlement. If the player leaves the settlement before ResetWorkshop() finishes its loop over every settler, usually because they've fast travelled away, RecalculateWorkshopResources() will begin failing, and any remaining population at the settlement will be counted twice—one by the native RecalculateResources() when it worked, and again by the manual addition of points to the workbench AV.
I think the best fix for this is to just change this line (2821 in UFO4P v2.1.1)
if !workshopRef.RecalculateWorkshopResources()to read
if !bResetMode && !workshopRef.RecalculateWorkshopResources()
The reason for this is that ResetWorkshop() will have already called this function (line 3071 UFO4P 2.1.1) just before starting the loop that calls AddActorToWorkshop() on each actor, so it's pointless to try counting them again, but the function will still be able to "remotely" increment the population value for the many other places where AddActorToWorkshop() is called with the intention of adding a new actor.