KeenSoftwareHouse / SpaceEngineers

2.93k stars 898 forks source link

Turret AI Improvements #51

Open NivvyDaSkrl opened 9 years ago

NivvyDaSkrl commented 9 years ago

Putting this in to let people know I'm working on it. I've identified a couple of possible improvements for turret AI.

I intend to address the first two items immediately; the third will require a bit more familiarity with how communication between blocks is handled.

Aimpoint calculation: Current algorithm only considers velocity. Reworking the algorithm to also consider acceleration should increase turret utility, particularly against astronauts and missiles.

Target prioritization: Current algorithm is a simple "closest first" for all target types. For certain target types (missiles, meteors), targets where the sum of the normalized relative position and normalized relative velocity of the target is close to zero (IE: it's coming right for us, Cap'n!) should really have the highest priority, though distance should remain a factor. This is the highest priority item; currently, meteor defense is very unreliable, which is frustrating.

EDIT: See pull request #65 . EDIT: No longer considering the following part of the same issue: Distribution of targets between turrets: Ideally, we should have a way of spreading the targets out a little between the turrets on an individual ship. One way of doing this is adjusting each target priority by a random amount, so that the more alike the priorities of two targets are, the more likely it is that the turrets will pick a different target at random. A better (but harder) way is to arrange for a shared target list between turrets on the same ship, or somehow partitioning the space around the ship into different fields of responsibility assigned to different turrets. This is a lower priority item than the above two, though.

MMaster commented 9 years ago

Great effort although I'm not sure if making turrets super accurate is good for game play.

sjsoft2015 commented 9 years ago

MMaster, aim must be very precise. But various guns should have a different level of scatter and damage. Let's look at the lasers. They are very accurate, but it should do less damage (requires a lot of energy). Again beam plasma is flying for a while and if you do not change the trajectory of it is you will necessarily get (you need to dodge). IMHO

NivvyDaSkrl commented 9 years ago

I tend to agree with sjsoft. My intent is to provide the best underlying algorithm for the purpose; actual accuracy on the game-play side can be tuned separately. But the methods in question are named along the lines of "GetPredictedTargetPosition()," not "GetApproximateTargetPosition()". I want to provide the best data possible; what the game actually does with it is up to those responsible for tuning game balance.

zrisher commented 9 years ago

I was disappointed to see this doesn't focus on decreasing turret CPU drag, but these are nice additions anyway. : ) Just please make sure the eventual solution doesn't slow them down even further, and if you could include some optimizations to turn them off when no one is near that would be superb.

The Autopilot mod has some features for better turret management, this might be a good reference for you: https://github.com/Rynchodon/Autopilot/tree/master/TurretControl/Scripts

NivvyDaSkrl commented 9 years ago

For the accuracy algorithm, I removed some vector mathematics and put more in. It should balance out.

For the target selection algorithm, I add a few vector mathematics expressions whenever there's a meteor or missile in the target radius.

That said, the number of turrets required to realistically protect an area has been reduced. Immensely. The starter platform in Easy 1 is pretty well protected on Armageddon difficulty with only four gatling turrets. And the missile turret even hits a meteor every now and then. :3

zrisher commented 9 years ago

I'm sure the devs would appreciate performance profiles with your final PR, and I would be really curious to see them too. It's pretty simple with the built-in utility:

VRage.Profiler.MyProfiler profiler = new VRage.Profiler.MyProfiler(47, false);

profiler.Stopwatch.Start();
    for (int i = 0; i < 100000; i++) {
        ... some expensive logic from existing turret tracking ...
    }
profiler.Stopwatch.Stop();
log("Old method: " + profiler.Stopwatch.ElapsedMilliseconds + " ms.");

profiler.Stopwatch.Reset();

profiler.Stopwatch.Start();
    for (int i = 0; i < 100000; i++) {
        ... the analogous part of your logic ...
    }
profiler.Stopwatch.Stop();
log("New method: " + profiler.Stopwatch.ElapsedMilliseconds + " ms.");
NivvyDaSkrl commented 9 years ago

Hmm. I just made the pull request. The changes aren't extensive. I'll try to figure out the profiling stuff; not familiar with it.

zrisher commented 9 years ago

PR #65