SpriteKit Game Loading Screen (Not A Splash Screen) - ios

How do you know when to use a loading screen before the game starts? I'm not talking about the splash screen that shows up when you open the app. I'm talking about an actual loading screen (usually with like a loading bar) before the game starts or before the menu options show up? (Examples: Angry birds, Ultimate Briefcase, Clash of Clans) How do you know when you reach the threshold of the number of assets, audio files, etc that need a loading screen? Do you put it in the scene file? or somewhere else?
(This is in context of Xcode / Spritekit)
Sorry for all the questions. Just trying to understand and make my game better. Thanks for the help!

Answer: You shouldn't use a loading screen unless you absolutely have to. Don't use one just for the sake of using one. Use a loading screen if there is a genuine perceivable lag. To determine whether your game lags, benchmark and test your code through the worst scenarios (maximum number of sprites etc.) even if they are unlikely to occur. To understand what constitutes as a lag, the following question will be of great help:
What is the shortest perceivable application response delay?

Where and how you should load your assets is entirely up to you. You should decide that based on many factors, but generally it depends on what happens in your game and how do you handle your resources internally (when do you need resources, when do you release them from memory etc).
I remember that in Apple's Adventure example game (not available for download anymore) all of the shared resources was preloaded at the beginning of the game. Still, you don't have to do that. You can preload your resources when it is appropriate for your app, or maybe you want to release the resources while you are in the menu (or in some other scene than a gameplay scene).
There is nothing written (like in the docs or somewhere else) about when you should show loading screen, or even a rule that you must have a loading screen. The point of a loading screen is better user experience.
Personally, if you have to make a user to wait like 10 seconds before the game starts (which is rare actually), I would do two things there:
1) Show loading image (or something animated, like spinning animation)
2) Show hints or interesting facts about the game, like every 3 seconds (or whatever is an acceptable delay in this situation). This way, you introduce a player with the game while he waits, which is better than let them just wait and look at spinning animation.

Related

How much does iOS app size impact app launch latency?

I am guessing an iOS App's size has direct impact on its launch latency, since iOS needs to load the App into memory before launching it. If so, I wonder how much is the impact?
Let's say if I reduce my iOS app from 100M to 80M, how much launch latency improvement I can expect?
Does anyone has experience on this?
Consider that programming a faster App Launch experience is not bound to App Size at all. You could assume even the opposite because in some (i would even say in most) cases coding a faster launch process to start up can (and will) involve more code to make it a very short interaction interrupt experience and so your app size would increase without even delivering more valuable content.
In other words just because you deliver more dynamic or static content does not increase launch time unless you load and instanciate everything you need later on in your app life cycle in UIApplicationDelegate instead of allocating objects at the time of its use.
The same ideals apply to tear down processing (dealloc or saving app state user defaults) if needed. But this experience is usually not seen as a visible interruption of interaction with the device and so often forgotten to be part of the apps life cycle.
You can avoid this prolonged start up experience for users with clever use of LaunchScreen storyboards or similar techniques like partly buffered content for the first seconds. Some apps even take screenshots to be presented at the next start up to make the user feel the last app state is loaded already while building up the real interface.
A common mistake, which you may have seen also very often, is to make use of introduction videos or animations to bridge the time in waiting for the window/view to appear after app launch. So just making use of Launch Screens is never the best solution but a wise decision if the content that needs to be loaded first hand will take a noticeably longer time and can not be avoided.
LaunchScreens are just entertaining/informing about processing and keeping the user engaged while it can be beneficial what you and your app want to represent.
So abbreviated launch time is clearly a design pattern issue and is not bound to app size. Ok, apart from downloading band width if that is needed.

Architecture of a SceneKit game, multiple view controllers for menu screens?

