# How can I make a reliable time-based object updating system?

So an object has a position, velocity, and is affected by gravity.

#include <simd/simd.h> // MacOS
struct Object {
vector_float3 Translation; // Units
vector_float3 Velocity; // Units per second
};


The game loop typically runs 60 times per second.

void ObjectUpdate(struct Object *obj) {
obj->Velocity.y -= 9.80655/60;
obj->Translation += obj->Velocity/60;
}


There are a couple problems with this approach:

• Lag exists, so the assumption of 60 updates per second being embedded in the code is not great.
• Floating point types are susceptible to precision errors at far distances from the origin, and are also more difficult to handle in some ways than integers.

I attempted to solve these with a fixed-point approach, and the use of clock() as well as keeping track of the time of the last update.

struct Object {
vector_long3 Translation; // 65536ths of a unit
vector_long3 Velocity; // 65536ths of a unit per second
clock_t LastUpdate;
};
void UpdateObject(struct Object *obj) {
const clock_t current = clock();
const unsigned long delta = (unsigned long)((current-obj->LastUpdate)*(clock_t)65536/CLOCKS_PER_SEC); // Try to find the number of 65536ths of a second since the last update, in a way that it does not matter whether clock_t is integral or real
obj->LastUpdate = current;
obj->Velocity.y -= delta*642682>>16; // 642682 = 9.80655*65536
obj->Translation -= delta*obj->Velocity>>16;
}


However, this suffers from other problems, most notably, being extremely chunky and unreliable. If I simply add delta to an accumulator and then print the accumulator, the value rises at an inconsistent rate, typically much slower than by 65536 per second.

How should I handle objects that need 'constant' updating and their updates are contingent on time?

• Safe to assume you've read Fix Your Timestep? A fixed timestep update is the usual solution to systems that need exact consistency. Mar 26 at 1:20

The problem was that clock() measures CPU time and not absolute time. Using clock_gettime() with CLOCK_MONOTONIC instead of clock() should solve the problem. The code will have to be updated to use struct timespec instead of clock_t like so:

struct Object {
vector_long3 location; // 65536ths of a unit
vector_long3 velocity; // 65536ths of a unit per second
long last_update;
};
void Object_update(struct Object *obj) {
struct timespec t;
if (clock_gettime(CLOCK_MONOTONIC, &t))
abort();
const long current = t.tv_sec<<16|t.tv_nsec>>16, delta = current-obj->last_update;
obj->last_update = current;
obj->velocity.y -= delta*642682>>16; // 642682 = 9.80655*65536
obj->location -= delta*obj->velocity>>16;
}