9
\$\begingroup\$

When playing GTA III on Android I noticed something that has been annoying me in almost every racing game I've played (maybe except Mario Kart): Driving straight ahead is easy, but curves are really hard. When I switch lanes or pass somebody, the car starts swiveling back and forth, and any attempt to correct it makes it only worse. The only thing I can do is to hit the brakes. I think this is some kind of oversteering.

What makes it so irritating is that it never happens to me in real life (thank god :-)), so 90% of the games with vehicles inside feel unreal to me (despite probably having really good physics engines). I've talked to a couple of people about this, and it seems either you 'get' racing games, or you don't. With a lot of practice, I did manage to get semi-good at some games (e.g. from the Need for Speed series), by driving very cautiously, braking a lot (and usually getting a cramp in my fingers).

What can you do as a game developer to prevent the oversteering resonance catastrophe, and make driving feel right? (For a casual racing game, that doesn't strive for 100% realistic physics)

I also wonder what games like Super Mario Kart exactly do differently so that they don't have so much oversteering?

I guess one problem is that if you play with a keyboard or a touchscreen (but not wheels and pedals), you only have digital input: gas pressed or not, steering left/right or not, and it's much harder to steer appropriately for a given speed. The other thing is that you probably don't have a good sense of speed, and drive much faster than you would (safely) in reality. From the top of my head, one solution might be to vary the steering response with speed.

\$\endgroup\$
2
  • 3
    \$\begingroup\$ You also need to consider who your target audience is. If it is enthusiast driving gamers, you'll only alienate them by 'fixing' reality. You probably don't race cars, and don't understand that at the high speeds of a race the problem you are experiencing is a very real thing that is a problem for real race drivers. The real 'fix' is to be more casual, and that's what Mario Kart is doing different. They are looser with the physics and don't model the forces needed to create fishtailing, and thus aren't of interest to hardcore driving game fans. \$\endgroup\$
    – DampeS8N
    Commented Dec 3, 2012 at 18:30
  • \$\begingroup\$ I don't know how easy you have access to this, but thought it might help. I played a PSX game a long time ago called Formula One.. they made several of them but it was the very first one. Anyways it was a simulation, but the options had steering and breaking assist options with a slider that you could increase or decrease. So if you had breaking assist very high for example, your car would break automatically if it was going into a turn too fast, and it would steer for you as well (depending on how much assist you wanted), so you might want to check that out for a solution. \$\endgroup\$
    – wardd
    Commented Dec 4, 2012 at 1:27

2 Answers 2

7
\$\begingroup\$

One solution would be to cheat a bit and guess what the player wants to do. When the player is on a straight section and presses left, you can assume that he wants to switch lanes. When he is close to a curve or intersection, he certainly wants to turn. The player is unable to control it's exact steering angle in a curve, so you could decide to give the player the benefit of doubt and always let him drive through curves in the ideal angle when he presses the turn button at the right moment (as long as physically possible - any player who tries to drive with through a hairpin curve with 200 km/h deserves to be punished by a short flight over the grass).

This, of course, could get tricky when the player actually wants to turn around on a straight section or actually wants to switch lanes just before an intersection.

Another solution would be to have a difference between tapping a key and holding a key. The longer the player holds the turn key, the higher the turning angle. This doesn't even feel unrealistic, because when you have a steering wheel, you need time to turn it all the way.

Edit: On a touchscreen, you could use sliders instead of buttons for controlling steering and speed in an analog way. When the screen is pressure-sensitive, you could also interprete the pressure (but give visual feedback on maximum pressure, or overzealous players might break their displays). When the device has orientation sensors, you could use device tilting to control steering.

\$\endgroup\$
2
  • \$\begingroup\$ Thank you for your correction, @kotekzot. But you can suggest edits to other people posts directly without having to ask them. \$\endgroup\$
    – Philipp
    Commented Dec 3, 2012 at 16:06
  • \$\begingroup\$ your idea is good. When the right button is pressed (0/1) , it will rotate the car with an angle that depends on the curve. Right like when you drive : you say 'i turn left' (0/1) but in fact you will turn the steering wheel more or less depending on the slope. And also something worth mentionning : the angle gradually changes, not all of a sudden. \$\endgroup\$ Commented Dec 3, 2012 at 16:55
0
\$\begingroup\$

I came across this (old) question while researching what other games than Grand Theft Auto IV and V have implemented, but I have a decent answer to achieve controllable oversteer. I only have some experience messing around with the driving model in Grand Theft Auto V, but this information should be applicable to most somewhat realistic driving models.

What seems to happen in most driving games, is that the car steering output is directly linked to player input - even if some sort of (temporal) smoothing is used. This causes a sluggish feeling or a jerky feeling - and the car does not correct itself after letting go of the controls. This is in contrast to a real car, where the car tends to center itself after releasing force on the wheel. Some games try to correct this by changing their handling model or having arcade handling models.

What can be observed in Grand Theft Auto V, is that user steering input is not directly linked to steering output. The vehicle steers by itself, towards its current velocity vector. This is visible when forcing a slight oversteer situation and observing the steered wheels - without any input, they countersteer by themselves. Any user input is then added on top of these "natural" corrections.

A downside to this approach however, is the car feeling too sticky and somewhat stubborn to get into a powerslide or drift - so this countersteer value can be limited to some angle.

This theory can be verified by re-implementing the steering system and comparing it with the original behavior.

  • When linking input to output directly, the vehicle is indeed extremely hard to control, even when having applied the speed-based steering input limiter.
  • When adding in the natural countersteer, the behavior is nearly identical to the games' implementation, but cars are "too" stable.
  • When adding in a 15 degree limit to countersteer, the behavior is almost identical.

A thing to keep in mind is that Grand Theft Auto V was taken as "ideal" here - though I have yet to find any other game that implements this system.

If you're curious for some code, here's a snippet of my implementation.

// Returns in radians
float Racer_calculateDesiredHeading(float steeringMax, float desiredHeading,
    float reduction) {
    desiredHeading *= reduction;
    float correction = desiredHeading;

    // Get the relative velocity vector
    Vector3 speedVector = ENTITY::GET_ENTITY_SPEED_VECTOR(vehicle, true);
    if (abs(speedVector.y) > 3.0f) {
        // Simplify it to an angle
        Vector3 target = Normalize(speedVector);
        float travelDir = atan2(target.y, target.x) - static_cast<float>(M_PI) / 2.0f;
        if (travelDir > static_cast<float>(M_PI) / 2.0f) {
            travelDir -= static_cast<float>(M_PI);
        }
        if (travelDir < -static_cast<float>(M_PI) / 2.0f) {
            travelDir += static_cast<float>(M_PI);
        }
        // Correct for reverse
        travelDir *= sgn(speedVector.y);

        // Limit to some degree, R* uses 15 degrees
        travelDir = std::clamp(travelDir, deg2rad(-15.0f), deg2rad(15.0f));

        // User input deviation
        correction = travelDir + desiredHeading;
    }

    return std::clamp(correction, -steeringMax, steeringMax);
}
\$\endgroup\$

You must log in to answer this question.

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