Jump to content

Calculate delay time while triggering


Overkillz

Recommended Posts

Hello dear community, well, Im currently coding a toptime and I would like to know if there is a way to calculate the delay time while triggering from server to client or reverse.

Might getting the player ping, bandwidth or idk. I know that the trigger delay time is minimum but those miliseconds are so important for the toptime list.

Thanks for reading, regards.

Link to post

Hy! I know this doesn't answer your question, but you could measure the time and calculate toptime on the same side. That would eliminate the really minimal delay time. Then after the client for example calculated the time, you could send it over. Then the delay doesn't matter, because you have it calculated already. 

Link to post
34 minutes ago, WorthlessCynomys said:

Hy! I know this doesn't answer your question, but you could measure the time and calculate toptime on the same side. That would eliminate the really minimal delay time. Then after the client for example calculated the time, you could send it over. Then the delay doesn't matter, because you have it calculated already. 

I know, but I wont follow this way. I need to keep some functions on the serverside due x reasons.

  • Like 1
Link to post

Maybe

getLatentEventStatus

Could work whilst using triggerLatentServer/ClientEvent as the function returns tick start, tick end, size and percentage complete..

Edited by Ab-47
  • Like 1
Link to post
13 hours ago, Ab-47 said:

Maybe


getLatentEventStatus

Could work whilst using triggerLatentServer/ClientEvent as the function returns tick start, tick end, size and percentage complete..

Does it work with trigger-Server/Client-event ? I see on the wiki that it only works with triggerLatentEvents

13 hours ago, Ab-47 said:

Maybe


getLatentEventStatus

Could work whilst using triggerLatentServer/ClientEvent as the function returns tick start, tick end, size and percentage complete..

Does it work with trigger-Server/Client-event ? I see on the wiki that it only works with triggerLatentEvents

  • Thanks 1
Link to post
16 hours ago, Overkillz said:

I know, but I wont follow this way. I need to keep some functions on the serverside due x reasons.

 

It is not possible when doing it based on two sides, unless the system time is set at the exact same time, while both systems are standing next to each other.

 

There is only one way to reduce the connection delay + serverside and that is to buy multiple servers in other countries which will give the start signal and receive the end signal. But which person is willing to go that far?

 

There is one real realistic thing you can do. Which is prioritise the connection.

Use triggerClientEvent to start the race. And use triggerServerEvent to end the race.

So instead of onColShapeHit use onClientColShapeHit + triggerServerEvent.

This should be faster, but make sure to validate that so that you know for sure, that I am not talking crap. (I am not a MTA developer after all)

 

 

 

 

 

 

  • Like 1
  • Thanks 1
Link to post
1 hour ago, IIYAMA said:

 

It is not possible when doing it based on two sides, unless the system time is set at the exact same time, while both systems are standing next to each other.

 

There is only one way to reduce the connection delay + serverside and that is to buy multiple servers in other countries which will give the start signal and receive the end signal. But which person is willing to go that far?

 

There is one real realistic thing you can do. Which is prioritise the connection.

Use triggerClientEvent to start the race. And use triggerServerEvent to end the race.

So instead of onColShapeHit use onClientColShapeHit + triggerServerEvent.

This should be faster, but make sure to validate that so that you know for sure, that I am not talking crap. (I am not a MTA developer after all)

 

 

 

 

 

 

Alright, well, I have a simple idea but idk if it is going to alter the client cpu.

What about of checking something onClientRender ? In that case, start the tick for the toptime and when the player hit a colshape then stop it and trigger the time. 

But Im a bit worried about checking that condition every frame ...

Regards.

  • Thanks 1
Link to post
34 minutes ago, Overkillz said:

Alright, well, I have a simple idea but idk if it is going to alter the client cpu.

What about of checking something onClientRender ? In that case, start the tick for the toptime and when the player hit a colshape then stop it and trigger the time. 

But Im a bit worried about checking that condition every frame ...

Regards.

 

It will fill up the client message buffer. Just read my crap or just do it and find out.

 

 

Note: for trigger[client/server]Events TCP messages are used and not UDP messages.

Just a quick summary of those two communication protocols and why I do not recommend you doing that. (to save you some time)

 

