Skip to Content

Under the hood

  1. Using parser app binary MoTec files are converted into json files.

  2. These files are used in scorer app to create produce accshiftassist.json file that contains the best RPM value for each:

  • track
  • car
  • turn angle
  • gear
  1. This file is used by assist app to inform driver about when it’s time to upshift.

All these steps can be explained in a chart: chart

Parser app

Parser is able to convert binary MoTec files into json files. Not all channels are included as most of them are not needed for the task ahead.

Parser is influenced by gotzl/ldparser project.

Scorer app

Scorer is most complicated part of the whole process and contains a lot of logic. There are default parameters, so it will work by just executing without any parameters. But if you want you can change quite a lot of things to produce results that you are happy with.


Usage of accshiftassist.exe:
  -1 float
        scoring multiplier - acceleration (default 1)
  -2 float
        scoring multiplier - acceleration diff (default 1)
  -3 float
        scoring multiplier - speed diff (default 1)
  -4 float
        scoring multiplier - end speed (default 0.8)
  -5 float
        scoring multiplier - G diff (default 0.95)
  -a int
        steering wheel 'from' angle > 0 (default -1)
  -b int
        steering wheel 'till' angle > 0 (default -1)
  -c int
        concurrency (10 - 100 is ok) Bigger number consumes more memory but its faster. (default 10)
  -d string
        MoTec files directory. Used if -p is set.
  -f string
        filter files with any text fond in filename. useful if folder have a lot of files.
  -h    help. this page.
  -i int
        automatically generated turn count. works if -a and -b is not set. (default 6)
  -j int
        automatically generated turn minimal angle. works if -a and -b is not set. (default 3)
  -l int
        ACC steering angle. Used together with -r. (MoTec file contains value in % and in game uses degrees. If you dont use default value then set it here) (default 900)
  -m    time multiplier for -x and -y. example: for gear 2 and -a 100 will result in 100 * 1.2 = 120 ms
  -o string
        output result json folder location. if not set no result file will be created.
  -p string
        parse MoTec files to given target directory defined in last parameter. Value for this param can be (today, new or any string to filter MoTec files defined in -d directory)
  -r    Run acc shift shiftSoundExe for the game.
  -s    Calculate scoring.
  -t int
        top results to take into account when calculating RPM to show as final result (default 4)
  -u    use unique rpm results to calculate total avg from -t value
  -v    verbose mode. shows debug messages.
  -x int
        time in ms before shift point. its used in scoring strategy (1s=1000ms) (default 500)
  -y int
        time in ms after shift point. its used in scoring strategy (1s=1000ms) (default 2450)

Under the hood

Code starts with normalizing parsers output files for all given channels. Then it finds all upshifts and groups them by car, track and turn angle. Afterwards multiple scoring algorithms are applied to each upshift. These are scoring things like G force difference, gained speed, exit speed, and more. In the end scores are aggregated and compared between each other to find the best RPM value.

Calculation speed

Initially I was writing this part in python. And I managed to create a prototype that was able to produce decent results. But managing this code quickly became problematic. Also processing speed was not sufficient thus hindering fine-tuning process.

I re-wrote all code in compiled language. Covered all the logic with vigorous unit tests and boosted processing speed by heavy utilizing multi-threading. This allowed to process tons of files in few seconds and freed up time to develop and test different scoring algorithms. All that made output much more reliable.

Simplified machine learning was implemented that helped to groom and fine-tune configuration needed to achieve best results.

What I learned

I quickly realized that upshift RPM is not allways the same as stated in random ACC posts on internet. For each car it is changing quite a lot based on the track, steering wheel angle and weather conditions.


Scorer is not able to calculate best RPM. It is using existing data to find best RPM. This means that the more *.id files you will have, the best results you will get.

Assist app

Assist app is actually quite small command line app. It is listening to ACC shared memory to read real life car data. Then this data is compared against scorer rpm.json results and informs user using incremental sound when it’s time to upshift.

Shift sound

On full throttle up-shift beeping sound is played that increases the tone when approaching perfect upshift RPM. When RPM is reached higher pitch sound is played.

After few laps driver will learn ideal timings and will be able to change gears in perfect time.

Assist is influenced by rrennoir/Jackal project.