I think maybe I should briefly mention something (from my limited understanding) about the chrono library, so maybe other begginners in this section can benefit from it too so that my post/code is less obscure to them and not useful only to me. Also is to review my understanding of it since anyone can correct what I say.
Chrono library is a time library part of the STL, you just need to #include <chrono> in order to use it. Most of the code live inside namespace std::chrono:: .The library doesn't allow inplicit conversions of arithmetic types to durations therefore you can say "seconds MySeconds = 3;//Error" because "3 what?! 3 hours?"
It is mainly composed by 3 things: duration, time_point, clocks.
clocks: it has 3 of these, the system_clock which is basically a calender (has functions to convert a time point to a real date), like your Window time, the steady_clock which is basically a stopwatch in nanoseconds (at least on my machine, no idea if this can change) and is great for timing, and lastly the high_resolution_clock which just gives you back one of the other 2 (the one with the shortest tick period).
name_of_one_of_those_3_clocks::now() returns you the current time.
duration: this is a template class on o the form of duration<rap, ratio<num,den>>. It is used to store an arbitrary duration of time, some of the default durations defined in the library are seconds and milliseconds .
Rap is the internal rapresentation used to store the time, it is usually a long long but you can also pass a float or double to it if you want to have your operations on that duration return "fractions of a tick".
ratio<num,den> is a ratio made up of numerator and denominator used to allow for proper conversion between different duration, seconds default to ratio<1,1> and milliseconds is ratio<1,1000> , so that if you do:
//s is a literal representing seconds, declared with many others in std::literals::chrono_literals
//but you can just do "using namespace std::chrono;" and it will give you access to those as well
seconds MySeconds = 4s;
milliseconds MyMilliseconds = MySeconds;
//Because of the ratio thing, now MyMilliseconds contains the value 4000
also some default ratios like the one used by milliseconds are provided so that you can do std::milli instead of writing ratio<1,100>
So in my code in the reply above
static duration<uint32_t, std::ratio<1, GameUpdatesPerSec>> GameUpdateTPS{ 1 };
GameUpdatePerSec is set to 25 and my GameUpdateTPS contains just 1 of this duration, so that if you convert it to milliseconds or assign one of this to milliseconds you get 40ms , 1000ms/25 = 40ms.
time_point: this are different than duration because this is a duration from a point in time. You can't just assign a time_point to a duration.
If I have got it right, then:
time_point + time_point returns error
time_point - time_point returns duration
time_point + duration returns time_point
time_point - duration returns time_point
You can always get a duration out of a time_point by calling it's member function time_since_epoch()
Lastly, back to duration, no implicit conversion will happen between a "finer precision" duration and a "coarser precision" duration, so between ms and s for example because you would lose precision, but the implicit conversion will happen the other way around because it is safe to go from coarser to finer.
You can still use duration_cast<Put_To_duration_type_here>(MyTime) to force that "upward" conversion which will result in truncation of the value stored inside the duration.
And is pretty much the chrono library to my understanding 