Proper scenekit architecture for multi level/screen games - ios

I'm new to scenekit, so when I started my first project I noticed it's slightly different from spritekit. Although not ideal, I used to use 1 gameviewcontroller and 1 gamescene in spritekit to code my entire game. (YES, this includes a menu, game/levels, settings, etc...)
I'm now wondering since I'm using SCNScenes (which are just loaded from the viewcontroller), I do not want my 1 view controller to be swamped with code. What is the best way to layout a game? Should i have 1 viewcontroller per SCNScene? (switching to a different view controller for: main menu, game level 1, game level 2, game level 3, game over, settings, etc..)
This may not have been worded perfectly, but i appreciate the help!
Aidan

My typical layout for games with multiple levels, maps, interactive game play menus:
MainMenuVC
SelectLevelVC, SelectMapVC, etc.
GameVC (Hud, score, in-game menus), DefenseVC (like an overlay, choose weapon)
EndWaveVC, EndGameVC
GameControl() - Timers, array iteration, check wave completed, nextWave, cleanup, etc.
Data - shared instance (arrays, switches) for data shared between VC’s and game objects
BaseObjects such as (defenses, explosions, sounds, movement, targeting)
GameNodes (all node creation and storage, model loading, particle loading, camera, lights)
I landed here though many iterations. There are some tradeoffs, but by separating VC’s from data and scenekit things can stay pretty clean. It also enhances the ability to do threading and timers in only a few places when needed.
The sharedInstance of Data allows game objects to iterate through arrays to find targets and objects, such as a defense trying to find an enemy and vice versa. When game objects need to start talking to each other, this is usually where game design starts going off the tracks. So, I iterate loops via timers in GameControl, sharing Data, and that keeps it pretty clean. Since I’m doing loops in one place, I can avoid trampling other objects while they are updating and also get some clean measurements of timing and control FPS.
Hope that helps.

Related

FPS drop when adding child to a scene ARKit/SceneKit

