Jump to content

Help optimizing dynamic map loading (canvas)


Krave
 Share

Recommended Posts

Hey guys, I've been working on an isometric game engine for my own game. Currently, it's a big, open world with the map data being retrieved dynamically from the Node.js server. 

To understand what I'm doing... for the most part it's a tile based world. So each map has a max number of cols,rows (19) and each world has a max number of maps by col,row (6). So it's a 6x6 world map consisting of 19x19 tiles per map. Whenever the players move onto a new map/region, the client requests a 3x3 matrix of the surrounding maps with the center map being the map the player is currently on. This part is pretty well optimized.

My problem, however, is finding a great way to optimize the drawing onto the canvas. Currently, I don't have a lot of lag doing so, but I also have a fast computer, but I worry that at times it could cause others to lag / mess with the rendering of other graphics.

Basically, how I have it working right now is when the data is sent back from the server, it adds each map and all the tile images for each col/row it has to render into a buffer. Each loop of the game loop, it will basically render a small section of the 25 tiles onto the specific map's hidden canvas. When all of the requested maps are done rendering (after a few game loops), the camera will go ahead and merge these hidden maps into 1 big map canvas of the 3x3 matrix (by slicing parts from the hidden canvases and merging them onto the new canvas).

Ideally I would love this whole process to be async. but I've been looking into web workers and apparently they do not support canvas well. Has anyone come up with a process to do something similar and keep it well optimized?

 

Thanks!

Link to comment
Share on other sites

You can draw parts of a map sequentially, so you draw each chunk individually, but its only really necessary if each chunk takes longer than 16ms to render (mostly refresh rates are 60fps, i.e. ~16ms). Batching from a hidden canvas to your main visible canvas is super quick though, its just copying image data from one canvas to another.

It sounds like you've already optimised by only attempting to draw the parts of the game world that are actually visible on screen. This is likely already quick enough, the only way of really testing is to fire it up on the lowest-powered device you're aiming to support and seeing if there are any problems.

Web workers could be used to retrieve the map data and maybe do any transformation to turn it into the data needed to render, but web workers can not manipulate the DOM and it does not sound like you're actually doing much so I expect the overhead of firing up workers would outweigh the cost of doing it in the main thread (not to mention handling web workers at the developer end is a fairly major chore, its certainly adds complexity).

Things like underlying tilemaps often do not change, or do not change often, so you can draw once and simply translate the layer/container/whatever.

Link to comment
Share on other sites

Thanks very much Matt. 

Actually I was considering to use the web workers to parse the map data and get everything ready for rendering, pre-rendering just to be safe. There really are not a lot of problems except for lag, at times, when loading the next maps. I believe the web workers parsing it could help out, but I really do believe the majority is coming from the rendering of the canvases, granted it's only set to render 25 tiles at a time per frame, which makes it much smoother and less noticeable, it's that little bit that comes from time to time I'm trying to solve and figure out the best way of approaching dynamic map loading like that.

Link to comment
Share on other sites

I used it to generate heightmaps before, but we're talking 512x512 (think I even went larger) textures from arrays, the web worker solution worked out well and kept jank off the main thread but, just so you're aware, it actually made rendering take longer because there is a cost associated with firing up web workers (you could probably also optimise that so you fire it up only once and then pass messages around), not to mention that it is far more complicated.

I'm not sure I understand why rendering 25 tiles is causing any lag at all for you. Are you using something like Phaser, or just Pixi, or something else?

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...