I'm working on a SceneKit game using Swift, and I'm thinking about the best way to organize the various screens/ states surrounding the actual main game scene. I have a simple prototype which consists of three states:
Splash Screen (choose game type) ->
Game ->
Game over screen (choose to play again or return to splash)
In the prototype I opted to go for UIKit to do the UI elements, rather than a SpriteKit overlay. Although it's just buttons at the moment, which would be easy enough to do in SpriteKit, I might in future want to add sliders (eg an options screen to set control sensitivity etc), text entry etc, and then you end up recreating great chunks of uikit.
So at present, each of the 3 scenes described above has its own UIViewController. The Splash and Game ViewControllers have their own SCNViews and SCNScenes, and the GameOver is a modal that displays over the main Game scene.
This structure isn't really ideal, as it means that the main game SCNScene gets reloaded whenever the viewDidLoad of the GameViewController fires. The main SCNScene is quite detailed so takes a few seconds to load, and with repeated cycles this seems to create memory issues. After 2 cycles of Splash -> Game -> GameOver I get a memory warning, and after the third cycle Xcode loses the connection to the iPhone (which seems, in my experience, to be caused by memory issues).
I would like to have a main GameViewController that loads the most frequently reused assets once, but still be able to segue between the various menu screens.
So what are the options here?
I thought perhaps I could have a main GameViewController which controls the loading and unloading of SceneKit assets and has the sole SCNView. Its viewDidLoad method would only be fired once, when the app first starts. Then, each of the other views would have a very minimal UIViewController, which would be presented as modals over the main GameViewController, with "OverCurrentContext" selected.
I wanted to ask whether this pattern sounds feasible, and how others organise their SceneKit games. I'm still quite new to native iOS development, so it could be that I'm missing some basic game design pattern.
My Experience with the use of only one GameViewController (my current work for MAC OS X: i started a a 'small' 3D game with a MainMenu/start screen, a Hud and 2 or 3 complete different 3D Scenes - this shall be ported then to IOS, too):
In the last week i tried what you asked for, to use only one GameViewController for "all" that stuff - for me it seemed to be the easy and "good" way to do it - but even after lot of hours with all my tricks I've learned the last years i was not able to reload load another (or change) 3D scene (or even not another sprite kit scene hud) after a scenekit scene is loaded in a single ViewController.
Maybe there is difference between MAC OS X and IOS but i even tried this in an iOS version and it has the same behavior.
What i was able to do: You can modify a loaded 3D scene or change data in the sprite kit hud etc., so you are able to use one 3d scene to add or show the things up when they are needed but as far as my tests here showed, you will need one ViewController to show up a complete new different 3d scene or 2d/3d Menus etc. I will post my further experiences as soon as I'm a step further. i hope this helps a little.

iOS Launch Screen Animation Time

