#32097 - Steve++ - Sat Dec 18, 2004 3:49 am
I'm designing a platform game engine. I started with a simple tile engine (able to scroll very large tile maps with multiple layers). Then I saw a post by tepples; he said that instead of designing tilemaps, we should design maps of objects - objects being A tiles high and B tiles wide. A level would be rendered using a compositor that draws the objects on the screen.
This got me thinking very deeply about the architecture. I'm definitely going with this idea. The foreground layer - where everything happens - will be encoded as a list of objects. The problem is that, if there is just one single flat list of objects, every frame the compositor must traverse the entire list and draw any objects in display range. I've thought of a simple optimisation (which I'm sure I've seen before):
Each level will be divided into a grid. Each cell in a grid will have a size of, let's say, 16*16 tiles. Each cell will contain a list of objects which it contains. In ROM, there will still be a single list of objects for each level. The cells' lists will be generated as part of the level loading process.
This also works for moving objects (sprites). As they move around the level, they must register and deregister themselves with cells. This optimises collision detection. One approach is to say that an object belongs to a cell if its origin pixel (top-left) is in that cell. This means that to test for collision, we'd need to check against every object in the host-cell, then every object in all the surrounding cells. The other approach is to say that an object belongs to a cell if at least one of its pixels is inside the cell. Assuming that the maximum object size is the same as the cell size, each object will belong to one, two or four cells. That way, collision testing is minimised, but in the worst case scenario, four times the memory is used for linked lists.
On the topic of linked lists, I'm not using the STL list template. I'm designing an object pool template that uses a stack to allocate and deallocate an object. This results in zero memory fragmentation. The beauty of this is that all the cells' linked lists will draw from the same object pool, whereas the best the STL list template can do is create one pool per list instance. This is a topic for another forum...
I would like to know if my idea is a bit too extreme and could be simplified to make better use of memory without too much CPU overhead. In other words, is this a sledgehammer approach or am I on the right track? I welcome any suggestions, improvements, critiques, etc.
- Steve
This got me thinking very deeply about the architecture. I'm definitely going with this idea. The foreground layer - where everything happens - will be encoded as a list of objects. The problem is that, if there is just one single flat list of objects, every frame the compositor must traverse the entire list and draw any objects in display range. I've thought of a simple optimisation (which I'm sure I've seen before):
Each level will be divided into a grid. Each cell in a grid will have a size of, let's say, 16*16 tiles. Each cell will contain a list of objects which it contains. In ROM, there will still be a single list of objects for each level. The cells' lists will be generated as part of the level loading process.
This also works for moving objects (sprites). As they move around the level, they must register and deregister themselves with cells. This optimises collision detection. One approach is to say that an object belongs to a cell if its origin pixel (top-left) is in that cell. This means that to test for collision, we'd need to check against every object in the host-cell, then every object in all the surrounding cells. The other approach is to say that an object belongs to a cell if at least one of its pixels is inside the cell. Assuming that the maximum object size is the same as the cell size, each object will belong to one, two or four cells. That way, collision testing is minimised, but in the worst case scenario, four times the memory is used for linked lists.
On the topic of linked lists, I'm not using the STL list template. I'm designing an object pool template that uses a stack to allocate and deallocate an object. This results in zero memory fragmentation. The beauty of this is that all the cells' linked lists will draw from the same object pool, whereas the best the STL list template can do is create one pool per list instance. This is a topic for another forum...
I would like to know if my idea is a bit too extreme and could be simplified to make better use of memory without too much CPU overhead. In other words, is this a sledgehammer approach or am I on the right track? I welcome any suggestions, improvements, critiques, etc.
- Steve