• Advertisement
Sign in to follow this  

Looking into fix my time step

This topic is 966 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello all.

 

I was looking at changing my game loop. But I have some questions,

(Q1)Like why do they have the accumulator in a while loop

(Q2)does that loop do the update or do you wait until the loop ends.

(Q3) What is t with long waits this just counts up and up each time you do a pass.

(Q4)lloks like it only works when frame time is small

(Q5)My test code maybe wrong.

(Q6)How do you proccess 8000 objects in a small amount of time. That will not make the time delay blow up.

(Q7)Its just me I have it all wrong Hoping.

 

This does not look wright if I add a 1 second delay at the end of the loop the while accumulator will spin for like depending on the wait can spin

upto 615 steps in the loop and more, this seams wrong why waste that loop.

I noticed in the article they put a if(frameTime > 0.25) frameTime = 0.25; whats the point of calling thy timer. In my current setup I just hard coded a 0.20 as my frame delta and vsync thats why I want to change to this, But I'm missing something.

 

this is the article

 

May be I have it wrong here is my test app.

.

#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif

#include<Windows.h>
#include <string>
#include <iostream>
#include <sstream>
#include<GameTimer.h>



int main(int argc, char* argv[])
{
														
       // Enable run-time memory check for debug builds.
#if defined(DEBUG) | defined(_DEBUG)
    _CrtSetDbgFlag( _CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF );
#endif
	
	
	
	std::cout << "Press Q to quit" << std::endl;

	__int64 ctr1 = 0, freq = 0;
	__int64 currentTime = 0;//hires_time_in_seconds();
	int acc = 0, i = 0;

	//get the time
	if(QueryPerformanceCounter((LARGE_INTEGER *)&currentTime)== FALSE)
	{
		std::cout << "Timer error" << std::endl;
	}
	
	QueryPerformanceFrequency((LARGE_INTEGER *)&freq);


	double t = 0.0;
	const double dt = 0.01;


	double accumulator = 0.0;


	size_t listsize = 0;
	std::string line; //stores the most recent line of input 
	while(std::getline(std::cin, line)) //read entire lines at a time 
	{ 
		//deal with the contents of `line`
		if(line.compare("q") == 0 || line.compare("Q") == 0)
			break;

	

		if(QueryPerformanceCounter((LARGE_INTEGER *)&ctr1)== FALSE)
		{
			std::cout << "Timer error" << std::endl;
		}
		__int64 newTime =  ctr1;//hires_time_in_seconds();
		double frameTime = ((newTime - currentTime) *1.0 / freq);//convert to seconds
		

		//if(frameTime > 0.25 )
		//	frameTime = 0.25;

		std::cout <<  "CurrentTime: = " << currentTime << std::endl;
		std::cout <<  "NewTime: = " << newTime << std::endl;
		std::cout <<  "Current Frame Time: = " << frameTime << std::endl;
		currentTime = newTime;

		accumulator += frameTime;

		int count = 0;
		while( accumulator >= dt )
		{
			count++;
			//Sleep(200);

			std::cout << "accumulator::" << accumulator << " Steps :" << count << std::endl;
			std::cout <<  "Current Frame Time: = " << frameTime << std::endl;
			//integrate( state, t, dt );
			accumulator -= dt;
			t += dt;
			std::cout <<  "Time t = " << t << std::endl;
		}

		Sleep(1000);


	}//end while running

	return 0;
}

.

Just found this post Now if I set a DT of 1/120 and a sleep(1000) there is over 23000 steps lol say good by to your game loop hehehe. 1/30 seams to work a lot better

but what happens if your render takes a second  say good bye again.

Can't  you just set a timer to fire every 0.03 seconds and update.

I think I may have to move this into my real app and see what happens.

Edited by ankhd

Share this post


Link to post
Share on other sites
Advertisement

Thanks.

And whats with this bit.

if(frameTime > 0.25 ) frameTime = 0.25;  Does it just stop spiral of death.

 

Ok t is the accumulated running time since started.

 

and with my up date, to compare is done by looping all objects  with DT of 0.20f each frame and I was wondering how to intergrate the fix my time step.

UpDate(0.20f);

render();

present();

 

 

And I know what the render is I put the Sleep there to act as a long render.

 

obviously I used large sleep values so I coud see what all the post are saying about jitter. and also why they where using max loop flag to quit.

but the jittercould be many steps in the loop or is that spiral of death.

 

Lspiro has it 1/30 for DT is all you need. I just tryed 1/120 to see what the other guy was talking about, Which gave me the spiral of 33000 steps of death.

 

I'm going to try the above in me real game and see what happens the update is decoupled from my render. As it stands the current setup I have on a Mplay. one pc's object arrives like 15 frames before the slower pc.'s object does. This is only for object motion. AT the moment my update function runs as fast as the render

as its like this

UpDate(0.20f);

render();

present();

 

Like Krohm said.

    What you miss is that vsync is unreliable (as a start) as drivers can force it off or on and you would be screwed. Plus, there's no current guarantee your  

    software will be faster than vsync so you actually do your computation in vsync multiples. The reason I'm asking.

Share this post


Link to post
Share on other sites

Hi!

 

 

 

(Q1)Like why do they have the accumulator in a while loop

 

Looking at your code: 

integrate( state, t, dt );

