Page 1 of 1

Time Limiter

Posted: Sat Jun 06, 2020 3:12 am
by TopherGopher
I'm a little nervous about posting this, as it seems to touch on an inflammatory topic, but after reading the documentation I could find, I need a little guidance. Please be gentle?

I'm attempting to create a mod for myself that simply alerts me on or around a pre-defined time duration. eg after two hours, my game informs me I should take a break / log off / etc. I tend to be bad at time management once the game boots up, but a flashing custom alert until I log off would be something that would nag me while still maintaining the in-game experience.

on_player_joined_game they get a start_time stored on their player, then (I figure) to make the mod light, I just subscribe to user input events - e.g. on_player_respawned, on_player_removed_equipment, on_player_placed_equipment - where when a user is actively clicking something, then I get player by index and if they have the "timelimit" user setting, then I'd check the elapsed time since they started. But time, in and of itself, is where life gets interesting in factorio.

The system clock is not exposed through the native Factorio API because it can cause desyncs in a deterministic architecture, makes sense why you would do that. So a few questions about desyncs:
  • My first question - how are desyncs detected? Is a checksum of my local variable cache essentially compared to a checksum of the server variable cache?
  • Does the desync occur just from making the call to os.time() or is it when I go to store that variable somewhere that things get wonky? (I don't even know if I can call os.time() - is the os library allowed?)
  • Are there any variable locations that don't get compared by the server? A local cache map maybe?
  • I think that the server effectively pauses the game and stops the ticks when saving, so is that a better time to perform this kind of check?
If there is no unique local cache (and I suspect there's not), I've done some research and I've been thinking of three potential workarounds:

1) There is an old (but super cool looking) mod that runs a script locally to essentially allow the game to query the system time - Stone Realtime Clock - this seems clunky and like it wouldn't scale well

2) Use "socket" to make a call to an NTP server kinda like this - the question is, will all the players make and complete the call at the same time when fed the same event hook? (Is socket allowed?) Then I would essentially remove the precision from that and use the elapsed minutes value rather than the elapsed seconds value to help do a little time smearing.

3) There's a mod out there called playtime, which essentially displays the amount of time that you've been playing the game. I thought I could build on this, but when I looked at the code underneath, it's based around ticks where 1 tick is assumed to be a second. He explicitly warns in his code that you can't rely on this, but really - how far off are we talking? Is it usually* 60 ticks to a second, but sometimes you have to drop a tick to catch up? Or do some systems just run at consistently different tick rates all the time as opposed to fluctuating? On average - are players typically* getting 60 ticks / sec?

Some relevant references I've been reading (if you can call reddit a 'reference'): I do realize Amazon has watches available for purchase :-), I was just looking for a way to make the game itself nag me. I tend to set an alarm and dismiss it thinking I'll just give myself 5 more minutes, but I'm still playing hours later. An in-game alert though that flashes down next to my logistic errors? Ooo baby.

Re: Time Limiter

Posted: Sat Jun 06, 2020 4:35 am
by Impatient
A factorio second has 60 factorio ticks. Always. Unless you run a factorio game that weighs heavy on your CPU computing power, one factorio second is equally as long as a real time second. ( https://wiki.factorio.com/Time ).
So performing a check if game.tick ( https://lua-api.factorio.com/latest/Lua ... cript.tick ) is equal or larger, than the tick you caculated to be at the end of your timespan, in any eventhandler, should serve you just fine.

You are right though, that in case you run a megabase map or heavily modded map the updates per second (ticks per second) can drop below 60 and thus the in game time will pass slower than the real world time.

You can activate the ups display via the debug options to see if and when that happens.

The lua doc says it has a time function. Maybe that fully serves your demand? ( I just read here https://lua-api.factorio.com/latest/Libraries.html that lua's os library, which also contains the time functions, as far as I understand, is not available to factorio scripts.