I’m working on a silly 2d RTS whose environment is depicted entirely with tiled Paper2d sprites, but I’m running into a serious performance bottleneck when I try to increase the size of the world. I can display about 400 sprites onscreen before the framerate shows any dip at all, but once I pass 400 it rapidly degrades, by the time I have 1,000 sprites onscreen the framerate is well below 22fps. This makes me think that I’m using paper2d outside the intended scope of its use case, is there an established design pattern to draw large numbers of sprites without a performance dip, kind of like a 2d equivalent of instanced meshes? Or am I unlikely to ever find a performant way to maintain thousands of actors onscreen at once?
There’s a paper grouped sprites component in which you can run a for loop and place all your static paper2d sprites into, then delete the source. This should still retain collision and should make your floor one render call to ease up the performance. I’ve done this before with huge maps because once you’ve gotten too big of a map you’re gonna get these issues. I think the better solution might be to use TileSets and Tile maps, split your map into sections and recreate them with tile maps in separate levels, then use level streaming to load in each map when you’ve reached a certain range of “closeness.”
Ooh, the grouped sprites component is good to know about, thank you! I suspect that using world composition/streaming is the inevitable best choice here, the reason I was seeking a way to keep everything in one level (which I suspect doesn’t exist) was to let the player zoom suuuuper far back and survey 25-30% of the map at one time. If I reduce that to more like 5% visibility and keep the zoom restricted to, say, 200-300 tiles onscreen at one time, the cost of tiles becomes negligible, and even when I keep thousands of 'em in a single level, the occlusion and frustum culling solves the performance problem.
Yes, Yes it does :). I see what you’re trying to achieve. Let me know how the grouped sprite component works for ya.
I’m going to semi-seriously screw around with it for a while, and I’ll let you know… weirdly enough, it’s the least efficient solution when I just do the glue & duct tape 30-second setup. With 600 map tiles onscreen, I average the following per stat UNIT:
Cube mesh with texture painted on: draw 16ms
Instanced mesh: 15ms
Individual sprites: 14ms-ish (it fluctuates a lot)
Grouped sprites: 17ms