CivOne
CivOne copied to clipboard
Better recovery with problem icons (was Creating world: `The given key '1699' was not present in the dictionary.`)
After launching the game and choosing nation, number of AI, etc, the app crashes with this exception.
-
I suspect it's something to do with failing to load the original Civ art assets, but I don't see where to input the path to assets -- I think the app prompted for that once in the past, and I don't know where to change it.
-
If there is a known cause for this error, it would be good if the error message gave useful advice..
The error is in SetIcon
, trying to load data from LZW-compressed image file:
protected void SetIcon(char page, int col, int row)
{
if (_iconCache[(int)Type] == null)
{
---> _iconCache[(int)Type] = Resources[$"ICONPG{page}"][col * 160, row * 62, 160, 60]
.ColourReplace((byte)(GFX256 ? 253 : 15), 0);
}
Icon = _iconCache[(int)Type];
}
Unhandled Exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. ---> System.Collections.Generic.KeyNotFoundException:
The given key '1699' was not present in the dictionary.
at System.Collections.Generic.Dictionary`2.get_Item(TKey key)
at CivOne.IO.LZW.Decode(Byte[] input, Boolean clearEnd, Boolean flushDictionary, Int32 minBits, Int32 maxBits) in E:\proj\CivOneMaster\src\IO\LZW.cs:line 81
at CivOne.Graphics.ImageFormats.PicFile.DecodePicture(Int32& index, UInt32 length) in E:\proj\CivOneMaster\src\Graphics\ImageFormats\PicFile.cs:line 124
at CivOne.Graphics.ImageFormats.PicFile.ReadPictureX0(Int32& index) in E:\proj\CivOneMaster\src\Graphics\ImageFormats\PicFile.cs:line 138
at CivOne.Graphics.ImageFormats.PicFile..ctor(String filename) in E:\proj\CivOneMaster\src\Graphics\ImageFormats\PicFile.cs:line 333
at CivOne.Graphics.Resources.get_Item(String filename) in E:\proj\CivOneMaster\src\Graphics\Resources.cs:line 207
at CivOne.Units.BaseUnit.SetIcon(Char page, Int32 col, Int32 row) in E:\proj\CivOneMaster\src\Units\BaseUnit.cs:line 862
--- End of inner exception stack trace ---
at System.RuntimeTypeHandle.CreateInstance(RuntimeType type, Boolean publicOnly, Boolean wrapExceptions, Boolean& canBeCached, RuntimeMethodHandleInternal& ctor)
at System.RuntimeType.CreateInstanceSlow(Boolean publicOnly, Boolean wrapExceptions, Boolean skipCheckThis, Boolean fillCache)
at System.Activator.CreateInstance(Type type, Boolean nonPublic, Boolean wrapExceptions)
at CivOne.Reflect.GetTypes[T]()+MoveNext() in E:\proj\CivOneMaster\src\Reflect.cs:line 73
at System.Linq.OrderedEnumerable`1.TryGetFirst(Func`2 predicate, Boolean& found)
at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Func`2 predicate, Boolean& found)
at CivOne.SaveDataAdapter.GetUnitType(Byte typeId) in E:\proj\CivOneMaster\src\SaveDataAdapter.cs:line 27
at System.Linq.Enumerable.SelectIPartitionIterator`2.PreallocatingToArray(Int32 count)
at CivOne.SaveDataAdapter..ctor() in E:\proj\CivOneMaster\src\SaveDataAdapter.cs:line 330
at CivOne.Common.get_AllowSaveGame() in E:\proj\CivOneMaster\src\Common.cs:line 355
at CivOne.Screens.GamePlay..ctor() in E:\proj\CivOneMaster\src\Screens\GamePlay.cs:line 413
at CivOne.Screens.NewGame.HasUpdate(UInt32 gameTick) in E:\proj\CivOneMaster\src\Screens\NewGame.cs:line 238
at CivOne.RuntimeHandler.Update() in E:\proj\CivOneMaster\src\RuntimeHandler.cs:line 63
at CivOne.RuntimeHandler.OnUpdate(Object sender, UpdateEventArgs args) in E:\proj\CivOneMaster\src\RuntimeHandler.cs:line 93
at CivOne.GameWindow.Update(Object sender, EventArgs args) in E:\proj\CivOneMaster\runtime\sdl\src\GameWindow.cs:line 40
at CivOne.SDL.Window.Run() in E:\proj\CivOneMaster\runtime\sdl\src\SDL\Window.cs:line 96
at CivOne.Program.Main(String[] args) in E:\proj\CivOneMaster\runtime\sdl\src\Program.cs:line 89
I found that the original Civ assets are copied/stored in
C:\Users\[username]\AppData\Local\CivOne
and the data there seems fine, so the problem isn't that the assets are just missing.
I deleted C:\Users\[username]\AppData\Local\CivOne
and re-ran the app. It prompted me to copy data files from original source, which I did, and now the app works.
So the problem must have been that the data got corrupted somehow.
So, the request here is to catch the exception at a reasonable place
(maybe CivOne.Graphics.Resources.get_Item()
),
and offer troubleshooting advice: "Delete IRuntime.StorageDirectory
and restart app"
No, it's worse. The corruption happens every time I quit and restart the app.
So, if I delete AppData\Local\CivOne
and launch the app, it prompts to copy data files, copies, and starts the game.
The game plays fine, then I quit.
I run the app again: the new-game options (# of players, etc), the Customize World screen, and the Load Saved Game screen, all work fine.
But the game crashes when it tries to show the game map main screen where I interact with the units and cities.
So you're still having the same problem as per the original repo, issue #507 ? Does your workaround from that issue help this issue here?
Ha! You know me better than I know myself. I forgot about #507... And I was better set up for debugging back in 2020.
I'm on my phone now, but I'm confident the same workaround from then on Mac will work now on Windows.
(I'd still leave the issue open for a usability enhancement for handling corrupt data files.)
Oh, and it's also interesting that the bad ICONPGA.PIC
file is corrupt in CivOne but not in original Civ under DOSBox.
I'm curious if I have a different ICONPGA.PIC
from other people.
This is the file I have: https://drive.google.com/file/d/19uho8XdfgRxrE4Whpb7VXOZskmahFDml/view?usp=drivesdk
(I'd still leave the issue open for a usability enhancement for handling corrupt data files.)
Absolutely.
Here's my ICONPGA.PIC file. There is a 5 byte difference, starting at byte 5016, between mine and yours.