Best Way of recreating 'Server Ticks' for a Fighting game?

In short, I’m trying to think of the best way to implant the closest thing to ‘Frames’ for a fighting game. The purpose is to achieve two goals-

  • When an input is delivered, it’s sent alongside an os:time() stamp that’s used to calculate a ‘minimum’ ping, to ensure players within the reasonable range of ping (0-200ms) are not at any disadvantage.

  • Moves should be able to ‘clank’ with each other. Instead of it more or less being random, if two attacks cross at the same time, they resolve in a special case, either a double-hit or both moves cancelling each other out.

The problem is that there’s no way to guarantee any length of time. All documentation shows that server-sided Heartbeat is inconsistent, and I can’t find any information about how reliable task.wait() is. And while the actual move-data may lag with the server, animations will not, creating some nasty de-sync.

Is this even a solvable problem, or will I have to compromise in some other way?

You could increment a value each time the deltatime returned by Heartbeat is above a certain threshhold like here:

local deltatime = game:GetService("RunService").Heartbeat
local SERVER_TICK_RATE = 60 -- ticks per second. 60 is probably the highest possible.
local min_time_between_ticks = 1 / SERVER_TICK_RATE


local function Update()
	while true do
		timer += deltatime:Wait()
		while timer >= min_time_between_ticks do -- This line here is what ensures that heartbeat is consistant.
			timer -= min_time_between_ticks
			currenttick.Value += 1 
		end
	end
end