Jump to content

How do you edit/fix a player inventory without loading save?

Go to solution Solved by Bumber,

Recommended Posts

I tried giving myself a generic tree cutting "fruittree-cutting", which crashed the game. Now the game crashes whenever I join my world. I tried doing a sqlite3 recovery, but that doesn't fix the issue.

Is there any way to get the block out of my inventory without loading the game? Or perhaps make the block not trigger a crash (e.g., JSON patching to fall back on an existing type?)

System.ArgumentNullException: Value cannot be null. (Parameter 'key')
   at System.Collections.Generic.Dictionary`2.FindValue(TKey key)
   at System.Collections.Generic.Dictionary`2.TryGetValue(TKey key, TValue& value)
   at Vintagestory.GameContent.BlockFruitTreeBranch.OnBeforeRender(ICoreClientAPI capi, ItemStack itemstack, EnumItemRenderTarget target, ItemRenderInfo& renderinfo) in VSSurvivalMod\Systems\FruitTree\BlockFruitTreeBranch.cs:line 140
   at Vintagestory.Client.NoObf.InventoryItemRenderer.GetItemStackRenderInfo(ClientMain game, ItemSlot inSlot, EnumItemRenderTarget target, Single dt) in VintagestoryLib\Client\Render\InventoryItemRenderer.cs:line 395
   at Vintagestory.Client.NoObf.InventoryItemRenderer.RenderItemstackToGui(ItemSlot inSlot, Double posX, Double posY, Double posZ, Single size, Int32 color, Single dt, Boolean shading, Boolean origRotate, Boolean showStackSize) in VintagestoryLib\Client\Render\InventoryItemRenderer.cs:line 197
   at Vintagestory.Client.NoObf.RenderAPIGame.RenderItemstackToGui(ItemSlot inSlot, Double posX, Double posY, Double posZ, Single size, Int32 color, Single dt, Boolean shading, Boolean rotate, Boolean showStackSize) in VintagestoryLib\Client\API\RenderAPIGame.cs:line 280
   at Vintagestory.API.Client.GuiElementItemSlotGridBase.RenderInteractiveElements(Single deltaTime) in VintagestoryApi\Client\UI\Elements\Impl\Interactive\Inventory\GuiElementItemSlotGridBase.cs:line 479
   at Vintagestory.API.Client.GuiComposer.Render(Single deltaTime) in VintagestoryApi\Client\UI\GuiComposer.cs:line 695
   at Vintagestory.API.Client.GuiDialog.OnRenderGUI(Single deltaTime) in VintagestoryApi\Client\UI\Dialog\GuiDialog.cs:line 375
   at Vintagestory.API.Client.HudElement.OnRenderGUI(Single deltaTime) in VintagestoryApi\Client\UI\HudElement.cs:line 30
   at Vintagestory.Client.NoObf.HudHotbar.OnRenderGUI(Single deltaTime) in VintagestoryLib\Client\Systems\Gui\Huds\HudHotbar.cs:line 571
   at Vintagestory.Client.NoObf.GuiManager.OnRenderFrameGUI(Single deltaTime) in VintagestoryLib\Client\Systems\Gui\GuiManager.cs:line 301
   at Vintagestory.API.Client.DummyRenderer.OnRenderFrame(Single deltaTime, EnumRenderStage stage) in VintagestoryApi\Client\API\IClientEventAPI.cs:line 82
   at Vintagestory.Client.NoObf.ClientEventManager.TriggerRenderStage(EnumRenderStage stage, Single dt) in VintagestoryLib\Client\Util\ClientEventManager.cs:line 191
   at Vintagestory.Client.NoObf.ClientMain.TriggerRenderStage(EnumRenderStage stage, Single dt) in VintagestoryLib\Client\ClientMain.cs:line 787
   at Vintagestory.Client.NoObf.ClientMain.RenderToDefaultFramebuffer(Single dt) in VintagestoryLib\Client\ClientMain.cs:line 965
   at Vintagestory.Client.GuiScreenRunningGame.RenderToDefaultFramebuffer(Single dt) in VintagestoryLib\Client\MainMenu\Screens\GuiScreenRunningGame.cs:line 241
   at Vintagestory.Client.ScreenManager.Render(Single dt) in VintagestoryLib\Client\ScreenManager.cs:line 668
   at Vintagestory.Client.ScreenManager.OnNewFrame(Single dt) in VintagestoryLib\Client\ScreenManager.cs:line 643
   at Vintagestory.Client.NoObf.ClientPlatformWindows.window_RenderFrame(FrameEventArgs e) in VintagestoryLib\Client\ClientPlatform\GameWindow.cs:line 76
   at OpenTK.Windowing.Desktop.GameWindow.Run()
   at Vintagestory.Client.ClientProgram.Start(ClientProgramArgs args, String[] rawArgs) in VintagestoryLib\Client\ClientProgram.cs:line 312
   at Vintagestory.Client.ClientProgram.<>c__DisplayClass9_0.<.ctor>b__1() in VintagestoryLib\Client\ClientProgram.cs:line 129
   at Vintagestory.ClientNative.CrashReporter.Start(ThreadStart start) in VintagestoryLib\Client\ClientPlatform\ClientNative\CrashReporter.cs:line 93


Edited by Bumber
Link to comment
Share on other sites

  • Solution

Figured out a solution. The gist of it was to use sqlite3 to select the "data" column from "playerdata" and output that to a file I could open in a hex editor. There was some data that included slashes ('/') followed by the word "hotbar", which I guessed was info about where to find the player's hotbar data in the save.

I opened the save file in a large hex editor and did a search for the data with slashes, which gave only 1 result. The hotbar data was a number 0-9 followed by some bytes until the next number. Empty slots aren't listed. I identified the slot with the bad item as the one right before the first empty slot (i.e., where a number is skipped.) I copied the previous slot's bytes over the one with the bad item. (I didn't delete the slot data in case doing so would have messed up other data.)

The save loaded successfully and I had two hotbar slots containing an identical stack of 2 firewood, confirming that the bad item had been overwritten by it. Hopefully this can be of use to someone else.

Link to comment
Share on other sites

  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.