Jump to content

Ideas for Dynamic Map Drawing / Re-Tiling


kaan
 Share

Recommended Posts

When I started building a game, I didn't think map drawing/re-drawing would be an early issue, but when I placed 30-40K 16x16 test tiles on the map, it became an issue, the fps quickly dropped to 10-20's

I initially intended to draw the entire map at start, and hoped PIXI would ignore the parts which are outside the viewpoint, I'm assuming this is not the case? (It obviously isn't, let's move on)

My current solution is to redraw the map at each 100px movements, I was initially only drawing the additional 100px's, however at the edge's things got complicated, things that should be behind things got above them, so I started redrawing everything, which is simple, yet ~3K sprites are destroyed and re-created at each update, which happens regularly if the character is moving

I tried using pixi-display and setting an explicit zOrder for each tile - and - more easily updating tiles, deleting/adding ~100 sprites at each update, yet the performance doesn't change much

So, currently, with the "redraw the entire viewpoint" method, the fps is 60, yet I feel some minor sluggishness, some frames are 50ms, the retiling takes 10-20ms, and considering there is few actual map data, I'm not sure whether re-visiting a hefty map data would be an overhead too (I'm unsure whether 2D range trees etc. are needed or not)

I'm just wondering whether I'm re-inventing the wheel, whether there is an intended solution that will solve the problem without any significant overhead etc.

I'm yet to inspect the existing solutions, pixi-tilemap to start with, I had to find an immediate solution and redraw-all was it

Link to comment
Share on other sites

You just cant analyze 30-40k tiles every frame with javascript, it will be slow. 

Your current solution is ok, and it is the required behaviour to use pixi-tilemap. Clear tilemap after movement and fill it. It's one of the best methods to get 60FPS there.

Are all your tiles from a single atlas or are they different? pixi-tilemap can have some problems when there's a number of textures, so please free to consult me on that.

Link to comment
Share on other sites

1 hour ago, kaan said:

I was initially only drawing the additional 100px's, however at the edge's things got complicated, things that should be behind things got above them, so I started redrawing everything

You mean, you cached the rendered map into a texture, and on the next frame, copied the middle part from the cache and redrew at the edges? I have implemented this approach, demo is here - http://forest.netlify.com/ (without PIXI, just 2d canvas). z-order should not be a problem, just save each sprite's z and sort by z before drawing....

 

 

Link to comment
Share on other sites

1 hour ago, Fatalist said:

You mean, you cached the rendered map into a texture, and on the next frame, copied the middle part from the cache and redrew at the edges? I have implemented this approach, demo is here - http://forest.netlify.com/ (without PIXI, just 2d canvas). z-order should not be a problem, just save each sprite's z and sort by z before drawing....

 

 

No it was more basic, I attempted to remove things that went outside the viewport, and add the new things every frame, yet since order is important with rpg tiling, it didn't work out, the logic has to be bulletproof, mine wasn't (sometimes a 16x16 tile that is under an 8x8 overrides the 8x8, my conditioning was simple, didn't include a solution to this problem)

3 hours ago, ivan.popelyshev said:

You just cant analyze 30-40k tiles every frame with javascript, it will be slow. 

Your current solution is ok, and it is the required behaviour to use pixi-tilemap. Clear tilemap after movement and fill it. It's one of the best methods to get 60FPS there.

Are all your tiles from a single atlas or are they different? pixi-tilemap can have some problems when there's a number of textures, so please free to consult me on that.

They are from multiple .png images currently, otherwise I was going to test pixi-tilemap

It was nice seeing Fatalist's example, the same slowness happens there too, so I guess it might be system related, every now and then, the 60fps becomes ~57, but since there is a pause that causes the dip, it is perceived as sluggishness (osx, gt750m, chrome, so anything is possible)

I do want to inspect Fatalist's code in more detail when I can, the stats are impressive

My next idea is to draw the map into 128x128 Sprite's, and add/remove these Sprite's to the map when the viewport shifts -- It's another lazy and easy to apply solution, it eliminates the need to analyze the map data at each update, solves the issue of order -- on theory, the only downside (to me) seems to be the extra memory usage (and some things are drawn multiple times, but shouldn't be significant)

Link to comment
Share on other sites

14 minutes ago, kaan said:

My next idea is to draw the map into 128x128 Sprite's, and add/remove these Sprite's to the map when the viewport shifts -- It's another lazy and easy to apply solution, it eliminates the need to analyze the map data at each update, solves the issue of order -- on theory, the only downside (to me) seems to be the extra memory usage (and some things are drawn multiple times, but shouldn't be significant)

Pixi-tilemap does something like that, its just all the sprites are stored in the buffer.

Something like @Fatalist solution is used in my gameofbombs.com - here's the js code (not pixi) https://github.com/ivanpopelyshev/bombermine-shuffle .

I ask you again to specify exactly how many textures are you going to use and what are they dimensions. I have experimental branch of pixi-tilemap that deals with 16 1024x1024 tilesets for rpgmaker MV, I can make configuration for your case or recommend how to improve it. 

Also I'm working on solution that allows to have a lot of z-ordered tile sprites with character sprites moving between them

Link to comment
Share on other sites

12 minutes ago, ivan.popelyshev said:

