Best VRally 4 Settings for Thrustmaster TMX / T150

VRally 4 is an arcade rally racing game. It supports using a wheel, but the default settings for the Thrustmaster TMX and T150 are so awkward that I almost gave up entirely. Using the wheel just seemed to make the game much harder to control. Obviously something was wrong.

The game is a lot of fun and I knew there must be a way to improve the wheel settings. Thankfully, with a little trial and error, I found out that the game had some misleading control settings with bad default settings that truly were making the game much harder to control. Fixing these makes the game feel much more natural and greatly improves the gameplay. The physics aren't altered, of course, so the cars still take some getting used to if you are coming from the DiRT Rally games, but now that the wheel isn't actively making the game worse, I can enjoy the game on its own terms.

For the TMX specifically, the bindings for controlling the menus are incorrect. This leads to an annoying mismatch between the on-screen button prompts and the actual button you need to press. This can be corrected with a little text file editing.

In this guide I will show the settings I use to fix the steering and improve the force feedback.

TMX Bindings

If you aren't using the TMX wheel, you can safely skip this section entirely. But if you are, you will have noticed that the A and B buttons aren't bound correctly for navigating the menus. In fact, A acts as the "cancel menu" button, making it particularly awkward, with one of the LB buttons acting as the "select menu" button instead.

If you want to fix this, you need to modify this file in your Steam Library:

steamapps\common\VR4\Common\Settings\InputBindings.lua

This file contains all the button bindings for every supported wheel. Looking through it, I found that the TMX incorrectly shares the same bindings as the T150 and several other wheels that share those same buttons. The TMX has a unique button layout, however, and so needs its own unique button bindings.

Open InputBindings.lua and find the line --Thrustmaster TX.

Now paste the following text directly before that line:

