DSJ2 playing AI
Posted: 22 Aug 2021, 23:57
For the last two years I've been developing a DSJ2 playing AI.
Here are some of the results:
AUS 305.03m https://www.youtube.com/watch?v=T2-VnDzhN8Q
HUN 238.51 https://www.youtube.com/watch?v=ET50-LNzcL0
SVK 135.53 https://www.youtube.com/watch?v=omNfTHvwrno
Jumps from all hills are available on my channel.
Here's a playlist: https://www.youtube.com/watch?v=T2-VnDz ... KKjW20uxTz
Replays: https://drive.google.com/drive/folders/ ... Oaalwhzn9K
For those who are interested in technical details below is a brief description.
Before getting any results I had tried many different approaches.
The one closest to success was image processing using python + different libraries implementing neural networks.
It's biggest disadvantage is the fact that it is quite slow - as slow as a human player jumping.
Then I started playing with reverse engineering in order to get the game's state without using image processing.
As time went by I was able to retrieve more and more info from each frame e.g. jumper's position, wind speed or slope angle.
I also extended Dosbox's debugger to:
- control the game using breakpoints and embedded python scripting
- profile the game to find the most CPU consuming operations (that's frame drawing)
- enhance logging
- and much more.
Thanks to the profiler I was able to disable frame drawing enteriely but still be able to control the jumper.
As a result each jump now takes only 0.2-0.3s instead 10 to 20 seconds.
At some point, when I lost interest in the project for a while, one of the world records was beaten by more than 3 meters.
That was the moment when I realized that there's still room for improvements on many hills and my focus shifted from machine learning/neural networks to more or less "how far one could jump on each hill, all's fair".
Many players know that in order to jump further you need the so called "hurricane" - low wind on the inrun becoming huge wind during the flight phase.
To find such winds I recreated the entire wind algorithm and wrote a program looking for the best wind conditions using basically brute force.
The amount of possible solutions is so huge that it's not possible to check all of them, but I went through billions in a few hours for each hill which was enough to find conditions never seen before:)
In short there are different parts of the solution:
- reading gibbons from the best replays and then modifying them,
- finding the best wind conditions,
- finding the suboptimal angle of attack in flight on each hill,
- finding the best frame to start landing,
- reading/saving replays on demand outside of dsj
and a few more.
The progress of results is mainly produced thanks to genetic algorithms where each jumper is a genome, and each genome is a list of mouse actions taken in each frame.
All this was coded mainly in C++ (Dosbox Staging) and embedded Python 3 for genetic algorithms.
In far future instead of the genetic algorithms I will try to use reinforcement learning or NEAT neural networks too.
Here are some of the results:
AUS 305.03m https://www.youtube.com/watch?v=T2-VnDzhN8Q
HUN 238.51 https://www.youtube.com/watch?v=ET50-LNzcL0
SVK 135.53 https://www.youtube.com/watch?v=omNfTHvwrno
Jumps from all hills are available on my channel.
Here's a playlist: https://www.youtube.com/watch?v=T2-VnDz ... KKjW20uxTz
Replays: https://drive.google.com/drive/folders/ ... Oaalwhzn9K
For those who are interested in technical details below is a brief description.
Before getting any results I had tried many different approaches.
The one closest to success was image processing using python + different libraries implementing neural networks.
It's biggest disadvantage is the fact that it is quite slow - as slow as a human player jumping.
Then I started playing with reverse engineering in order to get the game's state without using image processing.
As time went by I was able to retrieve more and more info from each frame e.g. jumper's position, wind speed or slope angle.
I also extended Dosbox's debugger to:
- control the game using breakpoints and embedded python scripting
- profile the game to find the most CPU consuming operations (that's frame drawing)
- enhance logging
- and much more.
Thanks to the profiler I was able to disable frame drawing enteriely but still be able to control the jumper.
As a result each jump now takes only 0.2-0.3s instead 10 to 20 seconds.
At some point, when I lost interest in the project for a while, one of the world records was beaten by more than 3 meters.
That was the moment when I realized that there's still room for improvements on many hills and my focus shifted from machine learning/neural networks to more or less "how far one could jump on each hill, all's fair".
Many players know that in order to jump further you need the so called "hurricane" - low wind on the inrun becoming huge wind during the flight phase.
To find such winds I recreated the entire wind algorithm and wrote a program looking for the best wind conditions using basically brute force.
The amount of possible solutions is so huge that it's not possible to check all of them, but I went through billions in a few hours for each hill which was enough to find conditions never seen before:)
In short there are different parts of the solution:
- reading gibbons from the best replays and then modifying them,
- finding the best wind conditions,
- finding the suboptimal angle of attack in flight on each hill,
- finding the best frame to start landing,
- reading/saving replays on demand outside of dsj
and a few more.
The progress of results is mainly produced thanks to genetic algorithms where each jumper is a genome, and each genome is a list of mouse actions taken in each frame.
All this was coded mainly in C++ (Dosbox Staging) and embedded Python 3 for genetic algorithms.
In far future instead of the genetic algorithms I will try to use reinforcement learning or NEAT neural networks too.