13

I'm developing a simple game with Swift & SpriteKit, and I've noticed FPS drops from 60 to 58-59 (and back). There is a noticeable lag when the drop occurs — it looks like 1 or 2 frames are dropped.

CPU load is about 20-25% and does not change a lot, memory usage is permanently about 8 MB.

Screenshot: App Screenshot

There are 6 object on screen: label, red object (Sprite), 2x green objects (Sprite), one box (Sprite) and "ground" (Rect shape node).

All objects except label have physics body (displayed with white borders).

Green and white objects are dynamically created, move from right to left and destroyed when offscreen:

func scheduleAddingLiquid() {
let wait = SKAction.waitForDuration(NSTimeInterval(getRandomNumber(1, end: 3)))
        let block = SKAction.runBlock({
            [unowned self] in

            let liquidNode = LiquidNode(texture: self.liquidTexture, sceneFrame: self.frame)
            self.addChild(liquidNode)
            liquidNode.move()

            self.scheduleAddingLiquid()
        })

        let sequence = SKAction.sequence([wait, block])
        runAction(sequence)

and:

func move() {
        let moveAction = SKAction.moveToX(-frame.width, duration: NSTimeInterval(3))
        let removeBlock = SKAction.runBlock({
            [unowned self] in

            self.removeFromParent()
            })

        runAction(SKAction.sequence([moveAction, removeBlock]))
    }

Red object "jumps" on screen touch:

if touches.count > 0 && isHeroOnGround && heroNode != nil {
            isHeroOnGround = false
            heroNode.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
            heroNode.physicsBody?.applyImpulse(CGVector(dx: 0, dy: 400))
        }

The lag occurs within random time interval after "jumping" (from about 0.5 to 1.5 seconds after jump).

The lag occurs not when collision occurs, just when red object is "in the air". And it occurs not every jump. The CPU load does not grow when FPS drops.

Tested on iOS 9.3, iPad mini 2.

Upd 1. Tested on iOS 9.3 iPhone 6 — FPS is about 50-55 for first few seconds, then it's constantly 60, without lags. So, it lags on iPad mini 2 only (I have only these two devices, cannot test on other ones).

UPD 2. I've commented out all objects creation code, except red figure. It's still lagging when "jumping". So, now I'm sure that it's related to applyImpulse method.

UPD 3. That's really, REALLY strange: I've removed all code from touchesBegan method, and it still lags on touches! The method is completely empty. I don't know why, but FPS drops if I click several times...

How to debug this?

artem
  • 16,382
  • 34
  • 113
  • 189
  • I suspect that your problem lies in the way how you mix skactiona and physics engine. I haven't looked at all in your code execpt I noticed that you are applying impulse + using move to. Those two don't plat nicely together. So check if those two are not interfering... That would be a start. – Whirlwind Aug 20 '16 at 13:45
  • More precisely, SKActions *should not* be used to move objects if you already move those objects using physics engine. If you are interested only in contacts then It is fine to use actions along with physics engine. – Whirlwind Aug 20 '16 at 14:23
  • 2
    A drop in 1 to 2 FPS will not be noticeable by your eye, so what you are calling lag, may not be lag, it may be pauses on the main thread, or it may be an undesired effect due to faulty programming. More info on what is really happening may be helpful in your case, or perhaps you may want to take it to http://codereview.stackexchange.com/ and let people see where you are going wrong with your code. – Knight0fDragon Aug 20 '16 at 14:39
  • @Whirlwind I'm not applying any SKAction for the object that is affected by impulse. SKActions are used only for non-dynamic objects. – artem Aug 20 '16 at 22:37
  • Do you have any gestures running that were not removed? – Knight0fDragon Aug 24 '16 at 16:00
  • @Knight0fDragon I don't use any gestures in this project. – artem Aug 24 '16 at 17:46
  • and you have nothing going on with touchesmoved or touchesended? – Knight0fDragon Aug 24 '16 at 17:49
  • @Knight0fDragon the only touch-related implemented method in scene is touchesBegan – artem Aug 24 '16 at 18:00
  • do all of your nodes have userInteractionEnabled = true? – Knight0fDragon Aug 24 '16 at 18:00
  • @Knight0fDragon all nodes have default value, I never changed userInteractionEnabled field. – artem Aug 24 '16 at 18:30
  • ok trying to think of things that would cause a lag when touch is applied – Knight0fDragon Aug 24 '16 at 18:31
  • Would it be possible for you to make a sample project which reproduces the bug and put it up on github? – aksh1t Aug 26 '16 at 21:45

2 Answers2

4

It only having issues on the mini makes me think there is something wrong with your mini (or that particular package on your mini). Try making a new project, copy the files over, then run it again. Also, you said 9.3, but there is 9.3.1, 9.3.2, etc. The two devices could have had different builds.

So, first, ensure your iphone and iPad are running the same version of iOS.. Maybe there was a bug, or maybe they patched a bug (thus causing one to work and not the other).

Also, try running it on the different emulators... if it runs flawlessly on the emulators, then I'm even more suspect of the mini (in it's current configuration).

