Forum

Fixing gravity/acceleration

Discuss programming topics for the various GPL'd game engine sources.

Moderator: InsideQC Admins

Postby Static_Fiend » Wed Apr 14, 2010 1:55 am

Sajt wrote:Darkplaces fixed this a long time ago. I don't remember if it was made into a sv_gameplayfix cvar, but it should be.


Indeed it was, sv_gameplayfix_gravityunaffectedbyticrate
Static_Fiend
 
Posts: 10
Joined: Wed Mar 17, 2010 1:47 am

Postby r00k » Wed Apr 14, 2010 3:53 am

I understand now, I had to do some ticrate leveling gamecode in my ctf mod. At different ticrate the hook cause irrational damages.
Code: Select all
void () HookPull =
{
   local vector vel;
   local float v, dorg, a, b, c;   

   if ((ctf_state & CTF_MATCH_PAUSED))
   {
      return;
   }

   if ((!self.owner.button0 && self.owner.weapon == IT_HOOK) || (self.owner.teleport_time > time ) || (self.owner.deadflag) || (gameover))
   {
      HookVanish();
      return;
   }
   
   if (self.enemy.style & CTF_OBSERVER)
   {
      HookVanish();
      return;
   }
   
   if (self.enemy.takedamage)
   {
      if (!teamplay || self.enemy.team != self.owner.team)
      {
         if (!CanDamage(self.enemy, self.owner,"hook"))
         {
            HookVanish();
            return;
         }

         self.enemy.deathtype = "hook";

         //R00k: tear-away hook if the chain is pulled too hard...
         
         a = vlen (self.enemy.velocity);
         b = vlen (self.owner.velocity);
         c = (a - b);
         
         if (c > 640)
         {
            sound (self, CHAN_WEAPON, "shambler/smack.wav", 1, ATTN_NORM);
            T_Damage (self.enemy, self, self.owner, 20);//same damage as an AXE hit
            HookVanish();
            return;
         }         

         //T_Damage (self.enemy, self, self.owner, 1);
         //at lower ticrates the hook damage is updated too fast
         //default 200a+100h = 30 seconds to death by hook
         
         self.hookdmg = (self.hookdmg + (sys_ticrate/0.1));

         if (self.hookdmg >= 1)
         {
            sound (self, CHAN_WEAPON, "blob/land1.wav", 1, ATTN_NORM);
            T_Damage (self.enemy, self, self.owner, 1);
            if (self.enemy.classname == "player")
            {
               SpawnBlood (self.origin, self.velocity, 10);
            }
            self.hookdmg = 0.00;
         }

         makevectors (self.v_angle);
      }

      if (self.enemy.classname == "player")
      {         
         setorigin (self, self.enemy.origin + self.enemy.mins + (self.enemy.size * 0.5));
      }
      else
      {
         self.velocity = self.enemy.velocity;//Fixme REMOVE/test effect
      }
   }
   else
   {
      self.velocity = self.enemy.velocity;//Fixme :REMOVE
   }
   
   if (self.enemy.solid == SOLID_NOT)// obsolete?
   {
      HookVanish();
      return;
   }

   makevectors (self.owner.angles);
   vel = self.origin - ( self.owner.origin + (v_up * 16 * (!self.owner.button2)) + (v_forward * 16));

   v = vlen (vel);

   if ( v > 100 )
   {
      vel = (normalize(vel) * hookspeedpull);
   }
   else
   {
      if (v <= 100)
      {
         vel = ((normalize(vel) * v) * 10);
      }
   }

   self.owner.velocity = vel;
   
   if (!(self.owner.flags & FL_WATERJUMP)) //Slow down the hook pull if underwater 20% less...
   {
      self.owner.velocity = ((1 - ((0.8 * self.owner.waterlevel) * frametime)) * self.owner.velocity);
   }

   if (ctf_state & CTF_TEAM_CAPTURE_CUSTOM)
   {
      dorg = vlen(self.owner.origin - self.dest);

      if (dorg > 10 && self.style == 3)
      {
         sound(self.owner, CHAN_WEAPON, "weapons/chain2.wav", 1, ATTN_NORM);
         self.style = 2;
      }
      else
      {
         if (dorg < 10 && self.style == 2)
         {
            sound(self.owner, CHAN_WEAPON, "weapons/chain3.wav", 1, ATTN_NORM);
            self.style = 3;
         }
      }
   }

   self.dest = self.owner.origin;
   self.nextthink = (time + sys_ticrate);
};


also to countermeasure QW CTF, this converts bunnyhops at any ticrate to simulate default Quake ticrate.
Code: Select all
   if ((ctf_playmode & CTF_DYNAMIC_HOOK) && (hookspeedpull > 999)) //normalize bunny hop at all ticrates
   {
      if ((self.flags & FL_ONGROUND) && self.button2)
      {
         if (vlen(self.velocity) >= 576)
         {
            self.velocity = (self.velocity * (576 / (vlen(self.velocity))));
         }
      }
   }
r00k
 
Posts: 1110
Joined: Sat Nov 13, 2004 10:39 pm

Postby mh » Wed Apr 14, 2010 9:04 am

