🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Discussion [Recreating Rendering]

Started by
1 comment, last by JohnnyCode 5 years, 3 months ago

Hey there, I've been trying for quite a while now to recreate the rendering system of the game called 'tibia'. It's a 2D grid-based game which consists of several 'height levels' each of those levels gets rendered on its own respectable layer, and there's a total of 14 layers, which are split into 2 sections, the underground layers (0 - 6) and overworld layers (7 - 13), which means that only 7 layers get rendered at a time. I've recreated the actual rendering but it's more or less a brute force approach and the FPS drops quite a lot as more layers are turned into a render. I'm using GMS2 which has pretty poor optimization (starting from the variables themselves, almost everything is declared as an int64 even 'booleans'). This is what I've done so far:

First of all, I'm saving all the map data inside of a buffer (buffer size is map_width * map_height * floors(12) * 4 BYTES). The first of the 4 BYTES is split into three groups [00][00][0000] respectively where the first group holds the multiplier of the sprite_data for the GROUND (terrain) the second group holds the multiplier for the TRANSITION(e.g. water -> grass, grass -> dirt) and the third group has 15 possible combinations which would hold Monsters/Npcs/Objects. Now then, the second BYTE holds the ID of the GROUND floor inside the spritesheet. There's a total of 255 combinations * 4 (the multiplier from the first BYTE), the third BYTE and fourth BYTE basically represent the same thing with different data(TRANSITIONS and OBJECTS). I've also created another buffer which holds the collision_map data, basically it's a map_width*map_height*floors*1BIT and it's a 1 or a 0 per tile.
Now then here comes the problematic part, the rendering itself. Basically when the game starts everything gets rendered first time via brute force 
 

for(z=0 z<ground_floors; z++) 
	for(i=0; i<width; i++) 
		for(j=0;j<height;j++)
draw_tile(x,y,tile_sprite);

 

 
When the camera moves(or the player if you will) depending on the direction I'm rendering only the row/column which is being revealed as he moves on, but the thing is I'm rendering it 6 times (because there are 6 floors). I've realized that I might render from top to bottom, and do something like:
 

for(z=max_floor; z>6; z--){
	for(i=0; i<row_size; i++){
		if(tile(z) != 0)
           draw_tile(x,y,tile_sprite);
        else break;
    }
}

 

 
Which would save quite a lot of calculations but only if there are tiles on higher floors, otherwise it would result in a drawing of floor_count * row_size calls. I've also been considering about checking if I'm currently at a floor which is greater or lower than ground_floors/2 and based on that I'd render either from the bottom up or from the top-down but I'd probably still have a lot of issues while drawing. My actual problem is that my FPS drops quite a lot when drawing on the last 2 top-most floors, for example it's something like 240 FPS on the lowest floor, while it's 35-40 FPS at the top-most floor. 
 
I hope that you can understand my gibberish code.
Thanks in advance, 
 
Alex
Advertisement

First question that pops my mind is why layers? Is it depth? The fact the data is layerd is amazing and does not demand layered render processing in the end?

On 3/13/2019 at 10:23 PM, Alex Xander said:

Which would save quite a lot of calculations but only if there are tiles on higher floors, otherwise it would result in a drawing of floor_count * row_size calls. I've also been considering about checking if I'm currently at a floor

Sure drawing from top to down is always the pick, you might be having some sort of actual floor reference and render from that if upper tiles are not visible and omit them?

Referencing that to the row/tile first processing, and then to the posetion of level, like


for(i=0; i<row_size; i++){

for (level=mostvisibleupperlevel,level>downmost;level--)

Just my few cents in the dark.

This topic is closed to new replies.

Advertisement