the Sim Settlements forums!

Register a free account today to become a member! Once signed in, you'll be able to participate on this site by adding your own topics and posts, as well as connect with other members through your own private inbox!

Question Wonky Food Production

TwoByteKitty

New Member
Messages
1
Hello!

I have noticed that since installing WSFW the number of settlers reported on my map is wrong (i.e., it will say 49 population when in fact the pop. is 16).

More importantly, farmers are claiming way more crops than they should. Two settlers assigned to farming will generate 29 food, for example. Whether or not I can assign new settlers to farming seems to be inconsistent.

WSFW was the most recent addition to my mod loadout when the problem started. I have also been experiencing random crashes when in the workshop build menu, but I am not sure that has anything to do with WSFW.

I'm fairly new to modding and FO4, so please let me know if there is any other info I should provide or this post belongs elsewhere.

Thanks for your time!
 
Okay, made some progress. I eventually coerced WSFW's version of WorkshopScript into compiling (not a trivial task), and got this in the log—less a stack dump from like 200 SS-related OnLoad events firing at once, and hundred-or-so lines of SS failing to None check stuff before trying to call code on it...
Code:
[07/08/2020 - 04:01:13AM] info: [workshopscript < (00135A90)>] setting Population value to 13.000000
stack:
    <unknown self>.debug.TraceStack() - "<native>" Line ?
    [ (00135A90)].workshopscript.SetValue() - "E:\Bethesda Softworks\Mod Organizer FO4\mods\WSFW Test\Scripts\Source\User\WorkshopScript.psc" Line 3509
    [WorkshopParent (0002058E)].workshopparentscript.SetResourceData() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\WorkshopParentScript.psc" Line 4245
    [WorkshopParent (0002058E)].workshopparentscript.ModifyResourceData() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\WorkshopParentScript.psc" Line 4226
    [WorkshopParent (0002058E)].workshopparentscript.AddActorToWorkshop() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\WorkshopParentScript.psc" Line 2631
   
[lines for 14—18 removed for brevity]

[07/08/2020 - 04:01:14AM] info: [workshopscript < (00135A90)>] setting Population value to 19.000000
stack:
    <unknown self>.debug.TraceStack() - "<native>" Line ?
    [ (00135A90)].workshopscript.SetValue() - "E:\Bethesda Softworks\Mod Organizer FO4\mods\WSFW Test\Scripts\Source\User\WorkshopScript.psc" Line 3509
    [WorkshopParent (0002058E)].workshopparentscript.SetResourceData() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\WorkshopParentScript.psc" Line 4245
    [WorkshopParent (0002058E)].workshopparentscript.ModifyResourceData() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\WorkshopParentScript.psc" Line 4226
    [WorkshopParent (0002058E)].workshopparentscript.AddActorToWorkshop() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\WorkshopParentScript.psc" Line 2631
   
    <truncated stack>
And the log decided to so "helpfully" truncate the stack so we have no idea what called it (sigh), so I had to try to catch the thread "in the act" in a save, and find it using ReSaver. Thankfully that was easier than expected.
Which immediately printed this to the log when the game unpaused after saving:
Code:
[07/08/2020 - 04:14:49AM] VM is freezing...
[07/08/2020 - 04:14:49AM] VM is frozen
[07/08/2020 - 04:14:50AM] Saving game...
[07/08/2020 - 04:14:51AM] VM is thawing...
[07/08/2020 - 04:14:51AM] info: [workshopscript < (00066EB6)>] setting Population value to 16.000000
stack:
    <unknown self>.debug.TraceStack() - "<native>" Line ?
    [ (00066EB6)].workshopscript.SetValue() - "E:\Bethesda Softworks\Mod Organizer FO4\mods\WSFW Test\Scripts\Source\User\WorkshopScript.psc" Line 3509
    [WorkshopParent (0002058E)].workshopparentscript.SetResourceData() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\WorkshopParentScript.psc" Line 4245
    [WorkshopParent (0002058E)].workshopparentscript.ModifyResourceData() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\WorkshopParentScript.psc" Line 4226
    [WorkshopParent (0002058E)].workshopparentscript.AddActorToWorkshop() - "C:\Program Files (x86)\Steam\steamapps\common\Fallout 4\Data\Scripts\Source\User\WorkshopParentScript.psc" Line 2631
   
    <truncated stack>
So, yep, we've got the right stack trace.

In the WSFW version of WorkshopParentScript, Actor.OnLocationChange() appears to have been last rewritten by Sclerocephalus of UFO4P—I recognize his code style—but the ResetWorkshop() call is vanilla code. Something to note here is that the OnLocationChange event is for the last workshop I was at, just before being teleported to the next station. So, leaving the workshop does not necessarily appear to be the culprit, since this ought to run either way.

On to ResetWorkshop...
Code:
function ResetWorkshop(WorkshopScript workshopRef)
[...]
    int i = 0
    while(i < maxIndex)
        Actor actorRef = WorkshopActors[i] as Actor
       
        if(actorRef)
            int iActorWorkshopID = WorkshopFramework:WorkshopFunctions.GetWorkshopID(actorRef)
            if(iActorWorkshopID == workshopID || iActorWorkshopID < 0)
                if(actorRef.IsDead())
                    WorkshopActors.Remove(i)
                    maxIndex -= 1
                   
                    ;Also need to update the loop index variable: with an actor removed, we need to check the same position again:
                    i -= 1
                else
