Godot's Tilemap Performance in my Tactical Space Game

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
Sometimes things just suck the life out of you. Some small features, stuff that was already working, just suddenly breaks everything and take all the life out of you and turns you into a leftover husk of a dead body programmer somewhere on the road. As some of you might know I've released my game in early access a couple of months ago and I've been working on it ever since then trying to come up with new updates and new features and fixing bugs and at the same time trying to see a little bit the feedback, what kind of impression I make, trying to promote my game on different forums or discord or reddit and see what people think. I've also pushed my game a little bit to some influencer and other Youtubers to see what they think.. And to be honest, the general... feedback i've gotten was pretty cold like single digit kelvin cold. On one hand I was kind of expecting something like that. I wasn't expecting like a rush for a game that's not even finished yet and I also think like that so that I can sleep at night.... but nevertheless I've taken all the feedback I've gotten and I've tried to put it to good use. I spent a lot of time analyzing all the results I got from the feedback or the influencer or the youtubers that actually talked to me about my game and I appreciate everything I got and I would say most of the comments I had turned around the fact that the game didn't look very good and that's kind of true but at the same time when you think about it there's plenty of games out there that do really well even with, well, allegedly poor graphics. I'm thinking of like undertale or binding of isaac or even worse dwarf fortress! Of course these games have a lot of other stuff going for them but what i mean is that it didn't stop people getting into it in the first place so what's different? So i started looking at screenshots of the most popular indie games and I compared them to the best screenshot I thought I had for my game and well the result is surprising I mean you can tell that my game looks boring. So I tried really hard to figure out what's wrong with it because I think the game itself when you play it is pretty fun at least I like it so if I like it someone else out there for sure must like it. So I need to make it look just as interesting as it is in real life and i'm not quite sure how to do that i'm not a very creative person i'm not an artist so i need to figure out logically what i can do to improve it. So i decided that for the next update i need to work on two things first i'm gonna try to take the screenshots and make them pop, make them more interesting make them look great and i don't know what that means. That means maybe moving the buttons around. That means maybe changing the screens. That means adding new graphic, making animations, I don't know but i need to figure something so for the first part of this it was well not easy but what i did is that i booted up Krita with a bunch of screenshots that i had and i started looking at how i can rearrange stuff without even worrying about how to implement that in the game because i really believe that you should always start with the top level stuff and then figure out a way to do it in your code even if it turns out that this is going to make your code look ugly the end result is really what's most important for the player one of the things i realized while i was looking at the screenshots of other games and my game is that at first i took a lot of screenshot without the fog of war because i thought the fog of war was boring and people wanted to see more planets and ships and shooting and stuff like that but comparing screenshot i realized that the fog of war that's kind of a blue cloud-like thing around the ship kind of makes the screenshot a little bit more colorful and by that a little bit more interesting but right now the fog of war is just a plain blue background and it's still not quite enough to make it look interesting so i thought maybe i can take the fog of war and make it more interesting add more color that's something i really have a lot of creativity to go with i mean like the stars the planets they're kind of you know already decided but the fuck of war could be anything right and it can add a lot of interest to a screenshot so i worked in krita i make a couple of different prototype and i came up with two prototypes that i really liked the first one is what i call the fancy version with um like the fog of war looking really cloud-like and having a lot of details in it and all that and the other one was something i call the more practical one because even me as a player i realized that the fog of war could have some more features right now it just shows you the places you haven't explored and to show you places you've explored that are not in your scanner range i just use like a ghost image of the planets and ships you've encountered before you still don't really know the range of your own scanner and if you've explored a big part of the galaxy it's kind of hard sometimes to tell where your scanner starts and where the explored remembered backgrounds start so i decided to go for the second version with a more practical look where you really see the limitation of your scanner range and you have like some kind of overlay to show the parts you've explored and i really like both version but i couldn't really figure out which one i wanted to try first in the game so i went back to the drawing board and came up with a third version that had a mix of all of those feature because one of the things that people said is that they really like the fog version or the cloud version but clouds in space it that doesn't really make sense so i tried to go back and redesign the cloud to be something more like a glitch in the matrix or something i don't know if i've pulled it off maybe i'll revisit it at some point but i i got kind of wet i was hoping i mean i'm not the best at using critter but i'm trying i'm trying now i was stuck with how am i going to implement this in the game recently i've been playing with the tilemap system in goodal for other stuff and i figured this could be a good way of implementing the area of the scanner and the highlight of the remembered part of the map i already have code iterating over all the tiles the player has been and toggling the remembered ship and the ghost image and highlighting the scanner part so i just need to place the code for the tile map a little bit everywhere and let the auto tiling system take care of like the border of the scanner and the remembered highlights and all of that and yes it took me probably an afternoon and everything was working fine or so i thought until i decided that it was time to see how it looked on my phone and i have an old tablet that i use for testing i really like to use it because it's pretty old it was already weak when i bought it so if it's running on this i know it's going to be running on pretty much any android phone out there and well after five minutes when i was about on the fifth frame of the game i realized that there was something wrong i've done a video before about how to use google profiler to see what's wrong with your code and you can check out the video in the corner there but in this case the profiler didn't give me much as you can see the idle frame is like 400 millisecond but the um actual script time is barely nothing so what's happening between the script time and the idle frame well good at is really good to tell you what's happening inside the game but it doesn't have many tools as far as i know to debug what's happening on the graphic card and it turns out that the issue with my tile map system is in the graphics i could debug on pc but on pc it's running fine and sometimes the bottleneck on a device is not the same as the bottleneck on another device so i wanted to try first to profile on device to see what's happening and turns out that my phone is using an old arm gpu so i went on the arm website and i downloaded a tool set for profiling the graphic capabilities of your phone of course it required me to do a little bit of back and forth and modifying some stuff and reading a lot of documentation but in the end i managed to set up a custom build process in godot run the gradle modify a bit my configuration so that it would use the libraries to debug the graphic performance from the arm utilities i installed and i managed to get um pretty good information about what's happening on the gpu of my tablet when i'm playing the game and turns out i have about 2 600 draw calls and on android that's a big no no a lot of 3d programmers will tell you now that draw calls are nearly costless on modern gpus and that's mostly true that's why on pc i don't see a difference but on android it's still very much a big issue if you go anywhere above like 400 draw calls and so 2 600 is yeah quite a lot so i profiled on my pc so that i could see every draw call one by one and when you look at it you realize that it's drawing every tile of the tile map one by one and that's really not good i was hoping that godot was going to be able to do some kind of i don't know batching or optimization for that but apparently it's not and so i had to go back to the drawing board and find a way to draw my tiles at least much faster and with not so many draw calls i had to think about it for quite some time i i spent probably nearly a day just thinking about the potential solutions for this problem and i came up with two ideas you see i need three things i need to display some kind of overlay for the unexplored part of the game now i want an overlay for the remembered but explored part of the game and finally i want some border around the active area of your ship scanner now i already use a trick for my unexplored part where i render a huge sprite and i punch hole in it using a mask texture that's the size of my tile map so i have a map that's 80 tiles wide and 80 tiles high so i have a texture 80 by 80 and each pixel represent whether or not the alpha should be on or off at this specific tile and then i have a shader that just goes and change the alpha of my sprite based on where i am in the tile map that works really well and it's a single draw call and the shader is pretty cheap so it's very performant so i was thinking i could do something similar for the remembered part of the map where i will just punch holes for the active scanner part of the map the problem is that i don't know how i can use this to render the side or the contour of my active scanner but i figured that maybe since this only changed when you change your scanner then i could maybe render this in the texture using the auto tiling so that i can after that use just the texture so it was a little bit of a tricky kind of solution but i thought it might work well now the other thing i figured is that maybe i can implement my own auto tiling system where i would generate a mesh dynamically inside gd script and then set the uv to a texture at last and just calculate which uv i have to use whether it's the remembered or the unexplored or the contour of my active scanner or something and this idea was really appealing to me but i was a little bit worried about the performance of it because each of my levels are 80 by 80 tiles big i need a lot of information for each of those style for example if i want to use index buffer rendering i need six indexes four vertices and four uv coordinates for each tile in my levels that's like four times four times six times four times four data points that i have to put and send to the gpu every time i need to update my tile map so i did what every insane person would do and i decided to implement both method and see which one is fastest of course i didn't take the time to implement it in the game properly with all the dudas and stuff i just wanted to see which rendering would be best so i created temporary scenes with the most basic setup i could think of and i was happy to see that the dynamic mesh solution wasn't that much slower than the mask occlusion technique i was using for the unexplored part of the level so i decided to take the generated mesh idea and implement it in the game and finally i got it working but my pain wasn't over yet because once i finally got it working on pc i quickly installed it on my tablet to see how much the performance had improved and oh wow me wasn't my pain to discover that i was still running at 2 or 3 fps i was like what the actual f i cut down like 2 000 drawcall my fps should be at like 30 right now so i booted up again the godot profiler to realize that now the rendering was fine but my gd script was incredibly slow so what the hell happened it seems that every time we move i have to update all the tiles around the player ship and if you have a scanner that's a little bit on the bigger side that's easily 20 tile wide of stuff you have to update so if you update it in a square that's about 400 tiles you have to check and update if needed but for me a 400 iteration loop is not that much and it i mean it could be it it would show on the profiler but it shouldn't like put my fps to like two or three that that doesn't make sense to me so there has to be something else that i'm doing that's completely killing the performance there's a couple of other methods that i called hundreds of times and they're not taking nearly as much so what's wrong with the way i'm doing my generation of my mesh now i found some subtleties that probably was killing my performance for example when you're generating a mesh you can't use regular ares because godot expects you to send it some pool dairy which is a different type of aries and godad that are supposed to be more optimized the thing is is that those pool varies are not passed by reference so since i was caching already the uv array but as a pooled vector2 array well every time i'm writing it or every time i was passing it to a method then it was being copied over and over and over and over more likely like 400 times and like i said that's an array that's 80 by 80 by 4 which means more than 25 000 indices inside this area so copying it 400 times in the memory is probably not good so what i did is that instead of caching this as a pool array i decided to cache it as a normal array that's passed by reference everywhere in godot and i only turn it into a pool area when i need to update the mesh at the very end of all the update process and just doing this finally brought my fps back to something like 15 20 or so it's still not great but like i said this tablet is already really bad so on anything else it's okay performance and on my other android phone i have like 40 fps or something and of course on pc i don't see any lag or any drop in fps so for now i'm gonna call it done but i'll probably need to revisit it because there's still something wonky about the fact that it's taking so long to update the simple scanner but that was such a big pain and i've been working on this for like two weeks and it's not even finished yet and it's something that was already working i just wanted to make it more pretty so that was a really big pain and i didn't really enjoy it but i'm glad i discovered a lot of new stuff about godot and about tile map in general and about the fact that i'm probably not going to be using any godot tile map for anything serious in the future also you might have noticed during the intro that to keep me sane i've taken to drinking some insane stuff like this orange vanilla coca-cola that i've been dying to try and i'm just going to drink in front of you now ah the sweet taste of orange crush mixed with some vanilla essence and regular coca-cola it's not the greatest i'll have to admit but at least it puts a smile on my face that's it for this week thank you for tuning it sorry for the lack of update recently the kids have been on summer holiday and they've been at home all day because of the coronavirus so recording has been quite hard that doesn't mean i haven't been working like you see i've been spending a lot of time trying to improve the look and feel of my game and i'm really looking forward to sharing with you more of the improvements i've done over the last few weeks so until then see you all in my next episode bye
Info
Channel: Ombarus
Views: 1,674
Rating: undefined out of 5
Keywords: Guillaume Bouvier, Ombarus, GameDev, Programming, Coding, Software Engineering, Solar Rogue, Tilemap, Godot, Profiling, Performance, Devlog, Indie Dev
Id: fQQRsqD6UKg
Channel Id: undefined
Length: 19min 50sec (1190 seconds)
Published: Wed Aug 26 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.