synchronise macro (handshake clients)

Discuss macro implementations, ask for macro help (to share your creations, see User Creations, probably either Campaign Frameworks or Drop-in Resources).

Moderators: dorpond, trevor, Azhrei, giliath, jay, Mr.Ice

Post Reply
User avatar
wolph42
Winter Wolph
Posts: 9999
Joined: Fri Mar 20, 2009 5:40 am
Location: Netherlands
Contact:

synchronise macro (handshake clients)

Post by wolph42 »

edit: sorry for the long post, but pretty complicated matter... its mainly aimed at the more MT script savvy user here.

Yesterday (after reading AM's post about a new card game he released) I build the card game SET. I've played this a lot with my son, as its a hugely entertaining (and brainwrecking) game.

Anyway, with this game time is of the essence and thus the matter of 'delayed updated over server' came up. So I started thinking whether there is a way to synchronise either the update or (much easier) the view port of all connected clients.

Example Issue
- one of the clients is the dealer and she clicks on the 'draw cards' macro.
- this macro puts a couple of cards on the map face up.
- issue is that the 'dealer' has the advantage of seeing them first and the other clients after the update. Not a big deal on fast internet, but might be a big deal when the connection is slow.

Possible solution
- as soon as the dealer clicks the 'draw cards' macro her view port is send somewhere else. So same map but lets say the game table is near 0,0 we send the viewport to 10000,10000. The same is done for the other clients
- after the update is done the viewport returns (preferably to its original position but thats currently not possible) to the game table.

Obviously the solution still suffers from the same 'delay' issue.

So I was thinking:
- its possible to get the time for each client
- so if you can get the (near) exact time of all clients then on each client you can run an individual time loop that finishes after a certain time is reached.

Example
For this to work you require a server and two connected clients (the server could be run by one of the clients as a seperate instance of MT)
Lets assume for simplicity sake that both clients have the same time (here's btw where the issue lies what this topic is about).

Now the dealer runs the 'draw cards macro: (sv = server, dl = dealer, cc = connected clients, c1 = client 1)

Code: Select all

dl (draw cards macro)
- broadcast (=remote execute macro) an initiation instruction to sv 
- end of macro

sv (initiation macro): 
- gets time of all cc (e.g c1: 0:00:00, c2:11:58)
- add (eg) 5 seconds to those times (so 0:00:05 and 2:12:03)
- broadcast a 'screen off' instruction to all cc's
- draw cards
- end of macro

c1 (screen off)
- set viewport to far away
- runs timer loop until its 0:00:05
- returns viewport to gamebord
- end of macro

dito c2
First question is: do you have any comments on this procedure?

What I'm currently breaking my head over is the fact that when you 'get' the times of the cc that there will be a delay in that as well. Thats the procedure Im bashing my head for against the wall.
One thought I had:

Code: Select all

sv (getCCTime)
- get current time and store on lib
- broadcast 'give me your time' to cc
- end of macro

cc (giveMeYourTime)
- get current time
- broadcast 'heres my time' to sv
- end of macro

sv (heresMyTime)
- get current time
- get time stored on lib
- checks how much time has passed (current - stored) divide by two (assuming that send and recieve over the interweb takes the same amount of time)
<!-- now we know how much delay there is lets say 1 second -->
- adds 1 second to the cc time as the actual cc time is one s later.
- store (earlier stored) sv and cc time on lib e.g. in a json object {c1: 0:00:05, c2: 2:12:03, sv: 13:22:12}
So now there is a json object with three timestamps that *should* have been retrieved at roughly exactly the same time, so there has been one point in time where it was 0:00:05 on c1, 2:12:03 on c2 and 12:22:12 on sv. With this you can have the sv as an absolute time and then calculate c1 and c2 relative to this time. Then when the screenOff(endTime) routine is broadcasted to the clients, the endTime can be adjusted relatively to the sv time.

I hope this makes sense. Basically currently I'm just looking for comments, suggestions, better ideas, gaps in the above etc.

thank you.


User avatar
aliasmask
RPTools Team
Posts: 9031
Joined: Tue Nov 10, 2009 6:11 pm
Location: California

Re: synchronise macro (handshake clients)

Post by aliasmask »

Yeah, doesn't seem to be an easy solution because those with more lag and slower computers will always be at a disadvantage. Also, the number of clients will matter because if 5 clients is polling the server for time, that will add further delay. The best hack is to write a java function that gets GMT time from an internet time service.

Code: Select all

[r, for(i,0,20): json.get(getInfo("server"),"timeInMs")+", "+json.get(getInfo("client"),"timeInMs")]
Connecting to myself, a fast connection I get a difference of 0 to 1 1/1000th of a sec difference between server and client. But the poll times between server times varies widely from 2 to 38 1/1000th of a sec. The 38 is still insignificant when it comes to computer draw times for a slower computer.

This is how I would do it:

Code: Select all

server - send to clients: I will post at start.time (server.myTime + X)
server - wait until start.time to post
client - get server.time minus client.myTime and subtract from start.time for new start.time
client - wait until start.time to post 
I would start with X at 1000, 1 second. I'm not sure how MT does the getInfo though. If server is running a macro, does it wait until macro is done or does it do it concurrently, or does it get the last time from the server. For example, lets say a macro runs for 1 second. The macro start on second 1 and a request for time comes in at 1.5. Does it return 1 last known time, 1.5 current time or 2 when the macro is done. I would say some testing with a friend across the country or in another country would help give a better picture of possible delay issues.

I actually use a server time stamp to sort chat logs and I notice that some posts appear before another post.. Like answering a question that hasn't been asked. That's what makes me think that in the above example, the last known time may be used rather than current time or after macro execution time. Then again, I'll have to check the code again because of that bug I found with sorting numbers in a json. I don't recall if I use a number or but a "t" in front.

The reason why I mention the getInfo time method is because it will make a difference in how you wait. The timer method using deferred macro calls breaks up the wait times in to different macro threads so other macros or operations can be run in between. You could run a recursive looping loop which will lock up the client until the timer goes off, but that could affect the client calls to the server.


Post Reply

Return to “Macros”