TCP = 100% success rate if the client remains connected and able to receive messages.

  • In case of failure the message will be automatic resend.
  • In case of success a message will be send back to inform the sender that the message has been delivered.
  • Messages will be send in order, one at the time. The rest have to wait in queue. 🔫

Available for scripting

 

UDP = success rate is not measure able, because there is no validation if a message has been received or not.

  • Method often used for streaming or for sending large files in pieces.

NOT AVAILABLE for scripting

 

In case of streaming (every frame) with TCP = trigger[client/server]Events

+ message 1 (frame 1)

Sending message 1.

+ message 2 (frame 2)

+ message 3 (frame 3)

+ message 4 (frame 4)

+ message 5 (frame 5)

+ message ...

+ message 30 (frame 30)

  • Receive response from message 1.
  • Messages in queue: 29!

Sending message 2.

+ message 31 (frame 31)

+ message 32 (frame 32)

+ message ...

+ message 60 (frame 60)

  • Receive response from message 2.
  • Messages in queue: 58!

+ message 61 (frame 61)

+ message 62 (frame 62)

+ message ...

+ message 90 (frame 90)

  • Receive response from message 3.
  • Messages in queue: 87!

CONNECTION TROUBLE ;@

CONNECTION TROUBLE CONNECTION TROUBLE

CONNECTION TROUBLE CONNECTION TROUBLE

CONNECTION TROUBLE CONNECTION TROUBLE

CONNECTION TROUBLE CONNECTION TROUBLE
...
 CONNECTION LOST 

 

 

 

 

 

 

 

41 minutes ago, Overkillz said:

In that case, start the tick for the toptime and when the player hit a colshape then stop it and trigger the time.  

 

You do not have to do this every frame. The events are already there for you. And this will not be any different from how it currently works.

Edited by IIYAMA
  • Like 1
  • Thanks 1
Link to post
8 hours ago, Overkillz said:

Does it work with trigger-Server/Client-event ? I see on the wiki that it only works with triggerLatentEvents

I've never used latent events, but I'm pretty sure it doesn't get triggerServerEvent/triggerClientEvent details. That's why I said to try triggerLatentServerEvent/client instead. However I think you may find this bit of information useful:

This function is the same as triggerClientEvent except the transmission rate of the data contained in the arguments can be limited and other network traffic is not blocked while the data is being transferred.

Give it a try but I do recommend IIYAMA's suggestion or something similar. 

Or even try this if it helps:

On 10/03/2019 at 23:26, WorthlessCynomys said:

Hy! I know this doesn't answer your question, but you could measure the time and calculate toptime on the same side. That would eliminate the really minimal delay time. Then after the client for example calculated the time, you could send it over. Then the delay doesn't matter, because you have it calculated already. 

 

  • Like 1
  • Thanks 1
Link to post
  • 4 weeks later...

@IIYAMA

I know I've left the topic moved off but, what about this.

i've been doing some research about an efficent way and might I found it and I would like to hear your suggestion.

What about if before I do the trigger I set to the player an elementData as getTickCount() and later check it on the client side and calculate the delayed time.

Lets check a draft code.

--##SERVER
function whateverItIsServerSide()
	local startTick = getTickCount()
	setElementData(thePlayer,"startTick",startTick,true) -- Obyously the player must be defined previously ...
	triggerClientEvent(thePlayer,"whateverFunctionClientName",thePlayer)
end

--##CLIENT
function clientSideWhateverName()
	local serverTick = getElementData(localPlayer,"startTick")
	if serverTick then
		local delayedTime = getTickCount() - serverTick
		outputDebugString("The Delayed Time should be: "..delayedTime)
	end
end
addEvent("whateverFunctionClientName",true)
addEventHandler("whateverFunctionClientName",getRootElement(),clientSideWhateverName)

I would like to hear your opinion. Thanks for reading and regards.

Link to post
8 hours ago, Overkillz said:

What about if before I do the trigger I set to the player an elementData as getTickCount() and later check it on the client side and calculate the delayed time. 

Tickcount is system based. This value is not compare able between the server and client. Especially when it is running on a different device.

Using a combination of trigger event and elementdata will not really matter.

Edited by IIYAMA
Link to post
On 10/04/2019 at 17:36, pa3ck said:

I don't understand why can't you just use serverside and forget about the client? What events are you using to trigger the start and end events

