Other How to handle websocket game status and delays

LucaMs

Expert
Licensed User
Longtime User
Sorry, I don't know how to explain well what I mean.

I'm trying to develop e websocket client-server turn based game using b4j + b4a.

Let's say PlayerA does his "move"; this info should be sent to all other players; PlayerC does not receive this info because of delay on his connection but the game continues and PlayerB does his move (also, during the game players who do not have the turn can act in other ways, then sending other informations).

So, even if anyway a player will receive all data in chronological order (I hope!) there will be many problems.

Since I think it would be absurd to send the complete state of the game every time (too much data to send and, moreover, it would not be enough since there are also players' extra-game actions), how to handle this?

[So far I had done everything in the local network, no problem, and I had not thought of this]


Thank you
 
Last edited:

techknight

Well-Known Member
Licensed User
Longtime User
any time you have delay, everything else has to wait for that person with delay. (Slow internet connection, international, etc).

Server sends data, client send ACK. Server has to wait for ACK or issue a timeout, and "boot" the player for "connection timed out". No real way around this.

In first person shooter video games, people with the highest "ping" cause issues for the rest of the players because the server has to wait for this guy. and vice versa. Client has X-Y-Z coordinate sent to server, but there is a huge delay before the client sends a new x-y-z position so all the other players see the person at location A. People shoot at location A. Nothing happens because the server is still waiting on new location data so then you see the client "jump" across the map and the shots actually missed.

it gets bad, trust me.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
b) I have taken a look at that service (quikly and unfortunately not in Italian). As I understood I would not have the possibility to allow players' actions when it's not their turn; so I thought I'd have more freedom, this way. To give an idea, while the current player "thinks to his move" and a ProgressBar indicates the time that he still has at his disposal, another player should be able to send an "object" to a third player. I think this is not possible using Google Play Game Services, or I'm wrong?
It depends on what you want to do exactly, but
Probably what I meant can be implemented using the "Gift part" of GPGS. This is just to say, because...
a) dependence on Google. Google changes many things often (see Firebase!) and I'd be forced to ask you to update your excellent library;
is still valid.

Anyway, I would like to ask if anyone who knows well Google Play Game Services knows if it has any "countermove" in case of clients' latency. As I understand, the service provides the game state to all clients but only one of them is allowed to change it; but what happens if the client does not change the game state on time? What happens if there is a delay in "Gifts"?


Thank you
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
I trust you; but then? Is there no solution? Especially it's hard to find a "standard" solution.

I dont know of any "solution" off hand other than using timeouts. That doesn't mean there isnt a solution, I just dont personally know of any. My advice is to keep timeouts strict. After a certain point, boot the client. And move on.

If player movement/operation is "round robin" like Poker, then when its a certain persons turn, the token or "make your move" signal is sent to client. if client doesnt respond within a certain timeframe, He/She gets the boot, Hand folds, a message appears "Player X left the table" or "Player X timed out and has been disqualified". Player disappears and the game moves on.

Another method is have a 30 second re-connect timeout. If your connection dropped, and you didnt signal the server that you wanted to "exit", the server can allow a reconnection while its waiting on your turn or otherwise. If you dont reconnect within that time period, the server removes you from the game. In Poker, the server could issue an automatic fold while its waiting for you to re-connect, keeping your seat. After so long, your booted from the game!
 
Last edited:
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
The problem is that any delay in the connection of a client affects every command sent to the client, not only when the client has the turn.

Example: player A has the turn and plays a card; all other clients will receive this information, even the "slow client"; and this for any "type of command" the server should send.


Thank you
 
Upvote 0

IlCasti

Active Member
Licensed User
Longtime User
In my honestly opinion i think something like clash of royal is..

It is a turn-based game in which server contacts clients every "x" seconds to verify if opponents are present.
When connection abort, game restart infinity time to reopen challenge until time battle left to zero.
Meanwhile, you could lose :mad:, but if opponent fall you shall win. :D:D:D
It's not server fault, game must go on!

What about client communication... Cards choosen? Where to place in?

And what about server communication... It sends other player what opponents do and start game development?
If so, when server job done (???how many milliseconds???), communicate results to all partecipants (animations? coordinate? updated scores?)

Is there possibility to compress data with WebSocket Client Library? It's done by default (I haven't read documentation yet, but this thread is a way to understand)? This could be reduce the amount of data sent. :)
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
Ti rispondo in italiano e, se ci riesco, traduco :)

La base del mio progetto sarebbe già quasi pronta; ma nascono problemi solo nel caso in cui un client, proprio un dispositivo fisico, abbia problemi di lentezza della connessione, non di caduta della connessione.

Non è necessario che il server interroghi ogni client per sapere se sia ancora connesso perché l'oggetto websocket sul server scatena un evento, Disconnected, quando un client appunto si disconnette (il server sarà informato dal sw lato client se la disconnessione sia stata una scelta dell'utente).

