lukaMis

How to improve performance on mobile

Recommended Posts

Hi

 

I am working on a simple game that requires player to shoot a circle with another circle. :)

Link: http://games.lukamis.com/circles/

 

As you can see I only have couple of tweens and couple of sprites in game loop but still i have serious performance issues.

My Samsung Galaxy S3 with Chrome can't keep steady 20fps.

 

What i have done so far:

- Game is 320 x 480 (

  this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;

  this.scale.setMinMax(320, 480, 512, 768)

);

- Phaser.CANVAS in place of AUTO

- Using phaser-no-physics.min.js so no heavy computation at all.

- I have enabled game.renderer.renderSession.roundPixels = true;

- I have moved info text from Phaser to DOM except for fps counter but that will be obviously removed.

- Js is minified with console.logs removed

 

Am i missing something / doing something wrong or is this normal.

Any ideas how to optimize further?

 

Tnx

Luka

Share this post


Link to post
Share on other sites

The android browser is one of the worst to develop for, they often lag behind any other browser. But still, it seems odd that a simple game like yours is causing much trouble. I did inspect your game using the Google Chrome inspector on my desktop pc, and I noticed that even on my very powerful desktop it doesn't seem like it's running as smoothly as it potentially could. Looks like there's quite a lot going on behind the scenes, you may have to optimise your game loops (update and render).

 

Use a Javascript inspector like in the Google Chrome dev tools to find the chokepoints in your game, do some benchmarking inside your app (log time differences between various actions to see how long it takes) and see if you can optimise any code. Some Javascript functions or methods are quite cpu-heavy and often those can be replaced by different structures. And in general, wherever possible, avoid loops (for, while) and remove variables when you're done with them to clear memory (especially if they're declared globally). These are some general tips for debugging Javascript code, hope it helps.

Share this post


Link to post
Share on other sites

@woubuc Tnx for your time but problem here is that i have nothing in update and render. That is whole code:

PhaserGame.Game.prototype.update = function () {  // console.log('Game works');  if(this.player.playerOnTheMove) {    // this.player.angle += 6;    var _distanceToCheck = this.player.width * 0.5 + this.enemy.width * 0.5;    if(Phaser.Math.distance(this.player.x, this.player.y, this.enemy.x, this.enemy.y) < _distanceToCheck ) {      console.log('TOTAL HIT');      this.collisionDetected();    }  }};PhaserGame.Game.prototype.render = function () {  game.debug.text(game.time.fps + ' fps' || '--', this.game.width-40, this.game.height - 30, '#FFFFFF', '12px Arial' );};

I only start checking for collision after i fire player and playerOnTheMove flag is true.

I only move my sprite with yoyo tween and those +'s in background are recycled with this.stars.getFirstDead();

I must be doing something wrong. I mean my phone is showing 16k bunnies on bunny test with no problem. 

 

Here is link to full Game state:

https://bitbucket.org/lukaMis/circles/src/9447b478dbc6126d5b4c772ac7f54113f4b85c9f/js/src/states/Game.js

 

Maybe you can see something i can't. 

Share this post


Link to post
Share on other sites

I'm only a beginner with PhaserJS myself, so I'm not comfortable with recommending Phaser-specific methods, nor am I 'fluent' enough with the Phaser functions to look over your script, so I'm afraid I won't be able to actually help you with this. I just thought I'd offer some general Javascript debugging and optimising advice. Someone else here will probably be able to look over your code and comment on it.

Share this post


Link to post
Share on other sites

Hi

 

I am a Phaser n00b and still getting my head around it, but I found a couple of bottlenecks on my side srcoller game which helped me.  I don't know if they will help you but here goes anyway:

 

I first tested by removing all backround images (background tiling especially), which was causing one bottleneck. 

The other was changing the fps to 30 in my create function.

game.time.desiredFps = 30;

 

Good luck and post back if you find the answer.
 

Share this post


Link to post
Share on other sites

The fps drop is not due to your coding, but due to this: 

border: 1px solid red;

on the canvas element. What this thing does (appart from setting a red border) is re-calculating the border 60frames per second.... yes anything applied to the canvas element is refreshed with the canvas so if the canvas game runs with 60fps the browser must try to keep up and update the border as well (or any other css property).

 

Remove that and you'll see great improvement. I my self strungled alot before I discovered that.

Share this post


Link to post
Share on other sites

Tnx for suggestions. 

 

@MichaelD: removing border on canvas did nothing to fps.  :P

 

Well, it is weekend, it is raining, i have nothing better to do, also i want to learn Phaser, so i decided to start from scratch and keep an eye on performance from beginning.

Share this post


Link to post
Share on other sites

bump!

 

Main culprit was Phaser.CANVAS in place of Phaser.AUTO. :unsure: 

I changed it to AUTO and now my Galaxy S3 hovers around 58+ fps even with non compressed js with console logs (for development) and with in game music.  :P

 

Is that normal and expected behavior?

 

 

 

Share this post


Link to post
Share on other sites

One of my games breaks on the iPad if I use Phaser.AUTO instead of Phaser.CANVAS, so you might want to check on a device running iOS to make sure you're all good! I may have screwed something up to cause this issue, so I'd be curious to know if you have the same issue.

Share this post


Link to post
Share on other sites

Does console.log slow stuff down even with the web console closed? When I have the web console open in Firefox it totally slows things down, but when I close it things run fine. I didn't even think that logging might be slowing down performance if not outputting to the screen.

Share this post


Link to post
Share on other sites

I couldn't say exactly what the effect of console log would be but personally I think you shouldn't really have any debug code whilst trying to maximize peformance... except.. to locate specific issues you may want to put a time start/end around any specific function or block of functions you want to check the performance of.

Share this post


Link to post
Share on other sites
On 4/23/2015 at 1:41 AM, lukaMis said:

Hi

 

I am working on a simple game that requires player to shoot a circle with another circle. :)

