I am making a racing game inside of Blender Game Engine. You can see the latest video here to get the impression of what type of game it is: https://www.youtube.com/watch?v=0i3m-xXtnhc

What I want to do is to replace current constant engine setup which has a constant Nm value(I guess that applyEngineForce() takes torque as input, but I am sure it uses Nm as unit) whith a new setup that calculates RPM, use RPM/torque curves(I've made 2 arrays for them already), aswell as use gearbox with multiple gear ratios(a custom number). This game is planned to be pretty realistic, but at the same time I must make sure that it is not too expensive(although CPU stuff is not the problem for me usually, it is more GPU and graphics).

So any type of help will be appreciated, thank you!:)

So what I have:

I have steering already. I have inputs for brakes, gas, shifting gears, e-brake and reverse.

What I need:

I need to use the inputs correctly to make engine act naturally. I need to have a gear and RPM dependent torque output as final result aswell as RPM to show in the HUDs. Finally I will put the torque into applyEngineForce() and if I am right, than the final value at 1st gear ratio should be around 3500 - 6000 Nm, but it is the case if applyEngineForce() uses torque.

I couldn't find more information about Blender Game Engine vehicle wrapper!:(

P.S. BGE uses python as it's built-in programing language so I use python for this.

My script at current state which needs improvements:

import bge
from bge import logic
import PhysicsConstraints
from gamesystem import gaudges

### Define ###
scene = logic.getCurrentScene()
car = scene.objects["Car"]
keyboard = logic.keyboard

#keyboard keys
gas = keyboard.events[bge.events.WKEY]
left = keyboard.events[bge.events.AKEY]
reverse = keyboard.events[bge.events.SKEY]
right = keyboard.events[bge.events.DKEY]
ebrake = keyboard.events[bge.events.SPACEKEY]

gasPower = car["gasPower"] * 10
brakePower = car["brakePower"]
ebrakePower = car["ebrakePower"]
reversePower = car["gasPower"] / 3 * 20
maxSteer = car["maxSteer"]
steerSpeed = car["steerSpeed"]
maxSpeed = car["maxSpeed"]

# Define tire objects
tireFL = scene.objects["TireFL"]
tireFR = scene.objects["TireFR"]
tireRL = scene.objects["TireRL"]
tireRR = scene.objects["TireRR"]

### Initialise ###

if not "ini" in car:
    pid = car.getPhysicsId()
    suspension = PhysicsConstraints.createConstraint(pid, 0, 11)
    cid = suspension.getConstraintId()
    suspension = PhysicsConstraints.getVehicleConstraint(cid)

    wheelRadius = 0.345
    suspensionRestLength = 0.5
    hasSteering = 1

    ### Tweakables ###
    damping = car["damping"]
    stiffness = car["stiffness"]
    compression = car["compression"]
    roll = car["roll"]
    grip = car["grip"]
    drift = car["drift"]

    ### Actions ###

    # Generate tires
    wheelAttachDirLocal = [0, 0, -1]
    wheelAttachPosLocal = [-0.745, 1.27, 0.59]
    wheelAxleLocal = [-1, 0, 0]
    suspension.addWheel(tireFL, wheelAttachPosLocal, wheelAttachDirLocal, wheelAxleLocal, suspensionRestLength, wheelRadius, hasSteering)
    wheelAttachDirLocal = [0, 0, -1]
    wheelAttachPosLocal = [0.745, 1.27, 0.59]
    wheelAxleLocal = [-1, 0, 0]
    suspension.addWheel(tireFR, wheelAttachPosLocal, wheelAttachDirLocal, wheelAxleLocal, suspensionRestLength, wheelRadius, hasSteering)
    wheelAttachDirLocal = [0, 0, -1]
    wheelAttachPosLocal = [-0.75, -1.18, 0.59]
    wheelAxleLocal = [-1, 0, 0]
    hasSteering = 0
    suspension.addWheel(tireRL, wheelAttachPosLocal, wheelAttachDirLocal, wheelAxleLocal, suspensionRestLength, wheelRadius, hasSteering)
    wheelAttachDirLocal = [0, 0, -1]
    wheelAttachPosLocal = [0.75, -1.18, 0.59]
    wheelAxleLocal = [-1, 0, 0]
    suspension.addWheel(tireRR, wheelAttachPosLocal, wheelAttachDirLocal, wheelAxleLocal, suspensionRestLength, wheelRadius, hasSteering)

    # Update suspension
    for tire in range(4):
        suspension.setSuspensionDamping(damping, tire)

        suspension.setSuspensionStiffness(stiffness, tire)

        suspension.setSuspensionCompression(compression, tire)

        suspension.setRollInfluence(roll, tire)

    suspension.setTyreFriction(grip, 0)
    suspension.setTyreFriction(grip, 1)
    suspension.setTyreFriction(grip / (drift * ((maxSpeed - gaudges.speed) / maxSpeed)), 2)
    suspension.setTyreFriction(grip / (drift * ((maxSpeed - gaudges.speed) / maxSpeed)), 3)

    car["ini"] = True
    car["CID"] = cid

### Car in action ###

suspension = PhysicsConstraints.getVehicleConstraint(car["CID"])

# Drift
suspension.setTyreFriction(car["grip"] / (car["drift"] * ((maxSpeed - gaudges.speed) / maxSpeed)), 2)
suspension.setTyreFriction(car["grip"] / (car["drift"] * ((maxSpeed - gaudges.speed) / maxSpeed)), 3)

# Gas
if gas == ACTIVE:
    car["gas"] = gasPower
    car["gas"] = 0

# Emergency brake
if ebrake == ACTIVE:
    car["ebrake"] = ebrakePower
    car["ebrake"] = 0

