This is me putting experience to good use. Rather than write a whole new post, I'm just copying a section of the project documentation file I am writing alongside the development process. May it help someone avoid the torture I endured.
3.1 Milestone 1: Scene
Construction
3.1.1 Problem Analysis
When Silent Dreams had already
released The Dark Eye: Skilltree Saga on PC/Mac/Linux, and were preparing to
release to mobile platforms, we discovered a terrible, terrible thing. While
faster iOS devices could run the game, at least up to a certain point, slower
devices like the iPad Mini or Kindle Fire would crash immediately after the
splash screen. We tried different types of texture compression. No results. I
spent the next 4 weeks barely eating or sleeping, but coding and rebuilding
scenes day and night. I had to separate all the elements in the game scene and
load them individually to see where the crash was coming from. What made that
exceptionally difficult was that so many of those elements were referencing
each other. And, as I discovered, an object causing a crash didn’t even have to
be present in a scene. It just had to be referenced by an object in the scene
to cause the crash just by preloading. Even worse, if the offending object was
referenced by another object not present in the scene, but that object in turn
was referenced from within the scene, the preload crash would still happen. I
thought I was going to lose my mind.
I had to create a set of loading scripts
that loaded objects into the scene sequentially, and then assigned them their
references one at a time. It was gruelling. Then, I had to spend another week
debugging and looking for null reference exceptions. But, I did finally find
the offending object, nestled in a tree of references, and with the scene being
nearly empty to begin with, all test-devices had no problem starting the game.
3.1.2 Solution
Learning from my tortured past, the
first thing I built for Rocket Potato was a scene constructor. The scene begin
with the scene constructor being the only present object, and all necessary
elements are loaded sequentially. I’m using the yield return
StartCoroutine(LoadElement()); command to make sure no elements are loaded
until previous elements are done. I’ve even combined that process with a
loading screen complete with a loading bar that fills a little with each
element, and a text label above that bar that displays the scene constructor’s
current activity, kind of like we know from games like The Sims. This should
assure a clean loading process even slower devices can handle, and it will help
me pinpoint problem objects.
Here is a code snippet of the work in progress:
For those unfamiliar, coroutines in Unity3D are being used here to load single elements at a time. The yield return command means that the function is halted there and will not continue until the coroutine running returns. Using the yield command also ensures that the next step is put off until the next frame. This forces the game to assign at least 1 frame of time to each loading process. In the case of LoadRoomDecoration(), one frame per loaded scene object, additionally.