I’m converting a working Unity Windows game to a Windows 10 Store app. I’ve succeeded in building the app (after much hair pulling and code-compatibility changes for .Net Core), but after going through initial screens, main menus and starting a new game, it gets an error when trying to load the first level:
This error repeats many times, then the game crashes with null-refs because the assets didn’t load. The sharedassets5.assets file is there (I see it in the installed location).
The first level is large (sharedassets5.assets is 310.7mb). It did not get these errors when I changed out the first level for a small test-level with minimal content (sharedassets5.assets is 6.6mb), and in that case it loaded the level and I could play the level (move my character around, interact, etc.).
I’m only using AssetDatabase.LoadAssetAtPath() to load these assets. It all works for native Windows .EXE build.
There is one warning I get when building the app in Visual Studio (before creating the Store app), but I don’t know if it is relevant:
Anyone have any ideas about this?
One thought I had, because we had this issue on another platform, was maybe too many file handles are being left open. The game does load a lot of prefab data at run-time from share assets when loading a level. But we didn’t have that issue on the Windows EXE version.
Thank you for the reply and your suggestion. I turned of AV and it still behaved the same.
It actually successfully loads the scene with Application.LoadLevelAsync(mapName). Looking at my output more closely, it starts throwing the file errors after LoadLevelAsync completes and the co-routine yields, and before it resumes to continue initializing the level. We run it in a co-routine so we can update a progress bar at various points.
Below is a code excerpt with a comment added where it starts reporting errors. Note that sw is a StopWatch and CheckPCTemplates() is a debug check on the integrity of an array for a previous issue that was a solved (having to do with Type.GetFields behaving differently in .Net Core). SetPercent() is updating the progress bar.
//this does a non-blocking load and yields until the load is complete.
GUIManager.GetInstance().fader.SetPercent(25, "Async Loading New Scene");
yield return null;
CheckPCTemplates("PLM 8");
asyncOp = Application.LoadLevelAsync(mapName);
//GUIManager.GetInstance().fader.SetPercent(25+(int)(asyncOp.progress*10), "Loading New Scene");
//yield return asyncOp;
while ( !asyncOp.isDone )
{
GUIManager.GetInstance().fader.SetPercent(25+(int)(asyncOp.progress*20), "Loading New Scene");
yield return null;
}
CheckPCTemplates("PLM 8");
Debug.Log("Loading async done in "+sw.ElapsedMilliseconds+"ms");
sw.Reset();
sw.Start();
GUIManager.GetInstance().fader.SetPercent(45, "Loading New Scene Finished");
yield return null;
//************* HERE IS WHERE FILE ERRORS APPEAR IN LOG **********
Debug.Log("Async-Loaded new level "+mapName+" in "+sw.ElapsedMilliseconds+"ms");
sw.Reset();
sw.Start();
Here is the log output showing the last two output strings above with the errors in between, including an error I didn’t mention before about “Trying to reload asset but can’t find object on disk”:
So it seems to be happening on returning control to the system from the co-routine and while the system is trying to do some garbage collection.
Super weird, I’ve never seen anything like it. Is it an option for you to submit a bug report so we could look into the issue? Though, due to holidays we could probably look into it only after the new year.
Alternatively, you could use process monitor (Process Monitor - Sysinternals | Microsoft Learn) to see the syscall that’s failing and with what error. That might give some hints of what’s going on.
One other detail that may be relevant, is that we load an empty scene first before loading the real level-scene in order to clear out the old scene data, otherwise the two large scenes fill up memory and the 2nd scene won’t load. That is not so much an issue coming from the main menu, but it still does that anyway as it is just built into how levels are loaded in the level-loading co-routine. Here is that part of the code preceding the part I showed and overlapping the actual level-scene load call:
GUIManager.GetInstance().fader.SetPercent(10, "Async Loading Transition Scene");
AsyncOperation asyncOp = Application.LoadLevelAsync("EmptyScene");
yield return asyncOp;
CheckPCTemplates("PLM 6");
Debug.Log("load empty scene in "+sw.ElapsedMilliseconds+"ms");
sw.Reset();
sw.Start();
//unload unused assets.
GUIManager.GetInstance().fader.SetPercent(15, "Unloading Unused Assets");
yield return Resources.UnloadUnusedAssets();
CheckPCTemplates("PLM 7");
Debug.Log("Unloaded Unused Assets in "+sw.ElapsedMilliseconds+"ms");
sw.Reset();
sw.Start();
//this does a non-blocking load and yields until the load is complete.
GUIManager.GetInstance().fader.SetPercent(25, "Async Loading New Scene");
yield return null;
CheckPCTemplates("PLM 8");
asyncOp = Application.LoadLevelAsync(mapName);
Using the Process Monitor, one thing I noticed immediately is many “NAME NOT FOUND” results for file access with files that don’t exist in the game installation. These files have the base name of actual existing files, but with extensions like .res, .resG, .resS appended.
Actual Files that Exist
Non-existent Files with NAME NOT FOUND result
The typical pattern is file access to the existing file, followed by failed access to the non-existent variants noted above.
I’m still figuring out how to get a stack-trace with source, but I’ll post more info when I have it.
A good way to get stacktraces for these guys would be to create a new breakpoint in Visual Studio at “kernelbase.dll!CreateFileW”, right click it, and instead of making it break, make it print a callstack to visual studio output and continue instead. That way, whenever the process tries to open any file, you’ll get a stacktrace for it. If you run it as a 64-bit app, you should also be able to make it print the file name by specifying “{(wchar_t*)rcx}”, as on Windows 64-bit, that’s the register where the first parameter gets passed, and it points to the file path for that function. The full breakpoint “when hit” action would be this:
{(wchar_t*)rcx} $CALLSTACK
Note, this will probably make the game super slow, but will tell you all the places where files are opened.
Thank you for the tip. Unfortunately, when I try it, the breakpoint says it can’t find that function CreateFileW. The full name I specified was from your post: “kernelbase.dll!CreateFileW”. It doesn’t complain when I initially specify the breakpoint, but when I run the debugger it says it can’t find the method and therefore the breakpoint will not hit. FYI: I’m running from Visual Studio debugger. Previously I was building the app and running the app from my Wiondows 10 Start Menu.
Also, when I run from the debugger (as opposed to the built app) the game crashes earlier (when I click the opening movie to skip past it), so it never even gets to the main menu and the part where the previous file errors occurred. Furthermore, a crash dialog appears that says, “A debugger is attached to Wasteland2DirectordCut.exe but not configured to debug this unhandled exception. To debug this exception, detach the current debugger.”, and asks if I want to open a new debugger. The exception it reports is “An unhandled wind32 exception occurred in Wasteland2DirectorsCut.exe [16208].”
On further testing, I avoided clicking the intro-movie and let it play out and it gets to the color adjustment dialog (part of our game on first run after installation), and when I click on the accept button it crashes. So it seems to be any click input crashes. I tried again and clicked while on the initial launch/loading screen and it crashed there as well with exception [13212]. The same occurs when I try keyboard input (pressed right arrow key); but it reports a different exception number. None of these input crashes occur when running the built app from the Windows 10 Start Menu.
Below is the start of the debugger output log in case there is something informative to you. I’ve included up to the point where the games starts outputting information.
In the project settings, debugger tab, set debugging to “mixed mode”. That will make Visual Studio be able to actually debug the exception, rather than saying it is not configured to do so. It would be very helpful to see the callstack of the crash.
OK, that helped! It now finds the CreateFileW function and is reporting the stack (and is very slow, as you warned). However with no kernel symbols it looks like this:
How do I get symbols loaded for KernelBase?
BTW, I also switched to x86 mode just because I saw a MSDN web page that said Mixed mode is only supported in .Net Framework 4 or higher. Not sure if that applies to .Net Core.
So when if finally gets to the Color Adjustment Dialog and I click, it gets the exception and opens a dialog in the debugger, as well as a “No Symbols Loaded” page with instructions on how to find the symbols for UnityPlayer_UAP_x86.d.pdb. The exception information is:
If I browse to the .pdb then it lets me look at the disassembly (no source available), and it is stopped at 11200DA2 in the disassembly below (halfway down the excerpt):
So that seems to be a break-point I have set in the GUI code. Doh! I’ll try clearing all break-points on the next build, but if I just keep continuing through these (it repeats a couple times whenever I click for input), it eventually starts loading the first level of the new game. Then I hit assertion break-points for Invalid Texture formats (“Invalid texture format: 29” in (Filename: C:/buildslave/unity/build/Runtime/Graphics/TextureFormat.cpp Line: 38)) at 103CE60C (an error we’ve been ignoring and which is in the shipped game with Unity 5), and I just continue when it hits those (lots of those):
Then once it gets past all those the game exits. The debug log is attached as a file so you can see all the file access stacks, but I don’t know if they help without the source.
I switched back to x64 (as per your original instructions) and it had no problem with Mixed mode debugging. I also added the path to the .pdb files so it had more informative stack traces from the start. Most of the file access stack traces are for FMOD (for streaming music, I assume).
The Debug output is attached as a file.
Search for “Could not open file” to find the start of the file errors.
The code that the stack traces point to had multiple fixes in 5.3. I assume you’re on 5.2? Do you think it’s a lot of work to try building on 5.3 to see whether the same happens there?
You listed the same file twice. I’m guessing you wanted the .assets and .resource file sizes. Here they are:
12/15/2015 04:51 PM 172,604,540 resources.assets
12/15/2015 04:51 PM 1,421,085,760 resources.resource
And just in case, here is the listing of all the Data files:
I’m on Unity version 5.2.2.p2. I’ll try installing and building with 5.3.
Good news! I was able to load the first level! So I got past the file reading errors! Thanks!
However, there was an error in a shader when building in Unity that I ignored and I’m getting a lot of error spam during the level because of that. And none of my NPCs are spawning, which could be related to those errors as well. So I’ll try to fix the shader error. Here is the shader error that was reported by Unity Editor:
I also had an error about AssetBundle.CreateFromFile() method not found, but that just required a simple name change to LoadFromFile().
The runtime error spam that I believe is related to the shader error looks like this:
I’ll try fixing the shader and see if that clears things up. I’m not a shader expert though, so any suggestions there are appreciated.
Do you get such assets when running in the editor? If you run it through a debugger, do you get a stacktrace for the asserts when Mixed mode debugger is enabled? The spam should go away if you build it as release or master, as these asserts are only enabled in the debug build.
On Windows store, we compile the shaders twice: once for modern GPUs that run full DirectX 11, and once for either very old (pre-2009) or mobile GPUs that run DirectX 11 with feature level 9.x. It looks like the shader fails to compile on the d3d11_9x target, because it has too many instructions. It means that it will not load on weak/mobile hardware: it will probably fallback to something, depending on your setup. Since it’s a standard shader, it probably happens because your have specified more options than d3d11_9x can handle.
The NPCs not spawning was my fault. I forgot I had disabled them when investigating a previous issue. They are spawning fine now. I made a Release build and it seems to be working, except for some of the atlas textures (used by NGUI) are not displaying correctly (like bad UVs).
But the update to Unity 5.3.1 has fixed the resource-file reading errors, which was the subject of this thread. I’ll continue and post a new thread if I get stuck with the texture issue. Thanks for your help, Tautvydas!