# Reverse
if reverse == ACTIVE:
    if car["speed"] > 0:
        car["brake"] = brakePower
        car["gas"] = -reversePower
        car["brake"] = 0
        car["gas"] = -reversePower
    car["brake"] = 0

# Steering
if right == ACTIVE:
    if car["steer"] > -maxSteer:
        car["steer"] -= steerSpeed
elif left == ACTIVE:
    if car["steer"] < maxSteer:
        car["steer"] += steerSpeed
    car["steer"] = 0.0

drive = car["drive"]
## drives
    # 1: rear
    # 2: front
    # 3: full
frontDrive = 0
rearDrive = 0

if drive == 1 or drive == 3:
    rearDrive = 1
    rearDrive = 0.5

if drive == 2 or drive == 3:
    frontDrive = 1
    frontDrive = 0.5

for tire in range(4):
    # Front tires
    if tire < 2:
        suspension.applyEngineForce(-car["gas"] * frontDrive, tire)
        suspension.applyBraking(car["brake"], tire)
    # Rear tires
        suspension.applyEngineForce(-car["gas"] * rearDrive, tire)
        suspension.applyBraking(car["ebrake"], tire)

suspension.setSteeringValue(car["steer"], 0)
suspension.setSteeringValue(car["steer"], 1)

gaudges.speed = car.getLinearVelocity(1).y * 3.6
car["speed"] = int(gaudges.speed)

if car["speed"] > maxSpeed:
    car.localLinearVelocity.y = maxSpeed / 3.6

if car["speed"] < -(maxSpeed / 2):
    car.localLinearVelocity.y = -((maxSpeed / 2) / 3.6)

To make sure that you see my knowledge level, here is what I know already aswell as what I need:


  • 1
    \$\begingroup\$ You're getting yourself in a hell of a ride :) To have it as realistic as it could get, I would suggest you model all of the parts of the drive-train, and find the specifications of a real car (which include engine output and speed for each gear). Use a state machine for the proper behaviour of each gear. Calculating everything as close to reality as possible will allow you to tweak and tune more easily. \$\endgroup\$
    – Vaillancourt
    Commented Sep 8, 2015 at 17:06
  • \$\begingroup\$ I mean using approximations as I won't have any existing cars in game. \$\endgroup\$ Commented Sep 8, 2015 at 17:20
  • \$\begingroup\$ Gear system: I have a curve for the car and I have to scale it somehow through each gears(1st gear have very high torque and small RPM line), I can do it easily by using each gear ratio value(an array). That way I have 3 lists: RPM list and torque list for curve(RPM is x axis and torque is y axis) and I use numpy.interp() to get the torque based on the RPM. \$\endgroup\$ Commented Sep 8, 2015 at 17:23
  • \$\begingroup\$ For the gears I can make a gear ratio array containing something like this: [3.3, 2.7, 2.2, 1.75, 0.9] and use it for car. what I need to find out, though, is how to correctly apply the RPM(based on brake/gas/e-brake/reverse inputs) so that it acts correctly and makes it feel right. Also - each gear has speed limit and I don't know if it is done automaticly in script and if it isn't, than I need also something for natural feeling of this. \$\endgroup\$ Commented Sep 8, 2015 at 17:25
  • \$\begingroup\$ For switching gears I can use a timer property during which car has a little of brakes applied so that it feels like it is shifting for real. \$\endgroup\$ Commented Sep 8, 2015 at 17:26

1 Answer 1


First, you'll need to make a model of your engine. It should be a simple function that would resemble the green line.

Torque and RPM relation graph

Quick and dirty inquiry at wolfram alpha gives this estimation:

def max_engine_torque_at_rpm(rpm):
    return -0.0000138889 * rpm ** 2 + 0.0799786 * rpm - 28.2671

Now this is incredibly trivial and not representative at all of what you really want. You should, at least, implement linear interpolation of some dataset, either of a real engine or a made up one.

Then, calculate how fast your wheels are spinning. This will depend on how realistic you want to get. As a most trivial example, just divide movement speed by 2 pi.

Then, divide the wheel's RPM by the current gear's ratio and the result will basically be the engine's RPM (unless you do some damage modeling at the transmission part). Plug that into the function defined earlier, and you get maximum torque from the engine. Scale that by current throttle input.

When you have the torque currently produced by the engine, multiply it by current gear ratio. The result is what should be outputted towards the wheels.

Again, all of this is very simplified. You can add simulation of friction, inertia, damage, and any other influences to any step of this algorithm.

  • \$\begingroup\$ Sounds like close to my target, but I am not the one who knows what exactly words like throttle etc. mean. I also don't get some of the parts. I may give oyu the file later and maybe you can tell me of the part responsible for wheel RPM is actually possible in default Blender vehicle wrapper? However, it is late for me now already... \$\endgroup\$ Commented Sep 8, 2015 at 20:08
  • \$\begingroup\$ @AdriansNetlis throttle is gas pedal \$\endgroup\$ Commented Sep 8, 2015 at 20:29
  • \$\begingroup\$ OK! Thanks! This already looks very useful. But could you, please, e-mail me so that I can easily ask you whenever I get lost with this so that I don't have to comment here whole the time? [email protected] Thank you very much!:) \$\endgroup\$ Commented Sep 8, 2015 at 20:34
  • \$\begingroup\$ @AdriansNetlis if your comments are within the scope of this question just add them here, there is no limit. If you have any other questions, add them separately. \$\endgroup\$ Commented Sep 8, 2015 at 20:40
  • \$\begingroup\$ ef max_engine_torque_at_rpm(rpm): return -0.0000138889 * rpm ** 2 + 0.0799786 * rpm - 28.2671 What does each of theese numbers, eg -0.0000138889 or 28.2671 stand for? \$\endgroup\$ Commented Sep 8, 2015 at 21:07

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .