Some things from Usenet:
Article 189584 of rec.games.programmer: From: jack <jacko11@telegram.infi.net> Newsgroups: rec.games.programmer Subject: Tilemaps: linked lists versus arrays, Seriously! Date: Wed, 03 Jun 1998 23:41:42 -0400 Organization: InfiNet Recently I have seen some debate on the subject of linked-lists vs. arrays in tilemap storage. I have no idea how widespread it is, but I am concerned that some tile-coders might get scared away from linked lists prematurely. I've looked at the issue, and decided that the argument against linked lists presented in the "Linked Lists vs. Arrays" article at Game Programmer's Galaxy is an argument that only works if you are writing a very simple tile engine; that is, if your objects are all very small (as small as one byte, as the article states!) and if you are not *separating* your layers. The problem is: putting more than one object on a space in the object layer in a tile based game. In the original "Tile Based Games FAQ 1.2" by Greg Taylor, he uses an array that only allows for one object on each space. However, he briefly touches on the subject of linked lists in putting more than one object on a space. As you might know, tile maps can be arranged in layers like this, top to bottom: ------------------------------------------------- OVER LAYER (roofs, overhangs, special effects) + OBJECT LAYER (items, people, monsters) + FRINGE LAYER (trees, etc.) + BASE LAYER (the ground) ------------------------------------------------- The "Tile Techniques" document, which came later, developed the linked-list idea a little more and provided an example or two. I recently visited the "Game Programming Galaxy" site (http://www.geocities.com/SiliconValley/Vista/6774/) and on its "Tile Based" info page, it lists the following as reasons for *not* including the "Techniques" file: ********* QUOTED SECTION *************************************** Oh, BTW: I won't put the TileTech article on this page, because the only new is the use of variable size objects - and the extensive use of linked lists is pure nonsense, memory wastement and makes the whole thing a lot more complicated. Take a look at the "Lists vs. Arrays" article, if you want to know more. ********** END SECTION *************************************** "Memory wastement" :-) ?? I decided to investigate, as I am writing an RPG tile engine. The "lists vs. arrays" article there briefly explains the machanics of arrays and lists, etc. It then claims that linked lists are unneccesary and a huge waste of memory, since (among other reasons I will deal with) a linked list map will waste 8 bytes per position if there is only one object on that position (four for the head* and four for the next*). But note that only *four* bytes are wasted on the *next* object and every new object thereafter, since the header doesn't have to be duplicated again. The solution the "Vs" article presents is simple: use multiple object layers; in essence, a 3-d matrix. But this "solution" is the starting point that would have made the "problems" with linked lists disappear: if *only* the object layer is stored with linked lists, much less memory is wasted even if your objects are just 4 bytes (and I'll get to *that* limitation). The BASE, FRINGE, and ROOF layers can be stored as simple matrix arrays since those objects don't need to be stacked. By using linked lists, you gain the flexibility of putting more than one object on each space without wasting lots of memory on every 10-space array that only has 1 or 2 objects in it. The Vs. article states that "I guess the average map has at least 2 tiles per position". Well, everywhere has a floor or a ground; that's one tile. But even in a world with *lots* of items, the typical position is not going to have two objects. Yes, some will have five or more, but not many. But *many* positions will have only one tile: think of the ocean, the vast expanses of land that will be only partailly forested, the stretches of desert, the item-less paths and roads in towns, the corridors of castles that need only one tile for the floor. By splitting your map into layers that are *stored differently according to usage*, you can move predictable bits off (floors, fringes, roofs) into efficient arrays. The unpredictable object layer needs to be flexible; we can't just limit it to 8 objects high everywhere, because we might need more. And we can't waste all the memory of using *arrays* 8 levels high, since we will hardly ever actually stack that high. Mostly, we'll have one or a few objects. Think of a treasure room in a dungeon, with corners stacked high with gold and jewels and magic weapons. Sure, we could hold it if every map position had 8 spaces built in. But then we'd be wasting *7* spaces for *every* tile and every floor space that didn't have any objects. Now, the space wasted by using a fixed 3d array instead of linked lists is fine for small objects. For instance, the "Vs." article states: **************** QUOTED SECTION ******************** "The average map has at least 2 tiles per position, giving you 12 bytes for pointers and 2 (or 4) bytes for data = 14 (16) bytes. This would allow you to store 14 tile layers for 1 byte, or 8 layers of word-size tiles. And that should be more tha enough for even very sophisticated games." ************* END SECTION ************************** Okay. But who is using just one byte to store each tile in an RPG?? That would only allow 255 possible object types (one of them being a placeholder for "no object.") I can't even see that happening in a decent Super Mario Bros. type game. So how about 2 byte objects? That's 65,535 tiles, which should be plenty. But in an RPG, even a simple one (let alone a "very sophisticated" one) the objects need to have local attributes. Yes, things like weight and size are constant across instances of an object, i.e., all #13 torches will weigh the same. But for *each torch* we need to store how much time is left on that particular torch, so they don't *all* burn out at the same time. For armor, we need to store damage points. We need to know who owns some objects, so that you can't just steal everything from a house without the owner noticing. (In Ultima, people call *thief*! and the guards come.) We need to store what animation frame something is in. Basically we must store *any* attribute that differentiates instance X from all other instances of that kind of object. This local data is going to take space. Lets' assume that each numeric attribute (damage, quantity/quality (torch time or magic charges), ownership) is one byte. That gives us 3 so far, and this is not a very big attribute list. Add another byte for animation frame; that's four. Add that to our original tile ID, and we get six bytes per object. ( Note that only objects *in the object layer* need to be stored this way; having differently-stored layers allows you this flexibility. In addition, things that don't need these extra local attributes are most likely static tiles, or scenery that the player will interact with very little. They can therefore be moved to the FRINGE or BASE layers, stored simply as plain tile #'s in a plain, efficient 2d array layer, in our scenario taking just two bytes per object. Only objects that need to will be stored largely. ) Let's do a pro and con analysis with a 64x64 tilemap. Using the suggested "vs." technique (which I am *not* recommending!), we have: a 64x64x8 fixed array, that is, 64 high, 64 wide, and eight "layers" deep. That's: 64x64 = 4096 positions per layer. Multiply by eight layers: 32768. Six bytes per object: 32768 x 6 = 199608 bytes for a 64x64 map. Note that this is the size regardless of whether the world has one object, or 32768. Still, 192K is not bad. But it still has the drawbacks I pointed out before: bascially the inflexibility and wasted space for most maps. Let's try it with linked lists, which is a bit more complex: 64x64 map. 4096 xy positions per layer. BASE, FRINGE, OVER layers: 2 bytes per object. 3 layers. 24576 bytes (24K) total. Now for the object layer: in an empty state, it contains 1 pointer (as a header) per position. 4096x4 = 16384 bytes = 16K. Let's humor the author of the "Vs." file and say that the average space has two objects (which I already disagree with.) Let's overestimate and up that to three objects on every position, *in the object layer*. That's: 10x3 = 30 bytes for three objects, plus four for the header = 34 bytes per position, times 4096 xy positions in the 64x64 map = 139264 bytes, or 136K. Let's add it all together: 24K total for the BASE, FRINGE, and OVER layers; plus 136K for a very unrealistically over-stocked object layer. That's a total of 160K for the map, considerably less than the 192K for the inflexible 64x64x8 scheme. And you get all the increased flexibility of having variable numbers of things. There's the crucial point; once the objects become larger than a pointer (as they will often be in a complex game) it becomes much less of a waste to use the pointers (and more of a waste to use too many objects.) For instance, the linked list version uses only 4 bytes (for the pointer) on an empty space in the object layer; using an array would require a 6 byte object there even if there were no objects stored (that is, if the object were assigned a dummy value.) It would still take up the space. Adding objects only adds 10 bytes each object (6 + 4 for pointer). Now *in practice*, since non-interactive objects have been dumped in the other, 2-byte-per-object layers, we will not need to use as many objects in the object layer; and hence, we will *save* memory while *gaining* flexibility. For a simple game with small objects, by all means use the fixed array; but for a RPG or really any game of real complexity, look at linked lists as a possible solution. Oh, and what about speed? Well, frequent pointer dereferencing is not going to cost much on a modern machine, and not even that much on a slightly dated one. I mean, it's pointer dereferencing, which takes a constant time. So as processor speed increases, the time it takes to dereference a pointer decreases as a percentage of total computing time. It's nothing to worry about. The gain in flexibility is more than worth a tiny speed hit. - dto@iname.com
Article 189707 of rec.games.programmer: From: Michael Duffy <mduffy@ionet.net> Newsgroups: rec.games.programmer Subject: Re: Tilemaps: linked lists versus arrays, Seriously! Date: Thu, 04 Jun 1998 15:22:44 -0500 Organization: Studio Blue jack wrote: [big friggin clip] Well, well, well. What do you know. Another intelligent thread. This isn't supposed to happen here people! (^_^) (that's sarcasm for those of you keeping score) That was a good post, and one that I agree with. I believe that since games have become more complex, that entire background/object/fringe/etc layering scheme has long outlived it's usefulness. In my isometric tile engine, I am set up with four unsigned longs per tile, which works out to 16 bytes per tile. The first three ULONGS contain the tile ID (for lookup), wall ID (if there is one), collision info, temporary A* algorithm variables, display flags, and other miscellaneous info. The last ULONG contains a pointer to a linked lists of objects, roofs, triggers, spell effects, possibly roofs, and whatever else might be in that location. A 256x256 map takes up about a meg of storage, which is fine on a 16 or 32 meg computer which is the norm these days. If your world is interesting, a 256x256 map is a lot of romping room, and you can always load new maps for new locations. My objects are stored in structures, and have lots of variables associated with them so they can be as complex as I need. I would say it is more important these days to use a structure that allows for complexity and features rather than one that fits on a 4 meg DOS based 386, especially if you are working on an RPG. Thanks Jack, I enjoyed your post. Later, Michael Duffy mduffy@ionet.net
Article 189817 of rec.games.programmer: From: "Paul 'Ozymandias' Harman" <ozzy@kasterborus.demon.co.uk> Newsgroups: rec.games.programmer Subject: Re: Tilemaps: linked lists versus arrays, Seriously! Date: Fri, 5 Jun 1998 10:59:58 +0100 Organization: COLT Internet Services Michael Duffy wrote in message <35770214.65B2853D@ionet.net>... >In my isometric tile engine, I am set up with four unsigned longs per tile, which >works out to 16 bytes per tile. The first three ULONGS contain the tile ID (for >lookup), wall ID (if there is one), collision info, temporary A* algorithm >variables, display flags, and other miscellaneous info. The last ULONG contains a >pointer to a linked lists of objects, roofs, triggers, spell effects, possibly >roofs, and whatever else might be in that location. A 256x256 map takes up about a >meg of storage, which is fine on a 16 or 32 meg computer which is the norm these >days. If your world is interesting, a 256x256 map is a lot of romping room, and >you can always load new maps for new locations. My objects are stored in >structures, and have lots of variables associated with them so they can be as >complex as I need. I'm sure that everybody else is in on the big secret, and I have no idea what I am doing, but... Why have a linked list of objects at a particular location? I can see it having benefits in "chess" like situations, where a particular 'playing piece' can only be wholly on one tile or another tile... but in more free-form games where an object can be anywhere - as in platform games - surely it's far more efficient to have a separate array of objects, and the objects take care of their own locations? i.e. rather than each tile knowing which objects are standing on it, each object knows on which tile it is standing. I can see benefits for drawing objects, and benefits for collision detection I suppose... but I can't see the method working properly for 'free-form' movement, like in a platform game, or a top-down "Super-Sprint" style racing game. Ozzy
Article 189850 of rec.games.programmer: From: Michael Duffy <mduffy@ionet.net> Newsgroups: rec.games.programmer Subject: Re: Tilemaps: linked lists versus arrays, Seriously! Date: Fri, 05 Jun 1998 11:00:32 -0500 Organization: Studio Blue Paul 'Ozymandias' Harman wrote: > Why have a linked list of objects at a particular location? > > I can see it having benefits in "chess" like situations, where a particular > 'playing piece' can only be wholly on one tile or another tile... but in > more free-form games where an object can be anywhere - as in platform > games - surely it's far more efficient to have a separate array of objects, > and the objects take care of their own locations? Well, that is a problem that is worth considering. At first, I implemented a system where all objects were stored in a separate linked list. But then to check the area around a tile or in a specific tile, I had to traverse the entire list to find it. That meant stepping through and checking every object on the current map, and with an RPG that meant stepping over a LOT of objects. So I tried having one linked list per row in the map. But that became a major hastle when moving object vertically, because I would have to remove from one list and re-sort into another. Also, when it came time to draw the map, both of the above methods became slow because I would have to check a LOT of objects that weren't drawn in the current frame. So instead I went to a linked list per tile approach. Now, the world coordinate system for my game is of a finer resolution than one tile. A single tile is actually 16x16 world measurement units in size. To convert from world coordinates to tile coordinates I just shift the X and Y postitions right by four bits. This way I can move my character in sub-tile increments, but it is really easy to search the map for objects. For example, I have Object A and I want to see what is next to it. I take Object A's position, and find the tile it is in by looking in my map array. Now I can add or subtract the map pitch and/or the tile pitch to the pointer to Object A's tile to check the tiles around it. When I have the address for the neighboring tile, I simply get the pointer to the linked list, and look through any objects in those linked lists. I still have to check the distance between objects if I need a fine measurement, but I'm only checking the several objects that could possibly be in range, instead of all objects in the world. Since my engine requires a LOT of checking of objects, this seemed like the most logical approach to me. However, I also have all my objects sorted into two lists. The first list is the per-tile list as described above. This is a simple single linked list. I also have all objects sorted into a red-black binary tree with each object's ID as the key value. Every object in the game has a unique ID that is assigned at object creation (except gold coins which aren't treated as individual objects). This way I can track individual objects without having to scan the entire map for them. Later, Michael Duffy mduffy@ionet.net
Article 189860 of rec.games.programmer: From: "Paul 'Ozymandias' Harman" <ozzy@kasterborus.demon.co.uk> Newsgroups: rec.games.programmer Subject: Re: Tilemaps: linked lists versus arrays, Seriously! Date: Fri, 5 Jun 1998 17:33:50 +0100 Organization: COLT Internet Services Michael Duffy wrote in message <35781620.CE2D0656@ionet.net>... >So instead I went to a linked list per tile approach. Now, the world coordinate >system for my game is of a finer resolution than one tile. A single tile is >actually 16x16 world measurement units in size. To convert from world >coordinates to tile coordinates I just shift the X and Y postitions right by >four bits. This way I can move my character in sub-tile increments, but it is >really easy to search the map for objects. Much as I hate to admit it, this method is growing on me... but I still can't see it being perfect for side-on platform games. I mean, if the character is curving in a jump-arc, that's a lot of nasty list manipulation I'm gonna have to do. But I do like the built-in proximity checking you get (from the point of view of the collision detection algorithm)... >However, I also have all my objects sorted into two lists. The first list is >the per-tile list as described above. This is a simple single linked list. I >also have all objects sorted into a red-black binary tree with each object's ID >as the key value. Every object in the game has a unique ID that is assigned at >object creation (except gold coins which aren't treated as individual objects). >This way I can track individual objects without having to scan the entire map >for them. So... You have an array of pointers-to-objects, and also each 'tile' has a linked list of objects. Hmmm.... there might be something in this... Ozzy
Article 189883 of rec.games.programmer: From: Michael Duffy <mduffy@ionet.net> Newsgroups: rec.games.programmer Subject: Re: Tilemaps: linked lists versus arrays, Seriously! Date: Fri, 05 Jun 1998 14:53:32 -0500 Organization: Studio Blue Paul 'Ozymandias' Harman wrote: > Michael Duffy wrote in message <35781620.CE2D0656@ionet.net>... > >So instead I went to a linked list per tile approach. Now, the world > coordinate > >system for my game is of a finer resolution than one tile. A single tile is > >actually 16x16 world measurement units in size. To convert from world > >coordinates to tile coordinates I just shift the X and Y postitions right by > >four bits. This way I can move my character in sub-tile increments, but it > is > >really easy to search the map for objects. > > Much as I hate to admit it, this method is growing on me... but I still > can't see it being perfect for side-on platform games. I mean, if the > character is curving in a jump-arc, that's a lot of nasty list manipulation > I'm gonna have to do. For a platform game where you only have maybe three or four dozen objects on the map, keeping all the objects in a separate sorted linked list is probably a good way to go. For objects like powerups you could probably even put a bit flag on the tile that says "something stationary is here", and then if you enter that tile you check your object list for the object that is in that location. For an RPG where I am dealing with lots of furnature, objects, chests, triggers, etc, my current scheme is proving to be pretty good. > >However, I also have all my objects sorted into two lists. > So... You have an array of pointers-to-objects, and also each 'tile' has a > linked list of objects. Objects in my engine are stored in the SBObject class. This class has a pobjNext pointer, which is used to sort it into a linked list, such as the tile's list of objects or in another object's inventory. I believe I also have a pobjParent pointer in case the object is in an inventory and you want to find out what is carrying it. The SBObject class also has pobjTreeParent, pbojTreeLeft, and pobjTreeRight pointers along with a flag ULONG, which is used to sort the object into a red-black tree. This is a binary tree which can be balanced as you add objects to it. I found the algorithm in Sedgewick's "Algorithms" book. The tree is sorted on the unique ID that each object has. My SBWorld object contains the pointer to the object tree, as well as the pointer to the map data. When you create the object, you also create the needed pointers because they are all part of the object. Later, Michael Duffy mduffy@ionet.net
Article 189727 of rec.games.programmer: From: lennart.steinke@uidesign.se Newsgroups: rec.games.programmer Subject: Re: Tilemaps: linked lists versus arrays, Seriously! Date: Thu, 04 Jun 1998 22:40:56 GMT Organization: Deja News - The Leader in Internet Discussion Hi! Since I wrote the "Tiles vs. Arrays" article, I guess I can add my 2 cent: > for the next*). But note that only *four* bytes are wasted on the *next* > object and every new object thereafter, since the header doesn't have to > be duplicated again. Since you have to store always a next pointer to NULL, you'll lose 8 bytes per position, regardless how many tiles (or other data) you store at this position. If you use 16bit per layer (whether they may be tile indices or attributes), you have 4 + (6 * countLayers) bytes per position. If you have one layer at that position, that would make 10 bytes... also 5 16 bit layers. So, if you have less than 5 layers, you'll use always less space than with a linked list aproach. Since, you'll normally store more than one tile per position (you'll use the basic and fringe/object layer relativly often), you can assume that 2 tiles per position are quite common. > The Vs. article states that "I guess the average map has at least 2 > tiles per position". Well, everywhere has a floor or a ground; that's > one tile. But even in a world with *lots* of items, the typical position > is not going to have two objects. Yes, some will have five or more, but Yup. But a fringe layer, or a tree, etc. > not many. But *many* positions will have only one tile: think of the > ocean, the vast expanses of land that will be only partailly forested, > the stretches of desert, the item-less paths and roads in towns, the > corridors of castles that need only one tile for the floor. If you take a look at commercial games (say LucasArts Desktop Series) you'll see that most positions are two or three layers (object, fringe and sometimes object). Oceans shouldn't occupy lot's of space (because you cannot do anything on them) and dungeons etc, use only less tiles, if you have lot's of different tiles (stoneA, stoneB, stoneA_with_carpet, etc..) > flexible; we can't just limit it to 8 objects high everywhere, because >we might need more. And we can't waste all the memory of using *arrays* > 8 levels high, since we will hardly ever actually stack that high. Hm... 8 objects at a tile of 32x32? In most rpgs, you won't have that many objects in one place. Since you need to _see_ what's on the tile.... And objects which can occur in masses (say coins) will usally be spread over severak tiles (like in Diablo) or be stored as sprites (like in Zelda). > dungeon, with corners stacked high with gold and jewels and magic > weapons. Hm... So, you step on one tile, and get 8 objects... :) I've never played a rpg in which this could happen ... But, the overhead involved in maintaing the lists (and loading a map made of lists on the fly) is IMHO no accaptable for this one treasure room.... And there's always the option of using sprites.... > (let alone a "very sophisticated" one) the objects need to have local > attributes. Yes, things like weight and size are constant across > instances of an object, i.e., all #13 torches will weigh the same. But > for *each torch* we need to store how much time is left on that > particular torch, so they don't *all* burn out at the same time. For Hm... guess those items are in your inventory... and you should use a list for that. If you're talking about torches on walls... if they would stop burning after a certain time, most torches would be totally burned _before_ the player finds them. > armor, we need to store damage points. We need to know who owns some > objects, so that you can't just steal everything from a house without That's done by a) Inventory stats or b) scripts for the houses. > we must store *any* attribute that differentiates instance X from all > other instances of that kind of object. This local data is going to take > space. Sure, but that space should not be stored in the MAP, because it's an attribute of an object... which can be carried around. If you take an object, you remove it from the map, and put it in your inventory... there's no need to store in the map that there has been an object before. If you want to the people to call "thief", set a game flag if you steal. > Lets' assume that each numeric attribute (damage, quantity/quality > (torch time or magic charges), ownership) is one byte. There's no reason to store this data in the map... Why should a grass tile have a "torch" value? Okay, you could now argue, that you could use a union approach (storing a type attribute per layer, and then cast the pointer accordingly) but that isn't the best way to do it... > animation frame; that's four. Add that to our original tile ID, and we > get six bytes per object. ( Note that only objects *in the object layer* So, _every_ object needs a torch, hp, and animation attribute? I don't think so. I wouldn't like to store those values for a chest, or a key... > BASE layers, stored simply as plain tile #'s in a plain, efficient 2d > array layer, in our scenario taking just two bytes per object. Only > objects that need to will be stored largely. ) If you want to start your player to push an object, it has to be on the object layer (or you start allways pushing if the player contionus to go in a "non_walkable" direction). > 64x64 map. 4096 xy positions per layer. > BASE, FRINGE, OVER layers: 2 bytes per object. 3 layers. > 24576 bytes (24K) total. Now for the object layer: in an empty state, > it contains 1 pointer (as > a header) per position. 4096x4 = 16384 bytes = 16K. So, you store BASE, FRINGE, OVER as an array. This makes 3 x 2 bytes per position. Now add 4 bytes for a pointer. That's 10 bytes. But only because you didn't use a list for the the other three layers. > Let's humor the author of the "Vs." file and say that the average space [..] > 10x3 = 30 bytes for three objects, plus four for the header = 34 bytes > per position, times 4096 xy positions in the 64x64 map = 139264 bytes, > or 136K. Yes. But... Say you have an average of 2 objects... that's 5 layers. 5 layers need 5 * 2 bytes = 10 bytes per position. If you assume 2 objects in your solution, you have 3 * 2 bytes // Object, Fringe, Roof 3 * 4 bytes // Pointer to 1st object, 2nd object and NULL ------- 18 bytes If we assume only 1 object on a average tile, that would be 14 bytes. 14 bytes would allow 7 layers. And as stated before, I don't think you need more than 7 layers. > There's the crucial point; once the objects become larger than a > pointer (as they will often be in a complex game) it becomes much less > of a waste to use the pointers (and more of a waste to use too many Correct. If you store all information which should be in the object in the map, you're right. But a map should only indicate where things are, not what they are. > all means use the fixed array; but for a RPG or really any game of real > complexity, look at linked lists as a possible solution. Yes, as I said in my article, lists are a fine thing- but not for tile maps, and definatly not in the way described in the tile techniques... because it uses lists for every layer, not only for the object layer. > It's nothing to worry about. The gain in flexibility is more than worth > a tiny speed hit. It's not only the derefferencing. Although the need to derefernce several time in your inner drawing loop should not be taken easily. It adds at least one comparison ( if (object !=NULL) ) and one derefernce. And then logic to check for another object, etc. And that in your _inner_drawing_loop_ . And, since your maps are no longer of a fixed size, it's very hard to read in certain parts of the map directly from the HD. Your code is harder to maintain. And, as I said in my article, linked lists are a fine thing. I just don't consider them usefull for tile maps. They're great for inventories, sprites, etc. But a since room is limited, it makes sense to limit the room in a map also. Small objects like coins will not be stored seperatly on a position (you'll use a stack of coins, like in diablo instead). Larger objects, like chests will occupy at least one tile. If you try to put several objects at the same place in diablo, they will roll sooner or later to an adjected tile. If you try the same in Zelda style game, it's simply not possible. The approach suggested here (using an array for all layers but object) is a nice idea, and it's hell of a lot better than the one described in the TileTech. In fact, I wouldn't have written the "vs." article, if this approach would have been used in the TileTech. On the other hand, I would have surly commented the habit of storing a "torch" value for every object :) Happy coding, Lenny ---------------- Lennart Steinke http://www.geocities.com/SiliconValley/Vista/6774/ -----== Posted via Deja News, The Leader in Internet Discussion ==----- http://www.dejanews.com/ Now offering spam-free web-based newsreading
Article 190263 of rec.games.programmer: From: "Paul 'Ozymandias' Harman" <ozzy@kasterborus.demon.co.uk> Newsgroups: rec.games.programmer Subject: Re: Tilemaps in RPG's Date: Mon, 8 Jun 1998 12:17:41 +0100 Organization: COLT Internet Services jack wrote in message <357972FF.5B0A8B55@telegram.infi.net>... >:-) Yes! You've made an *excellent* point, and it illustrates that I >should have clarified the scope of my original argument. (sorry to dump >this on you, but it has to go somewhere! :-) :-) ) I should have >made it more clear that I was really talking about RPG tile engines >specifically. My criteria for evaluating the flexibility (pros and cons) >of certain approaches were influenced by the fact that I'm writing an >RPG engine, and I tailored things to that outcome. My results, then, >might not be applicable to, say, a Super Mario 2d tile game. An even >bigger apples-and-oranges example: comparing the "Ultima 7: The Black >Gate" engine with that of "Quake". Which is better? Who knows? They're >meant for different things. <snip absolutely loads> Yes, I can't agree more. Use The Right Tool For The Job. The "tiles know what objects are standing on them" approach is great for RPGs and probably for Civilisation-style games, and "objects know where they are" is probably better for fast-moving side (or even top-down) scrollers. Ozzy.
Article 190708 of rec.games.programmer: Newsgroups: rec.games.programmer From: palm@netcom.com (Palm Computing) Subject: Re: Tilemaps in RPG's Followup-To: roger@palm.com Organization: Netcom Date: Thu, 11 Jun 1998 00:44:51 GMT In article <2061CEBD9141D1118CEF080009DE1692E83825@sun.panews.press.net>, Paul 'Ozymandias' Harman <ozzy@kasterborus.demon.co.uk> wrote: > >jack wrote in message <357972FF.5B0A8B55@telegram.infi.net>... >>:-) Yes! You've made an *excellent* point, and it illustrates that I >>should have clarified the scope of my original argument. (sorry to dump >>this on you, but it has to go somewhere! :-) :-) ) I should have >>made it more clear that I was really talking about RPG tile engines >>specifically. My criteria for evaluating the flexibility (pros and cons) >>of certain approaches were influenced by the fact that I'm writing an >>RPG engine, and I tailored things to that outcome. My results, then, >>might not be applicable to, say, a Super Mario 2d tile game. An even >>bigger apples-and-oranges example: comparing the "Ultima 7: The Black >>Gate" engine with that of "Quake". Which is better? Who knows? They're >>meant for different things. > > ><snip absolutely loads> > >Yes, I can't agree more. Use The Right Tool For The Job. The "tiles know >what objects are standing on them" approach is great for RPGs and probably >for Civilisation-style games, and "objects know where they are" is probably >better for fast-moving side (or even top-down) scrollers. > > Ozzy. > > With this interesting thread wrapping up a bit, I thought I'd share some differences in my code which may be interesting. In my game Reptoids for PalmPilots, an action game, I handle collisions by placing all objects in a two dimensional array of sectors, where a sector is n pixels. Checking for collisions amounts to checking against all objects in the sector. If the object overlaps another sector (or four for the corner case) those sectors are also checked. The two things I haven't seen mentioned so far though are that I completely redo the sector array each game cycle, just like I completely redraw the video frame. Since most of my objects move, redoing the list simplifies the movement code and there really isn't a speed hit. The other thing I want to mention is that objects are limited to twice the sector size. This limits the number of sectors to search. Reptoids doesn't have tiles, but for a Super Mario 2d tile game a sector could be n tiles big. Creatures bouncing around in arcs or crazy patterns are no problem! I also have a RPG and a strategy game which basically share object and map code. My map is essentially a two dimensional array containing the tile type (floor, wall) plus a flag if an object is present. I don't store a pointer to objects. Instead, I retrieve all objects in the tile by hashing the coordinates and looking in a hash table for the object. The hash table is sized so that generally the first spot contains the object. At a slight speed hit I save a lot of memory. In fact my tile size is one byte! I of course don't do layers. Someone earlier mentioned unique ids for objects. I too have found them incredibly useful for objects which track other objects. In my structures I keep my objects compacted to avoid wading through dead objects. I'm not sure this is the best decision (comments?), but does mean objects move and pointers can dangle. Unique IDs let me recover the pointers. They also simply saving the game's state. One last thing is that I'm always amazed/amused when people make doors be tiles. I treat everything other than dirt as an object. In fact, when you tunnel into a magma vein in search of gold, I create a magma vein object with a quantity value, and the object looks just like a magma tile. This is how I handle damage to tiles. -Roger Flores roger@palm.com
Article 190449 of rec.games.programmer: From: "Rick Craik" <NOSPAMrcraik@ntl.sympatico.ca> Newsgroups: rec.games.programmer Subject: Re: Tilemaps in RPG's Date: Tue, 9 Jun 1998 13:19:46 -0400 Organization: iSTAR internet Incorporated Hi Jack; May I butt in? I am working on Tilemaps in Strategy and have been following your thread of postings. A strategy game has a lot of features in comon with the RPG, like tiles, terrain, units/monsters, and a maybe a few objects. The main difference would seem to be what goes on between turns, or in a time slice. In a strategy game each game unit must do some processing, where in RPG, each monster is only activated when appropiate. While reading your posts, on Tilemaps in RPG's, I thought some of the storage strategies might not be appropiate for a Strategy game. I understand your scope was RPG games, but if possible, could you expand a bit to include Strategy games? What are the implications of: 1) Strategy games usually have smaller world map. 2) Computer opponents need to analyse tile information often. I believe your arguments for linked lists apply to Strategy games: [snip] >Basically, I'm trying to use the right tool for the right job, according >to needs. Our current question is: how much data do we need to store >along the Z-axis, and how flexible does it need to be? The answer of >course depends on what you are doing. [snip] The Strategy game designer should watch for performance hits that access tile info often. A small map, for example, should allow the designer to avoid disk accessing methods. Thanks for your attention, Rick
Article 191523 of rec.games.programmer: From: Michael Duffy <mduffy@ionet.net> Newsgroups: rec.games.programmer Subject: Re: Tile Based vs Non Tile Based Date: Mon, 15 Jun 1998 23:32:18 -0500 Organization: Studio Blue John Mancine wrote: > > > >I'm seriously considering implementing a z-buffered sprite engine that uses a > > >single image for the background (well, multiple non-overlapping tiled > images), > >and then z-buffers the character and object sprites in. I've been putting > some > >thought into it since looking at how nice Final Fantasy VIII's screens are > and > >thinking that it will probably be easier to do good graphics as a single > image > >rather than in individual tiles. Also, my artists are not too thrilled with > the > >entire tile idea, and tiles are tough to do in a 3D rendering package. > > I know exactly what you are saying. My 3D artist hasn't liked doing the iso > tiles at all either. Simply because you can't really dive into the details > as much as you can if you have more of a canvas to work on. > > One thing I don't get about not using tiles is how is the scrolling of the > screen handled? (not even thinking about doing 'paged' scrolling... that is > pretty cheap looking IMO) > How would it work? Would you have the whole 'world' divided up into > 1000x1000 sized "chunks" of images and then load these on the fly? Obviously > you can't load them all at once. > > Can you elaborate a little more? Because I am very interested in doing this. > And it would be the perfect time to do it in my project. > > Thanks, > jrm Well, these have been my thoughts on the subject so far: * z-buffering. No matter how you look at it, software z-buffering is slow. However, since you will only be z-buffering in a few sprites into a pre-rendered background as opposed to 3D where you would z-buffer the entire screen, it should be fast enough. You will store your background image as a 16 bit color image with a 16 bit z-buffer. You'll probably want to keep these as separate arrays (instead of packing the info in an unsigned long) because you may keep the graphics in video memory. I haven't written a z-buffer sprite routine yet, and the way you approach it will depend on the flexibility you want and how you draw sprites. You can either store the z-buffer info for each pixel of the sprite, or give the entire sprite the same z-depth. The latter approach would be faster and would have less memory storage requirements. However by doing this you give up the opportunity to do depth tricks like having your sprite merge through walls or have some sort of fog effect where the farther pieces of the sprite dissolve more into the fog. Since these effects are not likely to be used all the time, the tradeoff might not be worth it. Of course you could always store the sprite z-buffer info and then have your sprite routine draw either a per pixel or a per sprite z-buffered sprite in different situations. I'll likely just do a per-sprite z value. * paging in BG graphics. My thoughts here are still a bit underdeveloped since there are sooooooo many ways to approach this problem. Here's what I'm thinking so far: You have a 640x480x16 DirectDraw surface with back buffer for page flipping, and you store this in video memory (1,228,800 bytes). Then you have a say 1024x1024x16 background image buffer in video memory for holding your background (2,097,152 bytes). This is a double axis buffer, which means the info in it will be written to the actual back buffer with up to four block copies. The actual "tiles" of your background image are 128x128x16, so they tile 8x8 into the background buffer. You keep a duplicate of the background buffer in system memory for when you have to look up colors for alpha blending. You also have a 1024x1024x16 buffer in system memory that contains your z-buffer info. Both these buffers in system memory are double axis buffers, and they match up to the background buffer in video memory. So now when you build your scene you will decide where the upper left corner of your visible image falls in the background buffer and blit from they video memory background buffer to your back buffer with up to four separate blits. Note these are not block blits, but rather line by line blits of up to four different rectangles. Then you draw your sprites into the back buffer (not the background buffer), using the z-buffer in memory to decide how to z-clip the sprites. If you are doing blending effects with the sprites then you use the colors in the background buffer copy in system memory to calculate the blending. Now, how do you scroll this puppy? Well, scrolling little amounts is covered by using a different starting offset in the background buffer when you blit to the back buffer. Once you reach the edge of the background buffer, you will have to copy in a new row and/or column of your 128x128 background image tiles. The worst case scenario is when you move diagonally through the corner of the background buffer, in which case you will have to copy both a row and a column of tiles. A single 128x128 tile is 32k (32,768 bytes). A single row or column is 32k x 8 tiles, or 262,144 bytes (256 k). Both a row and a column together makes 491,520 bytes, which is still less than a 640x480 screen. You can even break this blitting job up over several frames if you use the next to the last/first row/column as your boundary line for when to update the background buffer. Anyways, the new info you use to fill in these rows and columns can be stored in memory compressed or uncompressed, read from disk, or whatever. To scroll you just update your axis in the double axis buffers, obtain the new info, write the new info into the system memory z buffer, the system memory background buffer, and the video memory background buffer. If your data is compressed, you can decompress into the system memory background buffer, and then blit the uncompressed image into the video memory background buffer. If you don't plan on doing any alpha blending, then you can eliminate the system memory background buffer and just work directly with the video memory background buffer. The fun part comes when you try to add animation to the background tiles. I haven't figured out exactly how I'm doing this yet, but it will likely entail writing the sprites of animation directly to the back buffer from sprite data stored in system memory. This is only one of several ways to approach this problem. * tile based movement and collision detection. Since your graphics will be built from 2d panes of graphics instead of tiles, you will need to store the tile and collision info separately. Essentially what this means is creating a separate tile map that contains collision info instead of graphic info. This will also be where you store your object info. ... That's what I'm thinking of so far. I'll likely take a stab at implementing it after a week to a week and a half, and I figure it will take about three weeks to convert my current tile based engine over to the new graphic approach. Then of course there are still other issues such as front wall removal, etc. Also, I'm considering storing the background graphics as large sprites instead of 128x128 tiles, and I will simply draw clipped sprites into the background buffer when it comes time to create new columns and rows. Don't know how well this will work though... It's late, I'm tired, and I doubt I'll make much more sense tonight (if indeed the above makes sense to you in the first place (^_^) ). Later, Michael Duffy mduffy@ionet.net
Article 191492 of rec.games.programmer: From: "John Mancine" <jmancine@voyager.net> Newsgroups: rec.games.programmer Subject: Re: Tile Based vs Non Tile Based Date: Mon, 15 Jun 1998 20:45:13 -0400 Organization: A poorly-installed InterNetNews site >Baulder's Gate draws the graphics one screen at a time instead of one tile at a >time. The movement system is based on an invisible hex (I assume hex) grid laid >over the graphic. Passing behind walls can either be accomplished by breaking >individual scene elements out at different layers, and using them to overdraw >characters that pass behind them, or the engine can have a z-buffer for each >image and use that to composite the characters into the background. > >I'm seriously considering implementing a z-buffered sprite engine that uses a >single image for the background (well, multiple non-overlapping tiled images), >and then z-buffers the character and object sprites in. I've been putting some >thought into it since looking at how nice Final Fantasy VIII's screens are and >thinking that it will probably be easier to do good graphics as a single image >rather than in individual tiles. Also, my artists are not too thrilled with the >entire tile idea, and tiles are tough to do in a 3D rendering package. I know exactly what you are saying. My 3D artist hasn't liked doing the iso tiles at all either. Simply because you can't really dive into the details as much as you can if you have more of a canvas to work on. One thing I don't get about not using tiles is how is the scrolling of the screen handled? (not even thinking about doing 'paged' scrolling... that is pretty cheap looking IMO) How would it work? Would you have the whole 'world' divided up into 1000x1000 sized "chunks" of images and then load these on the fly? Obviously you can't load them all at once. Can you elaborate a little more? Because I am very interested in doing this. And it would be the perfect time to do it in my project. Thanks, jrm