I spent yesterday cleaning up some more gameplay issues, and working out some of the AI a bit more. One nice fix is that I made the laser weapon that you carry into the game a real inventory item. That fixed the bug where you would pick up an axe, and then when you threw the axe, you couldn't fire the laser anymore.
Similarly, the enemies have real inventory items as well, and now have to worry about recharging, etc.
Now that the AI is a little better, it's much more obvious when it screws up. The enemies track you down, and stop when in range, and start shooting at you. Unforunately, they don't avoid each other yet, so they can get bunched up if on a bridge. That created the situation where 3 enemies were in single file crossing the bridge, and the one in front stopped b/c she was in range. The ones behind weren't quite in range, but they were stuck behind the first enemy. That's the sort of thing that can really take you out of the gameplay experience, so I definitely need to address it.
Similar issues arise even when the AI is on its own. For instance, if an AI gets in range of you, she shoots until she is temporarily out of energy. If still in range, she just stands there. Obviously it would make more sense if she moved somewhere. A cautious AI would seek cover when out of juice. An aggressive AI might approach the player and switch to a melee weapon, or plan to have more energy when she arrives to shoot with.
Another problem is that the AI currently paths to the player, but then stops early when in range. A better approach would be to go to the nearest spot that is in range of the player. That way, the AIs would not always be crossing bridges when they could just approach the river and shoot you from there. This is where a dumber AI would actually do better - just moving towards the greatest direciton towards the player until in range ( ie n,s,e,w would fix this ).
One thing that could help these situations would be different AI personalities. For instance, if some stayed back and shot from a distance, others sought cover, and still others charged the player, they would not bunch up and would be more interesting to fight.
The bunching up will be partly solved when I add in the dynamic A* cost near the enemies. Each enemy will add some temporary dynamic cost in a 3x3 meter area around it. It will remove its own cost before it moves ( so it doesn't avoid itself ), and then plan its own path, then add it back in for others to path around. This way the AIs should try to find local paths around nearby enemy characters.
The other way to solve it is to have different goals for the AI, as above, which should cause them to do different routes, or at least take the same route at different times. Perhaps I could have different roles, like scout, rusher, sniper, etc.
One idea I had for marking cover was to have the level designer place triggers and mark them as cover near obstacles. For instance, a designer could make a 3x3 trigger box around the base of a 1 meter wide pillar. When looking for cover, the AI could find the box, and then path to the side of the box furthest from the player's location, which should be 'behind' the pillar from the player's POV. That way the designer doesn't have to mark multiple sides of some piece of cover.
I found another navigation issue yesterday - and it boils down to the 2D mesh. On the full tower level, with the terrain, there is a vertical conflict. The ground terrain and the bridge are both valid places to walk, and each has the same x/z coordinates, and both are accessible by the player, so there is no valid way to make a 2d grid out of it. I will simply have to switch to a sparse map or hash instead of a 2d grid in order
to address it once and for all.
I added a couple more things to the editor, including the ability to rename objects via the Object Tab. This is nice, as it allows you to change "Entity_0001" into "Skull" or "Player Start". Much more friendly. This also applies to Triggers, Lights, etc, so this should make it easier to keep track of what is what. Here is a shot of the editor with some better names :
I am working on integrating the Novodex physics library into the engine. It seems to be a fairly clean API, and my work on my own physics system has prepared me pretty well to understand it so far. I've hidden all of the Novodex-related things so far into Novodex.cpp & h files, so the rest of the code can remain as oblivious as possible.
So far I have the static world geometry 'cooked' in as collidable but static geometry and pass that to novodex. I have to take out duplicate vertices first, so positions are as shared as possible, then I have to be sure and leave out any liquid or non-collidable triangles.
It seems to be coming along, and although I am creating physical actors and simulating them, I'm not actually using the results quite yet. The next step, most likely for tomorrow, is to draw the Novodex versions of the physics objects.
Once that seems to be doing something plausible, I will actually use the physics-derived information to move things around in the game. Lastly, I will set up the novodex trigger system and contact info.