This way, you can also see if (maybe) the problem has to do with the orientation (widescreen of iphone vs 4:3 or whatever of iPad).

Sometimes, I've had "very strange" things happen to my project files (even without plugins) and simply creating a new project, copying all the files over fixed it. If it's lagging when you click on an empty "touchesBegan" ... makes me think something buggy with Xcode / your mini is at hand--since it only happens on that one device (thus we know so far)...

Other things to consider,

  1. Which version of Xcode are you using? Try The latest beta / go back to 7.3. Any differences?

  2. Do you have another computer you could try building the project from?

  3. If swapping out the [unowned self] or leaving it in didn't fix anything, then my suggestion would be to load up your code with print statements and see what's going on.

  4. If you used the Scene Editor to make the sprite nodes, delete them all and remake them, or try making them programmatically. This has fixed random bugs in some of my projects (for seemingly no reason).

We need more code / info, but the above should hopefully fix your problem.

Fluidity
  • 3,985
  • 1
  • 13
  • 34
  • Thanks for reply! I have only 2 devices, iPad mini 2 and iPhone 6, both have the same version now (9.3.5). I've tried to run the game on simulators, it's ok on 5s/6, but lags on 6+/6s+ (I think it's because of screen size). 1. Xcode is latest stable release, i'll try the beta. 2. I have only one MBP (latest stable OS X). 3. Already tried, nothing changed. 4. No, I didn't use that. The most strange thing is that it lags ONLY on touches, even if there is no code for handling the touches. – artem Aug 29 '16 at 08:52
  • @RankoR interesting. it doesnt lag on hardware phone, but does on virtual. Is your Macbook core i or core2duo? I would definitely try new project import, beta Xcode. If that doesn't work you should put the project on GH so we can take a look. I have a 4.5ghz quad core hackintosh with r295x2.. xD if it lags on that, it has to be the code. I also have ipad 3, air, and regular iphone 5.... – Fluidity Aug 29 '16 at 10:59
  • also, i would start making a spreadsheet of the different configurations in which it lags / doesnt lag. it may or may not be useful, but it could be something to consider if future projects start having similar bugs. If there is an actual bug in xcode or iOS, that data would help Apple fix it as well. – Fluidity Aug 29 '16 at 11:08
  • It's MBP Retina 2013 15" with i7. I'll try in XCode beta later. I'll also try to reproduce the lag on new project and will put in on the GitHub (I can't put the current one there because of NDA). – artem Aug 30 '16 at 18:11
3

Well I suppose it is a bit late but I have a performance drop when I add some SKShapeNode to my scene. I have no lags with 200+ plain SKSpriteNode and everything starts freezing when there are 80 nodes with only about 30 SKShapeNode among them. Of course with no additional functionality, just a path, stroke/fill colours and lineWidth

Pavel Stepanov
  • 891
  • 8
  • 13