Jump to content

Upgrading Game from 2.2.2 to 2.4.4 Kills Performance


BrenX
 Share

Recommended Posts

Hi all,

 

I have picked back up a project I started a while back and have run into some issues. I decided to upgrade from 2.2.2 to 2.4.4 assuming that all of the effort and improvements will be a benefit. I learned that the scaling API had changed a little, so I fixed my code to use the appropriate methods, discarding the deprecated ones. That eliminated the exceptions I was seeing.

 

Unfortunately, though the game now runs, I have found that my FPS has dropped from around 55-60 to 5-15. I can toggle between these two versions of Phaser 2 and instantly see the difference in FPS. Everything else about the game looks the same and nothing is being reported in the logs.

 

The only clue I have is that the drop in FPS occurs when the tilemap is scrolling.

 

My game uses the following APIs/functionality:

  • Tilemaps (made in Tiled), collisions set using this.map.setCollisionBetween(2, 4);
  • Audio (mp3)
  • Tried out both Canvas and WebGL rendering (no perceptible difference)
  • Arcade physics

I'd greatly appreciate any tips/gotchas I should be watching for. Is there some flag I should be setting to correct the scolling problems?

 

Thanks!

 

Link to comment
Share on other sites

In case it's pertinent, here is the code for my camera settings:
this.game.camera.follow(this.sprite, Phaser.Camera.FOLLOW_TOPDOWN_TIGHT);

My map has 2 layers. One is a partially transparent overlay.

 

Scaling is set using the following code: 
this.game.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;this.game.scale.fullScreenScaleMode = Phaser.ScaleManager.SHOW_ALL;this.game.scale.pageAlignHorizontally = true;this.game.scale.pageAlignVertically = true;
Link to comment
Share on other sites

I had the same problem. At the beginning of this year I ported a game from Flash (Flixel) that uses Tilemaps, at the time the current version of Phaser was 2.2.2, the performance was ok in Chrome, Firefox showed a dropped in fps but that was expected. When 2.3 arrived I upgraded the game and I run into the same issue you mention, a huge drop in fps when using tilemaps. I haven't been able to fix this issue nor isolate the cause (too many internal changes in phaser, I know the problem has something to do with collisions, scrolling and rendering). Tilemap became useless for big worlds. Reducing the size of the tilemap world improves the framerate but other than that I can't say I have a solution.

There's another implementation of tilemaps that uses WebGL renderer and is optimized for big worlds, but it only supports P2 physics (my game used Arcade physics) https://github.com/englercj/phaser-tiled , maybe you can make it work.

 

Link to comment
Share on other sites

Thanks for answering, JackFreak.

 

When you suggest that I could improve performance by decreasing the size of my tilemap, would that involve developing some kind of "load/render only the visible parts of the tilemap for a large world"? Is there an out of the box mechanism for this? I can of course figure out what parts of a larger map are visible and somehow grow the in-memory tilemap as the user approaches a seam between two sub-maps. But this seems like overkill for a map that measures in at 96x96.

 

I may just have to stick with a older version of Phaser if upgrading means that my world has to be smaller... the whole point of the game is to give a large area to move around in.

 

I'm going to have a look at the link you sent and see if it's worth porting over. I may be too far along to justify too much effort changing tilemap implementations... but it's good to know there are options. I have a hard time believing that I'm pushing the rendering limits with my map size.

 

I'll report back if/when I figure anything out. I welcome any other input.

Link to comment
Share on other sites

BrenX. what I meant with the suggestion of decreasing the size of the world was because my tilemap world was about 1000 tiles in width per 20 tiles in height, it was a very large world!. When I cropped a part of that tilemap to a 250x20 map I noticed an improvement in performance and fps. The phaser tilemap already has a mechanism to render only the visible part, there's no need for extra implementation for this.

One thing that's important to know is that every tilemap layer creates it's own canvas, and it doesnt matter if you set your renderer to be WebGL, TileMap always uses CANVAS to render the layers. That's why I told you about the other implementation that uses WebGL, it should render much faster, unfortunately it doesnt support Arcade physics.