Il problema non è quando il giocatore che ha la connessione lenta è di turno; il giocatore ha 20 secondi di tempo per scegliere la carta da giocare; se entro quel tempo non fa la propria scelta, il server (il gioco) giocherà per lui una carta in modo casuale e poi passerà il turno al giocatore successivo.
Il problema è che qualunque dato il server invii a questo "client lento", anche quando non sia di turno, scombussola tutto. Ad esempio, tra i tanti tipi di dato che potrebbe ricevere, ci sono le carte giocate dagli altri giocatori, a turno... magari per colpa della sua connessione lenta riceverà queste informazioni tutte insieme: giocatoreA ha giocato carta 11, giocatoreB ha giocato carta 3... Ovviamente, nel momento in cui riceverà queste informazioni, partiranno le relative animazioni (le carte che passano dai due giocatori al tavolo). Ma questo è solo un esempio, i dati che il "client lento" riceverà saranno tanti e di tanti tipi diversi... oltretutto, il guaio è che li riceverà in ritardo ma li riceverà comunque, non c'è modo di sapere quando li riceverà né di eliminarli dalla "coda" dei messaggi che ha ricevuto, se non facendo salti mortali di "architettura".

Ora come traduco tutta 'sta roba? :D

Now, I should translate :(


In short: see post #26 :)
 
Last edited:
Upvote 0

IlCasti

Active Member
Licensed User
Longtime User
Theory:
When players can't "shoot" their cards, server will play best one for them.
You should sent to all players the information (string) to continue the challenge.
Assuming you were playing SCOPA I thought about a string schema to resume an entire game:
PL1-T1-C1-1C|PL2-T1-C1-1C|PL3-T1-C1-1C|PL4-T1-C1-1C|PL1-T2-C2-2C|PL2-T2-C2-2C|PL3-T2-C2-2C|PL4-T2-C2-2C|PL1-T3-C3-3C|PL2-T3-C3-3C|PL3-T3-C3-3C|PL4-T3-C3-3C|PL1-T4-C4-4C|PL2-T4-C4-4C|PL3-T4-C4-4C|PL4-T4-C4-4C|PL1-T5-C5-5C|PL2-T5-C5-5C|PL3-T5-C5-5C|PL4-T5-C5-5C|PL1-T6-C6-6C|PL2-T6-C6-6C|PL3-T6-C6-6C|PL4-T6-C6-6C|PL1-T7-C7-7C|PL2-T7-C7-7C|PL3-T7-C7-7C|PL4-T7-C7-7C|PL1-T8-C8-8C|PL2-T8-C8-8C|PL3-T8-C8-8C|PL4-T8-C8-8C|PL1-T9-C9-9C|PL2-T9-C9-9C|PL3-T9-C9-9C|PL4-T9-C9-9C|PL1-T10-C10-10C|PL2-T10-C10-10C|PL3-T10-C10-10C|PL4-T10-C10-10C

Totale 532bytes of data.
All slow players should receive all amount of this little string.
Animations, scores and all you want will be done by client or if you want, you can choose to send other information too.

Who lose its turn will come back at the real point of the game seeing what the others players did.
If game ends and players can't reconnect, they will see only the final score of it.

Today players have not too slow connection to play all around the world! o_O

PS: if you want we can speak italian in the other thread :D
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
PS: if you want we can speak italian in the other thread
Well, I have two thread about this just because, strangely, I understand better the Italian language :)

I understand what you're "saying": it is like: "send the entire current state of the game, since it will not be too much bytes of stuff".

But I don't need to send only the state of the game (game status?). Sometimes I might have the need to send "personal" messages to a client (even "visible" by the other clients or not) or other things (please see b) post #17).

I know, I have to implement a "kind of protocol" (when my brain will be able to do it, not now :p).
Something with Server's commands structure, client's "server's command parser" and vice-versa.
Receipts (maybe only sometimes required, depending on "command type")
and other stuff.
[I have already had to implement something to get around the matter "obfuscation"]


Thank you, @IlCasti
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
You need more than a protocol. You need an engine here. With all the robustness coded in. Personal Messages should be cached until the player signs back in again, or until the server gets confirmation that the player has read it. Thats how that works.
 
Upvote 0

LucaMs

Expert
Licensed User
Longtime User
until the player signs back in again
I have not been able to explain, perhaps.

There isn't a moment when "the player signs back," in that he does not lose the connection (or, better, if he loses the connection, I already have a workaround for this).

The only way to detect if the user had received the data at the right time is to force it to answer "received" always; but since it could not be able to do it, the server will have to prepare a time-out also for this.

An "engine" that implements all this is achievable, but the trouble is that I have to change almost everything I have already written :(


Thank you
 
Upvote 0

techknight

Well-Known Member
Licensed User
Longtime User
Flowcharts are a savior. Almost a requisite in software engineering. that would avoid the complication of re-coding.
 
Upvote 0
Top