”making the AI better at predicting shots” is a funny title, since the AI was so bad I probably could have build a random function that would make it statistically better at hitting the player.
First of all, the AI could not hit a target even if it was static.
Hit a static target pls
To be fair I have not really spend time with the AI beforehand, it was just there ‘to be there’. But it even could not hit you when you stood still.
Which sort of worked, since with the realistic steering (meaning that if you turn right you will only accelerate your rotation and it won’t stop without another input) most of the players were not really able to hit anything reliably either.
So after hearing so many complaints about that, I decided to make the steering non-realistic by default, so that the rotation stops when you lift the key. (You can still go for realistic in the settings menu – casual 0).
So back to topic.
What was the AI’s problem? It was correctly looking at the player when shooting, yet it missed almost every red laser projectile.
Because the “red lasers” are projectiles, it means that they inherit the ships velocity when they are fired. So if you move to the left while aiming to the top, your bullet will also move to the right when you shoot it.
bullet vector = ship velocity vector + ship direction* bullet speed.
(Please don’t kill me for using the wrong expression here and there)
So the calculation to fix that is pretty straight forward. We know the bullet trajectory needed to hit the target and we know the current ship velocity. So to calculate the right direction the ship has to face we calculate the bullet trajectory – ship velocity and then use tangens to the get the angle.
The next step
This works for static targets, but what about a moving target (like the player’s ship). We can still use the same math, but instead of aiming for the target, we have to aim at the target’s future position.
So we need to know how much the target has moved during the time the bullet needs to get there.
A first very basic approach, was to calculate the distance between ship and target and divide the result by the bullet speed. This would give us the time the bullet needed to travel the distance. The target to shoot for would then be updated to “ target position + target current velocity* travel time “.
Of course there is a sizeable error, because of course the bullet has to travel further (or less) than the current distance if it wants to hit the moving ship, so the timing is off.
This assumption is good enough if we assume that the bullet speed is much higher than the target speed. And most importantly it is very cheap, basically 2 lines of code (calculate distance/speed and add target velocity*time).
The AI is really good at aiming even with this naïve approach. Because of constant player acceleration and turning a really good prediction would not be much much better.
Or would it?
I thought “ugh why not” and started working on a “proper” solution. Then it came to my mind that this problem has probably been analyzed a thousand times before so I turned to Google and was not disappointed.
The solution is to build a quadratic equation so that bullet travel time and target travel time would be the same. It is not that complicated but I would rather refer to a great stackoverflow page with multiple solutions and great explanations.
So yeah. That’s it. I hope you are not too disappointed because the only interesting thing I basically skipped and referred to a link.
The AI still has some issues, like for instance it will take shots that will never reach the target because the bullets expire beforehand, but these are really minor.
I think most of you will find the AI really rather unbeatable now. Try it out here:
Wow, great. You’ve made a super good AI with godlike reflexes and super aim. This sucks. Your game is unbeatable, they are cheating.
Deal with it.
For now. Because of course this is not the final version of the AI. But it is always the right step to first make the AI smart so I can artificially cripple it so it becomes a competitive experience for the player without being too frustrating.
There are many ways to do so and I will explore some of them in the future.
I hope you liked this entry – now go and check out the game! : )
On related news
The world is now filled with shards. These are created in a grid (inside a bigger grid) around the player. I needed to make it so they are not instantly removed once out of sight, because some players may notice changing position and looks. So yeah it works.
Also the enemies are now randomly generated in a way. And a new enemy will respawn when the old one dies. But this currently happens very rarely as the player is mostly the one to fail.