A very simple, "5 minute" feature request

For collaboration on developing the mod capabilities of VS; request new features, report bugs, or suggest improvements

Moderator: Mod Contributor

Post Reply
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

A very simple, "5 minute" feature request

Post by chuck_starchaser »

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:

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;
}
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).
RedAdder
Bounty Hunter
Bounty Hunter
Posts: 149
Joined: Sat Jan 03, 2009 8:11 pm
Location: Germany, Munich
Contact:

Re: A very simple, "5 minute" feature request

Post by RedAdder »

Well this is a 5 minute feature only if there is a central ship object that handles acceleration.
Maybe you could search the existing codebase yourself and find the right place to add this?
I looked myself in unit.h, maybe one of these functions would serve?

Code: Select all

  ///Updates physics given unit space transformations and if this is the last physics frame in the current gfx frame
  virtual void UpdatePhysics2 (const Transformation &trans, const Transformation & old_physical_state, const Vector & accel, float difficulty, const Matrix &transmat, const Vector & CumulativeVelocity, bool ResolveLast, UnitCollection *uc=NULL);
  //class Cockpit * GetVelocityDifficultyMult(float &) const;
  ///Thrusts by ammt and clamps accordingly (afterburn or not)
  void Thrust(const Vector &amt,bool afterburn = false);
  ///Resolves forces of given unit on a physics frame
  Vector ResolveForces (const Transformation &, const Matrix&);
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: A very simple, "5 minute" feature request

Post by chuck_starchaser »

I'm not familiar with the code base, but a quick glance leads me to believe
you're in the right spot. Just need to add a vector3 filtered_thrust, and add
filtering to the function void Thrust(const Vector &amt,bool afterburn = false);
it would seem to me.
The question is, is this going to affect AI ships or the player's or both?
First priority is the AI's.

EDIT:
I'll take a look at the code this weekend; but can't promise anything, as
every time I've looked at VS code I've walked away head spinning... :D
denyasis
Hunter
Hunter
Posts: 75
Joined: Thu Mar 19, 2009 10:31 am

Re: A very simple, "5 minute" feature request

Post by denyasis »

I think that would help with the AI a lot -
chuck_starchaser wrote:so it shouldn't impact other things such as ship response or ai too severely.
Totally agree. If it even does - it's actually really easy to fix; at least in terms of the AI combat scripts. One can just add 1 interruptable second to the manuever.
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: A very simple, "5 minute" feature request

Post by chuck_starchaser »

Indeed it might. Not sure how it is in Vegastrike, but in PU, our players complain all the time that
the AI's are too good, with super-human aiming accuracy. Like they come out of a loop at the
exact right time with the exact aiming and start shooting.
If a bit of 2nd order acceleration delays their aiming a little bit it would be wonderful.
klauss
Elite
Elite
Posts: 7243
Joined: Mon Apr 18, 2005 2:40 pm
Location: LS87, Buenos Aires, República Argentina

Re: A very simple, "5 minute" feature request

Post by klauss »

LOL, reviving old threads...
chuck_starchaser wrote:Indeed it might. Not sure how it is in Vegastrike, but in PU, our players complain all the time that
the AI's are too good, with super-human aiming accuracy. Like they come out of a loop at the
exact right time with the exact aiming and start shooting.
If a bit of 2nd order acceleration delays their aiming a little bit it would be wonderful.
It's a nice idea... but it clashes with the multi-step physics system on VS.

VS has an irregular step schedule - "important" units are updated more often than "unimportant" ones (quotes to document the fact that importance isn't being estimated very well). The weirdness in movement is more likely a result of that, since between "keyframes" positions and orientations are interpolated linearly.

Further backing for this theory is the fact that units already have a maximum angular and linear acceleration, which should result in the kind of filtering you propose.

I would suggest, then, to implement second order interpolation between keyframes. Doing so with position is rather easy, with orientation... I don't know. It would have to be looked into.

NOTE: interpolation is done directly in the rendering loop, in mesh_gfx.cpp, if you want to take a look. For this units have a current and next (or current and previous?) position, but I believe they don't have current and next velocity - so adding them will probably be required.
Oíd mortales, el grito sagrado...
Call me "Menes, lord of Cats"
Wing Commander Universe
chuck_starchaser
Elite
Elite
Posts: 8014
Joined: Fri Sep 05, 2003 4:03 am
Location: Montreal
Contact:

Re: A very simple, "5 minute" feature request

Post by chuck_starchaser »

klauss wrote:LOL, reviving old threads...
Glad you are. I wake up with sadness every morning because of the lack of this feature; no matter how long ago I requested it :D
chuck_starchaser wrote:Indeed it might. Not sure how it is in Vegastrike, but in PU, our players complain all the time that
the AI's are too good, with super-human aiming accuracy. Like they come out of a loop at the
exact right time with the exact aiming and start shooting.
If a bit of 2nd order acceleration delays their aiming a little bit it would be wonderful.
It's a nice idea... but it clashes with the multi-step physics system on VS.

VS has an irregular step schedule - "important" units are updated more often than "unimportant" ones (quotes to document the fact that importance isn't being estimated very well). The weirdness in movement is more likely a result of that, since between "keyframes" positions and orientations are interpolated linearly.
I'm with you so far. Couldn't the importance computation weaknesses be got around with a few ad-hoc rules? For example, make it a rule that no less than 64 units are in the "update every frame" bin, with 16 of them should be chosen by shortest distance to the player, another 16 by size-over-distance, and the other 32 by whatever is the current criteria. That way you wouldn't have to have the Ultimate importance algorithm implementation. If something escapes through its bureaucratic loopholes, it gets caught by the other ad-hoc rules, anyhow.
Further backing for this theory is the fact that units already have a maximum angular and linear acceleration, which should result in the kind of filtering you propose.
No; it wouldn't quite... What I suggested is a gradual ramping up of acceleration, over a period of a second (NOT a ramping up of speed); on the simple premise that instantaneous acceleration implies instantaneous thrust, which no motor or turbine or even explosive propellants can deliver.
I would suggest, then, to implement second order interpolation between keyframes. Doing so with position is rather easy, with orientation... I don't know. It would have to be looked into.
If third order was possible, it would look A LOT better; but if second order is not present, then I agree it would be the first step.
NOTE: interpolation is done directly in the rendering loop, in mesh_gfx.cpp, if you want to take a look. For this units have a current and next (or current and previous?) position, but I believe they don't have current and next velocity - so adding them will probably be required.
I'll take a look. Thanks!
Post Reply