TrackIR and Battlescape: The Unofficial Guide

DIDDLER9000’s Guide to TrackIR in Infinity: Battlescape

(This is the same guide as the pastebin from Reddit, with some updates)

Disclaimer: This guide assumes you are already familiar with setting up and using head-tracking solutions in games that officially support them (IE: DCS, Falcon BMS, racing sims, etc). If you are brand-new to head-tracking you may wish to research that subject first.
Other disclaimer: I threw this together quickly mostly from memory. The two programs used here I’ve also had installed for a long time and the links are just from quick google searches. If there are any inaccuracies or if something doesn’t make sense, don’t be afraid to let me know either here, in Discord, or elsewhere.

Unfortunately, the game does not support TrackIR or similar solutions out of the box. The good news is that the game has axis input events for modifying your camera angle. With a bit of trickery, we can use our headtracking as a virtual joystick to control this. If at any point during this tutorial (esp. during vJoy) you are asked to restart your machine, do so before moving on.


  1. Verify head-tracking works as-is
    Open up TrackIR or your head-tracking application of choice and verify that your current setup allows you to look up, down, left and right with no blind-spots. If you’re an avid user of TrackIR you can probably skip this.

  2. Install vJoy
    vJoy is a virtual joystick driver that installs a “fake” USB joystick. We will use this to map our head movements to the game. vJoy has documentation available if you need to troubleshoot this step. Once installed, you should use the Configure vJoy application to ensure that at least the X and Y axes are enabled and that Enable vJoy is checked (near the bottom). It does not need buttons or other axes but will not cause problems if they are left on.

  3. Install FreePIE
    FreePIE is a program that allows its users to write scripts to emulate input. Don’t worry, you’re not writing any code here! That will be supplied for you. You do, however, need the program installed to run the script.

  4. Verify your head-tracking solution is currently running
    TrackIR must be open and running for this to work. If you are using Opentrack or another solution, ensure that it is emulating TrackIR and not its own interface (FaceTrackNoIR has a specific setting for this).

  5. Open FreePIE and enter the script
    Here is the script in plain text (Credits to windows_x_seven from the YSFHQ forums). Some of the constants have been modified from the original script. A link to the original can be found on the pastebin in the Reddit post.

def update():
yaw = filters.mapRange(trackIR.yaw, -180, 180, -vJoy[0].axisMax, vJoy[0].axisMax)
pitch = filters.mapRange(trackIR.pitch, -90, 90, -vJoy[0].axisMax, vJoy[0].axisMax)
vJoy[0].x = yaw
vJoy[0].y = pitch

if starting:
trackIR.update += update

Open FreePIE, go to File -> New, and you should be able to then paste the above block of code into the editor. Save this script so that you can open it later. You can now run the script either by pressing F5 or going to Script -> Run at the top.

  1. Verify the script is working properly
    Open the Windows Game Controllers dialog (fastest way: press Win+R, type joy.cpl, press enter). You should see an entry labeled vJoy Device if step 2 completed successfully. If you do not, you need to make sure vJoy is correctly installed. If you do, select it, press Properties, and you should see the X/Y axes move with your head. If you see vJoy Device listed but do not see its axes moving with your head, the FreePIE script is either not running or your headtracking is not working properly.

  2. Map the controls in-game
    Here’s the fun part. Open Infinity, go to Options -> Keybinds. Bind the vJoy Device to one of the four open assigned input devices (near the top). Press the gear button and ensure the deadzones are 0. Scroll to near the bottom, in the View section, and try to bind SetViewPitch by clicking on it and moving your head up and down. You can do the same for SetViewYaw by moving your head left and right. Invert axes as required (I had to invert pitch, myself).

  3. Feel like a cyborg with your cruiser guns slaved to your head
    That should be everything you need to do! There was a lot of setup involved but now that you’ve installed the required software, the only thing you’ll need to do from here is make sure the FreePIE script and your head-tracking is running before you start the game.


Hi, I succesfully made Trackir work in I:B, but deadzones cannot be disabled.
(I:B > Options > Keybinds > vjoy device > gear symbol).
There are no deadzones in Trackir, FreePie and joy.cpl.
Sometimes those annoying deadzones disappear after I restart I:B.
Best regards,

1 Like

Hey Olidz.

Putting the deadzone slider all the way to the left does not disable the deadzone? Sounds like a bug. It should go to zero.

I’m at work for the next 9 or so hours, but when I get home I’ll put up a screenshot or two on how to configure the deadzones in IB in case you cant find it. joy.cpl will not have any deadzone settings.

EDIT: I’ve circled the buttons you’ll be looking for. Note that Device #3 is the vJoy Device. The only other deadzone configuration will be located in your head-tracking software, which you should configure to taste.


Thank you DIDDLER9000, that’s what I did and still deadzones exist.
Sometimes, when I restart I:B, deadzones disappear and when I go into the Options and apply, deadzones reappear. In joy.cpl, deadzones never show up, so I guess there’s a bug in I:B.
Were you able to reproduce this bug ?



Thank you so much for this guide. I’m just getting into IB, and trackIR was the little thing I was missing. While we wait for a proper trackir support, your explanation is just perfect.

For some reason I got some error with your script, so I checked for the original, and here is the one working for me :
def update():
yaw = filters.mapRange(trackIR.yaw, -180, 180, -vJoy[0].axisMax, vJoy[0].axisMax)
pitch = filters.mapRange(trackIR.pitch, -90, 90, -vJoy[0].axisMax, vJoy[0].axisMax)
vJoy[0].x = yaw
vJoy[0].y = pitch

if starting:
trackIR.update += update

Again a big thank you :sunglasses: :+1: