Sign in to follow this  
Halsafar

Earth Time -- Game Time

Recommended Posts

To simulate realism you often want a passing day. You however do not need a passing day to take a full 24hr's earth time. It is unlikely that a player would be satisied by that... (unles you matched it up to there clock thus when u play at night, the game would be night, thats a neat idea.).. Anyway, curious how one would clock passing time accuratly. I know how much time is passing between frames, that is my basis on time passing. Using floats to contain the numbers is where I am having a crisis. It is unwise to use comparison greater that or less than on floats you know will be big and contain many decimal points. Using ints to contain the numbers means a huge loss in accuracy. I suppose you could cast the floats to ints and just compare the number outside the decimal place... So how can one go about this using floats and avoiding comparisons of floating points numbers?

Share this post


Link to post
Share on other sites
I'm not quite sure I know where these comparisons you are worried about are coming into effect? For a large amount of "time passing" effects you can get away with using only basic math (+-*/) and maybe only a few comparisons to mark significant points of the progression. Anyway, these comparison errors shouldn't be causing too many problems, I can't think for the life of me of where they would cause an error that wouldn;t get resolved in the next cycle.

Also, what are you using for timing? The basic timing system usually isn't floating point. That means that usually you will be using longs to get the time from the system, and that might be the best way for you to use the time in your game. No comparison errors at all this way.

Share this post


Link to post
Share on other sites
No, see I already have a QueryPerformanceCounter timer in use... Ever since I started game design. Yes, you use LARGE_INTEGER values.

To record the time which pass's between frames you end up recording a float. TimeDelta in a game is represented as a float.

As for floating point comparisons' I have read I believe that some systems will evaluate a float different than another might especially when the numbers get small. 1.0000000000002f > 1.0f on some comps may be true and may not...

Share this post


Link to post
Share on other sites
Quote:
Original post by Halsafar
No, see I already have a QueryPerformanceCounter timer in use... Ever since I started game design. Yes, you use LARGE_INTEGER values.

To record the time which pass's between frames you end up recording a float. TimeDelta in a game is represented as a float.

Why use a float inatead of using the integer values you are getting out of the counter? You aren't gaining any accuracy by converting between integers and floating point, it doesn't seem to make much sense in this case either.

Share this post


Link to post
Share on other sites
....have you used the performance counters?
Do you honestly think a 'whole number' of milliseconds pass each frame?

void SetStart() {QueryPerformanceCounter((LARGE_INTEGER*)&Start);} //Get start time
void SetFinish() {QueryPerformanceCounter((LARGE_INTEGER*)&Finish);} //Set the finish time
void SetDelta() {Delta = (Finish.QuadPart - Start.QuadPart) / (float)Frequency.QuadPart * 1000;} //Set Delta

Share this post


Link to post
Share on other sites
Quote:
Original post by Halsafar
....have you used the performance counters?
Do you honestly think a 'whole number' of milliseconds pass each frame?

void SetStart() {QueryPerformanceCounter((LARGE_INTEGER*)&Start);} //Get start time
void SetFinish() {QueryPerformanceCounter((LARGE_INTEGER*)&Finish);} //Set the finish time
void SetDelta() {Delta = (Finish.QuadPart - Start.QuadPart) / (float)Frequency.QuadPart * 1000;} //Set Delta

No, but a whole number of ticks certainly did. Like I said, converting to a float you are just losing the precision. If you are actually worried about that, then don't do the conversion. I've already said that I don't think it should be an issue though.

Share this post


Link to post
Share on other sites
Quote:
Original post by Halsafar
How would you write a timer to keep track of game time as 2.5min = 1 game hour?


__int64 game_time, real_time, real_time_start, game_time_start;

game_time = 24 * (real_time - real_time_start ) + game_time_start;

BTW, floating-point has a greater range than integers, but sacrifices precision for that range.

Share this post


Link to post
Share on other sites
I would suggest that you instead use the time() function to keep track of "real" time, and continue using your performance counter for time between frames.

If you use the performance counter, you may end up with drift, and there would probably be some problems with processors that alter their step-size for reduced power consumption (mostly laptops, but also some desktop CPUs, now)

The time() function, however, is related directly to real passing time and covers a larger range of values (it increments once a second and indicates the passing time since 1/1/1970)... it's more appropriate for what you're trying to do. Oh, and you don't need to query it every frame, maybe once every hundred frames or so, since it has per-second resolution.

Check out the rest of the time.h header for convenient helper functions and especially the localtime() function.

HTH

Share this post


Link to post
Share on other sites
Quote:
Original post by Halsafar
To simulate realism you often want a passing day. You however do not need a passing day to take a full 24hr's earth time. It is unlikely that a player would be satisied by that...


Probably best to use a Galactic Standard Week which breaks down to 1 earth hour.

Share this post


Link to post
Share on other sites
I need some further assistance now.
I am trying to alter a variable between 0.0f and 1.0f over a span of 24 game hours.

