j0hnskot Posted June 9, 2014 Share Posted June 9, 2014 Hello there!I got a tilemap and a sprite. I make the camera follow the sprite. But when the camera starts moving i got 10+ fps drops. I guess this is because of the tilemap. Are there any ways to decrease this loss of fps?My layer's size is 6400x480 (32x32 tiles) If i reduce the size i will probably gain some fps. But that's my last option since it reduces the size of the level. Any tips are appreciated! Link to comment Share on other sites More sharing options...
lewster32 Posted June 9, 2014 Share Posted June 9, 2014 Could you upload an example? Link to comment Share on other sites More sharing options...
j0hnskot Posted June 9, 2014 Author Share Posted June 9, 2014 Here is the game http://j0hnskot.weebly.com/blog/-include-name-my-platform-games-prototype The problems doesn't show up on good machines. On my main pc it works ok since it's not such a load for it. But on my netbook and mobile the performance loss is visible. Link to comment Share on other sites More sharing options...
lewster32 Posted June 9, 2014 Share Posted June 9, 2014 It's hard to say from such a complete game (great idea btw!) but I'd probably recommend commenting out various parts of the code (the HUD update and other bits) and see how the fps changes. I'm not completely convinced the issue is the camera following - you could comment out the camera follow part of the code and see if the game's fps drops even when the camera isn't following the player. If it doesn't, then maybe you could rather than using the camera to follow the player (which may be a little bit over-engineered for a simple scroller such as this) just apply a constant speed to the camera to make it scroll at the same speed as the player. Link to comment Share on other sites More sharing options...
j0hnskot Posted June 9, 2014 Author Share Posted June 9, 2014 Before the scrolling starts the fps counter is ~30 fps. When the scrolling start it goes to ~20 fps.Yesterday i tried disabling the follow() and the fps stayed at 30 so i guess this is a part of it. I'll try disabling more like the hud like you said and i'll let you know. (thank you for your comment on the idea!) Link to comment Share on other sites More sharing options...
lewster32 Posted June 9, 2014 Share Posted June 9, 2014 If you're only getting 30fps in the first place, something is definitely taxing your devices already - Phaser should typically run at 60fps. Something happening in one of your update/render loops that's impacting performance to the degree that the small amount of extra impact from scrolling is affecting the game much worse than it should. Link to comment Share on other sites More sharing options...
valueerror Posted June 9, 2014 Share Posted June 9, 2014 well .. as lewster already said... if your game starts at 37 frames (on my pc) (where nothing is happening) there is something else wrong.. scrolling tilemaps is definitely ressource hungry.. but even on a low end machine 2 - 3 layers should be oke.. Link to comment Share on other sites More sharing options...
j0hnskot Posted June 9, 2014 Author Share Posted June 9, 2014 valueerror can you please refresh the page and rerun the game and tell if you gained fps? I think the background messes with the performance, Link to comment Share on other sites More sharing options...
valueerror Posted June 9, 2014 Share Posted June 9, 2014 hmmm.. nothing changed.. but one thing i just saw is that the fps don't change when the scrolling starts.. so i loaded a layer-test-example i created for a github issue concerning the performance of tilemap layers and huh... the same problem occurred in my example (where there is no other code that could interfere at all) i should have 60 fps straight in my example ... at least it was that way some weeks ago...http://test.xapient.net/phaser/ALL/layers.html?count=1 i closed chromium browser and reloaded everything.. now i have 60fps in my example AND in your game ! still don't know why but i had a similar problem 3 days ago on my nexus7 where my mario game had 30fps instead of 60fps.. maybe you hit a new phaser bug somehow? Link to comment Share on other sites More sharing options...
j0hnskot Posted June 9, 2014 Author Share Posted June 9, 2014 I am stripping down my code and it drives me nuts. Every thing i stop from running gives me nothing or 1 fps maximum.Then i tried a tutorial of phaser , the one in the resources with the dude and the stars falling. On this example the same device runs on 31 fps max. Maybe i'm hunting ghosts here and the phone just sucks enough ? Link to comment Share on other sites More sharing options...
julacariote Posted June 10, 2014 Share Posted June 10, 2014 I have the same issue on my project, FPS drops from 60 to 40 when the camera scrolls to follow the player. My tilemap is not that big, 800 x 2016 pixels with 32px tiles. So I tried to display FPS on the Sci Fly phaser example: same thing happens, FPS is at 60 when no scrolling occurs and drops to 40 when camera is moving. On your example valuerror, FPS drops from 60 to 50 with one layer and from 60 to 25 with 4 layers. Such a drop sounds weird on a laptop with solid hardware, what do you think? Renderer is webgl (Firefox on Ubuntu). Link to comment Share on other sites More sharing options...
marvster Posted June 10, 2014 Share Posted June 10, 2014 I had the same issue, especially on firefox, but also on chrome (but not on ie, no joke).Everytime I've combined tilemap scroll (top down map) with camera following the player, frame rate goes down from 55-60 to under 15-30fps, which causes collision detection to fail. My solution was to have the camera fixed to screen and use a zelda like scene scrolling for the tilemaps. Link to comment Share on other sites More sharing options...
valueerror Posted June 10, 2014 Share Posted June 10, 2014 here is the github issue i opened a while ago..https://github.com/photonstorm/phaser/issues/839 on firefox the fps of my test are even worse.. here is the same example for you to test with canvas forcedhttp://test.xapient.net/phaser/ALL/layers-canvas.html Link to comment Share on other sites More sharing options...
julacariote Posted June 10, 2014 Share Posted June 10, 2014 On my laptop, the FPS never goes below 55 with canvas forced, even with 8 layers while it drops to 15 with webgl as renderer... (when scrolling of course). Link to comment Share on other sites More sharing options...
lewster32 Posted June 10, 2014 Share Posted June 10, 2014 It should be pointed out that neither the Phaser camera nor many of the other features are inherently fully optimised for a specific game type; their lower performance is the tradeoff you pay for ease of use. All the camera does is follow an object, which is pretty low-level. What's interesting is that despite the maturity of modern hardware and frameworks, the cross-platform nature means many of the same old performance tricks are still very much applicable. If you look into scrolling routines for tile-based games, you'll often find that instead of a camera moving around the map, the map itself is moved around and tiles outside of the 'camera' (usually the screen) are clipped with a very fast rectangular routine - Phaser's per-sprite bounds checking is not as optimal. Along with some additional logic that reduces the rate of update (or stops it entirely) of items outside of the camera, the results are much more performant, regardless (within reason) of the size of your world - one thing we do have over old hardware is much more memory! The bottom line is that old-fashioned optimisation techniques are just as relevant today as they were 20 or 30 years ago, and as game developers these are definitely relevant to your interests so you can squeeze every last drop of performance out of your games. Link to comment Share on other sites More sharing options...
j0hnskot Posted June 10, 2014 Author Share Posted June 10, 2014 @marvster Yes zelda-like scrolling surely increases performance. I'll work like that if i don't find another way to boost performance. @lewster If i understand correctly, you suggest to move the tiles towards the player instead of moving the camera? Or this is the way phaser works?As you saw i got some moving platforms in the game. Moving all the tilemap and the sprites towards the player wouldn't it be more expensive? Sorry if i didn't understand your explanation. As for my phone. I don't know why , but running an empty scene with nothing but an fps counter runs at 35fps max. Either there is a fps limit or i don't know what the heck happens. Link to comment Share on other sites More sharing options...
lewster32 Posted June 10, 2014 Share Posted June 10, 2014 @lewster If i understand correctly, you suggest to move the tiles towards the player instead of moving the camera? Or this is the way phaser works?As you saw i got some moving platforms in the game. Moving all the tilemap and the sprites towards the player wouldn't it be more expensive? Sorry if i didn't understand your explanation. A Tilemap is a kind of special group whose contents are assembled by reading data in a particular format, but beyond that I don't believe it includes much in the way of optimisation. The camera then moves around this group just as it would do in any other scenario. A more optimal strategy for a tile-based game (and one used in most that I know of) is to instead of building the entire group of objects at the beginning then scrolling around them, to rather only build the part of the tilemap that's needed to display onscreen - and scroll that part around, adding tiles to the leading sides as it scrolls, and culling them from the trailing sides. With object pooling to simply move culled tiles to a place where they're about to be shown and changing their texture frame, this can be very fast. Look here for a nice example. Unfortunately I expect that type of functionality would fall outside of the realms of what Phaser can (and indeed should) be doing within the framework, as it would likely break the camera in any other scenario, or lead to there being a need for two separate cameras; a tilemap camera and a normal camera. Phaser is attempting to provide a unified and wide-ranging SDK to help get the ball rolling, but if you're keen on very specific functionality or high performance for your specific type of game, you'll have to dig a little deeper and start expanding Phaser's repertoire yourself. marvster 1 Link to comment Share on other sites More sharing options...
julacariote Posted June 11, 2014 Share Posted June 11, 2014 Thanks lewster32, that's really interesting, I will keep digging on that. Still, can anyone explains me why valueerror examples work perfectly at 60 fps with canvas renderer on my laptop but drops to 20 fps with webgl renderer? Is it somehow because my GPU is crap? Is it because browsers on Ubuntu don't play well with the GPU? Or are they any other possible explanation? Link to comment Share on other sites More sharing options...
lewster32 Posted June 11, 2014 Share Posted June 11, 2014 I think when running GPU stuff in the browser in Linux often all bets are off; there are many things that can go wrong or be bottlenecked and I don't think there are many people around who can claim to understand the issue fully. The only way to be sure is to get the browser profiler out and see where the bottlenecks lie. Link to comment Share on other sites More sharing options...
valueerror Posted June 11, 2014 Share Posted June 11, 2014 webGL sucks on linux.. i tried nouveau and the binary blob -- both suck hard.. i force canvas because on mobile (with cocoonjs) webgl is even worse but canvas (with a little phaser hack) works perfectly... Link to comment Share on other sites More sharing options...
j0hnskot Posted June 11, 2014 Author Share Posted June 11, 2014 @lewster I did some tweaks to the tilemap by using objects instead of tiles to be able to move everything towards the player and the fps are stable now.There is little fps increase but the huge problem is kinda solved. The next step is to brainstorm a way to use object pooling and spawning the tiles on demand.If anyone got an idea please inform me! Link to comment Share on other sites More sharing options...
lewster32 Posted June 11, 2014 Share Posted June 11, 2014 Create a group for your tiles and fill it with a number of sprites (you may have to play with the number to see how low you can get it without running out mid-game) and then implement something like in the link I provided. The (slightly) tricky part will be writing a routine which analyses the data you use to store your maps and decides which column of tiles to draw at the leading edge of the scroll. In side-scrolling games of old, the maps were often stored top to bottom, left to right, rather than left to right, top to bottom - this allowed the scrolling routine to sequentially grab a column of tiles at once and initialise them past the right-hand side of the screen. If you can't arrange your tiles in this format a little bit of maths could help you grab columns of tiles at a time. For each column you grab from your data format, you'd loop through them and do something like this:// create a pool of tiles and assume you're using a sprite sheet/atlas to set the framesvar tiles = game.add.group();tiles.createMultiple(100, 'tile', 0, false);// getColumn would be a function you write which grabs an array from your data format// at the specified x position containing the type of tile, with 'empty' being a special// tile which represents empty space (surprisingly!) but could be 'ground', 'spikes' etcvar column = getColumn(x);// our simple culling routine - do this first to free up as many tiles as you can before// populating the leading edge of the scroll with new tilestiles.forEach(function(tile) { // remove any tiles that have moved off the left-hand side of the screen if (tile.x < TILE_WIDTH) { tile.kill(); // ... here you may want to do other cleanup work like resetting all of // the tile's properties, removing callbacks, tweens etc. }});var tile; // placeholder for operating on individual tilesfor (var t = 0, len = column.length; t < len; t++) { // ensure the tile for this row is not empty if (column[t] !== "empty") { // get a currently not in use tile from the pool tile = tiles.getFirstDead(); // make sure we have a tile - if this fails we need to ensure we're culling tiles // properly; if we are, increase our pool size if (tile) { // revive this tile and place it just to the right of the screen and at the right // height by multiplying the loop index by a constant that represents the height // of your tiles tile.reset(game.width.x, t * TILE_HEIGHT); // set the tile to the correct frame tile.frameName = column[t]; // ... here you would also set any other properties for this sprite - be careful // that all properties are reset or you may have revived sprites carrying over // properties, tweens and callbacks set previously } }}This code makes some assumptions; that the tiles are evenly sized and that the game only scrolls in one direction. It's easily adapted to allow the game to scroll in the opposite direction, but will require a bit more work to allow it to work in four directions. This routine has some things missing which you'll have to fill in the blanks for - namely the scrolling method itself, which should have a scrollPosition and also a way of knowing when it's scrolled more than one tile's width so it can call this routine to add new tiles to the leading edge. WombatTurkey 1 Link to comment Share on other sites More sharing options...
Quinten Posted November 19, 2016 Share Posted November 19, 2016 Maybe this will help someone who is looking for tips: I have a game with a tilemap made in Tiled. The tilemap is 128 x 128 in size with tiles of 16 x 16 resulting in a small sandbox world of 2048 x 2048 pixels. Now the game was running okay, but on an older laptop of mine it had some lag dropping in fps from 60 to 40/30 when moving the camera. (i'm not even talking about mobile, that i still have to tackle). First thing i did was putting the visible property of the 2 layers of the map to false. Which stopped rendering the tilemap, but kept all the game objects still colliding the map. Then i got rid of the tilesetimage, which i did not need anymore. Then i went back to Tiled and exported the whole map as an image and added that image as background to the level. in the preload: game.load.image('levelflat', 'assets/sprites/level.png'); and in the create function: var levelbg = game.add.image(0, 0, 'levelflat'); That made a very noticeable boost i must say. Resulting in no more lag on the old laptop. Even on mobile it was almost there, but there still was another element causing lag on mobile. Now i must note that this probably won't work with very large levels. It all depends on how large you can make the images of the backgrounds. pdiddles03 1 Link to comment Share on other sites More sharing options...
dieedi Posted November 29, 2016 Share Posted November 29, 2016 On 19/11/2016 at 10:39 PM, Quinten said: Maybe this will help someone who is looking for tips: Oh yes it was really helpful ! I've got some lags on my app and didn't manage to find why before seeing your post. I've had rendering problems after game start scrolling with some renders taking 40ms or more. I've did what you say, turn off visibility on tilemap and add back image as tilesprite and it's like night and day. (my game 8992px large ...) I'm now at 60fps during all the game. Thank you for this tip Link to comment Share on other sites More sharing options...
Quinten Posted November 29, 2016 Share Posted November 29, 2016 6 hours ago, dieedi said: Oh yes it was really helpful ! I've got some lags on my app and didn't manage to find why before seeing your post. I've had rendering problems after game start scrolling with some renders taking 40ms or more. I've did what you say, turn off visibility on tilemap and add back image as tilesprite and it's like night and day. (my game 8992px large ...) I'm now at 60fps during all the game. Thank you for this tip No problem you're welcome Link to comment Share on other sites More sharing options...
Recommended Posts