Link: http://games.lukamis.com/circles/

 

As you can see I only have couple of tweens and couple of sprites in game loop but still i have serious performance issues.

My Samsung Galaxy S3 with Chrome can't keep steady 20fps.

 

What i have done so far:

- Game is 320 x 480 (

  this.scale.scaleMode = Phaser.ScaleManager.SHOW_ALL;

  this.scale.setMinMax(320, 480, 512, 768)

);

- Phaser.CANVAS in place of AUTO

- Using phaser-no-physics.min.js so no heavy computation at all.

- I have enabled game.renderer.renderSession.roundPixels = true;

- I have moved info text from Phaser to DOM except for fps counter but that will be obviously removed.

- Js is minified with console.logs removed

 

Am i missing something / doing something wrong or is this normal.

Any ideas how to optimize further?

 

Tnx

Luka

Dude, any idea why game.renderer.renderSession.roundPixels = true; is giving me Uncaught TypeError: Cannot read property 'renderSession' of null ?  I am using Phaser 2.4.8 no-physics.min.js
Thanks in advance, this is my code:

        var config = {
            "width": this.w * RatioUtil.getDPR(),
            "height": this.h  * RatioUtil.getDPR(),
            "renderer": Phaser.CANVAS,
            "parent": 'game',
            "transparent": false
        };

        var game = new Phaser.Game(config);
        game.renderer.renderSession.roundPixels = true;
        game.forceSingleUpdate = true;


        //add states to the game
        game.state.add('Boot', Slot.Boot);
        game.state.add('Preloader', Slot.Preloader);
        game.state.add('MainMenu', Slot.MainMenu);
        game.state.add('SlotMachine', Slot.SlotMachine);

        //start the boot state
        game.state.start('Boot');

 

Share this post


Link to post
Share on other sites

For all future readers. I used to get 30 fps on an iPhone 4s, fixed by checking the device first, put the renderer on WebGL, remove the advanced timing and fps count and BINGO - 60fps :)
Also, after the game ran perfectly on iphone 4s, my Samsung Galaxy S3 Neo (Chrome) started to render the game at 30 fps when using WebGL instead of Canvas(60fps). After 2 weeks of testing and stuff, I have concluded that, for some reason, the android 4.4.2 phones like Canvas more than WebGL. Newer devices like Samsung Galaxy S6 and S7 don't care because of the power they provide.


So what you need to do is check the device, if android - Canvas, if iOS - WebGL. That is based on a very simple game, no physics or whatsoever.

Share this post


Link to post
Share on other sites

Just out of curiosity, try running the bunnimark from pixi.js. If you're new to phaser, then phaser is just the game engine that sits on top of the renderer. The renderer is where all the magic happens. http://www.goodboydigital.com/pixijs/bunnymark_v3/

I can usually run 100k+ sprites on my laptop at 60fps, and I've got old androids that will run 8,000 - 10,000 sprites at 60fps before I start to see frame rate drop.

If this is the case, then it may be well worth looking at developing inside pixi.js, without phaser. It seems daunting at first, but it's well worth the effort, trust me!

Share this post


Link to post
Share on other sites
On 6/20/2016 at 5:09 PM, megmut said:

