RimWorld

RimWorld

Take It To Storage!
thailyn May 30, 2023 @ 12:43pm
NRE after deleting a "Take from" stockpile
Steps to recreate the error:

1) Set up a bill that takes from several specific stockpiles.
2) Delete one of those stockpiles. (The bill still says "Take from N...", where the number of stockpiles to take from still includes the deleted one.)
3) Save the game and load from that save.
4) With a pawn selected, right click on the building with the bill in question.
5) Dev mode off --> nothing happens (no right click menu appears). Dev mode on --> the below error occurs.

Root level exception in OnGUI(): System.NullReferenceException: Object reference not set to an instance of an object at HaulToBuilding.HaulToBuildingMod+<>c.<GetIngredients>b__9_1 (RimWorld.ISlotGroupParent parent) [0x00000] in <f1ad2440d88c460986ca61a6e7e39d05>:0 at System.Linq.Enumerable+SelectManySingleSelectorIterator`2[TSource,TResult].MoveNext () [0x00051] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 at System.Linq.Enumerable+WhereEnumerableIterator`1[TSource].MoveNext () [0x0004e] in <351e49e2a5bf4fd6beabb458ce2255f3>:0 at System.Collections.Generic.List`1[T].InsertRange (System.Int32 index, System.Collections.Generic.IEnumerable`1[T] collection) [0x000db] in <eae584ce26bc40229c1b1aa476bfa589>:0 at System.Collections.Generic.List`1[T].AddRange (System.Collections.Generic.IEnumerable`1[T] collection) [0x00000] in <eae584ce26bc40229c1b1aa476bfa589>:0 at HaulToBuilding.HaulToBuildingMod.GetIngredients (RimWorld.Bill bill, Verse.Pawn pawn, Verse.Thing billGiver, System.Collections.Generic.List`1[T] chosen, System.Collections.Generic.List`1[T] missingIngredients, System.Boolean& __result) [0x0009b] in <f1ad2440d88c460986ca61a6e7e39d05>:0 at (wrapper dynamic-method) RimWorld.WorkGiver_DoBill.RimWorld.WorkGiver_DoBill.TryFindBestBillIngredients_Patch5(RimWorld.Bill,Verse.Pawn,Verse.Thing,System.Collections.Generic.List`1<Verse.ThingCount>,System.Collections.Generic.List`1<Verse.IngredientCount>) at (wrapper dynamic-method) RimWorld.WorkGiver_DoBill.RimWorld.WorkGiver_DoBill.StartOrResumeBillJob_Patch0(RimWorld.WorkGiver_DoBill,Verse.Pawn,RimWorld.IBillGiver) at (wrapper dynamic-method) RimWorld.WorkGiver_DoBill.RimWorld.WorkGiver_DoBill.JobOnThing_Patch1(RimWorld.WorkGiver_DoBill,Verse.Pawn,Verse.Thing,bool) at (wrapper dynamic-method) RimWorld.WorkGiver_Scanner.RimWorld.WorkGiver_Scanner.HasJobOnThing_Patch2(RimWorld.WorkGiver_Scanner,Verse.Pawn,Verse.Thing,bool) at (wrapper dynamic-method) RimWorld.FloatMenuMakerMap.RimWorld.FloatMenuMakerMap.AddJobGiverWorkOrders_Patch4(UnityEngine.Vector3,Verse.Pawn,System.Collections.Generic.List`1<Verse.FloatMenuOption>,bool) at (wrapper dynamic-method) RimWorld.FloatMenuMakerMap.RimWorld.FloatMenuMakerMap.AddUndraftedOrders_Patch1(UnityEngine.Vector3,Verse.Pawn,System.Collections.Generic.List`1<Verse.FloatMenuOption>) at (wrapper dynamic-method) RimWorld.FloatMenuMakerMap.RimWorld.FloatMenuMakerMap.ChoicesAtFor_Patch5(UnityEngine.Vector3,Verse.Pawn,bool) at AchtungMod.MultiActions.AddColonist (AchtungMod.Colonist colonist) [0x0001f] in <959daf06d03b47519bd351efd48511c8>:0 at AchtungMod.MultiActions.<.ctor>b__3_0 (AchtungMod.Colonist colonist) [0x00000] in <959daf06d03b47519bd351efd48511c8>:0 at AchtungMod.Tools.Do[T] (System.Collections.Generic.IEnumerable`1[T] sequence, System.Action`1[T] action) [0x00014] in <959daf06d03b47519bd351efd48511c8>:0 at AchtungMod.MultiActions..ctor (System.Collections.Generic.IEnumerable`1[T] colonists, UnityEngine.Vector3 clickPos) [0x00018] in <959daf06d03b47519bd351efd48511c8>:0 at AchtungMod.Controller.MouseDown (UnityEngine.Vector3 pos) [0x00076] in <959daf06d03b47519bd351efd48511c8>:0 at AchtungMod.Controller.HandleEvents () [0x0002f] in <959daf06d03b47519bd351efd48511c8>:0 at AchtungMod.Selector_HandleMapClicks_Patch.Prefix () [0x00005] in <959daf06d03b47519bd351efd48511c8>:0 at (wrapper dynamic-method) RimWorld.Selector.RimWorld.Selector.HandleMapClicks_Patch3(RimWorld.Selector) at RimWorld.Selector.SelectorOnGUI () [0x00000] in <95de19971c5d40878d8742747904cdcd>:0 at RimWorld.MapInterface.HandleLowPriorityInput () [0x0000f] in <95de19971c5d40878d8742747904cdcd>:0 at (wrapper dynamic-method) RimWorld.UIRoot_Play.RimWorld.UIRoot_Play.UIRootOnGUI_Patch3(RimWorld.UIRoot_Play) at (wrapper dynamic-method) Verse.Root.Verse.Root.OnGUI_Patch2(Verse.Root) UnityEngine.StackTraceUtility:ExtractStackTrace () (wrapper dynamic-method) Verse.Log:Verse.Log.Error_Patch4 (string) (wrapper dynamic-method) Verse.Root:Verse.Root.OnGUI_Patch2 (Verse.Root)

I'm not sure if this requires Achtung! to be also installed or not, or is load-order dependent. However, I looked at the save file and noticed a very suspicious "null" stockpile in the list stockpiles to take from for the bill in question.

Example (I had created a temporary stockpile -- in addition to "Zone_4" -- to take from for a bill, then deleted the stockpile, so I had 4 "take from" sources for a while, then temporarily 5, then back down to 4 (though the bill still said there were 5)):

<htb_extraData> <storage>null</storage> <lookInStorage>null</lookInStorage> <takeFrom> <stockpiles> <li>Zone_4</li> <li>null</li> </stockpiles> <buildings> <li>Thing_LWM_NeoFabricHamper685459</li> <li>Thing_LWM_NeoFabricHamper685975</li> <li>Thing_LWM_NeoFabricHamper719918</li> </buildings> </takeFrom> </htb_extraData>

I'm presuming that, since the stockpile was deleted, its name is no longer available when saving the extra bill data, which causes a problem later on when trying to populate the float menu. As far as I can tell, the pawns are still able to work the bill correctly while this issue is present (though I can't right click on it to force them to work there).

A possible workaround to fix the issue in game by changing the setting to "Take from everywhere", then re-adding specific stockpiles that still exist (the now-deleted stockpile can not be directly removed, of course), but that is not a satisfactory solution, since that requires then reconstructing the list of acceptable stockpiles to take from.
Last edited by thailyn; May 30, 2023 @ 12:57pm