[...]
                    if(CaravanActorAliases.Find(actorRef) < 0)
                        if(actorRef as WorkshopNPCScript)
====>                            AddActorToWorkshop(actorRef as WorkshopNPCScript, workshopRef, true, WorkshopActors)
                        else
                            WorkshopFramework:WorkshopFunctions.AddActorToWorkshop(actorRef, workshopRef, abResetMode = true)
                        endif
[...]
                    endif

                    ;Moved this block in here from an extra loop at the end of the vanilla ResetWorkshop function:
                    if(WorkshopFramework:WorkshopFunctions.IsNewSettler(actorRef) == true && WorkshopFramework:WorkshopFunctions.IsWorker(actorRef) == false)
                        if(CurrentNewSettlerCount == 0)
                            WorkshopNewSettler.ForceRefTo(actorRef)
                        else
                            WorkshopFramework:WorkshopFunctions.SetNewSettler(actorRef, false)
                            actorRef.EvaluatePackage()
                        endif
                       
                        CurrentNewSettlerCount += 1
                    endif
                endif
            endif
        else
            WorkshopActors.Remove(i)
            maxIndex -= 1
            i -= 1
        endif

        i += 1

    endWhile
[...]
...onto AddActorToWorkshop()
Code:
function AddActorToWorkshop(WorkshopNPCScript assignedActor, WorkshopScript workshopRef, bool bResetMode = false, ObjectReference[] WorkshopActors = NONE)
[...]
===>    if( ! workshopRef.RecalculateWorkshopResources())
        ; WSWF - Added if(assignedActor.bCountsForPopulation) to ensure it isn't increased when sending those NPCs
        if(assignedActor.bCountsForPopulation)
            ModifyResourceData(WorkshopRatings[WorkshopRatingPopulation].resourceValue, workshopRef, 1)
        endif
    endif

    if( ! bResetMode && bResetHappiness)
        ResetHappiness (workshopRef)
    endif
endFunction
AHA! Here's precisely where the bug is.

So, the game apparently decides to run AddActorToWorkshop on every actor in the settlement every time you visit it for some dumb reason. While this function is running, it repeatedly runs RecalculateWorkshopResources(), which in turn runs the native RecalculateResources() function on the workbench. RecalculateResources() records everything that's currently loaded in the settlement, including actor count.

If the player leaves the settlement, RecalculateWorkshopResources() will start returning false, and not running RecalculateResources(), because if it did, it would zero out resource values.

Now, imagine what happens if, say, the player enters a settlement with, say, 15 settlers. ResetWorkshop() makes its way through, say, two iterations of the while loop I copied up above. Population would be set to 15, then 15 again—but then, the player leaves the settlement! For the third settler, WorkshopParentScript incorrectly assumes that the actor hasn't already been counted, because RecalculateWorkshopResources() is refusing to do anything. So for the third settler, it increments WorkshopRatingPopulation to 16. Then for the fourth settler, 17...by the time the 15th settler is processed, the script will have recorded 28 settlers.

I'm actually not sure exactly the best way to go about fixing this, and it's going on 5 in the morning, so I don't want to try thinking too hard and maybe hurting myself at the moment. But, at least we know where the bug is now.
 
Sorry for the triple post (running into the 10k character limit lol), but here's a "formalized" UFO4P report: https://afktrack.afkmods.com/index.php?a=issues&i=29148
I think the fix is actually super simple, after I stared at the code a little harder, but I'd like if someone with more experience with this script (*ahem* @kinggath ) could take a look at it and see if there would be some side effects I haven't considered.

I think with this fix in place, the FixSettlerCount() workaround from WSFW could also safely be removed.

Edit: I've been playing with this tweak in place for a couple days and can confirm, no more weird settler numbers.
 
Last edited:
@EyeDeck I see you edited your post to say that the tweak worked. Can you post a git pull request with the tweak you want so I don't muck it up?
 
Sure, let me just remember how to use git. I noticed a few other miscellaneous (probably inconsequential) bugs that my nonstandard compiler picked out that I ought to fix too, while I'm at it.

Edit: Done.

Edit 2: While I was at it, since I haven't used git in years, I went ahead and published this neat little library I wrote a few days ago:
https://github.com/EyeDeck/AdvArrayLib
Check it out if you've got the time, you might find it useful.
 
Last edited:
On Jul 2 Kinggath said that he had solved the food issue, is there any info on if/when the fix was released? I started a new playthrough with SS2 yesterday and imported my usual Sanctuary blueprint (TSB.) which has plenty of vanilla crops and the one settler that turned up while the beacon was active was producing 30 food even before the Stranger had gotten me as far as building the 5 Residential and 5 Agricultural/Industrial plots.
 
I've seen this happen too - thought it was just Workshop Framework not playing nice with Plant Me (a planter mod I use), but I guess it's a Workshop Framework issue.

Also, sometimes with food objects that have different resource values, settlers will assign themselves sub-optimally. For example, if you have three 2-food objects and two 3-food objects that can be assigned, they sometimes auto-assign themselves to a 2-food object and a 3-food object, producing only 5 food total (they should assign themselves to two 3-food objects or three 2-food objects).
 
This is being looked at, yes. Kinggath is just swamped at the moment... :(
 
Top