metlslime wrote:the client and server only need readonly access to the shared model data once it's loaded, right? So they probably don't need their own copies of it.

In theory I guess so, but the concern is that the client thread might modify some memory while the server thread is reading it. It might not be a big deal but I'm just about paranoid enough to be worried about it.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Spike » Wed Apr 14, 2010 9:50 am

the client doesn't modify models, but it does flush the cache system occasionally, and on map changes.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby mh » Wed Apr 14, 2010 10:31 am

Well it makes some minor changes, like writing in visframes, but like I said I'm probably just being extra-paranoid about it. :lol:
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby mankrip » Thu Jul 01, 2010 8:07 am

Static_Fiend wrote:
Sajt wrote:Darkplaces fixed this a long time ago. I don't remember if it was made into a sv_gameplayfix cvar, but it should be.


Indeed it was, sv_gameplayfix_gravityunaffectedbyticrate

From what I've seen in this version of Nexuis' source code, their implementation was wrong, as it doesn't seem to add the other half of the velocity update after updating the position. The solution mh posted here also has the same problem.

To implement this fix properly, I've searched for every call to SV_AddGravity, and added another call after the position update in each function that calls it. Now it behaves the same as before when playing with high framerates.

However, I still have to check for everything else that may also (de)accelerate the velocity, such as friction.
Ph'nglui mglw'nafh mankrip Hell's end wgah'nagl fhtagn.
==-=-=-=-=-=-=-=-=-=-==
Dev blog / Twitter / YouTube
User avatar
mankrip
 
Posts: 915
Joined: Fri Jul 04, 2008 3:02 am

Postby mh » Thu Jul 01, 2010 9:09 am

Another crazy idea here. Since we're talking about host_frametime as a multiplier for all of the physics functions, why not do the change directly on host_frametime itself?
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Spike » Thu Jul 01, 2010 10:14 am

making physics framerate independant (gravity specifically), you need:
vel += graivty*time/2;
origin += vel*time;
vel += gravity*time/2;

yeah, you could be lazy, split time into two, call it twice, with the second time with the origin-based frametimes set to 0.
but it would give lower fps, as you'd prolly be tracing through stuff twice.
Spike
 
Posts: 2892
Joined: Fri Nov 05, 2004 3:12 am
Location: UK

Postby Baker » Thu Jul 01, 2010 12:36 pm

Interesting ...

This may some erratic behavior on some maps where the host_fps is really high (most NQ clients running in single player the maxfps is also the server maxfps).
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Baker » Thu Jul 01, 2010 4:36 pm

Related:

In JoeQuake build 1862, there is a feature called cl_independent physics which I am assuming the goal is to get all the benefits of a higher frame rate (mouse polling mostly I'd think) without screwing up the physics.

Code: Select all
   if (cl_independentphysics.value)
   {
      double   minphysframetime = MinPhysFrameTime ();

      extraphysframetime += host_frametime;
      if (extraphysframetime < minphysframetime)
      {
         physframe = false;
      }
      else
      {
         physframe = true;

         if (extraphysframetime > minphysframetime * 2)   // FIXME: this is for the case when
            physframetime = extraphysframetime;   // actual fps is too low
         else                  // Dunno how to do it right
            physframetime = minphysframetime;

         extraphysframetime -= physframetime;
      }   
   }

#ifdef INDEPENDENTPHYSICS
   if (!cl_independentphysics.value)
   {
#endif
      // get new key events
      Sys_SendKeyEvents ();

      // allow mice or other external controllers to add commands
      IN_Commands ();

      // process console commands
      Cbuf_Execute ();

      NET_Poll ();

      // if running the server locally, make intentions now
      if (sv.active)
         CL_SendCmd ();
The night is young. How else can I annoy the world before sunsrise? 8) Inquisitive minds want to know ! And if they don't -- well like that ever has stopped me before ..
User avatar
Baker
 
Posts: 3666
Joined: Tue Mar 14, 2006 5:15 am

Postby Sajt » Thu Jul 01, 2010 10:31 pm

Physics/collision programming drives me crazy. Fixed framerate is the least you can do to "improve" the situation a bit... but fixed framerate is evil too. Things were good in the old days... nothing rotated, and you could even use integers if you wanted...
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Postby mh » Thu Jul 01, 2010 11:20 pm

Obviously proper separation of server and client, with the server running at a fixed 72fps and the client running as fast or slow as it wants is the correct solution here.
We had the power, we had the space, we had a sense of time and place
We knew the words, we knew the score, we knew what we were fighting for
User avatar
mh
 
Posts: 2292
Joined: Sat Jan 12, 2008 1:38 am

Postby Sajt » Thu Jul 01, 2010 11:28 pm

Probably true. It means departure from the cherished "client sends input, server frame, rest of client frame" high-response scheme for local games, but that's probably a necessary (and probably unnoticeable) sacrifice.
F. A. Špork, an enlightened nobleman and a great patron of art, had a stately Baroque spa complex built on the banks of the River Labe.
Sajt
 
Posts: 1215
Joined: Sat Oct 16, 2004 3:39 am

Previous

Return to Engine Programming

Who is online

Users browsing this forum: No registered users and 1 guest