mariannoga Posted June 27, 2018 Share Posted June 27, 2018 I have been playing around with phaser3 and electron. I have developed simple 2D tile based map and the code just runs a single scene at the moment. It doesn't even render anything beyond a single frame - my update function inside the Scene get called multiple times a second but exits immediately if there is no update needed. However I can see in Dev Tools' Performance tab that rendering routines get called quite often. It results in unwanted CPU usage and my laptop fan goes through the roof and wakes up my neighbours. It's kinda annoying and I hope somebody can give me an idea about how to improve it. Platform is 2015 Macbook Pro 13''. I am using "phaser": "3.10.1", "electron": "^1.8.7" Ask any questions. I have attached a screenshot below that might give you some clue: Link to comment Share on other sites More sharing options...
samme Posted June 28, 2018 Share Posted June 28, 2018 Turn off ☑︎ Screenshots. Link to comment Share on other sites More sharing options...
rich Posted June 28, 2018 Share Posted June 28, 2018 This isn't enough information to even begin to help I'm afraid. There's no indication of canvas size, texture size, map size, etc. Bailing out of an update loop early won't make any difference. What's actually in the Scene? Link to comment Share on other sites More sharing options...
mariannoga Posted June 28, 2018 Author Share Posted June 28, 2018 Thought you might say more information is needed. I wasn't really sure what is relevant so let me answer your questions. Size is set as follows when opening Electron window: mainWindow = new BrowserWindow({ width: 1200, height: 768, resizable: false }); Then the phaser config takes it as follows: // main game configuration const gameConfig: GameConfig = { width: window.innerWidth, height: window.innerHeight, type: Phaser.AUTO, parent: 'game', scene: MapScene, fps: { target: 2 } }; The map size is (80 tiles x 16 pixels) x (50 tiles x 16 pixels) and that is pretty much what is in the scene. Tiles are PNG images with transparent background so there can be up to 3 sprites in some tiles one on top of another. Please let me know if you need more information. Link to comment Share on other sites More sharing options...
Antriel Posted June 29, 2018 Share Posted June 29, 2018 Assuming you want to render just 2 frames instead of as much as the system can handle, try changing the fps part of the config into: fps: { target: 2, min: 2, forceSetTimeOut: true } Unless you force usage of setTimeout, Phaser will use RAF to trigger updates and render, which will try to sync to your display refresh rate. Also without that `min` part, the ticker would lower the delta time to 5 FPS (the default), so if you want 2, set the min too. Link to comment Share on other sites More sharing options...
mariannoga Posted June 29, 2018 Author Share Posted June 29, 2018 Thanks for the response. I set the target, min and forceSetTimeOut as instructed. Render seems to be firing every 20ms which would be 50Hz. this simply means it did not work as expected. no change to the CPU usage. thanks for the efforts but I think I will need to try something else. Any other ideas? Link to comment Share on other sites More sharing options...
samme Posted June 30, 2018 Share Posted June 30, 2018 Seriously, uncheck the Screenshots box. nkholski, kvazmatik and squilibob 3 Link to comment Share on other sites More sharing options...
Antriel Posted June 30, 2018 Share Posted June 30, 2018 Hmm, looking at the source, it seems the ticker doesn't honor the fps settings and just goes with 16 ms ticks with `forceSetTimeOut`. Not sure if that's intended or a bug @rich? Link to comment Share on other sites More sharing options...
mariannoga Posted June 30, 2018 Author Share Posted June 30, 2018 Seriously? 7 hours ago, Antriel said: Hmm, looking at the source, it seems the ticker doesn't honor the fps settings and just goes with 16 ms ticks with `forceSetTimeOut`. Not sure if that's intended or a bug @rich? Well, that clarifies one thing fps settings are not going to solve the performance problem. Can phaser be instructed not to render the canvas if there was no change? Link to comment Share on other sites More sharing options...
Jambutters Posted July 22, 2018 Share Posted July 22, 2018 On 6/30/2018 at 7:39 AM, mariannoga said: Seriously? Well, that clarifies one thing fps settings are not going to solve the performance problem. Can phaser be instructed not to render the canvas if there was no change? Think melonjs has a feature like that. Provide a test case! Link to comment Share on other sites More sharing options...
mariannoga Posted August 13, 2018 Author Share Posted August 13, 2018 Ok then. If these are the answers then I conclude you guys are doing everything fine and I must be asking wrong question. Otherwise every single game in Phaser would be botched. Why is my CPU spiking when the game is not doing anything? Hard to believe it is just due to canvas rendering. Link to comment Share on other sites More sharing options...
gafami Posted August 16, 2018 Share Posted August 16, 2018 I think that in Phaser, they have a func call update() { }. This function work as a timer run with 0 delay. So when develop game based on Phaser just remember that you should avoid put many logic code inside update() func and everything will be fine. Link to comment Share on other sites More sharing options...
mariannoga Posted September 2, 2018 Author Share Posted September 2, 2018 No, it won't. I can avoid redrawing canvas in update() but the engine still invokes gpu routines to redraw the screen. My update function exits immediately but it won't stop cpu sky rocketing. Link to comment Share on other sites More sharing options...
samid737 Posted September 3, 2018 Share Posted September 3, 2018 On 6/30/2018 at 2:21 AM, samme said: Seriously, uncheck the Screenshots box. Before proceeding investigation, you already done the above mentioned? Link to comment Share on other sites More sharing options...
codemilli Posted November 28, 2018 Share Posted November 28, 2018 What screenshots? Link to comment Share on other sites More sharing options...
eddieone Posted November 28, 2018 Share Posted November 28, 2018 What does performance look like with screenshots off?? Link to comment Share on other sites More sharing options...
mariannoga Posted February 5, 2019 Author Share Posted February 5, 2019 I have been playing with my pet project in Phaser3 recently and I tried different things in order to improve performance. Here are some numbers that you might find interesting. As previously it is a tile based scene. The map is an 80x50 tiles each 16x16 pixels. The tests have been done for 2 layers tilemap to keep it simple. I tried few approaches including mapping 2 layer map to a texture and rendering as an ordinary image. It's quite surprising which approach had best performance. Screenshots were off for purists. Update is bailing out if rendered once. Each time rendered image is exactly the same. Comment if you like. Phaser3 Tilemap with DynamicTilemapLayer. Each tile rendered with putTileAt in a for loop. CPU Usage around 50%. this._tileMap = this.make.tilemap({ tileWidth: 16, tileHeight: 16, width: 80, height: 50 }); ... this._layers[A].putTileAt(t, x, y); Phaser3 RenderTexture with addToScene=false. Each tile rendered with drawFrame in a for loop. Output with addImage at the end. With this approach CPU usage is around 10-20% but the computer is surprisingly unresponsive, despite lower CPU usage than in previous test. How can rendering 1 image be so intensive? const config: RenderTextureConfig = { x: 0, y: 0, width: this._WIDTH*16, height: this._HEIGHT*16, }; this._rt = this.make.renderTexture(config, false); ... this._rt.saveTexture('map'); ... this.add.image(0, 0, 'map').setOrigin(0, 0); Phaser3 RenderTexture with addToScene=true. Each tile rendered with drawFrame in a for loop. CPU usage is negligible - 2-3%. By far the best approach. const config: RenderTextureConfig = { x: 0, y: 0, width: this._WIDTH*16, height: this._HEIGHT*16, }; this._rt = this.make.renderTexture(config, true); ... this._rt.drawFrame(spritesheet, frame, x, y); sanojian 1 Link to comment Share on other sites More sharing options...
sanojian Posted May 19, 2021 Share Posted May 19, 2021 Thank you for this @mariannoga, this saved me a ton of time and was not at all intuitive. Link to comment Share on other sites More sharing options...
Recommended Posts