Pixi-tilemap does something like that, its just all the sprites are stored in the buffer.

Something like @Fatalist solution is used in my gameofbombs.com - here's the js code (not pixi) https://github.com/ivanpopelyshev/bombermine-shuffle .

I ask you again to specify exactly how many textures are you going to use and what are they dimensions. I have experimental branch of pixi-tilemap that deals with 16 1024x1024 tilesets for rpgmaker MV, I can make configuration for your case or recommend how to improve it. 

Also I'm working on solution that allows to have a lot of z-ordered tile sprites with character sprites moving between them

What do you mean by "its just all the sprites are stored in the buffer." - If I create but not render Sprite's, will they still slow down things?

I currently have 12 map tilesets, all of them are smaller than 1024x1024

I intend to make the map smaller than 10.000x10.000, there will be areas which are just a rectangle, filled with a single tile, and the data for the map has to be <1MB, yet the actual number of tiles can be high, so my 128x128 pre-prepared map-piece-sprite idea might be a bust too, there might be 100K un-drawn individual child sprites in total (~16x16 tiles that are the children of the un-drawn 128x128's), not sure how much of a memory impact they will make

I was also going to specially declare some tiles and integrate pixi-display to them, for example a tree, or a castle arc where you walk inside, yet I decided that it's an extreme amount of complication for something so simple, so decided to skip it for now - so now you can't walk into a tree, and the castle doesn't have an arc, walls are unconnected :) - Even if you solve the technical challenge, modifying my custom map editor for such an extra layer/section would be challenging

Link to comment
Share on other sites

54 minutes ago, kaan said:

It was nice seeing Fatalist's example, the same slowness happens there too, so I guess it might be system related, every now and then, the 60fps becomes ~57, but since there is a pause that causes the dip, it is perceived as sluggishness (osx, gt750m, chrome, so anything is possible)

57fps is not low enough to cause it, I think that's just Chrome's vsync bug. It's smooth in other browsers. I don't think there is a way to eliminate that occasional sluggishness in Chome...

Link to comment
Share on other sites

38 minutes ago, kaan said:

What do you mean by "its just all the sprites are stored in the buffer." - If I create but not render Sprite's, will they still slow down things?

I currently have 12 map tilesets, all of them are smaller than 1024x1024

I intend to make the map smaller than 10.000x10.000, there will be areas which are just a rectangle, filled with a single tile, and the data for the map has to be <1MB, yet the actual number of tiles can be high, so my 128x128 pre-prepared map-piece-sprite idea might be a bust too, there might be 100K un-drawn individual child sprites in total (~16x16 tiles that are the children of the un-drawn 128x128's), not sure how much of a memory impact they will make

I was also going to specially declare some tiles and integrate pixi-display to them, for example a tree, or a castle arc where you walk inside, yet I decided that it's an extreme amount of complication for something so simple, so decided to skip it for now - so now you can't walk into a tree, and the castle doesn't have an arc, walls are unconnected :) - Even if you solve the technical challenge, modifying my custom map editor for such an extra layer/section would be challenging

Then you can use this branch: https://github.com/pixijs/pixi-tilemap/tree/dev-multitexture . Its exactly for your case. Every time you scroll just clear it and refill again, like you are doing now with sprites. It will use about 8 floats per tile = 32 bytes. That's the most efficient way for webgl because it uses gl.POINT mode which is really cheap. 

If you want canvas fallback, use rpgmaker approach: make a temporary associated texture. Tile with coordinates (x,y) will be rendered at (x % width, y%height) point at that texture, and to render it on screen you can use 4 PIXI.Texture rectangles. For demo please buy rpgmaker MV in steam and look at its output :) Do not use that approach on webgl, it will be slow!

Link to comment
Share on other sites

@kaan 57FPS is GC lag. It has to clean all your garbage Sprites you did create before.

Your case is important for me because I have to test my API somehow :) right now it is used only in future rpgmaker version. If you help me, I'll implement many more things for tilemaps, including some fantastic stuff I have blown brain of @Mat Groves with

Link to comment
Share on other sites

I think it's both the Chrome lag, as I see the occasional spikes on http://www.duckware.com/test/chrome/jerky3.html - and probably an additional delay too, might be from GC as you pointed out

Currently my map is very basic, it's basically a small land piece on an infinite default tiles, so testing is a bit futile - the thing is, I'm unsure whether a pre-calculation in terms of map data/placement is necessary (most probably not)

If the map placements is safe to re-calculate every frame, then the bottleneck becomes the drawing

So basically, I'm going to extend my map format and map data right now, move towards an actual production map a bit, with no default tiles, with tiles that fill a rectangle that they are defined to, so the map data will be compact, yet the actual map will be not - there are repeating tiles, there are repeating edge tiles, there are repeating animating tiles, and there are cosmetic tiles - so until an actual map is ready, it's hard to speculate where the actual bottleneck is going to be

You help everyone as much as you can, so I want to help your as much as I can, so I will try to test https://github.com/pixijs/pixi-tilemap/tree/dev-multitexture when I can, probably after the map data is ready

As a very small humble suggestion, the documentation of pixi-tilemap is a bit lacking, so for an outsider, it's unclear what exactly the library does best and how exactly it's going to be used

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

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