It looks like you are moving your simulation forward in fixed delta times. The accumulator acts as a way of collecting time up until the point where you start the simulation. At that point you want to either catch up or don't do your integration. So for example if you wanted to do your integration 30 times a second and your rendering 60 times a second the first time you got to that while loop the accumulator would have the value 1/60. The second time it would have the value 1/30, so do your integration step once. On the other hand, if you were on a slower machine the first time you got to that while loop you could have a value of 1/15 in the accumulator(rendering at 15fps), in this case you would need to to do two steps of simulation to "catch up" to your rendering. It just looks like a way to keep your simulations consistent. 

Share this post


Link to post
Share on other sites

Hey all.

I put the loop in the game. And gained 9 milliseconds per frame as a byproduct cool this updates the updates less then I was when running free.

But the units move so slow its like half a pixel per hour.

 

I set the if(frameTime > 0.35) and the time delta is 0.0299999, so it never makes it to the if statement thats all working.

thats just wrong there frame time is at 0.35;

 

I update my objects like this(see code)and I played with the values but the only way I could in crease the units travel speed was by reducing the mass of the unit before I had it set to

Unit mass = 100.0;//kgs had to move it down to 1.0; but even thats not that fast at all.

If I remove the timedelta from update velocity it moves faster. have I got it wrong for this fix your time step loop.

.

///over ride the motion data
	RTSComponentMotion.m_dMaxSpeed		= 2600.5f;
	RTSComponentMotion.m_dMass			= 100.0f;//kg
	RTSComponentMotion.m_dMaxTurnRate		= 1;
	RTSComponentMotion.m_dMaxForce		= 1000.0f;

		//if we have a destination
		if(HasDestination && GetDestination(&destination))
		{
			//we are walking set the walking animation
			CurrentUnitAnimationOrder.SetCurrentOrder(CurrentUnitAnimationOrder.RUN);

			//does object to object
			m_vSteeringForce = m_SteeringBehaviors->Calculate();
		
			//Acceleration = Force/Mass
			D3DXVECTOR3 acceleration = m_vSteeringForce/ ComponentMotion->m_dMass;

			//update velocity
			ComponentMotion->m_vVelocity += acceleration  * timedelta; 

			//make sure vehicle does not exceed maximum velocity
			ComponentMotion->m_vVelocity = Truncate(ComponentMotion->m_vVelocity, ComponentMotion->m_dMaxSpeed);
			
			//update the position
			ComponentMotion->m_vPos += ComponentMotion->m_vVelocity * timedelta;

And one more thing where and how to add some extra speed so the unit could run or walk.

Edited by ankhd

Share this post


Link to post
Share on other sites

Time delta is usually a small number, anywhere from 1/30 to 1/60, for example. So if we look at it with random numbers and assume the simple case of just position and velocity:

 

position = <5, 5>

velocity = <3, 0> 

deltaTime = 1/30

 

And your options are to use delta time or not:

 

w/delta time:

 

position = position + velocity * deltaTime

position = <5, 5> + <3, 0> * 1/30

position = <5.1, 5>

 

without delta time:

 

position = position + velocity

position = <5, 5> + <3, 0>

position = <8, 5>

 

So assuming this delta time 1/30(30 fps) the object being integrated/simulated without delta time would appear to move faster.

 

So if you weren't using a delta time before you have to rethink your scalar values and what they mean for objects in motion before. As in, you need to raise your velocity, lower your mass or increase the acceleration.

Share this post


Link to post
Share on other sites

Sorry all I just can't get my units to travel at speed.

 

 

if I use timedelta to update the velocity and also on the position, no matter what extra speed value the units travel is slow.

 

this setup.

//update velocity

ComponentMotion->m_vVelocity +=( acceleration) * timedelta;  I tryed adding extra speed here (acceleration * 200) * timedelta

 

I also tryed here adding extra to the position

ComponentMotion->m_vPos += (ComponentMotion->m_vVelocity * 550) * timedelta;

 

But the only way I managed to increase the speed is if I drop the timedelta from the position like so.

//update velocity

ComponentMotion->m_vVelocity +=( acceleration * 200) * timedelta; //fast unit and smooth motion

 

 

 

removed the time delta

ComponentMotion->m_vPos += (ComponentMotion->m_vVelocity);// * timedelta; no timedelta

 

 

the other setup that worked was using both timedeltas .

What part is wrong, Does both time deltas need to be there and whats happening to it when its not there.

Share this post


Link to post
Share on other sites

You've kinda awnsered yourself there :)

 

Just use the delta time on all velocity/acceleration/Etc calculations, And then add that to the position and then clear the velocity for the next frame.

 

Movement: Think of the values as that many units per second, So a velocity of <5,5> means 5 units/pixels/meters per second.

 

HTH

Share this post


Link to post
Share on other sites

Hey Thanks All.smile.png wub.png hehe.

Ryan20fun how did you know that the velocity was not being reset. Good heads up thanks.

 

I sort of was on that line of thinking but I reset the velocity in the onDestination call not per steps.

 

I have some fine tuning to do on the values, But all is working fine.

 

And it does perfect synchronization, Even with 1 PC renders at 13 millisecond and the other runs at 34 milliseconds per frame.

 

Again wow. I put this off for like a couple of years. My next gtame I'll do this from now on.

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement