Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Dark GDK / REAL framerate-independent movement and something about angles

Author
Message
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 5th Dec 2005 01:23
Righto, two questions for you brain boxes tonight - one about frame rate independent movement for players and one about angles.

Framerate:

I read the DBP timer tutorial in the newsletter way back and made myself a set of timer functions based off it, also some others based on ideas from the irc channel. The idea being to get a factor I can times the desired speed at 30fps at so no matter the framerate all players move the same speed on all machines. VITAL because im working on a multiplayer action game - sync must be kept.

I always suspected my system was allowing a bit of variation in when I was having a deathmatch with my friend, but it didnt seem too bad. However i have rewritten my entire network engine to something a bit more sensiable, effective and hacker proof - now the clients send keystates to the server and the server moves the objects locally and broadcasts their state on a timer, the players predict movement then using something simular to cubic splines. I wrote the prediction today and it was all buggered, first i thought it was the prediction (which i know isnt right yet, see angles section) but then for a test i just positioned the player at the position in the packets its receiving so i could see where he should be by where he jumps to - he was flying across the map at insane speeds.

The server is a darksdk application but doesnt draw objects, has backdrop disabled etc and for maxium processing effcientcy has an uncapped sync rate - the moment i capped the sync at 60 the player speed became normal again. Not a solution, i need that frame rate uncapped! Has anyone ever implemented framerate independent code that they KNOW truely is the same speed on all computers? heres my code.

At the start of each frame, i call these two functions in this order:

GetAdverageFps();
UpdateTime();

the code for these is:



then, when the server is about to move a player it calculates the speed like this:



the fSpeed member of aPlayerStates is the const speed for that tank in its current state. GetFactorOnAdverage() simply looks like:



I didnt used to calculate a factor off the adverage, but after testing many things that seemed the best on the client which never ran past 60fps anyway. Where am I going wrong?

Angles:

This is about the player prediction - whenever a new state packet arrives with position information the players start getting moved towards that point. The first thing I do is calculate the angle between the players current point and its destination point so i can rotate the player towards it smoothly. First question is, am I even using arctan right? The docs are really unhelpful with this command:



Secondly, when I have the destination angle, I turn the player towards it using dbCurveAngle - it seemed like a good idea at the time >.> The function gets called every frame so it seemed right. However, the docs specify that the first parameter is the destination, the second parameter is the.. curve.. i presume current angle and the third parameter is the speed. However the docs also say CurveAngle is CurveValue >.> So I opened the header and that says: dbCurveAngle( float a, float da, float sp ); - im presuming a is current angle, da is destination angle and sp is the speed, the oposit way around from the docs. Currently I am using:



is that right?

Thanks for your help, as always

King3D
18
Years of Service
User Offline
Joined: 23rd Nov 2005
Location: El Segundo, CA
Posted: 5th Dec 2005 04:57
I am a little skeptical of the average framerate calculation you use. Nonetheless, if you run application uncapped, the averages will be way off the mark, mate. I'd suggest calculating the average framerate after you have collected MAX_ADV samples or use std::min(frameCounter, MAX_ADV) as the max for your average framerate loop.

Additionally, instead of doing a memory copy of the Averages in UpdateTime(), try this:

// Assumes you a variable "frameCounter" to count the # of frames.
Averages[frameCounter % MAX_ADV] = currentFPS;

Rob
OSX Using Happy Dude
20
Years of Service
User Offline
Joined: 21st Aug 2003
Location: At home
Posted: 5th Dec 2005 10:22
It would also be better to use the high precision timer, for a more accurate reading.

Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 8th Dec 2005 20:55
Sorry that I seemed to ask a question and run there, a friend paid an unexpected visit and stayed a few days But he left this morning and im back again.

I may just be being slow today, but i'm going to need a little more explaining if thats okay

King - well spotted that I was calling the adverage calculation before updating the time - still, it should only be one frame behind and I dont see how it could of been a major problem..

MAX_ADV is obviously a constant, currently set to 30, which is just the number of frames I wished to adverage. The array is declared using it, the idea was I just tweaked that const to update the code until I found a number I thought worked right, 30 seemed good at the time.

As this is done on the server obviously the server has to be running for anyone to connect and until someone connects and starts moving around the factor isnt used - easilly a second will pass before anyone connects and if it was capped on 30fps (it isnt) then in that time 30 frames would of already passed and the array holding frame times will already be full so again I dont see why I would need to adverage the amount of frames that has passed so far OR the MAX_ADV because by the time its used the array will be full to MAX_ADV?

The subsitute for the memcpy looks interesting, I dont understand it if im honest though. Oh I understand what the code is SAYING, index the frame array at CurrentFrameNum MOD MAX_ADV and set it to the fps, but I;m not entirely sure how thats better than the direct mem copy? The memcopy shuffles the array down and inserts the newest at the top, wouldnt your code leave some frames older than 30 in the array?

A little code goes a long way to explaining things if you wanna chuck some out in the form of a function to explain what you mean

@Mr-Always-Changing-My-Bloody-Name (xD) - the high precision timer?

OSX Using Happy Dude
20
Years of Service
User Offline
Joined: 21st Aug 2003
Location: At home
Posted: 8th Dec 2005 22:14 Edited at: 9th Dec 2005 09:11
King3D
18
Years of Service
User Offline
Joined: 23rd Nov 2005
Location: El Segundo, CA
Posted: 11th Dec 2005 01:11
If you want to clear up all your time-related issues, simply drop the average framerate calculations. Sure, keep them around for debugging & display purposes, but that is it.

Your update loop should look like this:

update()
{
currentTime = Clock.getTime();
timeDelta = currentTime - lastTime;
timeDeltaSeconds = timeDelta * CONVERT_MS_TO_SECONDS;

// use time delta for all movement.
{
float distance = timeDeltaSeconds * speed;
x_pos = dbNewXValue(x_pos, x_dir, distance);
y_pos = dbNewXValue(y_pos, y_dir, distance);
z_pos = dbNewXValue(z_pos, z_dir, distance);
}

lastTime = currentTime;
}

This will work at any frame rate & is more or less bulletproof.
Sephnroth
21
Years of Service
User Offline
Joined: 10th Oct 2002
Location: United Kingdom
Posted: 11th Dec 2005 07:03
........so simple, so why is every article i have ever found on framerate indepedent code the size of a short novel?! All that stuff that i've tried to implement, sometimes pages of timer code, and then it comes down to this

Thanks king, if this works i'll be in your debt. Its 6am here and i havnt slept yet so I will try and implement this one tomorrow

King3D
18
Years of Service
User Offline
Joined: 23rd Nov 2005
Location: El Segundo, CA
Posted: 12th Dec 2005 02:10
Be sure to use the correct dbNew functions...

Login to post a reply

Server time is: 2024-05-06 15:52:21
Your offset time is: 2024-05-06 15:52:21