Basically, I got an obscure case for PlayerPrefs getting wiped on Windows 10 builds. Basically, if you shut down a Windows 10 x86 device by pressing and holding the power button while the game is running, the PlayerPrefs for our game appears to be completely wiped.
This does not occur if I shutdown the device through start menu.
This does not occur if I restart the device through start menu.
This does not occur if the device sleeps or shuts down on low battery.
This does not occur if the device shuts down due to 0% battery.
This only seems to occur if you press and hold the power button on the device.
I wouldn’t shut a computer down this way. But I can’t say anyone who downloaded our game wouldn’t, and if they did they’d lose their save. The only problem is, this doesn’t seem to occur consistently. For instance, after the player prefs were wiped the first time, I attempted to create save data and force shut down again using the same build and the issue did not occur. To make matters worse, I couldn’t reproduce the issue with a build attached to a debugger in Visual Studio, so there are no logs/errors I can provide that show anything.
Easy questions to get out of the way:
Yes, I’ve made sure that I am indeed saving to PlayerPrefs correctly before the forced shutdown occurs.
This was made with a Windows 10 build made using Unity 5.4.3f1. It’s been confirmed to happen on older Unity 5 builds, such as 5.4.2, and even as far back as 5.2.4. This does not occur on our Unity 4 projects.
I tested this using a x86 Windows 10 laptop and an x86 Windows 10 tablet
I don’t even know if this is an “issue”. It’s hard to say if it’s an issue with Unity reading the PlayerPrefs file (maybe it has been corrupted because of the forced shutdown?), or if the file location for the data is somehow affected by the forced shutdown (something that the OS does, maybe going back to a previous state or something?). I don’t really know. Is this a problem anyone else can confirm?
EDIT: Maybe Windows has processes for handling safe app shut down on low/zero battery which is why it doesn’t get affected in that case? However, if this occurs on a hard shutdown from the power button, I imagine this problem has the potential to occur in cases where the device (such as a desktop PC) loses power completely (like during a power outage). If that’s the case, that’d be a bigger problem but I don’t really want to be plugging my computer in and out of the outlet to test that.
SkaarjSlayer, thank you so much for this bug report! We experience similar obscure savegame wipes and had no clue where to start looking.
We can confirm this behaviour for our game built with Unity 5.3.7f1 UWP
Windows 8.1 Pro Desktop 6.3.9600 Build 9600 x64
Windows 10 Home 10.0.14393 Build 14393
Windows 10 Pro 1607 Build 14393.447
using the hardware reset button. This does not occur if I the hardware power button is pressed as it shuts down cleanly (“Shutdown…” screen appears).
Unity 5.3.7f1 UWP
Microsoft Lumia 950 XL, Windows 10 Mobile 10.0.14393.448
when battery is removed
Cannot reproduce for:
Unity 5.3.4f1 Tizen
Samsung Tizen Z3, SM-Z300H, Tizen 2.4.03
Samsung Tizen Z2 SM-Z200F, Tizen 2.4.0.5
Unity 5.3.4f1 Android
Samsung Galaxy S4 GT-I9515, Android 5.0.1
when battery is removed.
Have you already filed a bug report?
Update2: Cant reproduce with Tizen and Android, so the OPs observation is right. Trying a minimal demo on Windows builds only.
I did some in-depth testing on a small demo app. The demo app checks if a PlayerPrefs exist and if there is none, it generates a 6 char random string and saves it into PlayerPrefs, otherwise the old string is displayed. There a two buttons which set a new string and save to PlayerPrefs respectively.
My test devices were:
520 - Nokia Lumia 520, Windows Phone 8.1
550 - Nokia Lumia 550, Windows Mobile 10
950 - Nokia Lumia 950 XL, Windows Mobile 10
Desktop - Desktop PC, Windows 8.1 Pro Desktop x64 [1]
Tizen - Samsung Tizen Z3, Tizen 2.4
Android - Samsung Galaxy S4, Android 5.0
When I just start the app and do absolutely nothing (no new strings, no saving):
520: removed battery 12x, no corruption
550: removed battery 8x, 1x corrupted
950: removed battery 12x, no corruption
I could more reliably reproduce the corruption when I press “save new string” + “save to PlayerPrefs” twice and then remove the battery immediately:
520: removed battery 7x, 3x corruptions, 1x old state restored(?)
550: removed battery 4x, 3x corruptions
950: removed battery 7x, 6x corruptions
Desktop: pressed hardware reset 6x, 5x corruptions, 1x old state restored(?)
Tizen: removed battery 7x, 6x old state restored
Android: removed battery 7x, 2x old states restored
The error message in debug console is usually “Data corruption detected while reading player prefs. CRC 0 != -1473662496”.
Update: tested on Unity 5.5.0f2 (the latest beta) with Desktop, pressed hardware reset button 5x, 5x corruptions.
[1] I recommend against doing this to often as Windows displays all kind of unhealthy error messages on reboot.
If I open the file
%USERPROFILE%\AppData\Local\Packages\UnityPlayerPrefsReset_pzq3xp76mxafg\LocalState\playerprefs.dat
before restarting the app I get a file of the same size (180 bytes in
this case) filled just with 0x00.
Another interesting observation: If you start the app on Desktop and
open the playerprefs.dat in parallel (in notepad for example) and press
save after you changed the string, it correctly appears in the file.
It’s only after you press hardware reset that the file is corrupt. But
the content was just correctly stored in the file.
Hey Gerold_Meisinger, thanks for doing some more in-depth testing. Glad to know I’m not the only one with this issue. I don’t have anything new to add, though. I’m hoping some of the Unity people may be able to confirm this issue and shed some light.
Same thing happens if you use File.WriteAllBytes (Windows Store only!). I get a file of the same size with all zeros, even though it was successfully written before reset.
We kinda got to the conclusion that the corruption part is indeed a bug on the player prefs side. I doubt we can give any guarantees for File.WriteAllBytes, though.
The old data getting rolled back on Android is expected - if the data doesn’t reach the storage drive in time before power gets cut off, there’s nothing we can do to preserve new data.
Can someone please create a simple native Windows Store app which writes a file three times with a different string and check if this is a native Windows error.
I just tested it in 5.5.1p3 and it’s even worse now. PlayerPrefs is already gone when save a string twice. Thus I cannot test if it’s gone when rebooting because it’s already gone when restarting. I also tested it in 5.5.0p3 and restarting works fine.
The fix in 5.5.1p3 actually fixed it when targeting windows 10 SDK, but windows phone 8.1 used a little bit different path which made it worse indeed. I made another fix which landed to 5.5.2p1 (it’s not released yet). Sorry about that.