Jump to content

Rendering thousands of sprites, best way to handle this?


Ralph
 Share

Recommended Posts

Hi there, Im having some issues with performance when i render thousands of sprites. Currently having issues with loading around 20k sprites, but eventually plan on having more (maybe even up to 60k) around the map. I did some research and found this is a somewhat common issue but cannot get a clear and concise answer. I ran some chrome profiles on my game to see whats holding me back: here are my results. To be honest, I don't really understand what that information means other than 20k sprites is too much. (I have a fairly decent computer and its slightly choppy at 20k trees, at say 60k its very choppy) Also, when I say choppy, I mean like it looks choppy, my movement is still fine (to make the point that its not like the game loop thats lagging).

Essentially I have 20k trees being placed around a very large map that's being rendered with a tileSprite. However, it's not the map size that is holding me back since the performance I get is very dependent on the number of tree sprites. The tree's have no physics enabled on them and are just rendered and placed in a group then never touched again. Here is a snippet from my create function and how i render the trees.

 

    for(var i = 0; i<20000; i++){
        treeX = Math.round(Math.random()*(mapSize-1));
        treeY = Math.round(Math.random()*(mapSize-1));
        temp = position(treeX, treeY);
        createTree = game.add.sprite(temp[0],temp[1], 'tree2');
        treeGroup.add(createTree);
    }

The position function I called in the loop just gets the pixel location of the tree's based on a tile, as shown below:

var position = function(col, row){
    column = (33*col+1);
    rowFin = (33*row+1);
    return [column, rowFin];
};

Any ideas as to how i can beef up my performance? Any way I could not render the tree's until they are in view? (Kill then revive when seen?) Any tips are greatly appreciated!

 

Side note (if its useful), right now all I have is the tileSprite background, 20k trees, and movable player sprite. 

 

 

Edit: Would creating a chunk system be a good idea? If so anyone have any idea where to start with the best way to make one? 

Edited by Ralph
added question
Link to comment
Share on other sites

Chunk system is a good idea. Add chunks to the scene if they are somewhere nearby of your view.

You can drop ones that are far away at once, but for neghbourhood its better to drop only one per tick, like in minecraft. 

That all make sence only if you need them to be rich with objects, generated on fly, or downloaded from the server.

Link to comment
Share on other sites

1 hour ago, ivan.popelyshev said:

Chunk system is a good idea. Add chunks to the scene if they are somewhere nearby of your view.

You can drop ones that are far away at once, but for neghbourhood its better to drop only one per tick, like in minecraft. 

That all make sence only if you need them to be rich with objects, generated on fly, or downloaded from the server.

Thank you for the reply, could you give me some guidance as to where to start with a chunk system? And to unload chunks that were already rendered, does .kill() work to remove them? 

Link to comment
Share on other sites

9 hours ago, WombatTurkey said:

Just to add: Changing their visibility to false disables rendering IIRC so that might help (have a secondary timer checking players pos to enable) 

 

20k Seems like awful a lot though, can I ask what exactly is it for? (just out of curiosity)

Open world, bunch of farmable trees and rocks and other resources that they can later place again around the map. Is a bunch of sprites not the best way to do this? lol

Link to comment
Share on other sites

24 minutes ago, Ralph said:

Open world, bunch of farmable trees and rocks and other resources that they can later place again around the map. Is a bunch of sprites not the best way to do this? lol

I'd recommend looking into Phaser-Tiled or something, they only draw what's in the camera's viewport. It helps tremendously. You can have 8000x8000 maps run seamlessly with 2,5, and even 10+ layers. And as many tree's as you want. Warning, no mobile devices will beable to play these lag free  (AFAIK) :D

Link to comment
Share on other sites

1 hour ago, WombatTurkey said:

