Welcome to the AFK Mods bug tracker. In order to report an issue, you need to have a VALIDATED account to post one. Once you have followed the link the registration email sent you, please select a project from the drop down menu below. Select “Open New Issue” and fill out the form with as many details as possible.

Please also consider sending your bug report to Bethesda if you are reporting on an issue with Skyrim Special Edition, Fallout 4, or Starfield. Doing so will help everyone on all platforms.

Issue Data
Status: Closed
Issue Type: Bug Report
Project: Unofficial Fallout 4 Patch
Component: Fallout 4: Vanilla
Category: Settlements & Workshops
Assigned To: Sclerocephalus
Platform: All
Severity: Low
Votes: 1
Watching: N/A
Opened By EyeDeck on Jul 8, 2020 5:01 am
Last Edited By Sclerocephalus on Nov 22, 2020 11:49 am
Closed By Sclerocephalus on Nov 24, 2020 7:56 pm
Resolution: Fixed
Comment: Fixed for UFO4P 2.1.2

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.

Comments

2 comment(s) [Closed]
Sclerocephalus said:
 
This should never have run for bAlreadyAssigned = true. Only if false, an actor will actually have been added to the workshop (ResetWorkshop doesn't remove any actors from the workshop, not even temporarily).

Checking for bAlreadyAssigned == false now before running the resource recalculation. In that case, we also don't have to care about RecalculateWorkshopResources() returning 'false' because it doesn't include any actors whose workshopID doesn't match.

EyeDeck said:
 
Oh, fair enough. bResetMode and bAlreadyAssigned are usually equal in most cases anyway, but I suppose checking bAlreadyAssigned makes more sense. I checked the rest of the game code and it looks like there are a few rare cases where a new actor is added with the bResetMode flag set for some reason, so that should fix that if it ever comes up.

Just to confirm that it works, since it's been a while since I submitted this, I haven't noticed a single instance of settler under/overcounting ever since I implemented my version of the fix in ~200 hours or so. Prior to it I'd notice that at least one settlement would be badly over-counted nearly every time I checked the map/pip-boy numbers in a while, so even my slightly imperfect fix was a huge improvement.

Showing Comments 1 - 2 of 2