Just out of curiosity, try running the bunnimark from pixi.js. If you're new to phaser, then phaser is just the game engine that sits on top of the renderer. The renderer is where all the magic happens. http://www.goodboydigital.com/pixijs/bunnymark_v3/

I can usually run 100k+ sprites on my laptop at 60fps, and I've got old androids that will run 8,000 - 10,000 sprites at 60fps before I start to see frame rate drop.

If this is the case, then it may be well worth looking at developing inside pixi.js, without phaser. It seems daunting at first, but it's well worth the effort, trust me!

Well, until recently I thought so as well. However, PIXI is just a renderer. It's true that PIXI is crazy fast, but still, PIXI just renders and that's it. Everything else you will need to develop yourself, or maybe  :D steal :D from Phaser exactly what you need and make a bare essentials engine for your personal needs. That is what Phaser does exactly. In my case when I started coding with Phaser, there were a lot of issues that I thought to be Phaser's fault, but I was wrong - I just did not know how to properly optimize my code. I was looking like crazy for alternatives but even the paid ones were not as well supported as Phaser. Also, don't forget that there are a lot of shit devices and browser that cannot handle anything. 

Share this post


Link to post
Share on other sites
On 17.06.2016 at 0:42 PM, Igor Georgiev said:

For all future readers. I used to get 30 fps on an iPhone 4s, fixed by checking the device first, put the renderer on WebGL, remove the advanced timing and fps count and BINGO - 60fps :)
Also, after the game ran perfectly on iphone 4s, my Samsung Galaxy S3 Neo (Chrome) started to render the game at 30 fps when using WebGL instead of Canvas(60fps). After 2 weeks of testing and stuff, I have concluded that, for some reason, the android 4.4.2 phones like Canvas more than WebGL. Newer devices like Samsung Galaxy S6 and S7 don't care because of the power they provide.


So what you need to do is check the device, if android - Canvas, if iOS - WebGL. That is based on a very simple game, no physics or whatsoever.

I have completely different data with my android 4.4.2.

When I use CANVAS, I have 8 fps (the simplest possible game with 2 text labels based on native fonts (not bitmap) on the screen and 10-15 sprites). 

If I use WEBGL, I have stable 60 fps.

UPDATE: if I test it on old Ipad Air, I have 10-15 fps with WEBGL and 15-20 with CANVAS. On Iphone 6 I have 60 fps in both cases.

UPDATE: on Iphone 5, WEBGL doesn't work at all. CANVAS works (20-30 fps).

We are all doomed, guys ;)

Share this post


Link to post
Share on other sites
On 10/15/2016 at 7:21 PM, MadOwl said:

I have completely different data with my android 4.4.2.

When I use CANVAS, I have 8 fps (the simplest possible game with 2 text labels based on native fonts (not bitmap) on the screen and 10-15 sprites). 

If I use WEBGL, I have stable 60 fps.

UPDATE: if I test it on old Ipad Air, I have 10-15 fps with WEBGL and 15-20 with CANVAS. On Iphone 6 I have 60 fps in both cases.

UPDATE: on Iphone 5, WEBGL doesn't work at all. CANVAS works (20-30 fps).

We are all doomed, guys ;)

That's weeeird.... same Android version (galaxy S3 Neo) 60fps Canvas, 30fps WebGL, iphone 4s 20fps Canvas, 60fps WebGL, iphone 5,6 are all good with me. 

Share this post


Link to post
Share on other sites

I hit a fps problem using firefox under Linux Mint on an old laptop.

Using phaser.auto the game would run incredibly slowly (I guess because it tried to use WebGL) but if I specified Phaser.Canvas it ran at full speed.

 

Found it a bit frustrating that the "AUTO" option wouldn't detect the best performance automatically. 

 

Share this post


Link to post
Share on other sites
2 hours ago, Nobody Home said:

Found it a bit frustrating that the "AUTO" option wouldn't detect the best performance automatically. 

It can't, this would involve setting up BOTH a webgl and a canvas renderer, testing them, then making the distinction over which to use (this is exactly how modernizr, for example, works) but this would be incredibly slow for this use-case, feature testing can only be done if the tests are lightning fast and accurate-enough, certainly testing render performance can never be fast.

Auto (and I am assuming here, having never poked through the code) assumes that webGL would be your faster option so I assume that Auto just tests if webGL is available, it must surely be rare where GPU is slower than CPU-bound rendering so this test falls in the accurate-enough case whilst remaining fast. In any case its easy enough to remove the Auto and manually choose a renderer (or, even be device specific rather than feature specific) when you do run foul of an edge-case.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.