It turns out game.time() wraps around to 0 after ~30¼ game days ((2³² - 1) - 1,679,936,192 game milliseconds). One option would be to convert the C++ struct returned by game.get_game_time() into seconds and use that in place of game.time() wherever sub-second precision is not required. The Lua built-in os.time function could be used for the conversion, albeit at the cost of sub-second rounding errors. Here is an example of how to implement that: 9919135. If millisecond precision were required, get_game_time_in_seconds() in the aforementioned commit could be modified to return a fractional os.time(time_table) + ms * 0.001, however saving it without losing precision might be tricky since the engine doesn't expose a double-precision floating point save method.
Saving a large u32 — like that returned by get_game_time_in_seconds() in the commit above, assuming not modified for fractional precision — as a float32 is a bad idea; we begin losing precision with odd numbers above 16,777,216 (2²⁴) and even numbers above 33,554,432 (2²⁵). That means we can only save up to ~194.18 days of seconds into a float32 before we begin seeing ±1 second rounding errors. Past ~388.36 days, these grow to ±2 seconds. If counting were to begin from the epoch (as in os.time), we'd already be way over the precision limit when the game starts at 06:10 2011/09/10, and our rounding errors would be immense (±64 seconds). Even if counting began from 2011/01/01 instead, we'd be up to 21,795,000 seconds when the game starts. We could hard-code the counting to begin at the vanilla game start time, but that could break mods that use a different start time. As there seems to be no way to access the game start time directly from Lua, my solution against game.time() precision loss in f4b5ce8 was to detect fractional numbers in xr_logic.pstor_save_all and save those as float32, else save as s32 or u32 yielding 2,147,483,647 (2³¹ - 1) or 4,294,967,295 (2³² - 1) seconds of wiggle room, respectively.
To save a fractional get_game_time_in_seconds() without precision loss would likely require saving the fractional part separately, perhaps as a u16.
It turns out
game.time()wraps around to 0 after ~30¼ game days ((2³² - 1) - 1,679,936,192 game milliseconds). One option would be to convert the C++ struct returned bygame.get_game_time()into seconds and use that in place ofgame.time()wherever sub-second precision is not required. The Lua built-inos.timefunction could be used for the conversion, albeit at the cost of sub-second rounding errors. Here is an example of how to implement that: 9919135. If millisecond precision were required,get_game_time_in_seconds()in the aforementioned commit could be modified to return a fractionalos.time(time_table) + ms * 0.001, however saving it without losing precision might be tricky since the engine doesn't expose a double-precision floating point save method.Saving a large u32 — like that returned by
get_game_time_in_seconds()in the commit above, assuming not modified for fractional precision — as a float32 is a bad idea; we begin losing precision with odd numbers above 16,777,216 (2²⁴) and even numbers above 33,554,432 (2²⁵). That means we can only save up to ~194.18 days of seconds into a float32 before we begin seeing ±1 second rounding errors. Past ~388.36 days, these grow to ±2 seconds. If counting were to begin from the epoch (as inos.time), we'd already be way over the precision limit when the game starts at 06:10 2011/09/10, and our rounding errors would be immense (±64 seconds). Even if counting began from 2011/01/01 instead, we'd be up to 21,795,000 seconds when the game starts. We could hard-code the counting to begin at the vanilla game start time, but that could break mods that use a different start time. As there seems to be no way to access the game start time directly from Lua, my solution againstgame.time()precision loss in f4b5ce8 was to detect fractional numbers inxr_logic.pstor_save_alland save those as float32, else save as s32 or u32 yielding 2,147,483,647 (2³¹ - 1) or 4,294,967,295 (2³² - 1) seconds of wiggle room, respectively.To save a fractional
get_game_time_in_seconds()without precision loss would likely require saving the fractional part separately, perhaps as a u16.