Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SpriteKit using 95-100% CPU when running game with large tilemap (JSTileMap)

My project runs at 55-60FPS on an iPhone 6 but anything older is completely unplayable because something is eating CPU.

I think the issue is related to the number of tiles and layers on my map (64x256 with 4 layers) and Instruments shows "SKCRenderer:preprocessSpriteImp(..." taking 5198ms (23.2%) running time.

Does JSTileMap load every single tile's image (visible or not) at once? This post from RW indicates that is the case and that it could be worked around for large performance boosts: http://www.raywenderlich.com/forums/viewtopic.php?f=29&t=9479

In another performance note - Sprite Kit checks all it's nodes and decides which ones it needs to display each frame. If you have a big tile map, this can be a big performance hit. JSTileMap loads all the nodes (SKSpriteNode for each tile) when it loads the tile map. So, I was also seeing performance issues in the Sprite Kit version with my maps (which are 500 x 40 tiles). I added a check to my version of JSTileMap that's included in the kit that marks the hidden property of each tile, then intelligently unhides and hides only the tiles that enter/exit the screen space. That increased performance on these larger maps significantly.

Unfortunately that post does not go into detail regarding the steps taken to remedy this.

My first thought was to (I'm a beginner, please be gentle) create an array of nodes by looping through each point and checking for a tile on the specific layer. From there I'd work on adding/removing them based on distance from the player.

This didn't work, because the process of adding nodes to an array simply caused the app to hang forever on larger maps.

Could someone lend a hand? I'd love to work with larger/more complicated tilemaps but this performance issue is destroying my brain.

Thanks for reading!

UPDATE: Big thanks to SKAToolKit: https://github.com/SpriteKitAlliance/SKAToolKit

Their culling feature solved my problem and I'm now running even larger maps at less than 35% CPU.

like image 289
Norm Avatar asked Oct 31 '22 02:10

Norm


1 Answers

JSTileMap has some issues handling larger maps but you do have a couple of options to consider:

  1. Break your large map into several smaller pieces and load each new piece as required.
  2. Only load those objects which are in the player's vicinity.
  3. Only load those tiles which are in the player's vicinity.

I personally found it impossible to accomplish #3 with JSTileMap as I could not locate an array holding the map tiles. I solved this issue by using the SKAToolKit which provides easy access to map tile arrays. It is an excellent resource for parsing maps created in Tiled.

like image 146
sangony Avatar answered Nov 15 '22 07:11

sangony