upvote
I think it's more the patching thing that made "collect and replay inputs" less common.

Networked games have a "tickrate", just for the networking/state aspect. For example, Counter-Strike 2 has a 64Hz tickrate by default. They also typically have a fixed time interval for physics engines. Both of these should be completely independent of framerate, because that's jittery and unpredictable.

reply
Quake 1 ran game logic and model animation at 10 ticks per second (a reasonable choice when PCs running Quake at 20fps were impressive).

Camera and linear motion of objects were interpolated to the framerate.

reply
Fun fact, overwatch must have done a similar things because they would let you play back games up until some release when you could no longer replay them unless you'd saved the render.

I think if I remember right there were also funny moments where things didn't look right after patches?

reply
Overwatch also has “kill cams”, which basically create an entire alternate game state to show you how the enemy killed you, and they have the “Play of the Game” system that replays the coolest moment of the game at the end. It’s impressive tech.
reply
You don't need to tun the whole game at a fixed framerate, only the physics. That's actually common practice.

The bigger problem is that floating point math isn't deterministic. So replays need to save key frames to avoid drift.

Quake used fixed point math.

reply
Quake needs a FPU; if that was true it would run on a 486 SX.
reply
You're right, I must have gotten that mixed up. Sorry.

I guess floats are still mostly deterministic if you use the exact same machine code on every PC.

reply
One of the hardest determinism bugs I had to solve on the PlayStation three was that the PPU and the SPU actually used a different instruction set and had a different internal floating point register size. We had a multi threaded physics simulation, and during instant replay, we had to ensure that the job scheduler sent the exact same work to the correct cores or we got back subtly different floating point values, which of course, immediately caused major divergences.
reply
> I guess floats are still mostly deterministic if you use the exact same machine code on every PC.

Nope, they are not. Part of the problem is that "mostly deterministic" is a synonym for "non-deterministic".

reply
Floating-point non-determinism issues usually come from one of these sources:

- Inconsistent use of floating-point precision, which can arise surprisingly easily if e.g. you had optional hardware acceleration support, but didn't truncate the intermediate results after every operation to match the smaller precision of the software version and other platforms.

- Treating floating-point arithmetic as associative, whether at the compiler level, the network level, or even the code level. Common violations here include: changing compiler optimization flags between versions (or similar effects from compiler bugs/changes), not annotating network messages or individual events with strictly consistent sequence numbers, and assuming it's safe to "batch" or "accumulate" deltas before applying them.

- Relying on hardware-accelerated trigonometric etc. functions, which are implemented slightly differently from FPU to FPU, since these, unlike basic arithmetic, are not strictly specified by IEEE. There are many reasons for them to vary, too, like: which argument ranges should be closest to correct, should a lookup table be used to save time or avoided to save space, after how many approximation iterations should the computation stop, etc.

reply