Sign in to follow this  
lanceking

aoe2 and hero3-why they are so smooth?

Recommended Posts

Hi, I am new to tile-based games and I want to know how do they make such smooth graphic? 1. What do they store in their tileset? snow->grass,snow->dirt,ground->water,water->grass... If there are m and n types of terrain to intersect, then I have to store m*n tiles for the edge?? Or I just store one type of terrain in one tiles and draw multiple times to achieve the same effect? But the latter approach seems a bit slow... 2. The terrain brush in the editor is very cool, do you have any ideas to implement it? Many thanks!!

Share this post


Link to post
Share on other sites
In Heroes of Might & Magic 2 and 3, the terrain system works pretty simply. Each tile has just a terrain type attribute; all those fancy edges are actually picked at run-time, and stored only in memory only while on-screen, and re-picked when they come on-screen. It's not an expensive operation, but it does take more work than would make doing it at render-time acceptable.

All they do is decide the fringe based on the adjacent terrains. And there are a half-ton of restrictions that make it work in a limited art set.

No tile can have no adjacent tiles of the same terrain type. The minimum adjacency is one vertically adjacent and one horizontally adjacent. No 1xX paths, no 1x1 spots. This way, we chop out a huge number of possible fringings.

And to prevent fringing from every terrain type to every other... have you noticed that water always borders on sand? Fire up the editor and turn on the grid. Water tiles border only on sand. Sand borders on anything, and dirt borders on anything. But snow will border on sand or dirt, but nothing else.

So if some map-maker puts snow next to jungle; on the snow tile, fringe from snow to dirt, and on the jungle tile, fringe from jungle to dirt. Try it out; you'll notice that rock wall (Heroes 3) borders only on sand, and then the 'subterranean' borders on sand.

Share this post


Link to post
Share on other sites
Thank you for your reply!

But I am a little confused about "edges picked at run-time"...
Does Hero3 use this kind of tileset?

Each tile is 16x16 and there are 9 tiles in the above image.

I think edges are pre-edited and can not change at run-time, or we'll get
a different looking map every time?

Share this post


Link to post
Share on other sites
Yes; the graphics aren't generated at run-time, but which fringe graphic (the outer 8 in that tileset you posted) to use at a given tile is chosen at run-time, to save memory.

Share this post