The variable alters the light in the sky. So obviously from hours 17-04 it should go down and from 04-17 it should go up.

I am racking my brain on coming up with a decent way to do this.
See it needs to be based off of what hour and minutes I pass in...

Maybe I am just having a bad sunday but every method I try and write to acomodate this ends up crashing into problems.

fPerHour = 1.0f / 24.0f;
fPerMinute = fPerHouse / 60.0f;

sunLight = fCurrentHouse * fPerHouse + fCurrentMinute * fPerMinute;

Share this post


Link to post
Share on other sites

if (fHour < fSunDownHour && fHour > 4.0f) {
m_fSunlightAmount = ((fHour * fPerHour) + (fMinutes * fPerMinute));
m_fSunsetAmount = ((fHour * fPerHour) + (fMinutes * fPerMinute));
} else {
m_fSunlightAmount = ((fSunDownHour * fPerHour) + (fMinutes * fPerMinute)) - ((abs((fHour-fSunDownHour)) * fPerHour) + (fMinutes * fPerMinute));
m_fSunsetAmount = ((fSunDownHour * fPerHour) + (fMinutes * fPerMinute)) - ((abs((fHour-fSunDownHour)) * fPerHour) + (fMinutes * fPerMinute));
}

Share this post


Link to post
Share on other sites
Have you considered maybe using the sine function, and offsetting it by the time of day you want the sun to come up? (also, you could add one and divide by two to get the values between [0.0 .. 1.0] )

e.g.

brightness = (sin(x - timeAtDawn) + 1)/2;


This would give realistic interpolation between light and dark, I think. Oh, you'll have to convert the hour value from [0 .. 23] to range from [0 .. 2pi] to get the value of x (and for figuring timeAtDawn)... but that should be as easy as scaling it (2pi/23).

Share this post


Link to post
Share on other sites
Is X the current time in milliseconds?
Thus time at dawn would be at 17:00, 17*60*60*1000 = ms at dawn.

I never thought of using sin for it...
Thats smart tho, it will allow for an up/down curve without any massive calculations and if.. statements.

Share this post


Link to post
Share on other sites
I am not quite understand how I would sin the time of day.
Sure, sin of any number between 0-90 will be between 0....1 and 90-180 will be 1...0 which is perfect, but what unit to I relay this to when using time of day.

Time of day, in what unit would I replace x with and timeOfDawn in the last reply.

Share this post


Link to post
Share on other sites
well, I was thinking that x would be the current number of hours, (not milliseconds) which you could get from the time() function I mentioned in my above post, after converting from seconds. Or, more conveniently, the tm->tm_hour value you get from localtime() (which automatically adjusts to the time zone of your computer).

Really, look at the time.h header that I mentioned before... it would make things much easier on you (and reduce a lot of unnecessary computation). Especially if you'd like to map it to "Real Time" ... Also, using a performance counter to gauge large-scale time is not recommended.

But yeah, you could use milliseconds; the scaling factor to convert to radians would be different, but still easy to compute. Good luck with your project.

Share this post


Link to post
Share on other sites
Yah, it works nicely, the only problem is the units.
I am just simply using the hour and minutes and it fades up and down nicely but way to fast. In a 24hr period it'll go up and down almost each hour.


m_fSunlightAmount = (sin((fHour*fPerHour + fMinutes*fPerMinute) + fSunDownHour) + 1)/2;

Share this post


Link to post
Share on other sites
Quote:

I am not quite understand how I would sin the time of day.
Sure, sin of any number between 0-90 will be between 0....1 and 90-180 will be 1...0 which is perfect, but what unit to I relay this to when using time of day.

oh, remember sin() and cos() take radians as input, not degrees. So, it would be the hours value between dawn = 0, then dusk = pi = 3.14159..., and dawn again at 2pi = 6.28318... Or, if you wanted time to progress faster, you could make an entire day pass each hour. Then, at x:00 would be dawn, x:15 could be high noon, x:30 could be dusk or twilight, x:45 could be midnight, then (x+1):00 would again be dawn.

You could really scale these however you want, to acheive the values for x and timeAtDawn. Just remember that the period of sine is 2pi and scale that to whatever period in hours/minutes that you want.

Share this post


Link to post
Share on other sites
Yes I was already doing that but your post helped me anyway, I was forgetting to scale the sundownhour appropriatly. She now works perfectly, well maybe not perfect... Still a little off.

//determine the per hour change
float fPerHour = 2*PI / 23.0f;
float fPerMinute = fPerHour / 60.0f;
float fSunDownHour = 17.0f * fPerHour;

m_fSunlightAmount = (sin((fHour*fPerHour + fMinutes*fPerMinute) + fSunDownHour) + 1)/2;
m_fSunsetAmount = (sin((fHour*fPerHour + fMinutes*fPerMinute) - fSunDownHour) + 1)/2;




This is a smart concept for the use of sin, I think you've taught me something I'll use again.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this