what are these sync'd with? i'm finding the timestamps look like the results from time() but they're offset (typically the timestamps are "larger" -- meaning they're f'ing up my mod logic because the two are not sync'd).
so what's the mechanism for dealing with this? if i'm not going to use time() what function gives me the correct basis for using these timestamps?
do i have to deduce the offset in some method and then correct for it?
The timestamp parameter has almost the same format as the return value of the time() function. You can use it as the second parameter to date(). The only difference is that time() returns an integer (the unit is seconds), while the timestamp parameter has three decimal places (milliseconds). That means (timestamp-floor(timestamp))*1000 is the number of milliseconds of the timestamp.
Sorry, I can't really test now, maybe you could provide a set of timestamps for us?
the combat log timestamps are based on your clock. if you change you clock, they'll change like time() does. BUT if you change your clock during your wow session, time() will respect the change but the timestamps from the combat log won't. this makes me think that they're actually reconstructed using the current up time clock (hence the millisecond precision) and at some point there must be some kind of coordination between the two clocks in the wow initialization code.
i've had my timestamps indicate that events will be happening almost a minute late and then other times only like 20 seconds. but so far, in very, very limited testing they're always late so i can account for it by checking for any case where the timestamp is greater than the current time and using that as a fudge factor. but still, this doesn't seem right.
the api says that the timestamps are the same FORMAT but not that they're sync'd with time().
Have you compared the timestamps with GetTime() return values?
i'm guessing that the timestamps are based on GetTime() with a fixed offset since local clock changes don't affect them once the client has started. i suppose GetTime() might be a better basis for things now that i think of it since it's got better precision than time() does. maybe that was the thinking behind not sync'ing up timestamps with time().
it would be nice if there was an api call to access what the offset is so you can be accurate. as it stands the only way i can think to work it is to check timestamps, compensate for any offset and see if the timestamp is "in the future" and if it is, increase my offset to compensate. prolly good enough, but kind of kooky.
okay, i guess the obvious solution is to ignore the timestamps entirely and just consider the moment i get the damage event to be the time it happens and then just use GetTime() for everything. this is purely a dps meter, so it's not like super critical to have ultra exact info. probably would have figured that out sooner if the timestamp didn't exist...
okay, i guess the obvious solution is to ignore the timestamps entirely and just consider the moment i get the damage event to be the time it happens and then just use GetTime() for everything. this is purely a dps meter, so it's not like super critical to have ultra exact info. probably would have figured that out sooner if the timestamp didn't exist...
Well, if it's a fixed offset you are better off just getting it once and adding it to the stamp, though if it's a clock drift... GetTime() won't help you since that's where it comes from most likely
I still don't understand what problem specifically you are looking to solve.
the combat log events contain a timestamp of when the event actually occurred. i was trying to use them for a dps meter. basically, checking the age of the event and tossing it out after a set number of seconds, but having a hard time finding the age of the event.
i'm going to just ignore the timestamp now and instead just use the time the client gets the event and call it good enough.
Well, if it's a fixed offset you are better off just getting it once and adding it to the stamp, though if it's a clock drift... GetTime() won't help you since that's where it comes from most likely
it's not a clock drift, it's simply a fixed (unknown) offset. recording GetTime() when i get the event will mean i just need to GetTime() at any point to determine the age of that event. right now, i use time() and an offset to figure out the age based on the recorded timestamp... which is more effort than necessary.
The timestamp from the event should be close to the result from time() because the value is passed into the date() function as the second argument. The value will not be exactly equal to time() because it has fractions of a second precision while time() does not. If the difference between the timestamp and time() is more than a second then the timestamp is probably from the server.
If the timestamp and the return from time() are off by a large number then your system clock and timezone are misconfigured. time() is a UNIX epoch and has no concept of a timezone or daylight savings, it is the same everywhere during an exact timepoint. It is represented as a logical local time by using the systems timezone setting.
my timestamps were a large number of seconds offset from the current time -- like 20-60. it seemed pretty consistent during the course of a wow session such that reloads didn't change the offset. logging out and logging back in did change the offset.
i believe the timestamp is the official time that the event was recorded on the server, but put into a logically consistent time-frame for the client by offsetting the the value to be appropriate for the date() function. from what i can deduce, the offset used is calculated once when you log in. i have no idea why the difference would be so large other than maybe the sync is using only hours and minutes.
i know the values are not strictly server time because i altered my clock between wow sessions and the timestamps changed accordingly (i shifted by a few minutes only). i also know the value isn't dynamic because i shifted my clock back to normal with the client running and the timestamps retained their offset value (but time() calls reacted to the newly correct clock).
i can only figure the timestamps are meant to be consistent compared to each other, but not necessarily sync'd against anything else.
the combat log events contain a timestamp of when the event actually occurred. i was trying to use them for a dps meter. basically, checking the age of the event and tossing it out after a set number of seconds, but having a hard time finding the age of the event.
i'm going to just ignore the timestamp now and instead just use the time the client gets the event and call it good enough.
Why not just use timestamps if that's what you want to do.
Algorithm like this:
Store time stamp t in list.
Check if any element t_old in list t-t_old > toss_threshold, then toss element.
You can also use client time, same algorithm... Requires one more API call in the latter case. That's why I'm confused about the discussion. I don't see why one would even have to mix timpstamps from the CL and client-side times at all.
Why not just use timestamps if that's what you want to do.
Algorithm like this:
Store time stamp t in list.
Check if any element t_old in list t-t_old > toss_threshold, then toss element.
You can also use client time, same algorithm... Requires one more API call in the latter case. That's why I'm confused about the discussion. I don't see why one would even have to mix timpstamps from the CL and client-side times at all.
hmm... not sure i follow how that would work.
how do i know when "now" is? i'd have to rely on a steady stream of combat events to behave as a clock.
right now i'm recording combat events and then using an onupdate script to periodically cull the ones that have "expired" (trying different values, but probably a few times a second).
my basic logic is this:
incoming damage event gets recorded with time it happened and the amount of damage
every .25 seconds, i check the list of events that have been recorded and see if any are older than 5 seconds. if so, they are removed and the dps value is adjusted.
I think it would be an interesting exercise to try to find a combat log situation where DPS has any meaning where you get no combat log events (remember there are loads happening, such as buffs expiring and such) that have nothing to do with damage.
I'm pretty confident that you can get away without an OnUpdate timer. Or rather just one that flushes if indeed the combat log is silent.
Here is how that would work. Use the algorithm above and just add the following to OnUpdate:
waittime = waittime + elapsed
if waittime >
toss_threshold then tossall() end
and in your combat log event handler you simple do waittime = 0 if you got any event at all.
Yes elapsed can drift, but you are talking just tossing idle timestamps that no longer update and you are talking only a few seconds and drift over such short periods is minimal if practically non-existant.
In any case, this is a rather clean way of doing this and requires no API calls at all for timing.
If you wanna go fancy shamcy you can instead of having one waittime to detect an idle combat log, you can have one waittime per stored timestamp and expire them that way. Sounds overkill to me simply because in all situations that DPS actually matters the CL is very busy so the OnUpdate will do nothing but loop over a large list to never actually return true.
In short use OnUpdate only to detect that the CL is idle and flush the list. This will work swell and has no timer issues really.
I think it would be an interesting exercise to try to find a combat log situation where DPS has any meaning where you get no combat log events (remember there are loads happening, such as buffs expiring and such) that have nothing to do with damage.
I'm pretty confident that you can get away without an OnUpdate timer. Or rather just one that flushes if indeed the combat log is silent.
Here is how that would work. Use the algorithm above and just add the following to OnUpdate:
waittime = waittime + elapsed
if waittime >
toss_threshold then tossall() end
and in your combat log event handler you simple do waittime = 0 if you got any event at all.
Yes elapsed can drift, but you are talking just tossing idle timestamps that no longer update and you are talking only a few seconds and drift over such short periods is minimal if practically non-existant.
In any case, this is a rather clean way of doing this and requires no API calls at all for timing.
If you wanna go fancy shamcy you can instead of having one waittime to detect an idle combat log, you can have one waittime per stored timestamp and expire them that way. Sounds overkill to me simply because in all situations that DPS actually matters the CL is very busy so the OnUpdate will do nothing but loop over a large list to never actually return true.
In short use OnUpdate only to detect that the CL is idle and flush the list. This will work swell and has no timer issues really.
yeah, you make some good points. a little more about my particular case:
i'm storing dps per target -- that is, how much damage each target is taking. my algorithm is simply how much total damage over the last X seconds divided by X.
the way i'm doing this is to record events for each target in a separate table. this is trivial when storing data, but less so when clearing old events. if i iterate over all the player tables each combat event, i'd likely run into performance issues whereas using an update script i would only iterate over the player tables only a few times a second.
seems like just bailing on the timestamps and using the GetTime() function would simplify things, unless GetTime() would cause its own performance problem. is it a slow function?
Basically GetTime() is expensive enough to worry about it within OnUpdate.
Really given that you get elapsed in OnUpdate and that the time intervals you are looking at are reasonably short, there is no good reason to use GetTime() or other API calls at all.
You can do this without using time stamps and without using GetTime, just using the elapsed parameter of OnUpdate.
When a CL event that is damage relevant happens, add it to a table with a retaintime = 0. Then in onupdate add elapsed to retaintime and prune when threshold is exceeded.
Yes there is an issue with timing not being 100% because of the slack between the CL event and the next onupdate, but think about it. You have the same effect anyway even if you do use GetTime, because have to wait for the next OnUpdate to do your check anyway, so timing with OnUpdate (no matter if using GetTime, or elapsed) is only accurate up to frame rate if you compare to a time intervale-exceed threshold.
What you want to do should be reasonably efficient. The CL fires like crazy in 25 man raids during peak damage dealing and addons lean heavily on OnUpdates already to keep their buffs updated, threat bars rendered etc. Really one can do this without GetTime() and given that it costs you one really should do without.
As a side, why don't you consider an "activity based" timing for your DPS formula? Those are easier to implement and easier on computation (no table pruning) than sliding windows. Another alternative is local means. You just take 3 (or whatever fixed number you are comfortable with) damage events and their respective time intervals and take that as DPS formula. Because the window size is static this is very efficient to implement. The last proposal requires no OnUpdate use at all, which is really nifty and can be implemented with a circular buffer very elegantly.
Trading an OnUpdate for a CLEU may be a bad thing if you are wanting to do it because you think OnUpdates are costly. CLEU fires more often than OnUpdate in some situations. Both of them must be carefully optimized to avoid performance costs.
Rollback Post to RevisionRollBack
To post a comment, please login or register a new account.
so what's the mechanism for dealing with this? if i'm not going to use time() what function gives me the correct basis for using these timestamps?
do i have to deduce the offset in some method and then correct for it?
Sorry, I can't really test now, maybe you could provide a set of timestamps for us?
i've had my timestamps indicate that events will be happening almost a minute late and then other times only like 20 seconds. but so far, in very, very limited testing they're always late so i can account for it by checking for any case where the timestamp is greater than the current time and using that as a fudge factor. but still, this doesn't seem right.
the api says that the timestamps are the same FORMAT but not that they're sync'd with time().
i'm guessing that the timestamps are based on GetTime() with a fixed offset since local clock changes don't affect them once the client has started. i suppose GetTime() might be a better basis for things now that i think of it since it's got better precision than time() does. maybe that was the thinking behind not sync'ing up timestamps with time().
it would be nice if there was an api call to access what the offset is so you can be accurate. as it stands the only way i can think to work it is to check timestamps, compensate for any offset and see if the timestamp is "in the future" and if it is, increase my offset to compensate. prolly good enough, but kind of kooky.
Well, if it's a fixed offset you are better off just getting it once and adding it to the stamp, though if it's a clock drift... GetTime() won't help you since that's where it comes from most likely
the combat log events contain a timestamp of when the event actually occurred. i was trying to use them for a dps meter. basically, checking the age of the event and tossing it out after a set number of seconds, but having a hard time finding the age of the event.
i'm going to just ignore the timestamp now and instead just use the time the client gets the event and call it good enough.
it's not a clock drift, it's simply a fixed (unknown) offset. recording GetTime() when i get the event will mean i just need to GetTime() at any point to determine the age of that event. right now, i use time() and an offset to figure out the age based on the recorded timestamp... which is more effort than necessary.
If the timestamp and the return from time() are off by a large number then your system clock and timezone are misconfigured. time() is a UNIX epoch and has no concept of a timezone or daylight savings, it is the same everywhere during an exact timepoint. It is represented as a logical local time by using the systems timezone setting.
i believe the timestamp is the official time that the event was recorded on the server, but put into a logically consistent time-frame for the client by offsetting the the value to be appropriate for the date() function. from what i can deduce, the offset used is calculated once when you log in. i have no idea why the difference would be so large other than maybe the sync is using only hours and minutes.
i know the values are not strictly server time because i altered my clock between wow sessions and the timestamps changed accordingly (i shifted by a few minutes only). i also know the value isn't dynamic because i shifted my clock back to normal with the client running and the timestamps retained their offset value (but time() calls reacted to the newly correct clock).
i can only figure the timestamps are meant to be consistent compared to each other, but not necessarily sync'd against anything else.
it was constantly +1 minute compared to time() in my case, while the server time was -1 minute (compared to time())
Why not just use timestamps if that's what you want to do.
Algorithm like this:
You can also use client time, same algorithm... Requires one more API call in the latter case. That's why I'm confused about the discussion. I don't see why one would even have to mix timpstamps from the CL and client-side times at all.
hmm... not sure i follow how that would work.
how do i know when "now" is? i'd have to rely on a steady stream of combat events to behave as a clock.
right now i'm recording combat events and then using an onupdate script to periodically cull the ones that have "expired" (trying different values, but probably a few times a second).
my basic logic is this:
incoming damage event gets recorded with time it happened and the amount of damage
every .25 seconds, i check the list of events that have been recorded and see if any are older than 5 seconds. if so, they are removed and the dps value is adjusted.
i don't see how i can avoid the onupdate script.
I'm pretty confident that you can get away without an OnUpdate timer. Or rather just one that flushes if indeed the combat log is silent.
Here is how that would work. Use the algorithm above and just add the following to OnUpdate:
and in your combat log event handler you simple do waittime = 0 if you got any event at all.
Yes elapsed can drift, but you are talking just tossing idle timestamps that no longer update and you are talking only a few seconds and drift over such short periods is minimal if practically non-existant.
In any case, this is a rather clean way of doing this and requires no API calls at all for timing.
If you wanna go fancy shamcy you can instead of having one waittime to detect an idle combat log, you can have one waittime per stored timestamp and expire them that way. Sounds overkill to me simply because in all situations that DPS actually matters the CL is very busy so the OnUpdate will do nothing but loop over a large list to never actually return true.
In short use OnUpdate only to detect that the CL is idle and flush the list. This will work swell and has no timer issues really.
yeah, you make some good points. a little more about my particular case:
i'm storing dps per target -- that is, how much damage each target is taking. my algorithm is simply how much total damage over the last X seconds divided by X.
the way i'm doing this is to record events for each target in a separate table. this is trivial when storing data, but less so when clearing old events. if i iterate over all the player tables each combat event, i'd likely run into performance issues whereas using an update script i would only iterate over the player tables only a few times a second.
seems like just bailing on the timestamps and using the GetTime() function would simplify things, unless GetTime() would cause its own performance problem. is it a slow function?
Basically GetTime() is expensive enough to worry about it within OnUpdate.
Really given that you get elapsed in OnUpdate and that the time intervals you are looking at are reasonably short, there is no good reason to use GetTime() or other API calls at all.
You can do this without using time stamps and without using GetTime, just using the elapsed parameter of OnUpdate.
When a CL event that is damage relevant happens, add it to a table with a retaintime = 0. Then in onupdate add elapsed to retaintime and prune when threshold is exceeded.
Yes there is an issue with timing not being 100% because of the slack between the CL event and the next onupdate, but think about it. You have the same effect anyway even if you do use GetTime, because have to wait for the next OnUpdate to do your check anyway, so timing with OnUpdate (no matter if using GetTime, or elapsed) is only accurate up to frame rate if you compare to a time intervale-exceed threshold.
What you want to do should be reasonably efficient. The CL fires like crazy in 25 man raids during peak damage dealing and addons lean heavily on OnUpdates already to keep their buffs updated, threat bars rendered etc. Really one can do this without GetTime() and given that it costs you one really should do without.
As a side, why don't you consider an "activity based" timing for your DPS formula? Those are easier to implement and easier on computation (no table pruning) than sliding windows. Another alternative is local means. You just take 3 (or whatever fixed number you are comfortable with) damage events and their respective time intervals and take that as DPS formula. Because the window size is static this is very efficient to implement. The last proposal requires no OnUpdate use at all, which is really nifty and can be implemented with a circular buffer very elegantly.