I'm working on an ARKit project for 4 months now.
I noticed that when adding a child to my scene rootNode, there is a FPS drop. The device freezes for less than a second.
I did a lot of research and trials, noticed that all Apple's code examples have this FPS drop too when placing an object.
It does not matter if the node is added directly (scene.rootNode.addChild(child)) or if it's added in the renderer loop at different phases (didUpdateAtTime, didApplyAnimations etc...).
I found that once an object has been added to a scene, the next added object will render immediately. I use a 3D model created in SceneKit editor, clone it to generate my different nodes before adding them as child. I do this loading work before placing the objects.
Instruments shows that the renderer loop is busy for the duration of the freeze.
The only solution that I found is to add my nodes to the scene behind a loading screen before starting the whole experience.
Is that a normal behavior in game programming to render nodes before using them ?
Thanks guys
With the release of ARKit 3.0 and its satellite – RealityKit (framework with optimised rendering engine and changed scene's hierarchy, that was written in Swift hence it has no Objective-C binding), a drop-frame, when adding a child, is reduced to an imperceptible value.
And such a predictable behaviour of ARKit3/RealityKit ligament is especially true for devices with processors A12 Bionic and A13 Bionic manufactured on 7 nm process (and, of course, due to the fact they have last-gen neural engines and powerful GPUs).
For devices with a less powerful processors (A9, A10, A11), it is advisable to use 3D models with a total number of polygons of no more than 10K per model, and with usual shaders like .blinn or .phong (not PBR).
I believe it's quite a common practice for games and apps that use game engines, to firstly load (or cache) all the necessary game assets (like 3D models, textures, sound files, etc) into RAM before using them. For further details please read this article and this article.
However, it’s worth saying that AR games, unlike VR games, consume considerably more processing power, therefore they need to be carefully optimised. So, you're absolutely right, rendering nodes before using them and it's a normal behaviour in game programming.

Rendering a big grid with SpriteKit

I'm a total newcomer to SpriteKit and game development in general, I've been toying with SpriteKit to make a strategy game set in space.
My backend architecture use a grid system to represent the Universe, I have empty cases and cases with systems/planets/etc...
My grid is backed by GameplayKit GKGridGraph, I use an algorithm that generate a node with random properties for each node of the grid and I subclassed it to add a custom entity to it, which all the properties of this specific universe case.
To render it, I simply use SKShapeNode and SKPriteNode with various colors, shapes and textures.
I enumerate all nodes (GKGridGraphNode) in my GKGridGraph instance, and for each of those nodes I get generate the corresponding SKNode (my SKNode generations is a component of each GKGridGraphNode entity attached object), and I set them a position, and add them as a child to my main node (let's call it mapNode) which is a simple SKNode. In the end it looks like a grid.
It works well for a 30/30 grid, I have 60 FPS while scrolling my grid (custom implementation, I modify my mapNode positon as the user move his fingers).
But as soon as I try a 50/50 or a 100/100 grid, I have literally too many nodes on the screen for the scrolling to works. I know I shouldn't add every of my node on the screen, so I thought about various strategies and I wanted some input on them:
Instead of scrolling my mapNode, I could render only the nodes I see on the screen, and then add/remove nodes as the user scroll left/right/up/down. So it's not really scrolling anymore, it simulate it. I can think of it, but not really how I should implement it in practice. Is it the right solution?
Maybe I could render all my node as one big node? Is there a way to do that? But then I'll loose functions such as nodeAtPosition, which I use extensively to get the entity (custom object) associated with my nodes.
Edit: Actually, my current code is open source, here is the scene in I'm rendering: https://github.com/Dimillian/LittleOrion/blob/master/Little%20Orion/Little%20Orion/scenes/UniverseScene.swift
Is there any other smart way of doing that?
SKTileMapNode was made just for this in Xcode 8
https://www.raywenderlich.com/137216/whats-new-spritekit-ios-10-look-tile-maps
Alternatively, you would only want to load the nodes that are in and near your current view. You would need an algorithm to do this, and would be a big headache compared to tilemaps.
I suspect the algo would involve checking which nodes are in the view's .frame' and then using 'addChild' on them--concurrently, add a reference to them to an array, which you would check against nextupdate()andremoveFromParent` if they were no longer visible ..
It would get hairy trying to optimize this though. The goal would be to load only a few nodes out on each end so that way you have some buffer in moving the camera (less updates).
You could create a math function to pre-determine which nodes are where in relation to the current frame coordinates--so you don't have to iterate through the nodes--but that would require even a lot more work and headache--and it's what people developing on consoles, etc, have to do with high-end games and limited power.
I recommend skimming through a Direct3d/DirectX/OpenGL game development book, just to get an idea of what goes into everything... They aren't hard to find: walk into a bookstore and look for the thickest / heaviest book--that will be the DirectX game development book.
You will see how what we can do with 30 lines in SK requires thousands of lines and vector calculus in C++ and low-level AV frameworks. It will give you an appreciation, understanding, and perspective of game dev, which will help you in your SK journeys :)

How to create "fluid" or "squishy" bacteria-like nodes in swift

I'm currently designing a game in Swift and Spritekit that calls for bacteria-like graphics for the main player. I have no idea how to approach the physics and visual effects of a node like this. If you don't know what I'm talking about, here's a visual:
So basically the player is a circle/oval that can completely alter it's shape based on the surrounding structures.
I've tried this by creating a huge array of nodes strung together to create the larger structure, however this is extremely inefficient and lags the computer when I try to scale it up to multiple players. I also want to fudge this the least amount as possible since it requires realistic (or at least expected) physics of something like this with the ability to jump, move, slide, etc.
Thanks!

Split Screen 2 Player Local Multiplayer with SpriteKit

I want to make a 2 player mode, split screen style, like Tiny Wings HD did where each side of an iPad gets a flipped orientation screen of the current Level.
I wanted to also implement it on tvOS (without the flipped orientation) as I feel TV begs for this sort of gameplay as it's pretty classic to have this style of gameplay on TV (e.g. Mario Kart 64 or Goldeneye).
Over on the Apple Developer forum, someone suggested that it could be done as follows, but, there we're no other responses.
"You can have two views attached to the main window (add a subview in your viewcontroller). To both views you can present a copy of the scene. Then you can exchange game data between scenes via singletons."
I was looking for a more in-depth explanation as I don't exactly understand what the answer is saying.
I'd just like to be able to have two cameras both rendering the same scene but one focusing on player 1 and the other player 2.
Obviously this isn't a simple answer, so I don't expect a full in-depth tutorial.
Unfortunately I could find no info on this.
Has anyone tried this?
A sample project would be ideal or some documentation/links that might help.
I'm sure a demonstration of this would be valuable to quite a lot of people.
No Cameras involved or necessary
The players just look like they're moving along the x axis because the backgrounds are scrolling by. You can allow the players to move up & down on the y axis whether jumping, ducking, rolling or following a path like in Tiny Wings, but the player never leaves their x position. You can even have each half of the screen background scrolling at different speeds to represent that one player is moving faster than the other.
In your update method in you scene file you can scroll your backgrounds, and in your touches methods you can jump, duck etc the players
Instead of using an SKView to present an SKScene, you can use SKRenderer and MTKView. SKRenderer renders a scene into a Metal pipeline, which in turn can be presented by an MTView.
Crucially, you can decide if SKRenderer updates the scene, allowing you to render the same scene frame multiple times (possibly using different cameras).
So a pipeline might look like this:
Apple actually talk about this option in Choosing a SpriteKit Scene Renderer. There's also a section about using SKRenderer in Going Beyond 2D with SpriteKit from WWDC17 which is quite helpful. This answer also shows how to use SKRenderer (albeit in Objective-C).

How to optimize my memory usage with sprites...between SpriteFrameCache and SpriteBatchNode

I have seen the usage of plist and png atlasses for the game i am developing. However I've notice a slight performance swiftness(speed up) keeping the 60 fps, and for a side note my app has not crash at the moment.
The thing is I noticed I have used SpriteFrameCache with plist to do CCactions and animations for my characters(sprites). However some of the characters ive been using SpriteBatchnode, but it was on accident, since I am relatively new to deep development of a game, I didnt notice this difference before, they both work, but I feel like both are the same, its just that one has an easier way of implementation than the other, i was thinking that perhaps it was developed in an earlier version....
so my question is. is there a difference between the two? will my game benefit for using SpriteFrameCache over SpriteBatchNode?
Thanks for the help.
FYI: this doesnt slow down my developing, its just a question because I know at the end when my game is finished maybe i would want to optimize performance for my game.
Batch nodes draw all child sprites in one draw call.
Sprite frames hold a reference to a texture and define a region in the texture to draw from. The cache allows you to access sprite frames by name.
Both are different concepts, they are not replacements for each other. You can use sprite frames to create sprites or sprite frame animations. In addition to that sprite batching enables you to speed up rendering of two or more sprites using the same texture.
Note that if you use a batch node with only a single child sprite this will not be any different from rendering the sprite without the batch node, since both create a single draw call so there is no positive effect in using the batch node.

Resources