3

I'm having the issue on a simple but fast-paced SpriteKit game, but I've reduced my code just to a bouncing ball and still get the issue to a lesser extent:

override func didMove(to view: SKView) {
    super.didMove(to: view)

    physicsWorld.contactDelegate = self
    physicsWorld.speed = 1
    physicsWorld.gravity = CGVector(dx: 0.0, dy: 0.0)

    let borderBody = SKPhysicsBody(edgeLoopFrom: self.frame)
    borderBody.friction = 0
    self.physicsBody = borderBody
    borderBody.contactTestBitMask = BallCategory

    addBall()
}

func addBall() {
    let size = CGSize(width: 20, height: 20)
    let position = CGPoint(x: frame.width / 2, y: 50)

    let texture = SKTexture(image: #imageLiteral(resourceName: "whiteCircle"))
    let ball = SKSpriteNode(texture: texture, size: size)
    ball.position = position
    ball.physicsBody = SKPhysicsBody(circleOfRadius: size.width / 2)
    ball.fillColor = .white
    ball.lineWidth = 0
    addStandardProperties(node: ball, name: "ball", z: 5, contactTest: 0, category: BallCategory)
    ball.physicsBody?.isDynamic = true
    addChild(ball)
    launchBall()
}

func addStandardProperties(node: SKNode, name: String, z: CGFloat, contactTest: UInt32, category: UInt32) {

    node.name = name
    node.zPosition = z
    node.physicsBody?.isDynamic = false
    node.physicsBody?.affectedByGravity = false
    node.physicsBody?.mass = 0
    node.physicsBody?.restitution = 1
    node.physicsBody?.friction = 0
    node.physicsBody?.linearDamping = 0
    node.physicsBody?.angularDamping = 0
    node.physicsBody?.angularVelocity = 0
    node.physicsBody?.contactTestBitMask = contactTest
    node.physicsBody?.categoryBitMask = category

}

func launchBall() {
    let ball = childNode(withName: "ball")!
    ball.physicsBody?.velocity = CGVector(dx: 0, dy: 500)
}

This code results in a ball (SKSpriteNode) bouncing up and down. When I run this, CPU usage starts at around 10% on my iPhone 6s and then after increases to around 25-30% after maybe 30-60 seconds (no idea why it's increasing). Throughout all of this, the frame rate stays very close to 60 FPS, usually going no lower than 58 FPS (it's the same way when I run the full game).

Almost any time an alert pops up (e.g., text messages, logging into Game Center, etc.), the lag shows up and shows up at random times when I'm running the full game.

I've also tried deleting and re-running the app, cleaning the project, deleting derived data and running in Release mode. None of these worked permanently.

Should I give up on SpriteKit and try another framework? If so, which? Cocos2D?

Any help is appreciated.

enter image description here

SuperCodeBrah
  • 2,874
  • 2
  • 19
  • 33
  • 2
    The real shame (and sham) is that Apple doesn't have sufficient love or consideration for games, gamers, gaming and game developers to prioritise and otherwise give preference to its own game engines. This is the kind of thing that makes it clear Apple still has its infamous (and decades long) disdain for games well and truly entrenched in its culture. – Confused Nov 15 '17 at 07:11
  • Just so we are clear, if I copy this code into a new example verbatim, I should expect to see jitters? – Knight0fDragon Nov 15 '17 at 14:50
  • btw, I am not sure if it is a good idea to set the mass to 0 (Although in this example you aren't applying any forces to it, so I am not making a claim that it could be causing the jitter, just something to think about when developing) – Knight0fDragon Nov 15 '17 at 14:55
  • Knight0fDragon, I didn’t create a new project with only that code (and can’t at the moment) but I did comment out just about everything in my existing code other than maybe the variable initializations. I ran that code on my iPhone 6s and although it was definitely more consistently smooth than the full code, I would eventually see jitters if I watched it. I was running this in an SKView that did not take up the whole scene but in terms of GameScene.swift, that’s pretty much all that was there. I can try running this in a fresh project this evening. – SuperCodeBrah Nov 15 '17 at 15:08
  • One other thing is that I also ran the scene without the bouncing ball. The overall CPU usage is lower, but it still followed the same pattern of ticking up from the initial usage. I believe it started around 5-6% and ticked up to ~15% similar to how the above code starts at about 10% and ticks up to 25-30%. – SuperCodeBrah Nov 15 '17 at 15:11
  • OK, if you can provide an example that we can copy and paste into a new project, we will be better able to assist you in solving this problem. For all we know, it may just be your phone. – Knight0fDragon Nov 15 '17 at 15:13
  • As I mentioned in one of the other comments, I don’t have this issue with the One More Brick game, but I’ll post something this evening. Thanks. – SuperCodeBrah Nov 15 '17 at 15:18
  • btw a velocity of 500 means you are moving 1250 points per frame (velocity is meters per second, 1 meter = 150 points, 1 second = 60 frame 500 * 150 / 60 = 1250) Are you sure your ball is just not moving at a super fast speed that your eye isnt catching it correctly, thus causing a jitter? (I am going to assume that you are using the default height of 1334) – Knight0fDragon Nov 15 '17 at 15:21
  • I actually changed the default size of the scene. I started with a Ray Wenderlich tutorial that had that as a step so my scene is smaller than the default. The ball is moving slightly fast but there’s definitely a difference between when it’s smooth and when it’s jittery. In the game, the ball speeds up over time and I’d say that it’s more likely to be jittery when faster, but can absolutely still be jittery when slower. I’ve shown the game to others and they agreed. Would a larger or smaller scene make a difference? – SuperCodeBrah Nov 15 '17 at 15:31
  • Wait....it speeds up overtime? Nothing here in the code suggests that. It should be moving at a constant velocity of 500 meters per second, if you made the scene smaller, then your ball will be bouncing more and more off of the walls, Your ball is moving so fast that if your scene height was 625 and the center of your ball was at the bottom of the screen and had a radius of 0.5, your ball would appear to always be in the same spot (In a perfect world of course, simulation adjustments and tweaks will ruin this effect) – Knight0fDragon Nov 15 '17 at 17:42
  • Set your velocity to 150/60 (1 meter / second converted to points per frame), that should allow your ball to move at about 1 point per fame, see if you notice any jitter. – Knight0fDragon Nov 15 '17 at 17:44
  • Just saw these last two comments. As is the ball is not really moving that fast, which makes me wonder if I missed something in the code I posted above and also makes me wonder if this might reveal the real problem. I think my scene is set to iPhone 6/7/8 dimensions, so it’s smaller than the default, which should exacerbate the speed issue that you’re talking about (yet the speed looks reasonable to me). I’ll try to post a full, brand new project to GitHub tonight. – SuperCodeBrah Nov 15 '17 at 19:34
  • 1
    You want to target your scene size to 1X sizes, and allow the retina display to handle the 2x and 3x. It makes your code a lot more simple. By default, Apple sets the scene size at a 2X display, which means in theory it is suppose scales the scene down to a 1X size, then use the retina graphics to scale back up to a 2X size. What actually goes on behind the scenes is a mystery. – Knight0fDragon Nov 15 '17 at 19:45
  • I think I mentioned elsewhere that the SKView is not the only thing in the view controller. In other words, the actual shape of the scene is not accurate to the shape of template scene because there are UIViews above and below the SKView. I wonder if this is causing issues with rendering and maybe some kind of translation has to be done with each frame (although I think I already tried setting the SKView to take up the entire view controller). If so, I’d think this could be easily fixed by adding the SKView programmatically. – SuperCodeBrah Nov 15 '17 at 20:01
  • 1
    The size of your SKView is irrelevent. Your SKScene should be a static size, and the system scales it to fit the view – Knight0fDragon Nov 15 '17 at 20:02
  • So does it really matter what size I set it to? I’m not actually adding anything in GameScene.sks - everything is added programmatically. – SuperCodeBrah Nov 15 '17 at 20:09
  • I think I figured it out. I copied the code into a new project and used the default view controller, which takes up the whole screen. The VC that I'd been using had the SKView only taking up part of the screen with separate views above and below it. When I switched to the whole screen VC, I stopped noticing the jitters. I thought this might have been the project itself (i.e., something corrupted in my original project) but when I added the old VC into my new project, the jitters came back. Also, when using the full screen, FPS is 60 in Xcode but it's 120 FPS when using the old VC. – SuperCodeBrah Nov 16 '17 at 01:29
  • I still see the occasional jitter, but the situation is much better. Additionally, I was toying around with the update function and noticed that the position of the ball was being updated in line with the time delta. For example, if the time delta was 1/60 and the ball moved by 2, a time delta of 1/30 would result in a movement of 4. If I followed the earlier conversation correctly, it was not expected that this was happening. – SuperCodeBrah Nov 16 '17 at 01:32
  • These two comments were slightly off base. I posted an answer. Thanks to both of you for your comments. They were helpful in getting a better understanding of how SpriteKit/game engines work. – SuperCodeBrah Nov 16 '17 at 02:35

2 Answers2

2

This is the result of Apple prioritising system calls over just about everything else.

When the system wants to know something, check something or otherwise do its thing it does so at the mercy of everything else.

No other engine will be able to help with this, there's no way to silence the system's constant activities through code.

You can get a slight improvement by putting on Flight Mode and turning off WIFI and Bluetooth. The system seems to be somewhat aware that it's in a quieter mode and does less because it's got no 4G or other connectivity it can go communicating with.

Further, there's been some pretty big changes to palm rejection in iOS 11 that's played havoc with the first round of iPad Pro models and creative software, creating multi-second rejection of all touch input. When this kind of thing can make it through to a GM you can be pretty sure they're slipping other messiness through.

Here's some complaints about iOS 11 performance: https://www.macrumors.com/2017/09/25/ios-11-app-slowdowns-performance-issues/

Confused
  • 6,048
  • 6
  • 34
  • 75
  • There’s a game that I downloaded a while ago, One More Brick, that also uses bouncing balls, as many as several hundred on the screen at once, and shows virtually no lag (https://itunes.apple.com/us/app/one-more-brick/id1084813529?mt=8). I’m wondering if my issue could be solved with a fixed time step game engine. – SuperCodeBrah Nov 15 '17 at 14:19
  • "virtually no lag" can be made appear to be the case by a physics engine interpolates well when it does get a snag in frame rate, so... yes and no. You still need a physics engine and/or particle engine that's able to do this. – Confused Nov 15 '17 at 14:32
  • That’s helpful. Can you recommend such an engine? I’ve messed around with the update function in SpriteKit, but am struggling to make things any smoother. If SpriteKit can’t do this, then it seems basically useless. – SuperCodeBrah Nov 15 '17 at 14:42
  • I do not think this is an issue with the system, Apple does a fair job with giving priority to the main app. The major issue with iOS 11 apps crashing is the apps are dependent on the iOS framework for its library calls, it is not built into the binary itself, When Apple fixes (and introduces) bugs, it ends up causing the apps to crash because developers did not develop the app in the safest way possible, not that they should. (E.g. manually setting default values of all the variables of an object since Apple loves changing these values with each iteration) – Knight0fDragon Nov 15 '17 at 15:00
  • What you've said, @Knight0fDragon is also true. But the greater problem is the constant pinging and system calls taking the priority. When you do physics testing of fast movement, it's VERY obvious, ALL THE TIME, and incredibly annoying. See how Nintendo manages far less resources in a far more respectful manner for games, as does Sony and Xbox... xbox to a lesser extent than the others, but nothing is as bad as iOS. Android is so far worse it's not worth talking about. – Confused Nov 15 '17 at 15:17
  • @SuperCodeBrah all physics engines SHOULD be capable of compensating for a missed frame, or lots of missed frames. The problem comes from how they're incorporated and the tick checked and monitored for missed frames, and then compensated for. Which is down to individual engines. Unreal Engine, for example, does a brilliant job of dealing with this in a multitude of situations, as it's gotta deal with the issues of network latency and missing frames for high speed games. But it's not good on iOS. Too big, too heavy. – Confused Nov 15 '17 at 15:21
  • And then there's the problem of initiatives. It's only really arcade, simulations and physics based game developers that look super closely at these problems. Most of the popular game engines are designed from a simplistic view of what constitutes a game without worrying about integrity of the simulation. For the longest time developers used to say that there was no human perceptible difference from 30fps to 60fps. This is obviously nonsense, but because they only ever played the type of games where this wasn't an issue, they couldn't see it. RPG and Strategy games aren't big on dynamic fast! – Confused Nov 15 '17 at 15:23
  • @SuperCodeBrah if you roll-your-own cocos2D with Chipmunk, you can get a very smooth compensation for missed frames, as these two were, for a while, made to go together quite well. But you'll probably have to make some sort of checking system to see if the frames have been drawn. The simplest way is to have delta time rule over game objects you care about... – Confused Nov 15 '17 at 15:27
  • There wasn't a real perceptible difference between 30 and 60 at the time because it was discussed via a visual context. As development evolved, developers and designers started understanding that input lag is what started giving us the ability to recognize the difference. Our brains are capable of picking up these responses at a much higher rate than we can visually see them, which is why 120hz gaming is becoming a very important thing now. – Knight0fDragon Nov 15 '17 at 15:28
  • This is patently untrue, @Knight0fDragon, and has been a known issue since at least the 1960's. You're listening to only the materials in the field you're interested in and ignoring the rest of the world's research on these things... and ignoring the entire LAN gaming movement of the 1990's, too. – Confused Nov 15 '17 at 15:30
  • @Knight0fDragon, more importantly, do you know how to force SpriteKit to use (and respect) delta time movement for physics objects? This doesn't solve the problem of hiccups, but does at least provide the use of the correct trajectory without stutters. – Confused Nov 15 '17 at 15:31
  • ... no, you are just adding in unnecessary data that is beyond the scope of the argument here. LAN was about latency issues, different argument then how fast a person can perceive change – Knight0fDragon Nov 15 '17 at 15:34
  • the physics objects only works on delta time, The problem is due to limited powers of the CPU, accuracy is dropped for speed – Knight0fDragon Nov 15 '17 at 15:36
  • Thank you both for the discussion. Just to reiterate from the original question, if I track the frame rates in Instruments, either with the full code or the segment above, I get something like 60, 59, 60, 60, 59... I know that there is averaging taking place, but frame rate seems to stay high. – SuperCodeBrah Nov 15 '17 at 15:38
  • No, the LAN gaming movement was ALSO obsessed with frame rate. Please, check yourself, you're wrong about the priority of game frame rates and games. Solo games, too. Don't just assume you know what you're talking about, there was an entire industry making high refresh rate monitors for this exact reason during the 1990s. See Sony quarterly reports to see how profitable it was. – Confused Nov 15 '17 at 15:39
  • @SuperCodeBrah, Once I see this in action, i will be better able to assist you, i really think your eyes are just playing tricks on you because of how fast the ball is moving. – Knight0fDragon Nov 15 '17 at 15:39
  • The problem is making the game RESPECT delta time in the physics. There is a way to force this in Sprite Kit, I think, but it's relatively new and not something anyone has paid much attention to because almost nobody uses SpriteKit and all are self appointed experts. – Confused Nov 15 '17 at 15:40
  • No, @Knight0fDragon, many naturally talented sports people, sim enthusiasts and all sorts of high speed game lovers can perceive VERY small changes in frame rates and all sorts of inconsistencies in movements. Not everyone can do this, for those of us that can we're amazed that others can't, just as you're amazed that others can. – Confused Nov 15 '17 at 15:41
  • I’ve also noticed that my scene frame rate will stay around 60 FPS, but in the debug navigator in Xcode, it says my frame rate is a consistent 120. I’m wondering if there are additional resources being used on the containing view controller. Here’s a screen of the debug navigator: https://i.stack.imgur.com/Drcas.png – SuperCodeBrah Nov 15 '17 at 15:42
  • High refresh monitors have nothing to do with LAN, back in the 90s nic speeds were too slow to even be capable of maintaining a 60fps frame rate. High refresh monitors are important because of input lag, The problem was when you push a key on the keyboard, you noticed that tiny delay that changed on the monitor. This is a lot different then watching say a movie. You have no idea what you are talking about and are combining too many gaming problems together to fit your needs. – Knight0fDragon Nov 15 '17 at 15:43
  • @SuperCodeBrah the best solution isn't one... it's to not draw the skipped positions that were missed in any trajectory, to move to drawing position based on delta time. Whilst SpriteKit uses delta time for somethings internally, the last time I used it there were obvious situations where it was drawing "old" frame positions and not checking to make sure it was deltatime accurate for fast moving objects. – Confused Nov 15 '17 at 15:43
  • Yes, a small percentage of people can perceive higher framerates, again this is not the argument here. – Knight0fDragon Nov 15 '17 at 15:44
  • @Knight0fDragon I just said SOLO games, too. Nevermind. You can't be convinced and have wrong beliefs and ideas about games and their responsiveness. It's ok. I'll wait for you to realise that twitch gamers were enjoying high refresh rates long before you knew why. – Confused Nov 15 '17 at 15:44
  • Whatever, you can go live in your world of misinformation, after all, it explains your name lol – Knight0fDragon Nov 15 '17 at 15:45
  • @Knight0fDragon the perception between 30 and 60fps capacity is quite strong in MOST people. Sensitivity to changes at 60fps is also the majority for any isolated, obvious, focusable movement. Study saccades, pursuit and fixation for a while, you'll see that there's a body of science around this stuff... and a very good set of reasons that Apple focused on Core Animation and 60fps for the iPhone interface... FROM THE BEGINNING! – Confused Nov 15 '17 at 15:46
  • Again, we're talking about perception and prediction, with regards presented content and the need to input dynamic responses. These are things that humans are VERY good at, in the majority. If you're not, you won't even know what we're talking about because you simply can't do it and have never felt what we're talking about to be a problem. If you don't perceive much difference between 30fps and 60fps, you're in the minority. @Knight0fDragon – Confused Nov 15 '17 at 15:48
  • Frame rate and its accuracy is such an issue, even between 60 and 120fps, that Apple's deemed it a sufficient priority to make the new iPad Pros run at 120fps for most scrolling content, and most journalists even notice the difference. Input lag, the thing you'll probably bring up next, is something that humans compensate for in a remarkably short space of time, naturally, subconsciously. Some drummers, for example, have been demonstrated being able to detect and predict for lags as low as 4ms. There are entire fields of research around this for the benefit of multiple different industries. – Confused Nov 15 '17 at 15:52
  • Okay, when I previously switched preferredFrameRate to 30, I noticed a huge difference for the worse. Is this indicative of anything in and of itself? – SuperCodeBrah Nov 15 '17 at 15:52
  • at 30fps, when there is a stutter, the difference in where your mind predicts the object should be and where it's actually drawn are physically twice as far apart as they are at 60fps. And, unfortunately, those system calls are so heavy that they cause 30fps games to have these stutters, too. @SuperCodeBrah – Confused Nov 15 '17 at 15:54
  • Just to get back on track, the only real "solver" is to force respect and reverence of deltatime. You might have to do a lot of research to find out if it's even possible to get SpriteKit to draw according to this rather than whatever it's doing that makes stutters so obviously obvious. – Confused Nov 15 '17 at 15:56
  • we need to stop before we get flagged, you need to go back to the top of my comments and just keep looping if you want to keep argueing – Knight0fDragon Nov 15 '17 at 15:57
  • Yeah, you've been wrong since then... I see you're stubbornly holding onto your delusions, and have given you the key words you need to do your own research. You'll find a lot more is known about this than you know... a bit of a Dunning-Kruger-ish moment for you ;) @Knight0fDragon – Confused Nov 15 '17 at 15:58
  • See previous comment – Knight0fDragon Nov 15 '17 at 16:04
  • Confused, do you have anymore information on the delta time issue? I’ve read about trying to address this in the update function but I haven’t gotten a good implementation so far. I tried to change ball.position (didn’t work based on print statements of the ball’s position). I think I tried SKAction.move(to:) based on the velocity and frame rate but that didn’t seem to work and I’d think that’s an expensive operation. I tried velocity only to have the ball fly everywhere after a collision. I could maybe try SKAction again, but are you aware of other methods? – SuperCodeBrah Nov 15 '17 at 16:09
  • Here is a very smart guy finding similar issues in a different way: https://gamedev.stackexchange.com/questions/150748/surprisingly-in-spritekit-game-engine-deltatime-is-not-frame-time @SuperCodeBrah – Confused Nov 15 '17 at 16:15
  • To do this "right" in an environment of very uncertain frame rendering issues, the need is for every frame to (before anything else) check when the last frame was rendered. If everything was as it should be, then all is fine and the game engine can go on as normal. The moment it's discovered a frame(s) have been missed, the engine should start working out when the next frame is due to be drawn and using delta time calculations to predict where objects should be at that time. The problem shown in @fattie's question is that delta time isn't linked to frame time. So need to use CADisplayLink – Confused Nov 15 '17 at 16:20
  • And there's a problem with CADisplayLink, too, where it would adjust itself according to what the system considered to be the current load, and "throttle" frame rates to 40, 30, 15 and a bunch of other numbers, and report those times rather than always 60fps. This problem existed for at least 4 years that I know of. But I'm not sure if it was fixed with the release of 120hz iPads, or was an initiative in preparation for variable frame rate screens. I've always believed it was the latter. So it's probably a "feature", not a bug. – Confused Nov 15 '17 at 16:22
  • I can’t dig into that link at the moment, but would I likely save myself time and frustration by implementing Cocos2D? I would have already done this but I didn’t want to spend possibly multiple days on it only to face the same problem. – SuperCodeBrah Nov 15 '17 at 16:26
  • I also don’t know objective C but I really want to make this game. – SuperCodeBrah Nov 15 '17 at 16:27
  • In that question, fattie thought deltaTime was the time between frames, he was just confused with terminology. He wanted time changed since last frame, not overall time change. He posted that question here on SO somewhere too and I discussed it with him. – Knight0fDragon Nov 15 '17 at 16:28
  • As to your physics question, I do not understand what you are asking. The physicsbody respects delta time, the problem is it doesnt accurately compensate for the differences between the change in time (Thus you could potentially go through an object with enough lag) This is because it is designed to work fast, not accurate. You will almost never see physics kit do anything accurate unless apple decides to somehow utilize the GPU (or maybe add a special GPU core for physics) to do the physics math. – Knight0fDragon Nov 15 '17 at 16:29
  • Not sure what your talking about with CADisplayLink, it works kind of like VSync, so if you are seeing it throttle, then something is causing the refresh to be delayed – Knight0fDragon Nov 15 '17 at 16:33
  • Just to let you guys know, SpriteKit does not work in a fixed update pattern what so ever, There is no frame dropping or frame skipping needed on your end (The system technically does this for us on the back end) You do however need to compensate for the change in time if you are manually making changes. Both SKActions and PhysicsKit already go off of the time difference between updates. – Knight0fDragon Nov 15 '17 at 16:41
  • PhysicsKit is making the stutters he's seeing by not predicting when the next frame will be drawn relative to the last drawn frame precisely because Apple is doing something fishy with CADisplayLink that permits them to throttle the frame rate. @Knight0fDragon There is quite a long answer of mine that talks about why they might be doing this, from the links here: https://stackoverflow.com/questions/42012120/scenekit-drops-to-40-fps – Confused Nov 15 '17 at 16:45
  • So in direct opposition to your claim, @Knight0fDragon, that no frame dropping or frame skipping compensation is required on our end... you are wrong. Because of the above it is required to find a way to force SpriteKit to revere delta time, or manage it by ones self... with the caveat being that because iOS does arbitrary throttling that it doesn't report, you need to make allowances for the results of polling CADisplayLink being different rates for reasons you can't get information about... just need be prepared for. It's not always going to give 60fps time stamps of when rendering. – Confused Nov 15 '17 at 16:48
  • Knight0fDragon, are you implying that using SKAction.move with a zero duration within the update function won’t work because it’s still time dependent? If so, how else might I compensate for time? – SuperCodeBrah Nov 15 '17 at 16:50
  • the delta time does not go off of CADisplayLink, and if CADisplayLink refesh is lagging behind, then the system handles the actual frame skipping, nothing you can do will make it any faster. You need to compensate for the time difference provided by the update – Knight0fDragon Nov 15 '17 at 16:53
  • 1
    @SuperCodeBrah a zero duration would fire and finish during the same update cycle it was created on – Knight0fDragon Nov 15 '17 at 16:54
  • To my earlier question, does it make sense that this is fully a frame rate issue given that FPS consistently shows as 59-60? Also, any idea why XCode shows 120 FPS when on that view controller while other view controllers show 60 FPS? – SuperCodeBrah Nov 15 '17 at 16:54
  • @Knight0fDragon you've missed the point. One needs to know when the next frame will be rendered, which is reported by CADisplayLink, and it VARIES. The other part you got right, yes a compensation mechanism needs to be made to cope with changes in this reported rate. – Confused Nov 15 '17 at 16:55
  • if it is showing 120 then it is lying to you, the only device capable of 120 is the newest iPad, and you need to add something to the plist to make it 120 capable (Unless this changed in the newest iOS, you have to ask Confused about that) – Knight0fDragon Nov 15 '17 at 16:55
  • @Confused, this library is not set up to predict the future, you only work in the present. – Knight0fDragon Nov 15 '17 at 16:58
  • 1
    @Knight0fDragon CADisplayLink specifically says when the next frame will be rendered. It is its purpose in life. Here's how to use it for a gentler case: http://www.paulwrightapps.com/blog/2014/8/20/creating-smooth-frame-by-frame-animations-on-ios-based-on-the-time-passed-between-frames – Confused Nov 15 '17 at 16:58
  • Maybe this is a dumb thought, but I’m wondering if it’s capturing the sum of the view controller as a whole and the SKView within it and there is some kind of inefficiency in rendering that could be addressed. – SuperCodeBrah Nov 15 '17 at 17:01
  • Before you commit to SpriteKit, consider this: https://forums.developer.apple.com/thread/64553 – Confused Nov 15 '17 at 17:04
  • @Confused that method gets called the moment refresh is happening, not the time the next update fires, could you tell me what line he is using to predict the next frame? Maybe I am missing it. SuperCodeBrah it is possible, I haven't done multiple SKViews for a few years now. – Knight0fDragon Nov 15 '17 at 17:05
  • What am i looking at here? I am not familar with cocos2d, but from the looks of it, that guys problem is he is working in a fixed update environment but getting unfixed update calls. Further comments suggest that cocos2d switched from a fixed time update to use CADisplayLink... I think I am reading that right... and that is what caused the change. – Knight0fDragon Nov 15 '17 at 17:22
  • Subsequent issues have been around, since then, with regards the variance in frame rate caused by iOS attempting to throttle for what it senses is going on, and using CADisplayLink to do this... hence the need to monitor its variance rather than presume it's a constant 60fps. It isn't! – Confused Nov 15 '17 at 18:34
  • @Confused... it was never suppose to be a constant 60fps, I do not ever remember Apple saying it was. You can set what you prefer, but it was never guaranteed. They even explain how to get the actual FPS in their documentation. It is not the same as VSync, because LCD doesnt have a concept of VSync, so it is never going to provide the constant speed. – Knight0fDragon Nov 15 '17 at 19:19
  • @Confused, I see it now, they do have a `targetTimestamp` to tell you when the next update should happen. Will have to see if the `targetTimeStamp` is consistently wrong then, or if it is just currentTime + preferred. Apple doesn't talk about it a lot. – Knight0fDragon Nov 15 '17 at 19:23
0

Turns out I had 2 SKViews in my view controller. By default, when you start a project as a SpriteKit game, Xcode sets the view controller root/superview of the GameViewController as an SKView. At some point, I had added a second SKView because I didn't intend for the scene to take up the entire screen and I apparently didn't realize that the VC root view was still set as an SKView. So every time GameViewController loaded, it was loading two SKViews, which is why I saw 120 FPS in Xcode.

I fixed the issue by simply removing the SKView class designation from the VC root view.

enter image description here

SuperCodeBrah
  • 2,874
  • 2
  • 19
  • 33
  • Interesting, I use multiple SKViews to achieve multiple camera angles on an SKScene, I never took notice to this happening, will have to in the future – Knight0fDragon Nov 16 '17 at 16:15