I focused again on the fog of war script, I removed all the movement and other stuff so I could get a more accurate understanding of what was causing slow downs.
I think I’ve got something a little bit more focused and stripped down now, it clocks in at 0.29-0.36 ms logic once every 60 tics which means it won’t put a dent in the 60 frames per second I’m aiming for in the project. In fact I can have it running at zero tic intervals and still clock 60 frames per second. This is even with 16 agents in the scene.
I got this improvement in performance by avoiding unnecessary checks.
But rather than using lists and checking if a vertex is already in a list as I originally intended, I used a property:
see = False
and then looped through the players to see if any of them could see the vertex. If someone can see it I set “see” to True and stop checking for the other players/agents. If see == True at the end of the loop I color the vertex white. Otherwise it goes black.
After some thorough testing of different approaches to the problem I can say:
When making checks, stacked loops like [[for vertex in mesh] for player in scene] can really multiply pretty quickly. They can cause performance problems. It’s important to get out of the loop, or at least stop making checks once you have the data you need. once see == True, there’s no need to continue checking.
Likewise, “if vertex in seen list” can cause problems one the seen list gets above a few hundred entries. It’s better to perform your transformations or alterations inside the main loop rather than creating a list of targets for your operations. On the other hand, a short check of whether something needs to be checked at all (the view_sphere list builder is a good example) can save a lot of performance drain later.
Using ob.getDistanceTo(point) is preferable to writing your own distance checking function. Even though my own function was only checking 2d distance rather than 3d, and my script used simple manhattan distance rather than a more complex calculation, the blender function getDistanceTo is a compiled function, and runs much faster. Nearly 3 times faster in fact. I just wish getDistanceTo could be performed on two points, rather than one object and a point, I could improve my A* script a lot with it.
I’ll be looking at some more RTS tools soon, if you have some particular function of a traditional RTS you’d like to see worked on, please make a request here.
Some things I’ll be tackling:
infantry sprites
infantry squads and formations
A* navigation speed ups
avoiding traffic jams by pathfinding units
loading infantry in to vehicles or buildings and unloading them
objectives and victory condition checks
Hopefully each experiment will result in a usable template that others can take to use in their own projects.
I’ll also be trying to learn how to tidy up my python scripts a bit while working on these functions.
EDIT:
I did some experiments with shadow casting.
Unfortunately, not only does it not look good (there are gaps in the shadows) it also takes a massive performance hit.
I’m going to try doing something with shadow paths based on linear extrapolation, hopefully I can get it to work, otherwise we don’t have the ability to block vision with buildings. I remember old games often didn’t have that function, but I’ve seen it working in newer games, so it should be possible.