Super efficient tile engine design?

Started by
4 comments, last by Psychopathetica 12 years, 6 months ago
Hello there. I'm pretty much a beginner but I've had experience with game modding and such so I'm pretty much self-taught. After that I took a C++ class which I didn't find difficult so I have some decent basic grounds covered. Right now my goal is to create a super efficient tile engine capable of handling huge worlds(virtually unlimited amount of tiles would be nice). I'm wondering what techniques would be needed to achieve this and what a good way to tackle the design of a tile engine would be so I can easily implement tile interactions and things like that. I do remember Nick Gravelyn's(spelling?) tile engine tutorial series so I'll probably check that out for a bit of guidance. Also, I haven't attempted to start this tile engine so I don't really have a clear idea on how effective various implementations will be until I have done some testing.

Thanks!
Advertisement
By large number of tiles, I assume you mean size of map dimensions (not the number of different textures)?

I'm not sure why anyone would bother trying to write a "super efficient" tile engine these days. Just make a tile engine, and if you run into memory issues, partition the world into "chunks" and stream the chunks from disk as needed. A modern computer can handle very large amounts of memory very quickly, so I think the more difficult task would be the actual generation of these large maps.

In general, efficiency is probably the last thing you should be worrying about at this stage. Follow Nick's tutorial (or any of the other many tile engine tutorials available) and get something working first.

In general, efficiency is probably the last thing you should be worrying about at this stage. Follow Nick's tutorial (or any of the other many tile engine tutorials available) and get something working first.


Exactly what this gentleman said.

Drawing thousands and thousands of small 2D images onscreen with a hardware accelerated API doesn't require much optimization - it's lightning fast already. When you do find it's slow, then you'll be able to optimize that specific bottleneck intelligently.
Thanks, that's the answer I was looking for. I was wondering if I could create a system where I could just load the chunks that are saved so I could technically have pretty much unlimited tiles(not like I need that much). Also I don't plan on having too many on screen at once.

Thanks, I'll just tackle the problem and troubleshoot it if I have issues.
You don't need unlimited tiles, only as many as your environment has: you can probably afford to keep several million tiles' worth of map in memory. How large are your game's levels? The fanciest performance trick you should contemplate before actually hitting memory limitations is compressing map files to reduce I/O activity when loading levels.
And of course, you don't need to render millions of tiles, but only the fixed amount (a few hundreds or thousands) that overlap the viewport.

Omae Wa Mou Shindeiru

It's actually possible to create massive size worlds almost unlimited in size similar to world of warcraft and grand theft auto in a 2D environment without having to split the world into chunks. I managed to pull this off in an old language Visual Basic 6 and it doesnt matter how big the world is, even if its 10000x10000 tiles (over 100000000 in size!) it never slows down! This is how I pulled it off. Basically only draw what you see. And instead of cycling through the entire map to draw the little bit visible, it cycles only through whatever polygons are visible. For example. If the map is only capable of displaying 32x24 tiles on screen maximum then thats how big the loops gonna be no matter how big and gigantic your world. Then after that the only limit is your imagination. The X1 and Y1 and X2 and Y2 is the visible rectangle that moves around in your gigantic map. As the map moves so does the coordinates of your visible window.


Coordinates.X = Int(-(Map.Position.X) / TILE_WIDTH)
Coordinates.Y = Int(-(Map.Position.Y) / TILE_HEIGHT)

X1 = Coordinates.X
Y1 = Coordinates.Y
X2 = Coordinates.X + Map.Screen_Tile_Width
Y2 = Coordinates.Y + Map.Screen_Tile_Height

If X2 <= 0 Then X2 = 0
If Y2 <= 0 Then Y2 = 0
If Y2 >= Map.Height - 1 Then Y2 = Map.Height - 1
If X2 >= Map.Width - 1 Then X2 = Map.Width - 1
If X1 <= 0 Then X1 = 0
If Y1 <= 0 Then Y1 = 0
If X1 >= X2 Then X1 = X2
If Y1 >= Y2 Then Y1 = Y2

For Y = Y1 To Y2
For X = X1 To X2

Color = D3DColorRGBA(255, 255, 255, Fade)

Vertex_List(0) = Create_TLVertex(Map.Position.X + ((TILE_WIDTH * X) + 0), Map.Position.Y + ((TILE_HEIGHT * Y) + 0), 0, 1, Color, 0, 0, 0)
Vertex_List(1) = Create_TLVertex(Map.Position.X + ((TILE_WIDTH * X) + TILE_WIDTH), Map.Position.Y + ((TILE_HEIGHT * Y) + 0), 0, 1, Color, 0, 1, 0)
Vertex_List(2) = Create_TLVertex(Map.Position.X + ((TILE_WIDTH * X) + 0), Map.Position.Y + ((TILE_HEIGHT * Y) + TILE_HEIGHT), 0, 1, Color, 0, 0, 1)
Vertex_List(3) = Create_TLVertex(Map.Position.X + ((TILE_WIDTH * X) + TILE_WIDTH), Map.Position.Y + ((TILE_HEIGHT * Y) + 0), 0, 1, Color, 0, 1, 0)
Vertex_List(4) = Create_TLVertex(Map.Position.X + ((TILE_WIDTH * X) + TILE_WIDTH), Map.Position.Y + ((TILE_HEIGHT * Y) + TILE_HEIGHT), 0, 1, Color, 0, 1, 1)
Vertex_List(5) = Create_TLVertex(Map.Position.X + ((TILE_WIDTH * X) + 0), Map.Position.Y + ((TILE_HEIGHT * Y) + TILE_HEIGHT), 0, 1, Color, 0, 0, 1)

If Not ((Vertex_List(4).X < R.Left) Or (Vertex_List(0).X > R.Right) Or _
(Vertex_List(4).Y < R.Top) Or (Vertex_List(0).Y > R.Bottom)) Then

Direct3D_Device.SetRenderState D3DRS_ALPHABLENDENABLE, True
Direct3D_Device.SetTexture 0, Map.Texture_List(Map.Background_Tile(X, Y))
Direct3D_Device.DrawPrimitiveUP D3DPT_TRIANGLELIST, 2, Vertex_List(0), Len(Vertex_List(0))
End If

Next X
Next Y

This topic is closed to new replies.

Advertisement