Im just spawning the players and their vehicles (Frozen) at server side to later, in a determinated (when the race round starts) unfreze them. immediately I do a triggerClientEvent to start the timepassed of the race to calculate their toptimes. Obyously this must be at client side to do some draws ...etc

I know that I can unfreze the vehicles at clientside, but, this is what happen if I do it

Regards.

PS: I already tried to use setElementSyncer(theVehicle,false) but it doesn't work

Edited by Overkillz
Link to post

Can you not use getRealTime timestamp and calculate the time that way? 

 

You might need to adjust it a bit for local time, since client side it will return the client's PC time rather than the server time, but you can adjust that before a race begins. 

Edited by pa3ck
Link to post
4 hours ago, pa3ck said:

Can you not use getRealTime timestamp and calculate the time that way? 

 

You might need to adjust it a bit for local time, since client side it will return the client's PC time rather than the server time, but you can adjust that before a race begins. 

I was just thinking about this, getRealTime could actually work. I assume getRealTime would use the servers local time otherwise you could create a custom script where you could use fetchRemote to return a specific time using PHP. It's not that difficult either, PHP is somewhat similar to Lua. However you would need an online website for that. I wouldn't really recommend fetchRemote, just the standard MTA getRealTime should do the trick.

Link to post

@pa3ck & @Ab-47

How to suppose to I do that ? In my mind I can only get that I must be aware about the exactly milisecond of server side and client side, but I bet that bot or them aren't running exactly the same one.

What I mean ?

Imagine,

  • server time is: 13 hours, 42 minutes, 31 seconds and 931 miliseconds
  • client time is: 12 hours, 42 minutes, 17 seconds and 351 miliseconds.

There is not way to reach it by using getRealTime as far I can understand.

Link to post

You start counting the timer once you unfreeze the client (You can trigger a client side event for player to "start"). Once the player finishes you stop counting, you take out the ticks that the player took to finish, and just forward it as a parameter to server to do your toptimes work, this makes it little to no delay.

  • Like 1
Link to post

@DizzasTeR

Yes, I've already tried this, but If I freeze the vehicle serverside (When the player spawns ...etc) and later I unfreze the vehicle at client side, It causes the following issue.

I already know that I can use a setTimer to do a triggerServerEvent and unfreze the vehicle server side after it has been unfreze at clientside,  but my question is, there is a better way to reach it ? (I know it sounds weird.)

Will I get a problem If i unfreze a vehicle that is not frozen ? (Not at home to test it)

Link to post

@DizzasTeR

Well, but here are few questions respecting that.

  1. If I create a vehicle at serverside and I want to freeze it at client side, I must use a trigger. During that short time, the car could be moved by the player.
    • Possible Solutions: Use toggleAllControls or play with more thatn a single trigger
  2. If I create the vehicle clientside. The vehicle won't be visible for the rest of players.
    • Possible solutions: Deal with more than a single trigger or use setElementSyncer(But this has some limitations as far as I could read at the wiki)

The best way I can use to avoid several triggers is toggleAllControls right ?

Regards.

Link to post

you can keep the freeze/unfreeze part at server side, even at ~300 pings if the connection of the client itself is stable (No losses and stuff) it should be very reasonable and fine, the main thing is to start ticking the timer when your client event trigger for the "onClientRaceStart" for example is called on client side, and then the rest as I said in first reply.

Link to post
1 hour ago, DizzasTeR said:

you can keep the freeze/unfreeze part at server side, even at ~300 pings if the connection of the client itself is stable (No losses and stuff) it should be very reasonable and fine, the main thing is to start ticking the timer when your client event trigger for the "onClientRaceStart" for example is called on client side, and then the rest as I said in first reply.

Thats what Im doing from the beginning, the tick starts when the trigger has arrived at clientside, but anyways some miliseconds are missing. I know that the difference is practically inapreciable, but, I want a perfect time.

Edited by Overkillz
Link to post

You can't make it perfect, because even then the system and processing itself is not always perfect, stuff has to PROCESS and the process time will vary, as for me, I made whats called "Anti delay" for our race servers and what it really is, is what I told you, I was able to tie my toptime (Even miliseconds) with a person of 30 ping, and I had ~200. Guess that's all from my end you can try doing it better than this but I don't see it making a difference.

  • Like 1
Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...