Making a Minute-Accurate In-Game Clock

edited July 2019 in Mechanic's Corner
Goal: Make a clock for my Mudlet UI that is accurate to the minute, rather than the "about half past..." times that the pocket watch provides: https://imgur.com/a/qibswoz

Data: The gmcp.IRE.Time module provides a "daynight" variable that gets sent to the Nexus client to tell it which graphic to show to illustrate the time of day. The variable starts at 0 at 5AM (in-game time), and counts up to 200 before turning over again. It mostly counts in multiples of three, but sometimes multiples of four.

From this we can gather that:
  • In an RL day, 1 second IRL = 0.0023148 in-game time units, and 432 IRL seconds = 1 in-game time units. This is used to convert the in-game time units to a number that lua's os.date function can turn into a time to display. We add 39600 to this because the in-game clock (according to the "daynight" variable) starts at 5AM
  • Going by an in-game day, 1 second IRL = 0.05 in-game time units. This is used to manually increment the game time since the "daynight" variable only counts in threes, that way we can still get accurate times in between "daynight" increments.
24h = 200tu
1h = 8.333tu
1m = 0.1388tu
1s = 0.0023148tu

86,4000s = 200tu
432s = 1tu

60m = 200tu
1m = 3.33tu
1s = 0.05tu
So using this data we can figure out what the equivalent RL time would be, based on the "daynight" variable.

Code: This runs every second on a timer:
--Get gmcp time data and grab the "daynight" variable
sendGMCP("IRE.Time.Request")
listTime = gmcp.IRE.Time.List.daynight

--If "daynight" has changed since the last time we checked, then use it to set the time by calculating how
--far into a RL day we are, multiplying "daynight" by 432 and adding 39600 to account for starting at 5AM.
--Then, store the current "daynight" value to check against later
if listTime ~= oldTime then
	gameTOD = (os.date("%I:%M %p",(listTime * 432) + 39600))
	oldTime = listTime
	timedifference = 0

--If "daynight" has not changed, then we need to increment the clock manually. Since the timer runs every
--second, we need to increment by 0.05.
else 
	timeDifference = timeDifference + 0.05
	gameTOD = (os.date("%I:%M %p",((listTime + timeDifference) * 432) + 39600))
end

Problem: What results is a clock that accurately tells time at 5AM(of course) and within a couple hours either side of that, but that gets more inaccurate throughout the day. For instance, this clock will say "12:20" while the in-game pocket watches says "About half past one", and will stay that way until my clock catches up, then jump ahead to "2 o'clock." When in-game midnight comes, my clock still says anywhere from "11:22" to "11:44" or thereabouts.

So it seems like the relation between the "daynight" variable, actual in-game time, and the time shown on the pocket watch isn't nearly so clear cut, and it even seems like the time of midnight in relation to the "daynight" variable may change.

Does anyone have any idea how "daynight," in-game time, and pocket watches relate, or how the time system works in general? Does midnight change?

@Orael if you could find the time to chime in.

Thanks!

Comments

  • edited July 2019
    A few things:

    the daynight variable is a 60 second number (every 60 seconds you get one). The problem comes from this value doesn't update as it happens but as per prompt. So you can get more than one at once if you have standing around. The second issue comes in there are some times that have 2 daynight values. (530a, 730, 930, 1130, 130p, 330, 530, 730, 930, 1130, 130a, 330). Every daynight value is a change in time (unless it is one of those double half hours)
    Another problem is that a day should be 3600 seconds long, but its not, so the day can be under or over 3600 seconds. (I suspect this is being from the timer being used for the day has a day being milliseconds under an hour.

  • Ayisdra said:
    A few things:

    the daynight variable is a 60 second number (every 60 seconds you get one). The problem comes from this value doesn't update as it happens but as per prompt. So you can get more than one at once if you have standing around. The second issue comes in there are some times that have 2 daynight values. (530a, 730, 930, 1130, 130p, 330, 530, 730, 930, 1130, 130a, 330). Every daynight value is a change in time (unless it is one of those double half hours)
    Another problem is that a day should be 3600 seconds long, but its not, so the day can be under or over 3600 seconds. (I suspect this is being from the timer being used for the day has a day being milliseconds under an hour.

    How do you recommend approaching the problem or dealing with those issues?
  • You can start your own 3600 second timer and then check (and correct as needed) the clock every so often (day change at least or the last daynight value you get).  This might be the easiest way rather than relaying on Time.Update or sending a request for the time every minute.

    One thing I didn't see in your post the first time, There is a gmcp Time.Update which sends daynight every time it changes (but it doesn't actually send it it as it updates, but sends all the updates at once per prompt. This is where I said you could get more daynight updates per prompt). That's probably going to the best way of dealing with it with how the Time.Update works. I have asked Time.Update to work more properly (sending daynight updates as they happen rather than grouping them, adding in day/month changes, etc), but it is low on the list obviously.
  • edited August 2019
    Wrong thread!
    I'm Lucidian. If I don't get pedantic every so often, I might explode.
Sign In or Register to comment.