--Thrustmaster TMX
{
    Device 	= EnumDeviceFamily.I_ICF_STEERING_WHEEL,
    Index	= 4,
    GUID	= { 3061777487 },

    --Menus
    {
        Actions = { "I_POP_MENU_JUST_PRESSED", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON8,
    },

    {
        Actions = { "I_SKIP_MOVIE", "I_MENU_VALIDATE", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON5,
    },

    {
        Actions = { "I_MENU_CANCEL", "I_MENU_EXIT", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON9,
    },

    {
        Actions = { "I_MENU_SECONDARY", "I_X_JUST" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON3,
    },

    {
        Actions = { "I_STICK_LEFT_JUST", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON11,
    },

    {
        Actions = { "I_STICK_RIGHT_JUST", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON12,
    },

    {
        Actions = { "I_LT_PRESSED", },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON4,
    },

    {
        Actions = { "I_RT_PRESSED", },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON6,
    },

    --Pov
    {
        Actions = { "I_MENU_UP", "I_MENU_ARROW_UP" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_UP,
    },

    {
        Actions = { "I_MENU_DOWN", "I_MENU_ARROW_DOWN" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_DOWN,
    },

    {
        Actions = { "I_MENU_LEFT", "I_MENU_ARROW_LEFT" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_LEFT,
    },

    {
        Actions = { "I_MENU_RIGHT", "I_MENU_ARROW_RIGHT" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_RIGHT,
    },

    {
        Actions = { "I_MENU_UP_PRESSED" },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_UP,
    },

    {
        Actions = { "I_MENU_DOWN_PRESSED" },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_DOWN,
    },

    {
        Actions = { "I_MENU_LEFT_PRESSED" },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_LEFT,
    },

    {
        Actions = { "I_MENU_RIGHT_PRESSED" },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_RIGHT,
    },

    --Stick
    {
        Actions = { "I_MENU_UP", },
        Trigger = TriggerType.TriggerAxisPressNeg,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRY,
        Combine	= false,
        Invert	= false,
        Context = InputActionContext.eContextMenuExtra,
    },

    {
        Actions = { "I_MENU_DOWN", },
        Trigger = TriggerType.TriggerAxisPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRY,
        Combine	= false,
        Invert	= false,
        Context = InputActionContext.eContextMenuExtra,
    },

    {
        Actions = { "I_MENU_LEFT", },
        Trigger = TriggerType.TriggerAxisPressNeg,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRX,
        Combine	= false,
        Invert	= false,
        Context = InputActionContext.eContextMenuExtra,
    },

    {
        Actions = { "I_MENU_RIGHT", },
        Trigger = TriggerType.TriggerAxisPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRX,
        Combine	= false,
        Invert	= false,
        Context = InputActionContext.eContextMenuExtra,
    },

    {
        Actions = { "I_MENU_UP_PRESSED" },
        Trigger = TriggerType.TriggerAxisNeg,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRY,
        Combine	= false,
        Invert	= false,
        Context = InputActionContext.eContextMenuExtra,
    },

    {
        Actions = { "I_MENU_DOWN_PRESSED" },
        Trigger = TriggerType.TriggerAxisPos,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRY,
        Combine	= false,
        Invert	= false,
        Context = InputActionContext.eContextMenuExtra,
    },

    {
        Actions = { "I_MENU_LEFT_PRESSED" },
        Trigger = TriggerType.TriggerAxisNeg,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRX,
        Combine	= false,
        Invert	= false,
        Context = InputActionContext.eContextMenuExtra,
    },

    {
        Actions = { "I_MENU_RIGHT_PRESSED" },
        Trigger = TriggerType.TriggerAxisPos,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRX,
        Combine	= false,
        Invert	= false,
        Context = InputActionContext.eContextMenuExtra,
    },

    {
        Actions = { "I_Y_JUST", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON10,
    },

    {
        --RotateCamera X-Axis
        Actions = { "I_IAD_MOVE_CAMERA_X" },
        Trigger = TriggerType.TriggerStickMove,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LZ,
        Combine	= false,
        Invert	= false,
    },

    {
        --RotateCamera Y-Axis
        Actions = { "I_IAD_MOVE_CAMERA_Y" },
        Trigger = TriggerType.TriggerStickMove,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_RGLSLIDER1,
        Combine	= false,
        Invert	= false,
    },

    {
        --Move Left/Right
        Actions = { "I_IAD_MOVE_PLAYER_X" },
        Trigger = TriggerType.TriggerStickMove,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRX,
        Combine	= false,
        Invert	= false,
    },

    {
        --Move Up/Down
        Actions = { "I_IAD_MOVE_PLAYER_Y" },
        Trigger = TriggerType.TriggerStickMove,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRY,
        Combine	= false,
        Invert	= false,
    },

    --Painting
    {
        Actions = { "I_RB_PRESSED" },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON2,
    },

    {
        Actions = { "I_LB_PRESSED" },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON1,
    },

    --Ranking screen
    {
        Actions = { "I_MENU_PREVIOUS", "I_LB_JUST", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON1,
    },

    {
        Actions = { "I_MENU_NEXT", "I_RB_JUST", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON2,
    },

    {
        Actions = { "I_MENU_PREVIOUS_PAGE", "I_LT_JUST", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON11,
    },

    {
        Actions = { "I_MENU_NEXT_PAGE", "I_RT_JUST", },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON12,
    },

    --Gameplay
    {
        --Accelerate
        Actions = { "ACTION_RACE_ACCELERATE" },
        Trigger = TriggerType.TriggerStick,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LRZ,
        Combine	= true,
        Invert	= false,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --Brake
        Actions = { "ACTION_RACE_BRAKE" },
        Trigger = TriggerType.TriggerStick,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LY,
        Combine	= true,
        Invert	= false,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --Clutch
        Actions = { "ACTION_RACE_CLUTCH" },
        Trigger = TriggerType.TriggerStick,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_RGLSLIDER0,
        Combine	= true,
        Invert	= false,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --Steering
        Actions = { "ACTION_RACE_LEAN" },
        Trigger = TriggerType.TriggerStick,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_AXIS_LX,
        Combine	= false,
        Invert	= false,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --Handbrake
        Actions = { "ACTION_RACE_HAND_BRAKE" },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON5,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --GearUp
        Actions = { "ACTION_RACE_GEAR_SHIFT_UP" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON2,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --GearDown
        Actions = { "ACTION_RACE_GEAR_SHIFT_DOWN" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON1,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --Respawn
        Actions = { "ACTION_RACE_RESPAWN" },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON4,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --NextView
        Actions = { "ACTION_RACE_NEXT_VIEW" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_LEFT,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --PrevView
        Actions = { "ACTION_RACE_PREV_VIEW" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_RIGHT,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --DisplayGhost
        Actions = { "ACTION_RACE_TOGGLE_GHOST_VIEW" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_POV_UP,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --Whipers
        Actions = { "ACTION_RACE_TOGGLE_WIPERS" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON9,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --Headlights
        Actions = { "ACTION_RACE_TOGGLE_HEADLIGHTS" },
        Trigger = TriggerType.TriggerButtonPress,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON10,
        Context = InputActionContext.eContextGameplay,
    },

    {
        --RearView
        Actions = { "ACTION_RACE_REAR_VIEW" },
        Trigger = TriggerType.TriggerButtonDown,
        Control = GenericDeviceControlId.I_ICI_GENERICDEVICE_BUTTON12,
        Context = InputActionContext.eContextGameplay,
    },
},

That text contains the new bindings for the TMX. The last thing we need to do is remove the old TMX bindings from its shared list.

Find the line:

--Thrustmaster T500RS, T300RS, T100, T150, TS-PC RACER, T-GT, TS-XW, TMX

Below that line, we need to remove the TMX identifier (3061777487) from the GUID line. It is the last one in the list.

It will look like this when you are finished:

--Thrustmaster T500RS, T300RS, T100, T150, TS-PC RACER, T-GT, TS-XW, TMX
{
  Device = EnumDeviceFamily.I_ICF_STEERING_WHEEL,
  Index = 4,
  GUID = { 3059614799, 3060663375, 3059352655, 3061253199, 3062432847, 3062105167, 3063022671 },

If you already have been playing the game, you will need to go into the control settings and reload the TMX preset for these to take effect.

Thrustmaster Control Panel Settings

VRally 4 will change the rotation angle directly in-game, so the Thrustmaster Control Panel can be left at the maximum. Be aware that the game actually changes this value and doesn't always reset it back to the original if you force the game to close or it crashes.

Setting Value
Rotation 900° (TMX) 1080° (T150)
Overall Strength of all forces 100%
Constant 100%
Periodic 100%
Spring 100%
Damper 100%
BOOST Off
Auto-Center by the game

Spring is not used by VRally 4, so the value actually doesn't matter. Some games require Spring to be on for their force feedback to work, so I keep it at 100% as a general rule.

Damper is used to control the Overall Damping setting.

BOOST should always be turned off. For an in-depth look as to why, see my BOOST Force Feedback Analysis.

VRally 4 Settings

In Options > Controls > Key Bindings > Steering:

When I first tried the game, despite the interface showing the Sensitivity at 0, the steering was not linear, easily seen by the control gauge that changes when you turn the wheel. All I had to do was change the Sensitivity to 10 and back again to 0 to correct the error and allow proper linear steering.

Setting Value
Sensitivity 0
Deadzone 0%
Maximum Angle 535

Maximum Angle will change the value at the driver level to provide a proper Soft Lock. This can be annoying if it doesn't reset the driver back to its original value if you force the game to close or it crashes. Just be aware to check the Thrustmaster Control Panel if that happens to set the value back to normal.


In Options > Controls > Vibration & Feedback:

Setting Value
Overall Effects On
Overall Force 75
Overall Damping 0
Self Aligning Torque 48
Road Feedback 5
Overall Vibration 70
Suspension 85
Tyre Slip 0
Collision 80
Ground Surface 70
Engine 45
Steering Centre Force 100

Overall Force controls the overall amount of all other forces.

Overall Damping adds weight to the wheel.

Self Aligning Torque is the main calculated force in the wheel. This is what you should adjust if you want the forces to be stronger or lighter.

Road Feedback changes the amount of force based on the type of road you are driving on. I don't find this particularly useful.

Overall Vibration controls the amount of all the vibrations.

Suspension rumbles the wheel when you go over large bumps.

Tyre Slip vibrates the wheel when you lose traction. I turn this off since you are sliding all the time in this game, making the wheel vibrate endlessly, which I find extremely annoying.

Collision rumbles the wheel when you hit rocks or other objects on the side the track.

Ground Surface rumbles the wheel when you go over a bridge, certain special terrain sections, or leave the main track. I like this effect, but you could turn it down if you like.

Engine vibrates the wheel when you hit the red line, which is fairly rare, so I leave this effect on, but have it turned quite low. You could safely turn this off if you don't like the vibration effect at all.

Steering Centre Force centers the wheel when you reset the car to the track, so it's fine on the default 100. It has no effect when you are driving.

Conclusion

This game was a real surprise to me. I truly thought it just was not going to be possible to play with a wheel, but once I got these settings right, the game just came to life. Now the wheel actually improves the gameplay and makes it easier to get a feel for the physics of this game, rather than being a hindrance.

Let me know if you have any comments or questions.

Question or Comment?