Game Development Community

dev|Pro Game Development Curriculum

Your guide to WheeledVehicles

by Daniel Buckmaster · 11/29/2008 (6:00 pm) · 12 comments

Like I said, last time I was away from my main Torque codebase, I took the demo with me and determined to see how much I could change the default buggy in starter.racing without code changes. Frankly, I don't like how the standard buggy controls, so I set out to see how I could make it more fun. I actually didn't accomplish my goal of no source changes - I cannot reccomend highly enough James Jacoby's auto-centre resource (included in T3D 3.0). But aside from that, I learned a lot about what goes into making a WheeledVehicle in Torque.

Below I've listed all the major datablock fields for WheeledVehicles, their tires and springs, as well as the onAdd method. I have probably left some out; I have probably made some mistakes and inaccurate diagnoses. So here's my disclaimer: I'm lying. If you believe everything I say, it's your own darn fault. As a corollary to that - if you have knowledge about the actual workings of WheeledVehicles, not just anecdotal evidence, please share. I'd love for this to become a detailed reference point for vehicle programming.

I was originally going to publish my own new 'default' WheeledVehicle datablocks, but I've lost the changes I made, so you'll have to figure out values yourself. I've tried to make the process as easy as possible with some example values.

Thanks, Morrock, for explaining the things I couldn't figure out!
And thanks, Howard, for the info on MaxWheelSpeed :)

Anyway, without further ado:

WheeledVehicleData


maxSteeringAngle: This is pretty simple. Beware though, the value is in radians. That makes a value of 3.1 equal to 180 degrees. The comment says this should match the animation; I think this is just an aesthetic issue. The vehicle still turns at the angle you specify, whether or not the animation covers this.

cameraRoll: Whether or not the camera should roll with the vehicle (the camera always pans and tilts with the vehicle). If it's on, I find it's pretty disturbing. It's easier to see what's going on with a level camera - and that's the point of the 3rd person perspective, after all. However, this also affects first-person viewing, which isn't such a good thing, I think.

cameraMaxDist: The maximum distance the camera is allowed to get from the car. Pretty simple.

cameraOffset: How high above the vehicle the camera is placed.

cameraLag: In the comments, this is labelled as 'velocity lag'. When you set it to higher values (I went up to an adventurous 2.5) the camera seems to point to where the car will be going - at lower values, the camera points in the direction the car is facing. Note that at high values and higher vehicle speeds, the camera lags far behind the vehicle - further than cameraMaxDist should allow.

cameraDecay: Another velocity lag thing. Higher values mean the camera stays much tighter to the vehicle.

mass: Simply how heavy the car is. Larger values make the vehicle fel more ponderous and mature, as well as more stable - smaller values give the vehicle an edgy, agile feel.

