Timer system on server

If I have a timer system that starts on the client, fires an event to take it to the server, and the server calculates the time, then sends it back to the client, how would I display this time to the client as the timer is running? The reason I’m doing it on the server is to prevent exploits.

1 Like

Rule 1. Never trust the client.
What exactly are you trying to do with the timer? Do you want to compare the timers of the two?

Why the client though? Any exploiter could just remove the client script and your script would be useless, it’s best to just handle everything on the server.

If you had a text label you could make it count down with a for-loop?

local textLabel = script.Parent

game:GetService("ReplicatedStorage").TimerEvent.OnClientEvent:Connect(function(t)
    textLabel.Visible = true

	for i = t, 0, -1 do
		textLabel.Text = i
        task.wait(1)
	end
end)

(local script parented to a text label)
*Forgot the wait()

1 Like

It looks like they’re being given a copy of the timer but do not have control over what it’s for, the server is running its own version.

Well Im trying to make a speedrun sort of thing where the player can have a timer to beat a certain level, and it saves that time and also displays the time on the client while the time is being calculated. How would I display the time on the client if its being handled on the server. Also the player can toggle speedrun mode on or off, and can pick a certain level. I also need to send the level they chose to the server so I can stop the timer when the player hits the endpoint(the endpoints are handled on the server).

That fixes my issue, however Im still confused on what to do with the exploit stuff, I don’t really know too much about it.

Don’t let the player do any logic with this timer, it should be for visual representation only. Have the server running a duplicate timer itself, and let it perform the logic.
For your speedrun application it sounds like you should have the client send a “finished” remote event to the server when they beat the level, and have the server stop the timer and save how much time was remaining for statistics.

I think I understand what you want. So to start the run, say if the player touches a block, the server detects the touch, who touched it, then you can have the server run a timer within the script. When the server detects the touch, it should also send information to the player, using a RemoteEvent, to start a timer for how long. When the player finishes, the course, the server detects the touch and stops the timer, also telling the client to stop its timer. (I suggest sending the client what the server’s finish time is, as there’s always a short delay between RemoteEvents).

Now regarding exploit, I take it the biggest issue will be running over the max speed or flying. For that, you could theoretically have the server check the player’s head or primarypart’s position and compare it from the last position. You can use .magnitude to do this.

1 Like

Or the client can stop it itself as the client has no impact on the actual time.

Well, the endpoints are handled on the server, so the client doesn’t know when the level is finished. Also, I’m not really even entirely sure what you’re saying, if you’re saying that I should only use the client to send when the level is finished, and nothing else, how would the server know when to start the level.

The overall architecture of your game is up to you, but any solution will have risk of exploiters since the core gameplay is where the players’ character is, something they have control over.

You’re right the event wouldn’t be a good idea with your current plan. Perhaps like @1Minecraft0954 said, use .Touched events to determine the beginning/end using parts in workspace.

The biggest thing you can do for exploiters is sanity check everything they do. They shouldn’t have impossible magnitude, positions, finish times etc.

2 Likes

Well would it be possible to just do what I currently have(client tells server to start timer with level information, server starts timer and shows client, server sends end time to client) and just sanity check it?

I think that should also work, as long as the client can’t rig the end results. The most important thing would be to have the server control the timer; if that’s what you’re doing I don’t see an issue with it (I’m happy to be correct if I’m wrong).

Along with sanity checks, although completely up to you, if I were to make the same type of game, I would have an absolute minimum time. Say if your fastest run is 25 seconds, depending on how perfect your run was, the server can dismiss any time that is shorter than 23 seconds or whatnot. That way, if all your sanity checks fail, an exploiter cannot physically get a time of 257 milliseconds, but 23 seconds and hopefully that’s enough to deter most exploiters from exploiting everything all at once.

1 Like

Do you have any idea of how I should sanity check them though, I’ve never really dealt with exploit stuff before. Also the minimum time thing might help but if the exploiter finds out what that time is, and everything else fails then since I’m going to be adding leaderboards for these times later on, they would probably be at the top so I want to make everything else as secure as possible

Unfortunately, exploiters will probably dominate leaderboards even with sanity checks. Even without a cheat menu someone could still write macros to automate your levels, with enough patience.

2 Likes

Well as long as they can’t modify something in script to directly change their time I think i’ll be fine, I doubt anyone would do that for my game.

The more complicated the better! (and harder).
So using magnitude, you could do something like

(just for example)

local A = 12
local character = workspace:FindFirstChild("ZeInventor")
while true do
wait(0.05)
local position1 = character.PrimaryPart.Position
wait(0.2)
local position2 = character.PrimaryPart.Position
local difference = (position2 - position1).magnitude

if difference > A then
warn("player isn't playing nice")
character.PrimaryPart:Destroy()

end
end

I haven’t tested it but that’s along the lines of what I would do.

1 Like

Thanks, do you know where I should put something like that though, like should I create a new server script that constantly does that?

As MP3Face mentioned though, it’s virtually impossible to completely rid exploiters of your system, that’s why most games don’t have a global leaderboard.

I was also thinking, the server could constantly check and compare a player’s times. If they’re all extremely fast on their first go, something’s probably a little shady. Now they could spend several runs purposefully being slow but at that point, you may as well treat them as an actual person if they’re that dedicated to being on the leaderboard!

If you wanted, you could do a simple age check on their account. Most exploiters aren’t game enough to use their main account and a lot of the time, they’re too lazy to make an account and come back a week later.

1 Like