It seems like the fade animation between the launch screen and my first view is really slow.
I don't think it used to be like that. Is there a way to control the speed of that transitional animation?
I looked at some apps on my phone and the launch screen doesn't fade as slowly as mine. What things could I have done to affect that?
(No I don't have slow animations turned on, only the fade animation is slow)
In WWDC 2012 video iOS App Performance: Responsiveness they enumerate a whole list of issues that have impact on the app startup time, ranging from attaching to unnecessary frameworks, optional linking to frameworks that you really could make required, the use of static initializers, overly complicated initial scenes, too much information stored in preferences, etc.
That video covers a range of topics, like the above, which impact startup time. In the demonstration, they show how one might benchmark the startup time. Unfortunately, in my experience, there's a good chance that you might not be able to do anything to fix this issue (e.g. you need certain features and therefore need certain frameworks), but it's still an illuminating video and it might give you some ideas of things you can try to alleviate the start-up performance issues.
If your app splash screen show more time, so please check following things in your app.
1. AppDelegate.m
in didFinishLaunchingWithOptions method have you called any heavy method which takes more time for finish task if yes then change that method location, basically in appDelegate class don't write any heavy methods.
2. first view of your app.
check viewDidLoad() method, if you call many method or any heavy method from here then your launch image will show still your control not come out from viewDidLoad method, so if you want call any methods at view launch time then call them from viewWillAppear or viewDidAppear method (in viewDidAppear method don't call any UI related methods)
I never figured out what was going on here, but the next day when I started up xCode and the simulator it was back to the normal loading time.

Should my iOS game free memory at all when it enters background mode?

There are a couple of games that I want to mention, to show how they handle entering the background mode:
Clash of Clans. It seems it doesn't free any memory at all when it enters background mode, in fact I can open lightweight applications like Notes and get back to the game to continue playing without any noticeable delay, which seems pretty cool to me from the user's perspective.
Game of War. The game immediately falls back to the loading screen and the initialization process starts all over again when it runs inmediately after it enters background mode, it's just like restarting the game, which is very annoying sometimes.
So, in the case of my game, it has an average memory footprint of 25 mb (and it's going to be less with some optimisations), I know the "Free up as much memory as possible" stuff recommended in order to be a good neighbour on the iOS platform, but considering that freeing memory when the game enters background mode could cause my game to have an "annoying" pause when it enters foreground mode...
...should I save the progress and pause the game when entering background mode without freeing up any memory at all, or should I free as much memory as possible and load those resources again when entering foreground mode, with the respective loading pause?
As you yourself point out (by giving two games as examples that use opposite strategies), there is no unique answer to your question.
I think a proper answer can be worked out in a given case by clearly defining the use cases you want your app to support.
E.g., one use case, as you mention, could be "the user can switch to a lightweight app and go back to the game without unnecessary waits". (UC1) Then, you should also have a list of lightweight apps and reference devices where you want to make sure that the use case is actually satisfied.
On the other hand, you may want to support a slightly different use case: "the user will always come back to the point where she left the game, unless the app was terminated, in which case the app should present the main menu". (UC2)
In the first case, not freeing up could be the best approach; in the second case, you may want to minimise the chance that the app is terminated while the user does another task (lightweight or not), so that she can go back to the place where she left, even though she has to wait for all resources to load.
There might even be cases where an intermediate approach is best, where you free up only a part of memory, so to strike a balance.
And, of course, it would make no sense going for the first use case (UC1) if your app memory footprint is so large that it will be terminated almost immediately after switching to another app on most of the devices. In such case, it might make more sense freeing up memory, so you at least can spare the app load time (vs. resources load time) when you go back to it.
So, in the end, it depends...
I would save the progress and pause the game when entering the background without freeing up memory, as many people if they need the memory just delete it from the history thing, or the "carousel of cards". Multi tasking is emphasized in ios 7 so you don't want them to restart the game.
for example, somebody wants to text someone in the middle of playing your game. They exit the game and text someone. But then they have to load the game again. Nobody likes this.
While your game doesn't take up much memory, most users don't bother to close out of applications. I would recommend freeing up as much memory as possible without sending them back to the start menu, much like #sergio recommended with his 'intermediate' option.
I strongly suggest to free up memory. I have an iPhone 4, and some apps are now taking too much persistent memory, so that switching between them becomes a nightmare. E.g. recently, I could not switch between Safari and Twitter anymore, without them reloading all their state (taking more than 20 seconds in both directions).
Bottom line: Try to keep important state, but with as little memory as possible (i.e. not retaining images / textures), otherwise the app will get closed on older devices and you will effectively lose more state.
Save the progress and free the memory with the loading pause, especially if your game is for older devices. I have an iPhone 4, and when a game is running in the background without freeing memory, my foreground apps crash every 15 minutes. But if you have things such as "Vehicle/weapon upgrade is done in x minutes", you will need to save game progress and free the memory, so only the upgrade timer is running. If you do enough optimisations you may decrease the memory footprint, so I would recommend you to keep the optimisations in mind while coding and then the background performance will be your least problem.

Why is performing an event on iOS faster the second time around?

I don't have any hardcore data supporting this, but generally, you'll notice that any app you play with or one you're working on, when the app first loads, doing something such as displaying a modal view controller is slow the first time, but every subsequent time, it's really fast. For my app, when I present a modal view controller the first time, it takes about 3 seconds, but if I do it over and over again after that, it takes less than a second every time. What is the reason for this?
There's a bunch of possible explanations here.
Something's been cached. The first time, it had to load something from "disk," the second time it was already in memory. This could be an entire framework, or NIBs or graphic resources in the OS itself.
Memory management. iOS didn't have enough memory to satisfy the request the first time. iOS spent some time clearing out memory, possibly quitting background applications. The second time, it's already available.
Probably many others.
Caching. Off the top of my head, images are often cached, and I wouldn't be surprised if the nib was cached as well.
No, I don't notice this in my app. The cause of what you are seeing could be a hundred different things, so we need a bit more data to make an informed answer.
Suggest you run Instruments, narrow down the time window to the initial 3-second pause, then see what the machine is doing during that time. Run it multiple times and look at CPU, IO, memory, anything that could be slowing it down.

Resources