Page 1 of 1
Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 3:09 am
by EccentricDuck
For the platformer I'm working on I'm building the framework around a Entity-Component model. However, I'm trying to decide whether I should treat tiles as Entities or as their own thing.
A pure approach would be to treat them as Component-based Entities because nothing in the game environment "should" be otherwise. However, I'm interested more in a practical approach and the consequences of going one way or the other. Would someone be able to fill me in on their experience and why they went one way over the other?
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 6:42 am
by JarrodParkes
IMO terrain and/or tiles do not necessarily need to be component based. As such that for most game applications, tiles do not require much or vary outside of their base properties. Whereas entities may be broad and vast, most tiles all work the same way, and usually are optimized assuming this. I do not think the overhead, however, would be that extreme to provide them within the component design, my question is just how much do they really need to support that design? Then again, just my opinion from a non-seasoned game developer.
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 8:51 am
by Falco Girgis
ABSOLUTELY DO
NOT MAKE TILES ENTITIES!!!
An "entity" is a free-floating object that can be placed everywhere. A tile is nothing more than an index into lookup tables of attributes and images. Because of this, they must be evenly spaced to correspond to a 2D array.
You are literally destroying the point of a tile engine by making tiles entities. Instead of utilizing mega-fast lookup tables for all of your game's terrain, you are going to be managing tiles/terrain in lists just like other entities. You're going to need some kind of BSP or broad-phase algorithm to even manage the tiles onscreen semi efficiently. Even then, the best you could hope for is something along the lines of O(logn), when a direct lookup table is a perfect O(1).
There is a reason that 2D RPGs dating back to the NES and Sega Master System used tiles. It's because they are the absolute most efficient method algorithmically of populating a map. Making the terrain entities as well will waste a shitload of space, processing, and will undoubtedly generate far more complex code for management. Sure, it sounds cute from a 100% OO whorish standpoint, but don't.
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 9:00 am
by JamesParkes
GyroVorbis wrote:Sure, it sounds cute from a 100% OO whorish standpoint, but don't.
I felt like I should have known this, but now I'm glad there's a good answer and reasoning behind doing it that way. I've been enlightened!
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 9:43 am
by Lisergishnu
Thanks Gyro, I had the same question
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 4:59 pm
by dandymcgee
GyroVorbis wrote:
You are literally destroying the point of a tile engine by making tiles entities. Instead of utilizing mega-fast lookup tables for all of your game's terrain, you are going to be managing tiles/terrain in lists just like other entities.
Totally agree. This man makes an excellent point.
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 6:38 pm
by EccentricDuck
Thanks for clearing that up - though that brings another question to mind.
My framework is in C# and I'm currently using structs to represent tiles. It's an approach I'd seen recommended elsewhere. Each struct contains a static constant width and height, a texture reference, and a collision enum representing Passable, Impassable, or Platform (one-way passable). Is this a less cachable and less speedy lookup than storing each of those parameters in an indexed array? The values are typically looked up in conjunction for collision and rendering.
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 7:44 pm
by Ginto8
EccentricDuck wrote:Thanks for clearing that up - though that brings another question to mind.
My framework is in C# and I'm currently using structs to represent tiles. It's an approach I'd seen recommended elsewhere. Each struct contains a static constant width and height, a texture reference, and a collision enum representing Passable, Impassable, or Platform (one-way passable). Is this a less cachable and less speedy lookup than storing each of those parameters in an indexed array? The values are typically looked up in conjunction for collision and rendering.
I think you're misunderstanding him - he means to index the tile's "type", rather than its individual bits of data. You can have a TileType (or something of the like, I think that this is basically what your tile structs are) with TONS of data in it, depending on the game. But the most important thing is that the bulk of the data is not stored in the tile itself: the individual tile just references (in index form) which grouping of data it represents. You might add a small amount of data to each individual tile to distinguish different states of the same tile (lit, unlit, on, off, damage), but the vast majority of the data should be stored somewhere outside of your tile array.
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 7:54 pm
by Falco Girgis
Ginto8 wrote:EccentricDuck wrote:Thanks for clearing that up - though that brings another question to mind.
My framework is in C# and I'm currently using structs to represent tiles. It's an approach I'd seen recommended elsewhere. Each struct contains a static constant width and height, a texture reference, and a collision enum representing Passable, Impassable, or Platform (one-way passable). Is this a less cachable and less speedy lookup than storing each of those parameters in an indexed array? The values are typically looked up in conjunction for collision and rendering.
I think you're misunderstanding him - he means to index the tile's "type", rather than its individual bits of data. You can have a TileType (or something of the like, I think that this is basically what your tile structs are) with TONS of data in it, depending on the game. But the most important thing is that the bulk of the data is not stored in the tile itself: the individual tile just references (in index form) which grouping of data it represents. You might add a small amount of data to each individual tile to distinguish different states of the same tile (lit, unlit, on, off, damage), but the vast majority of the data should be stored somewhere outside of your tile array.
^ this.
Shit, our tile structures have all of the above, but our map is a simple array of either chars or uint16s to index into these arrays.
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 8:55 pm
by EccentricDuck
So if I'm understanding correctly, my Tile struct should basically reference data that is pre-loaded elsewhere.
After doing some digging, I've confirmed that's what is happening via the XNA Content Pipeline. I was looking at my level class which loads tiles based on lines read in from a .txt file, and it seemed to load the same content again and again the way it's written (it was a sample I'd borrowed for getting the tile engine up and running quickly). In actual fact, the Content Pipeline loads one instance on the back-end then saves and re-uses that instance so that each subsequent call to load the same texture just references the same instance on the back-end. So while each of my tiles is being passed a reference to a Texture2D that appears to be loaded anew each time, they are all actually referencing the same Texture2D because of the Content Pipeline.
ADDENDUM: Actually, I realized there's possibly a gross inefficiency with it. There's no reason to have hundreds of unique tile structs representing the same tiles again and again in separate locations when the level array contains the only unique data points, the position coordinates. I'm not going to say that's a huge waste of memory (even if it is a small waste), but more-so I wonder if that fucks up how cacheable the tiles are since it's dealing with hundreds of unique structs rather than references to a select few (even if each struct is referencing the same data it provides a layer of indirection which might make back-end optimization more difficult).
Given that the game doesn't run 100% smoothly on our designer's craptop which he brought to the Game Jam (which for a properly implemented platformer with little going on in the environment it should) I wonder if this might be the issue. I'll get back to you on what I notice. The memory footprint of the game is only about 200k, though it uses about 15% of my processor on a 2 GHz Core 2 Duo consistently without taking any action in-game (pot shot at Java: any Java game I've written tends to use more than this just to run Java). I'll report back on what I get afterward by pre-loading the individual unique structs. I'll also try it with objects because I have a feeling that if I do that, passing them by reference rather than by value might be more effective but I'll see what the results show.
Re: Tile: Entity or its own thing?
Posted: Thu Feb 02, 2012 9:52 pm
by avansc
if your tiles are static, then yea, no need to have them be entities.
if they are dynamic, there may be some advantages to that. Also, you can do some pretty cool things if your tiles are entities, baring that your entity/component system is robust.
Re: Tile: Entity or its own thing?
Posted: Fri Feb 03, 2012 9:10 am
by JamesParkes
Sounds like this discussion is moving towards one of my favorite object-oriented design patterns, the flyweight design pattern! A flyweight is ... (as defined by Wikipedia) ... an object that minimizes memory use by sharing as much data as possible with other similar objects; it is a way to use objects in large numbers when a simple repeated representation would use an unacceptable amount of memory! Correct me if I'm wrong, but I think this is what you would like to be shooting for with your tiles. Let me know if that helps or is totally useless
.
Re: Tile: Entity or its own thing?
Posted: Sat Feb 04, 2012 11:51 am
by EccentricDuck
It seems not to make the slightest bit of difference whether I load the content on one struct (or object) per tile type and just reference that in my array, or create hundreds of unique ones containing the same values. My guess is that C# is just optimizing everything on the back-end, treating all those different objects/structs as a small number of single objects anyway (since they contain exactly the same values for structs/objects of the same tiletype) and giving me the same effect no matter what I do. The simpler way would therefore be to not worry about it because the way it was before is simpler to read.
The thing that really surprised me was that I didn't notice any difference between structs and objects. I didn't use a tool to test, but judging by system resource usage on the process the game fluctuated within the exact same regions for processor usage between the different configurations.
The flyweight pattern is being enforced for content by the XNA Content Pipeline which automatically loads only 1 piece of each content type when they're first loaded in code and just re-uses that piece when it's loaded elsewhere. What I didn't know was that C# seems to be optimizing all the extra instantiated tile objects by seeing that the data they contain is non-unique and enforcing the flyweight pattern on them. I can't say for sure that this is what is happening, but it seems to be the case since testing it with the flyweight pattern gave the exact same effects as what was happening.
Re: Tile: Entity or its own thing?
Posted: Sat Feb 04, 2012 9:05 pm
by JamesParkes
whheelll ... very cool. it seems like the XNA content pipeline is doing some pretty powerful stuff!