A very simple, "5 minute" feature request
Posted: Thu Jul 23, 2009 5:52 am
The Vegastrike engine models acceleration, linear as well as angular, based on
Newtonian physics, very well. However, there is something "unnatural" in the way
ships move: Changes in acceleration are often instantaneous and sudden.
This feels unnatural because the pilot cannot even move the joystick instantly or
turn the power dial to maximum instantly for that matter; and even if she could,
the engines would probably show a bit of delay in response.
My proposal is NOT to model 2nd order acceleration. That would be too much
and would require new data for units and whatnot. My proposal is a simple and
rather "cosmetic" solution:
Just filter acceleration changes linearly by 25% of input step value per physics
frame; so that it takes 4 physics frames to go from no acceleration to the desired
(input) value. Both for linear and angular accelerations. Or just limit change to,
say, 10% of maximum acceleration for the ship; so that it would take 10 physics
frames to go from 0 accel to max accel. 10 physics frames are about 0.7 seconds,
so it shouldn't impact other things such as ship response or ai too severely.
Or, if the engine doesn't have an "input acceleration" but rather a value of thrust,
same thing: just make a variable "filtered_thrust" that follows the incoming thrust
command, but can only change by so much per physics frame.
C code:I wrote it as if accel was a scalar, but the same exact code could be written
for thrust vectors and yaw, pitch, roll commands. In fact, the function could be a
template function.
Of course, flt_accel would be a class variable, rather than a static within a function.
Just wrote it like that to show the essence of the simple filter.
And, of course, 0.1 would be a variable from vegastrike.config.
The basic idea is to use just one value globally for all ships, rather than add a column to
units.csv. If you want to get fancy, the variable could be scaled by ship size, but it wouldn't
be necessary, I don't think.
If it looks like a simple little thing it's because it is; but it would have an
enormous impact on the believability of ship movements, I promise.
EDIT:
The filtering may not need to be applied to the player's ship, as the player is already
limited biologically in terms of being able to move the joystick instantly. So this proposal
is for ai's for sure; but for the player's ship conditionally or in a subdued form (e.g. 0.2).
Newtonian physics, very well. However, there is something "unnatural" in the way
ships move: Changes in acceleration are often instantaneous and sudden.
This feels unnatural because the pilot cannot even move the joystick instantly or
turn the power dial to maximum instantly for that matter; and even if she could,
the engines would probably show a bit of delay in response.
My proposal is NOT to model 2nd order acceleration. That would be too much
and would require new data for units and whatnot. My proposal is a simple and
rather "cosmetic" solution:
Just filter acceleration changes linearly by 25% of input step value per physics
frame; so that it takes 4 physics frames to go from no acceleration to the desired
(input) value. Both for linear and angular accelerations. Or just limit change to,
say, 10% of maximum acceleration for the ship; so that it would take 10 physics
frames to go from 0 accel to max accel. 10 physics frames are about 0.7 seconds,
so it shouldn't impact other things such as ship response or ai too severely.
Or, if the engine doesn't have an "input acceleration" but rather a value of thrust,
same thing: just make a variable "filtered_thrust" that follows the incoming thrust
command, but can only change by so much per physics frame.
C code:
Code: Select all
float filtered_accel( float input_accel, float max_accel )
{
static float flt_accel = 0; //note static...
//compute difference between incoming and filtered
float accel_delta = input_accel - flt_accel;
//limit the difference both, for accel and deccel
if( accel_delta > max_accel * 0.1 )
accel_delta = max_accel * 0.1;
if( accel_delta < -max_accel * 0.1 )
accel_delta = -max_accel * 0.1;
//add the limited delta to the filtered accel
flt_accel += accel_delta;
return flt_accel;
}
for thrust vectors and yaw, pitch, roll commands. In fact, the function could be a
template function.
Of course, flt_accel would be a class variable, rather than a static within a function.
Just wrote it like that to show the essence of the simple filter.
And, of course, 0.1 would be a variable from vegastrike.config.
The basic idea is to use just one value globally for all ships, rather than add a column to
units.csv. If you want to get fancy, the variable could be scaled by ship size, but it wouldn't
be necessary, I don't think.
If it looks like a simple little thing it's because it is; but it would have an
enormous impact on the believability of ship movements, I promise.
EDIT:
The filtering may not need to be applied to the player's ship, as the player is already
limited biologically in terms of being able to move the joystick instantly. So this proposal
is for ai's for sure; but for the player's ship conditionally or in a subdued form (e.g. 0.2).