Anyway, a world that's 96x96 tiles doesn't sound too big, but I notice that the performance hit happened mainly when the tilemap had to scroll. When my tilemap wasnt scrolling the performance was pretty acceptable. 

You can try this debugger to get a little more info about what's going on with your game: https://github.com/englercj/phaser-debug 

 

Link to comment
Share on other sites

Thanks so much for following up, Jack.

 

I tried the Phaser Debug plugin and it is very useful. Of course, its usefulness is directly proportional with my ability to understand the output... so I have a bit of learning to do.

 

Clearly, the problem is the postUpdate > stage processing (I've attached a screenshot). I'll have to do a bit of research to find out exactly what that is and what it is in my code that might be causing this processing.

 

I'm on the trail and will post back when I've learned more.

 

post-13799-0-16381300-1451569160.jpg

Link to comment
Share on other sites

Ok, a quick follow-up.

 

Here is the output from the Chrome profiler. It looks like my processing is being pegged by TilemapLayer.renderRegion() and to a lesser degree Game.updateLogic().getImageData()

 

attachicon.gifprofile.jpg

I could be wrong but I read that as saying that TilemapLayer.renderRegion() is spending all of it's time in drawImage... did you switch from WebGL to canvas renderers between your screenshots? Random thought: maybe try using the debugger to break (use a break point) inside renderRegion() and see what sized region it is trying to draw? (probably looking at the left, top, right, bottom arguments it was passed should be enough, I'd presume)

EDIT: crazy thought, how do you draw your minimap? I mean I assume it's not drawing the entire tilemap scaled down... ?

Link to comment
Share on other sites

The parameters I see coming in are:

 

scrollX = 561

scrollY = 629

left = 35

top = 39

right = 85

bottom = 76

 

...so, nothing out of the ordinary, from what I can gather. I put in a conditional breakpoint and the dimensions of the rendered area (in tiles) never goes above 51 x 38.

 

The minimap is drawn using an approach I came up with that goes something like this:

  1. I created a scaled-down version of my tileset where each tile is 1px x 1px (I used "nearest neighbor" to keep the scaling from trying to be too clever and smoothing out the colours).
  2. At run time (on level start), I draw the base minimap bitmap sprite by traversing the tilemap and mapping the tile locations in the real map to the pixels in my mini tileset. The minimap is drawn once, one pixel at a time.
  3. During gameplay, I draw a rectangle sprite on top of this bitmap and update its position as the user moves about the level. I just need to map the global coordinates to a pixel position in the minimap, offsetting it for the size of the rectangle (which is calculated using the viewport size).
  4. Gravy.

It all seems to work quite well, other than the overlay rectangle's movement being a little jittery. I need to write a smoothing method that averages the player position to fix that.

 

If I remove the minimap altogether, there's no perceptible impact on performance.

Link to comment
Share on other sites

Just posting an update. I rolled back to 2.3.0 and all tilemap performance issues went away. That might indicate a regression in the 2.4.x development stream.

 

I'm not familiar with the changelog from 2.3.0 to 2.4.0 (I could look it up) but I wonder if any big changes were made to tilemap rendering, collisions, etc.

Link to comment
Share on other sites

I could be reading the diffs wrong, but it looks like in v2.3.0 TilemapLayer extended PIXI.Sprite, whereas in v2.4.4 TilemapLayer extends Phaser.Sprite.  The API docs in TilemapLayer.js state that this was a change of extension from Phaser.Image to Phaser.Sprite.

 

This makes me much more curious about the direction of tile maps in Lazer (Phaser 3.x).

 

Tom

Link to comment
Share on other sites

  • 3 weeks later...
  • 2 weeks later...

@veggis

Oh, no sorry. I'm writing about performance after upgrading from phaser 2.3 in general. Not about post-rendering.

Yes, of course I've used profiler. This is screen http://www.screencast.com/t/ZsEgJG5G   

If I use Canvas mode and advancedTiming turned on - I have a lot of lags on device. Whan I put advancedTiming = false and go to webGl renderer - it solve problem partly, the performance become better.

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...