jptrrs / HumanResources

A technology overhaul for RimWorld
MIT License
17 stars 12 forks source link

Pawn frozen while trying to document a tech (& Exception) #143

Closed vsaulue closed 3 years ago

vsaulue commented 3 years ago

What's happening

A pawn attempts to document some spacer tech on a study bench, throwing exceptions. The game repeatedly tries to queue this invalid documentation task on every tick, leaving the pawn stuck doing nothing.

Main errors:

Exception ticking Gawen (at (158, 0, 169)): System.ArgumentNullException: Value cannot be null.
Parameter name: key
  at System.Collections.Generic.Dictionary`2[TKey,TValue].FindEntry (TKey key) [0x00008] in <567df3e0919241ba98db88bec4c6696f>:0 
  at System.Collections.Generic.Dictionary`2[TKey,TValue].TryGetValue (TKey key, TValue& value) [0x00000] in <567df3e0919241ba98db88bec4c6696f>:0 
  at Verse.GenCollection.TryGetValue[T,V] (System.Collections.Generic.IDictionary`2[TKey,TValue] dict, T key, V fallback) [0x00000] in <c36f9493c9844ddaa7fb5c788416098f>:0 
  at HumanResources.JobDriver_DocumentTech.TryMakePreToilReservations (System.Boolean errorOnFailed) [0x00043] in <d5067b80eea44b50b6f7403aed5bedbb>:0 
  at (wrapper dynamic-method) Verse.AI.Pawn_JobTracker.Verse.AI.Pawn_JobTracker.StartJob_Patch1(Verse.AI.Pawn_JobTracker,Verse.AI.Job,Verse.AI.JobCondition,Verse.AI.ThinkNode,bool,bool,Verse.ThinkTreeDef,System.Nullable`1<Verse.AI.JobTag>,bool,bool)
  at Verse.AI.Pawn_JobTracker.TryFindAndStartJob () [0x000bd] in <c36f9493c9844ddaa7fb5c788416098f>:0 
  at (wrapper dynamic-method) Verse.AI.Pawn_JobTracker.Verse.AI.Pawn_JobTracker.EndCurrentJob_Patch2(Verse.AI.Pawn_JobTracker,Verse.AI.JobCondition,bool,bool)
  at Verse.AI.Pawn_JobTracker.JobTrackerTick () [0x00151] in <c36f9493c9844ddaa7fb5c788416098f>:0 
  at Verse.Pawn.Tick () [0x00098] in <c36f9493c9844ddaa7fb5c788416098f>:0 
  at Verse.TickList.Tick () [0x0015c] in <c36f9493c9844ddaa7fb5c788416098f>:0 
Verse.Log:Error(String, Boolean)
Verse.TickList:Tick()
Verse.TickManager:Verse.TickManager.DoSingleTick_Patch2(TickManager)
Verse.TickManager:TickManagerUpdate()
Verse.Game:Verse.Game.UpdatePlay_Patch2(Game)
Verse.Root_Play:Update()

Gawen started 10 jobs in 10 ticks. List: (Wait_MaintainPosture (Job_13474288)) , (Wait_MaintainPosture (Job_13474290)) , (Wait_MaintainPosture (Job_13474292)) , (Wait_MaintainPosture (Job_13474294)) , (Wait_MaintainPosture (Job_13474296)) , (Wait_MaintainPosture (Job_13474298)) , (Wait_MaintainPosture (Job_13474300)) , (Wait_MaintainPosture (Job_13474305)) , (Wait_MaintainPosture (Job_13474308)) , (Wait_MaintainPosture (Job_13474310))  curDriver=JobDriver_WaitMaintainPosture (toilIndex=0) curJob=(Wait_MaintainPosture (Job_13474310))
Verse.Log:Error(String, Boolean)
Verse.AI.JobUtility:TryStartErrorRecoverJob(Pawn, String, Exception, JobDriver)
Verse.AI.Pawn_JobTracker:FinalizeTick()
Verse.AI.Pawn_JobTracker:JobTrackerTick()
Verse.Pawn:Tick()
Verse.TickList:Tick()
Verse.TickManager:Verse.TickManager.DoSingleTick_Patch2(TickManager)
Verse.TickManager:TickManagerUpdate()
Verse.Game:Verse.Game.UpdatePlay_Patch2(Game)
Verse.Root_Play:Update()

+ full log

Additional info:

Maybe related (same stacktrace): Error when documenting tech.

Steps to reproduce:

I've failed all my attempts at reproducing on a new lightly modded game. All I can do is upload my main savefile for now, which remains bugged.

jptrrs commented 3 years ago

Thanks for reporting and coming up with this detailed information on the error context. It was very helpful in understanding what was going on. Yes, this looks like a migration issue. It seems like your pawn was about to start to write that tech down when the file was saved, but after the update it can no longer be done at the regular study desk. You'd need a network terminal and a server. This nullifies the selected tech, causing the job to fail before it even started. I'll see if there's a way to prevent this from happening in the future, as there are other saving/loading situations that could cause the same deadlock. But as for your save file, the fix is pretty simple:

  1. Go to Options and turn on Development mode.
  2. Open the debug actions menu, on the fourth little icon that appear on the top of your screen.
  3. Search for "EndCurrentjob(InterruptForced)" and select that.
  4. Click on the affected pawn. On my tests, there were no residual issues.
vsaulue commented 3 years ago

Hi, thanks for the quick answer !

Your fix doesn't solve my issue: the game keeps trying to requeue the exact same job again. No worry for my savefile: for now I just removed the tech from the list of things to document.

After some further testing, it's not a migration issue. I was able to reproduce on a new game with Vanilla techs only.

Root cause

The bugged pawn:

From what I see in the source code and the savefiles: both the technologies to document, and the techologies to research ends up in the same "homework" list. It looks like this specific situation confuses the "document" workgiver/jobdriver...

Steps to reproduce (v2):

See: zipped savefile (it should throw the exception when loaded) full log

jptrrs commented 3 years ago

You're right! That set of projects on the homework was confusing the document WorkGiver. But it was just poorly equipped to handling the new bill filters. It's fixed, I'm updating the mod now.