1
votes

I'm making a game right now with a friend and we're having a dispute over how to draw the tiles in the game. The game is 2d, top down, with an isometric look. Each tile is either a floor tile (which the player can move on) or a wall tile (which the player and other objects collide with). Each tile is a combination of 4 textures which are determined by what the adjacent tiles are. This makes long flat walls be unique to corners. As it stands, drawing 4 textures for ever tile on screen takes up a good bit of speed.

So I suggested that we change how these tiles are drawn. Since the tiles don't move or change texture, I came up with the idea that we could paste all of the textures onto a single large image before the game starts running, and then draw that instead of each individual tile. The tiles and their collision boxes still exist, but aren't drawn. The change has resulted in a fairly significant boost to speed. My friend says that the complications of doing this aren't worth the speed boost, and brought up these concerns:

  • While the game runs faster, the initial loading time is longer.

  • In XNA, the maximum size of a texture is 4096x4096, meaning with our tile size that each "megatexture" could only account for 128 tiles.

  • We need a separate megatexture for each screen layer, which could get complicated.

Despite this, I still think that the megatexture method is better, and we should use it. So what should we use? What do other tile-based games do? Let me know if I'm not specific enough.

3
When you say "a significant boost to speed" what do you mean exactly? If you boost from 60 fps to 90fps, that doesn't really matter draw-wise, because the screen can usually only refresh at 60fps. However, an increase from 20fps to 60 is much different, and would probably be worth changing the textures. (Btw, could you maybe add your draw code?)davidsbro

3 Answers

1
votes

Firstly, you sound like 128 tiles is a tiny bit of tiles. You can do really amazing things with 128 unique tiles on a single map. You can also opt to blend these textures using alpha textures to create thousands of unique tiles. Per map this is plenty, take a look at some good old games. They do a very good job at hiding the grid and making things look really good with only a quarter of unique tiles.

On the technical site, the amount of textures a graphics card could store is limited and with to many textures you run into the problem where the GFX need to dispose of textures taking extra time obviously. If you declare one big spritesheet for a single area you are a lot less likely to run into problems. Just load a new spritesheet for another area if needed.

I am not sure about XNA but i strongly believe it, like many engines, stores it's textures as powers of two. So if you do not have these constraints on your textures the size will be rounded up. This is another big reason to create sheets.

My personal experience is that having a spritesheet with 16 textures vs 16 separate textures can improve the performance very much. I can zoom much further out on a tilemap drawing 1000's of sprites with a spritesheet. Since you are talking about tile size of about 32x32 which draw roughly 2000 sprites on a fulle HD screen i really sugest using sheets, or even two sheets if you really need the extra tiles. Do not worry about the size either, a 4048x4048 is a bit over 10MB in simple dds (DXT1) format without alpha and every texture gets converted to dds with xna. Even with two 4048x4048 sheets there is plenty of room left to draw other things.

-edit-

Reading your comment I understand you want to free draw big textures for the background, this is no problem at all. Like tiles you have to know what you want to draw to the screen. Say you pick the 4048x4048 size, at most you have to draw 4 of these when you stand in the corner of one. You could detect when you are close to a edge and load one when needed. I have no idea what it does to your FPS when loading a 10MB texture but you could always use a separate thread. Neither do I have an idea what it does to the cpu if you draw 4 4048x4048 textures to the screen every frame, but this is easily tested. 50MB of textures sounds a lot to me but I usually work with a single 1028x1028 tilesheet at max for a complete map. You can already get pretty neat results with 256x256 if one uses his space correctly. Check on http://wayofthepixel.net/ what people can do with little colors and space.

Anyway, since 64MB cards are not uncommon you are already close to the max so I suggest using 1024x1024 textures. These will surely load faster and like 4048x4048 you only need 4 of the smaller ones at max so this reduces things a lot. Of course you can draw on a larger canvas and cut it up in pieces afterwards. A 1024x1024 texture saved in DXT1 format is about 600kb this means you could draw plenty without effort since HD resolution just requires 4 of these at any time to be drawn.

0
votes

You will be unlikely to ever answer this question based on feedback from SO. However, can you easily write the software so it works either way (via compile option or setting). If so, you can defer the question until the game is ready to go -- If it turns out that you need the speed optimization after everything is included, the answer will be obvious. If it turns out you don't need the optimization, the answer will also be obvious. It's the fuzzy middle that makes life interesting.

If this is complicates things too much, you basically need to do the same this based on performance computations (likely supplemented by performance testing). These can be quite difficult, but you may not have much choice.

A possibility better solution is to research / test other algorithms that give you a solution that satisfies both of you.

0
votes

The boost is relative on the complexity of drawing each tile individually.

As computers get more and more powerful, you can give up on some performance improvements to decrease loading time and code complexity; in the end it's up to you to decide whether you prefer loading time or fps.

I'll take in count that as you are questioning about this, you're having performance problems rendering your map. Are you rendering the whole map instead of only the visible part of it? This is a very recurrent problem during game development.

I can also give an example of Ragnarök Online, an "old game" that started development around the year 2000. It has a 2D/3D map and renders each 2D tile "individually", that is, it is rendered in one DirectX call per texture. The game runs fine with a lot of effects, sounds, some 3d effects(cliffs) even in older computers. You should try to render the tiles using 3d primitives instead of relying on SpriteBatch(which I think that you are using) and see if you have some improvement.