Link to post
Share on other sites
You mean even the MAP ARRAY is generated at run-time?? I can
hardly believe it... :(
This totally overthrow my understanding of tile-based games...
I thought what we got from a map editor is a two dimension map array.
This array should be very small. For a ushort map element indexes
into a tileset with each tile to be 16x16, a 4096x4096 pixel map only need a
256x256 map array, which only take 128kB memory. Does we really need to save
this memory?
If the map array is generated dynamicly, then what data do we save
from the map editor?

Share this post


Link to post
Share on other sites
No, I think what he meant, is that you have a basic grid of terrain types which are read in at load time, but the smooth transitions between the different terrain types are calculated when you load it in, so that it can be made to look pretty. But those transitions aren't stored in the file.

Share this post


Link to post
Share on other sites
Yes, it's also how I do it.

Basically I read base tile data from the map file, and store this in an array. Then I create a second array of equal size for the transition tile data, and calculate for every tile the appropriate transition offset in the grid. This is all done when loading the map, so that displaying the map is only a matter of looping bith arrays and drawing textures on screen.

Share this post


Link to post
Share on other sites
Doing as the above posters suggest is the way I did it with Golem and with the Accidental Engine. After the map is loaded into memory (or randomly generated, as is the case with my work) a post-processing pass iterates over the map and for each tile it counts the neighbors of the tile that share the same basic landscape type, generating a unique code for a given neighbor pattern and using this code to index into a table of transition tiles. Unlike previous posters suggested, I did not place any artificial constraints on base type placement (isolated 1x1 blocks of terrain were allowed) thus necessitating a larger set of transition types. (46, to be precise). I highly recommend setting limitations, since a 46-type tile set can quickly get out of hand if you want to provide randomized alternatives for each of the transition patterns, to eliminate some of the more obvious repetition.

Share this post


Link to post
Share on other sites
I am really confused... maybe because my bad English :(
So you mean that you are actually modify the GRAPHIC DATA(the image file)
when loading it? So you don't store this kind of tileset in your image file?


I am wondering what your tileset will look like?

Share this post


Link to post
Share on other sites
My guess (and that really is just a guess) is that AAA-games like AOE2 use terrain splatting or a similar technique to create smooth transitions. So they store the terrain texturesd (grass, sand, rocks) and blend these together using an alpha map they deduct from the terrain type map.

Share this post


Link to post
Share on other sites
lanceking, no, no no! You store the tileset graphics on disk, certainly. And in the map data, you store the terrain type for each tile. But you don't store /which/ transition to use in the map data; which transition to render gets chosen at run-time.

Separate the two in your head; the graphics are pre-drawn. The basic shape of the map is authored. The edges between tiles are NOT rendered or generated at run-time! WHICH edge graphic to DRAW is chosen at run time.

Share this post


Link to post
Share on other sites
Wyrframe, one more question.
Why we only store terrain type in map data, not the tileset index?
If we store tileset index in map data, then we need not to detemine
which tile to use at run-time, right? Seems many map editors are
exporting this kind of map data.

Share this post


Link to post
Share on other sites
Tileset index is the same as terrain type. Generally you have a tileset, which contains a certain number of terrain types (tiles), numbered starting from 0 (to give each one a unique identifier). Then tileset index 4 refers to the 5th terrain type in the tileset (we're counting from 0, remember?)

Share this post


Link to post
Share on other sites
Hi Raveler, if tileset index is the same as terrain type, then why do
we need to "pick which edge to use at run-time"?
To wyrframe, I still think we should store which tile to use in the map
data, not to "pick which tile to use at run-time", this should be a pre-process
done by the map editor. Am I right?

Share this post


Link to post
Share on other sites
Okay, let me back up one step. I'm not describing all tile-based systems; I'm describing for you the Heroes of Might and Magic map system. Let me simplify the system to see if I can explain it better.

Say you have three terrain types. Forest, Grass, and Water. Forest and Water are impassable. Forest can border on grass, and grass can border on water, but forest and water cannot border on eachother. This means more specifically that you can have forest and water adjacent in the map, but that there is only artwork for forest alone, grass alone, water alone, forest to grass, and grass to water.

Each tile has a terrain type, which is one of these three. This is all the information the map need store on disk.

When we render, we pick which tile from the artwork to draw. This will be one of dozens of different tiles, based on the tile we are looking to draw and the 8 which surround it. Let's assume that we're only looking at a straight edge of terrain, with one type on the left and one type on the right.

Grass | Water

There are two tiles here; a grass tile on the left, and a water tile on the right. When rendering the grass tile, we just draw a plain grass tile as if the water wasn't there. When rendering the water tile, however, we are going to choose a water-to-grass transition, with the "land" on the left side of the tile.

Now imagine this situation...

Forest | Water

We don't have a forest-to-water transition, but we do have forest-to-grass and grass-to-water. so that's what we render; pick a forest-to-grass transition for the left tile, and a grass-to-water transition for the right tile. Instant happiness.

What I'm telling you is that for this style of terrain system, all that needs be stored is the base terrain type. Tile index is not the same as terrain type, but the terrain type tells you what part of your tileset you'll be rendering, just not specifically which tile. Which was your original questions.

Now, for other tile-based systems, yes, you will often want to store the exact tile index in the map. But the HM&M3 system you don't need to. For the Age of Empires system, I suspect something very similar comes into play.

Share this post


Link to post
Share on other sites
When i made a map editor system in gamemaker, i put a check system in the game loop. It checks to see what kind of tile is placed to the left, right top bottom and corners and changed itself to fit that.

it was very teadeous though.

Share this post


Link to post
Share on other sites
Another way to do it is to load your different tiles (say you have 3xgrass, 3xtrees, 3xwater for now) into an array.

then each tile in your game can just have a couple layers (depending on how you allow tiles to be layed out, Im going to assume for simplicity sakes only two different types are touching at any one time).

then you have a blend mask, simple alpha texture to blend from the top layer to the bottom layer, this way you can have any transition you want, without having to prebuild transition textures.

so now where you would have 9 different Grass -> water tiles, you now have just 3 different blend textures, giving you 27 possibilities ( 1 - 3 grass, 1 - 3 blend, 1 - 3 water).

this gives the added advantage of getting things like Mud -> grass, and swamp -> grass for free :) because you can use the same blend textures for most liquids to most types of land... you will of course need a new one for something like trees.

this method can also be extended to take into account all 4 neighboring tiles, you just need to have 4 layers per tile and a few more blend textures.

hope this helped.

Edit: Sorry I guess thats what you were talking about in your second method. I've done this system before and it worked fine, no problems with framerates.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this