massCenter: this vector gives the centre of gravity of the vehicle relative to its normal centre (usually somewhere on the bottom of the vehicle's bounding box). A high centre of gravity will make the vehicle more prone to tipping (and less prone to rolling over back onto its wheels), and moving it forward will tend to make the steering more edgy (at least in the default buggy). This setting, I found, is quite important for the overall control of the vehicle.

massBox: This box is used when calculating the moment of inertia which, from my limited understanding, is used when calculating forces acting on the vehicle. Big mass boxes (I went up to 20 units a side) make the vehicle feel like it's floating on a cloud, barely responding to controls, and floating gently around the map. However, when I set the box to "1 1 1", I hit the terrain and bounced so high that it took over a minute to fall back to earth, which then sent me sailing again. The happy medium seemed, strangely, to be "5 5 5". When I first found that, I thought I had discovered the holy grail of vehicle performance. I was wrong. However, a larger mass box does give a distinctive feel to a vehicle - a more floaty, Halo-style touch as opposed to a hard, realistic simulation approach.

drag: How much air resistance is applied to the vehicle's body.

bodyFriction: The friction when colliding with the vehicle's body. This makes pretty much no difference when driving, but if the car flips, low values will make it slide a long way.

bodyRestitution: I really have no idea what this does.
But Morrock does!
Quote:restitution is the percentage of kinetic energy kept by this object in a collision. So an object with 0 restitution colliding against a static object will just stay. A restitution of 1 will never stop bouncing. When 2 rigidShape's or vehicles collide I'm pretty sure it averages the two restitutions.

minImpactSpeed: The minimum speed the vehicle has to travel to throw the script callback.

softImpactSpeed and hardImpactSpeed: These speeds define when the soft and hard impact sounds are played.

minRollSpeed: This is a hacky way to keep your vehicle from rolling over - simply set the minimum roll speed to something way higher than your vehicle will ever reach! The engine seems to apply force to the vehicle when it looks like it will roll over, so it just looks like you're really lucky, rather than the subject of divine intervention.

integration: This variable doesn't seem to do a lot. However, I think at higher values, the physics is simply processed better and takes more processing power. There is a slightly noticeable difference (unless it was just the placebo effect...) at higher values (I tested 1, 8 and 16).
From Morrock:
Quote:integration, you were pretty much right on. For each tick on the server, and frame on the client, the object has it's physics updated this many times. This makes it much more accurate (see problems with Euler Integration to understand this) but with 2x, 3x, etc... the processing power. I'd say it's worth it for a vehicle in games that need realism and not just physics, for example a serious racing sim. Also, because of this, it has to be an integer (or will be rounded otherwise.)

collisionTol and contactTol: Again, these variables are sort of mysterious in their actual function. Setting them both to 0.01 didn't make much of a difference, except that I got stuck in the terrain a bit (that has never occurred to me except when testing this variable). Setting them both to 1 made the car immobile. The wheels would turn when I steered, but they wouldn't go round.
From Morrock:
Quote:collisionTol is the distance between possibly colliding (uh...something, it's either bounding boxes or faces, by the way it's looped I'm almost certain it's faces) for Torque to consider checking if they are colliding. contactTol is the difference in velocity of the vehicle and the colliding object relative to each other for Torque to process the physics data as a contact response and not collision response. There is a difference in these that contact response is based on spring forces to make to "contacting" objects to smoothly rest against eachother. While collision applies opposite impulses based on the 2 objects forces and restitutions. 0.1 is pretty optimal for both of these in almost all situations.

engineTorque: The power of the engine. Higher values don't seem to affect initial acceleration, but when you do something like come down from air time, you will get off to a quicker start. And the vehicle does generally feel more powerful.

engineBrake: The braking force when you simply take your hands of the controls.

brakeTorque: The braking force when you press the brake.

maxWheelSpeed: I've no idea of the physics behind this, but higher values let you go faster. I'm sure there's a caveat, but I can't find it. Think of this as your speed control.
From Howard:
Quote:MaxWheelSpeed is broken, has been since the beginning and probably always will be. Set a car on flat land, set the speed to 5 and let it run. It will "creep" up in speed forever. Someone should look at this and add a limiter.

WheeledVehicleTireData


staticFriction: Seems to affect the friction when the vehicle is not moving (in effect, parking brakes...).

kineticFriction: The friction when the vehicle is moving. Lower values make you slide more around corners.

lateralForce and longitudinalForce: These forces are applied to the vehicle when turning. Testing between 1000 and 15000 for both values, I couldn't feel an extreme difference, but the higher values certainly make the steering tighter and easier.

lateralRelaxation and longitudinalRelaxation: I have absolutely no idea what these values do. Except Torque crashed when I set them both to 10 and hit the terrain with the front right wheel. Huh.

lateralDamping and longitudinalDamping: This controls how much the car wobbles around on its chassis. Low values like 10 will leave the car bouncing back and forth for quite a while after you stop.

WheeledVehicleSpringData


damping: How 'bouncy' the suspension is. Low values like 100 are very loose, but the default at over 1000 is far too tight for my taste. Low values make you bounce and jiggle around a lot more. I found this setting extremely important to the 'fun factor' of the vehicle's behaviour.

force: How strong the suspension is.

antiSwayForce: This force tries to keep the vehicle more level by adjusting the lateral suspension, so the body will tend to roll less. Personally, I think it spoils the fun...

Other things to try


%obj.setWheelSteering: By default, only the front two wheels steer. If you get all four wheels to steer properly, then the car becomes freakishly agile, but a bit more difficult to control. Note that the second argument in this function is not a Boolean - it seems to be a modifier for steering. So if you set it to 1, the wheel turns fully in the direction you want. If you set it to -1, it turns the opposite way. If you want four-wheeled steering on a car, you need to set the back two wheels to -1, or else you get a weird strafing car. Play around with it a bit.

%obj.setWheelPowered: Again, only the back two wheels are powered by default. Changing this gives better performance on hills and in other odd situations where the back wheels leave the ground. It also gives you much better acceleration, and an all-round more powerful feel. I highly recommend four-wheel drive for the dune buggy.

Note that both of these are object methods, not datablock settings - so they can be changed in real-time during gameplay. It might be interesting to have a vehicle with two modes - two-wheel drive, front steering road mode, or a mean four-wheel drive, four-wheel steering off-road setting.

About the author

Studying mechatronic engineering and computer science at the University of Sydney. Game development is probably my most time-consuming hobby!


#1
11/29/2008 (6:22 pm)
This helped me alot. Thanks Daniel!
#2
11/29/2008 (7:50 pm)
Idiot-proof explanations are always welcomed! Cheers.
#3
11/30/2008 (7:23 am)
very useful, will help not only noobs
#4
12/13/2008 (10:16 am)
Bookmarked! EXCELLENT info. thanks fr th eclear explanations.
#5
12/18/2008 (5:26 pm)
Nice resource, will certainly make it easier to integrate and debug vehicle behaviors. Mind if I clear up some of the fields you couldn't get?

collisionTol is the distance between possibly colliding (uh...something, it's either bounding boxes or faces, by the way it's looped I'm almost certain it's faces) for Torque to consider checking if they are colliding. contactTol is the difference in velocity of the vehicle and the colliding object relative to each other for Torque to process the physics data as a contact response and not collision response. There is a difference in these that contact response is based on spring forces to make to "contacting" objects to smoothly rest against eachother. While collision applies opposite impulses based on the 2 objects forces and restitutions. 0.1 is pretty optimal for both of these in almost all situations.

integration, you were pretty much right on. For each tick on the server, and frame on the client, the object has it's physics updated this many times. This makes it much more accurate (see problems with Euler Integration to understand this) but with 2x, 3x, etc... the processing power. I'd say it's worth it for a vehicle in games that need realism and not just physics, for example a serious racing sim. Also, because of this, it has to be an integer (or will be rounded otherwise.)

restitution is the percentage of kinetic energy kept by this object in a collision. So an object with 0 restitution colliding against a static object will just stay. A restitution of 1 will never stop bouncing. When 2 rigidShape's or vehicles collide I'm pretty sure it averages the two restitutions.
#6
12/19/2008 (1:45 am)
Thank you! Mind if I put your additions into the main body of the resource? With credit, of course ;)
#7
12/19/2008 (2:19 pm)
Of course you can add them in, that's why I said them :)
#8
01/12/2009 (7:08 am)
This source must go into TDN.
I was looking for these. Thanks a lot!
#9
05/02/2009 (8:49 am)
MaxWheelSpeed is broken, has been since the beginning and probably always will be. Set a car on flat land, set the speed to 5 and let it run. It will "creep" up in speed forever. Someone should look at this and add a limiter.
Good job on the explanations.

#10
05/02/2009 (12:22 pm)
Thanks for the heads-up! Added your comment to the resource itself, assuming that's okay ;)
#11
02/26/2014 (8:28 pm)
Thank You Mr Buckmaster , and the gentlepeople who added to this resource . After many years still helping we noobs who are , shall we say , a bit late to the party . BTW , Im only just beginning to learn , using the TGE demo in 3DGPAI1(2004)THX
#12
02/26/2014 (8:44 pm)
Glad to hear it helped! You might want to check out T3D once you find your feet with the engine... lots of the knowledge will transfer over directly! I'm pretty sure this resource does, at least!