I'd recommend looking into Phaser-Tiled or something, they only draw what's in the camera's viewport. It helps tremendously. You can have 8000x8000 maps run seamlessly with 2,5, and even 10+ layers. And as many tree's as you want. Warning, no mobile devices will beable to play these lag free  (AFAIK) :D

That what was what i first looked into but I dont want to manually add in these items, plus the map will constantly be changing, items respawning and being removed/placed so I thought doing it through a loop and managing it manually would be the best way to do it. Can a tile map really do all that?

 

Edit: Also my map is 65k x 65k (px) lol but map size hasnt put a damper on any performance just number of sprites around the map. Seems like a chunk system would be the way to go, I looked into the chunk-map thing someone linked above but unsure as to what to really do with it. The concept i want is there but dunno how to turn that into something useful for me. Ill prob end up writing a chunk system from the ground up that will suit my games needs (But that was the path i didnt want to have to take). 

Link to comment
Share on other sites

I'm in the same boat really, I want to built a game that allows for free-roaming an enormous map.

I'm planning on building a gulp task that breaks down one huge Tiled map into chunks that can be loaded dynamically as the world is traversed.

When it comes to game entities, though, you don't want to be cycling through everything in the map - it's just not feasible to have every entity loaded and updated. So you have to decide how you want to break it down.

  • Visiting an area could make these entities spawn, and if, for example, you destroy them, they could just respawn the same as before once you return to that chunk
  • You could store some kind of state for each entity (with some global ID) to record a player's progress, making sure entities don't respawn once destroyed
  • Or a mix of the two - some entities you might want to always respawn, some entities you might never want to respawn

It would be nice if there was a plugin that does some of the upfront work for this without being game-specific (maybe that chunkmap plugin does), but I think solutions need to be tailored for each game for the most part.

Link to comment
Share on other sites

9 hours ago, hexus said:

I'm in the same boat really, I want to built a game that allows for free-roaming an enormous map.

I'm planning on building a gulp task that breaks down one huge Tiled map into chunks that can be loaded dynamically as the world is traversed.

When it comes to game entities, though, you don't want to be cycling through everything in the map - it's just not feasible to have every entity loaded and updated. So you have to decide how you want to break it down.

  • Visiting an area could make these entities spawn, and if, for example, you destroy them, they could just respawn the same as before once you return to that chunk
  • You could store some kind of state for each entity (with some global ID) to record a player's progress, making sure entities don't respawn once destroyed
  • Or a mix of the two - some entities you might want to always respawn, some entities you might never want to respawn

It would be nice if there was a plugin that does some of the upfront work for this without being game-specific (maybe that chunkmap plugin does), but I think solutions need to be tailored for each game for the most part.

I ended up doing somewhat what you described.

 

I made a solution for myself so I thought i would post the logic of it for anyone viewing this in the future.

The route i ended up taking was to just have a array of the map as 32x32 tiles and store all the positions of the to-be created sprites in it. The way I did it was set up a Grid array, that was a 2000x2000 multidimensional array where each "box" was a 32x32 pixel tile. If there was a sprite say on pixel 44k, 22k, I just divide by 32 to get a grid location, so grid[1375][688] is equal to say, a tree. So how I used this was I would check for my player sprite position and set it at a starting point.  Then in my update function, I would constantly be checking to see if the player was over 2k pixels away from the starting position defined when the player sprite was spawned. If the player was 2k away from that point, a new position is set and a region 3k by 3k pixels around the player are rendered, using the grid to get the position of the soon to be created sprites, then spawning them in at that moment. I didnt set up a system to kill the sprites from the old location, which might be an issue if a player walks back and forth between chunks a bunch because then it would be spawning sprites in the same location numerous times, but thats for another day. Basically I just create sprites in an 3k by 3k pixel area around my player using a location for the sprites that was already determined and set into the grid array (Like a map file, but its just an array).

Kinda hard to explain, but if anyone would like me to go more in depth, message me or something and I will prob get back to you :) Thanks for the help everyone on this thread. 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

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