Skip to content

Tournament Writeup 2023‐09‐18

derivator edited this page Sep 20, 2023 · 6 revisions

rlane

Strategy

The fighter aims to fly in a circle around the origin, choosing the direction that takes it farther from the enemy fighter. The goal is to defeat missiles by running them out of fuel. I found this worked better than attempting to shoot down incoming missiles from a long distance, presumably because the main thrusters are much more powerful than the lateral ones and delaying turning to shoot at missiles means it can keep using the main thrusters to accelerate. It ignores missiles that are more than 2 km away or aren't headed right for us.

After 120 seconds it abandons the evasive strategy and seeks towards the enemy fighter. It also overrides normal movement to avoid the edge of the map.

Radar

The fighter's radar starts by scanning the line at the other side of the map where the enemy fighter can spawn. This can speed up the initial search versus scanning in a full circle.

Once the enemy fighter is found then the radar alternates between refreshing existing tracks and searching for incoming missiles. The search for missiles is done in an arc centered on the enemy fighter under the assumption that they'll be coming from that direction.

The radar attempts to differentiate targets that are at the same bearing but different ranges. When the search mode finds a contact it will push the sections closer and further than the contact into a stack to be explored next, using the min/max distance filters of the radar.

A simple weighted moving average is used for filtering. I still need to implement a Kalman filter...

Radio

Radio messages are timestamped, checksummed, and encrypted. It uses frequency hopping to evade jamming. There's only a single message type implemented which contains the position and velocity of the enemy fighter.

Missiles randomly alternate between listening for updates from the friendly fighter and watching random channels for enemy radio messages. Once an enemy radio message is found the missile will spend a portion of its time replaying that message on the channel where it was recorded. My goal was to do a replay attack that would give enemy missiles stale data or at least jam their channel. I assumed the top opponents would have checksums on their messages and so corrupting them wouldn't be effective. I saw the replay attack increased the win rate against stichinksi's AI from the previous tournament by 10%.

Radar Jamming

The fighter doesn't use its radar for jamming but the missiles do until they get within 12 km and start searching with their own radars. Since the missiles are often between the friendly and enemy fighters this can help break the enemy's lock.

Miscellaneous

  • Missiles consume target updates over radio if the SNR given in the message is higher than what the missile's own radar is returning.
  • Missiles fly to a spot slightly offset to the side of target in order to be harder to hit.

stichinski

TODO

hopeful-quail

1190 loc, 461 insertions(+), 237 deletions(-)
Changes:

  • Fix bug that caused missiles to attempt to collide with the map origin. This made missiles basically useless in previous tournament.
  • Implement shaped charge missile logic. The explosive shaped charge creates is
    pub const MISSILE_WARHEAD: Warhead = Warhead {
        // count: 20,
        // mass: 0.05,
        width: 0.4,
        speed: 1e3,
        ttl: 0.2,
    };

Pretends this is a normal bullet/gun and re-uses the existing bullet aiming logic.

  • Filter contacts that have nonsensical velocities or nonsensical positions.
  • Fix aiming solution to be much more reliable and accurate. Previous algorithm often didn't converge before hitting the iteration limit.
  • Missiles were implemented to lazily seek only contacts that they knew about. Because of rlane's jamming, this resulted in missiles seeking the target for a short while, getting closer to rlane's missiles than the fighter, and then losing the contact after the timeout because they couldn't receive a new contact update from the fighter before they got close enough to reacquire themselves.
  • Fixed bug that sometimes prevented properly scanning contacts.
  • Added random chance (50%) to send contacts on the radio to help deal with the contention of missiles and fighters both broadcasting contacts.
  • Emojis and unicode in debug output.
  • Bullets only fire if within a given angle.
  • Missiles remember contacts for 10 ticks instead of default 60.

derivator

For this tournament I wanted to track the effect my changes had on my win rate, so I modified the tournament binary to not play the full tournament but only evaluate my AI against the rest:

image

Unfortunately I couldn't test against hopeful-quail before the tournament, because an API update broke his code and it wouldn't compile anymore. It was fun to see how improving the weak points I identified in my previous writeup improved my win rate substantially, but this led to a big temptation to keep chasing easy wins with small incremental improvements, when I had really wanted to make more substantial changes.

Some possibly interesting observations:

  • The missile update that made the shaped charge ability the default behavior really hurt me for some reason, putting me at half my previous winrate against rlane from the get go. Adapting to the update is what gave me my biggest gains against him.
  • Since missiles don't explode anymore when out of fuel, I tried removing the check that prevents them from doing so, but curiously that actually reduced my winrate against stichinski.
  • I did ok against the others, but rlane wiped the floor with everyone. Overall my AI still has many huge flaws, e.g.:
  • Due to a flaw in my radar logic, I do substantially worse when playing on the right side of the map.
  • I don't think rlane's jamming affected me that much, because I had countermeasures in place, but mostly because I always died too fast for it to matter.