Closed craftworkgames closed 7 years ago
I think the very first thing to do is choosing boundaries for each target platform, as:
So low platforms "deserve" a lower quality to have a playable game.
Another point is data structure, what do you really need to render a tiled map ? A single dimension array of Byte may be enough (2D are managed by calculating rows), 255 values should be more than enough to do something quite good as tile have to be optimized at the source. Behind the scene tile effect on characters use these values to work (ex: water tile = 0 => slower speed, sink for ground vehicle, ... or water are 0, 1, 2, 3 for 4 different depths if needed by the game, like a strategy game where small and huge rivers, shores, etc are very relevant)
Then, a good way to manage big world is using 3D worlds strategy with octree, occlusion and pseudo-random numbers/noise generators as for 3D worlds, storing heightmaps is definitely not the best way, but having one single 32 bit integer for an entire chunk used as seed (generated heightmap's size depend on target resolution), and generate heightmap a bit ahead if it has a reasonable chance to be used, freeing memory used by the one left behind, may do the job.
(look at my comment in the #138 issue, SharpNoise can be use to generate tiled map (at planetary scale !) for example.)
choosing boundaries for each target platform align everything to the lowest capable = poor game/poor quality on high-end hardware
There are many different platforms... Windows, Mac, Linux, iOS, Android, Windows Phone, Ouya, Playstation, Playstation Moble, Xbox...
Another point is data structure, what do you really need to render a tiled map?
@InfiniteProductions
Yes it's possible to infer the X and Y position of a tile by the index of a single dimension array (x = index % mapTileWidth
, y = floor(index / mapTileWidth)
), or by multidimensional arrays. Having each tile as a int
or uint
would probably be a good idea but pretty sure that breaks the existing API for Tiled maps.
Then, a good way to manage big world is using 3D worlds strategy with octree, occlusion and pseudo-random numbers/noise generators as for 3D worlds, storing heightmaps is definitely not the best way, but having one single 32 bit integer for an entire chunk used as seed (generated heightmap's size depend on target resolution), and generate heightmap a bit ahead if it has a reasonable chance to be used, freeing memory used by the one left behind, may do the job.
@InfiniteProductions Tiled maps are 2D only... But, yes there are some better ways to do things for certain games, and that's why AAA games have their own special written engine because they know the target hardware architecture that will be used and the assumptions of their single game in advance. But, MonoGame.Ex is not an engine. Not every game has the same assumptions, requires the same algorithms or runs on the same architecture... The best MonoGame.Ex can provide is just the pieces of software people can choose to use, or not use, to build their game. A lot of thought has to be put into these pieces of software to make sure they are de-coupled, unlike engines which can couple things together for convenience or efficiency. Open a new issue if you want to talk about 3D techniques unrelated to Tiled maps.
The best MonoGame.Ex can provide is just the pieces of software people can choose to use, or not use, to build their game.
Yep, that's pretty much it. MG.Ex is intended to help you build your games faster by providing one possible implementation of the features you might need. For a lot of games this will be more than enough. It lowers the need to roll your own everything.
Of course, it's not going to cover every possible scenario. Sometimes you'll still want to roll your own bits for the specific needs of your game. That's one of the benefits of being open source. If you need to make changes you can fork the project or just copy and paste the bits you want.
As for this particular issue, it really boils down to the limitations of using render targets and sprite batches. We might have to come up with a different way to render the map. Maybe by using a polygon mesh instead of rendering every tile a single sprite and trying to stitch them together at the edges.
I'm not really worried about this issue. I'm certain it can be solved. It's just not going to be a simple tweak to the existing implementation.
Hi there,
I'm not using the library (yet) but just looking at it and thinking about ways to contribute. One thing I do in my codebase now for performance is using quadtrees to cull what's visible. Memory overhead is low(er) than normally stuffing an entire tilemap into memory and the quadtree takes care of pulling out what's visible and what isn't along with managing the memory usage and dead child nodes. Maybe I can take a look at this from this angle (spike out an example and see if you agree it's a good approach then fold the code into the library).
@bsimser That's sounds great. I've created a new branch called tiled-memory-usage
. Please make a fork of that branch so it's easier to merge the changes back into the library.
Ugh. Months later and I still haven't got to this. Just wondering @craftworkgames where things are at with the map rendering. I see #221 which is huge. I stumbled over the RenderTarget2D problem yesterday when I loaded up a 1024x1024 map of 24px tiles. It blew up and I had to size my map down to 512x512 to make it work. Should everything go through #221 now? Is the tiled-memory-usage fork still where we should be working? Thanks.
Is the tiled-memory-usage fork still where we should be working? Thanks.
Everything is in the develop
branch at the moment. The render is still a work in progress and I don't think anyone is actively working on it. And yeah, #221
I guess I'll close this issue since the memory issue is technically fixed with in new renderer.
Currently we are rendering each layer of the entire map to a render target and caching that render target in memory for future renders. This gives the best possible frame rate performance at the cost of memory.
Ideally, we'd like to have the ability to use different draw strategies for different situations. I've had a couple of attempts at implementing this but it's more complicated than I first realized. This discussion is about what we can do about it.
We started discussing this issue in #132 but that was off topic. Here's the relevant bits.