PDA

View Full Version : [Spike] Multiplayer e Netcode


fek
12-12-2005, 14:26
Ovvero, vi lasciamo i compiti per le vacanze e per lo sviluppo principale ci risentiamo all'inizio dell'anno prossimo :)

Quindi io e Vic vi proponiamo un bello Spike corposo e divertente: Multiplayer e Netcode.

Prendete qualche branch del gioco e vedete se riuscite a connettervi ad un gioco in esecuzione e a duplicare la sua griglia di gemme in locale.

Punti da tenere ben presente sul netcode:

- L'architettura dovra' essere il piu' possibile peer-to-peer, quindi entrambi i giocatori fanno contemporaneamente da server e da client, ovvero nessuno deve essere avvantaggiato dalla latenza.

- Sarebbe bello funzionare anche dietro ad una NAT...

- ... e magari usando il protocollo HTTP :)

- Eventualmente studiare l'uso di un protocollo di trasporto basato su UDP o TCP.

In pratica, vorrei che il livello di trasporto fosse il piu' possibile astratto e ben separato dalla logica del netcode.

Studiateci un po' e diteci qualche possibile soluzione a questi problemi.

71104
12-12-2005, 16:55
possiamo eventualmente creare una nostra versione del gioco aggiungendo qualche pezzo non TDD per gestire il networking da mettere poi nella cartella degli spikes? ovviamente senza affezionarci troppo a quello che scriviamo :)

fek
12-12-2005, 16:57
possiamo eventualmente creare una nostra versione del gioco aggiungendo qualche pezzo non TDD per gestire il networking da mettere poi nella cartella degli spikes? ovviamente senza affezionarci troppo a quello che scriviamo :)

Quando crei un branch nel quale fare gli spike puoi fare quello che pare a te :D

cionci
12-12-2005, 17:01
- Sarebbe bello funzionare anche dietro ad una NAT...

Impossibile se almeno un client non ha una porta aperta...

fek
12-12-2005, 17:32
Impossibile se almeno un client non ha una porta aperta...

So che appoggiandosi ad un server esterno solo per la connessione, si puo' iniziare in qualche modo il canale e poi prosegue senza bisogno del server. Ma non domandarmi di piu' :)

cionci
12-12-2005, 18:18
Passando da un server esterno è facile...riguardo al fatto che c'è il server che inizia le connessioni e poi i client continuano da soli: non ho mai sentito di questa cosa, ma presumo che sia una possibilità di UDP (magari facendo uno spoofing dell'indirizzo sorgente), ma sicuramente non del TCP...

fek
12-12-2005, 18:47
Passando da un server esterno è facile...riguardo al fatto che c'è il server che inizia le connessioni e poi i client continuano da soli: non ho mai sentito di questa cosa, ma presumo che sia una possibilità di UDP (magari facendo uno spoofing dell'indirizzo sorgente), ma sicuramente non del TCP...

Si', credo di ricordare che sia una cosa che si puo' fare con pacchetti UDP, ma la mia preparazione in merito e' davvero minimale, di piu' non so' dirti.

BlueDragon
12-12-2005, 19:46
Bello questo Spike di Natale! :)
Mi sa che farò qualche prova nel periodo di ferie... ;)


- ... e magari usando il protocollo HTTP :)

A che ci serve il protocollo HTTP? Pensi che il netcode necessario per Diamonds sia affine?


- Eventualmente studiare l'uso di un protocollo di trasporto basato su UDP o TCP.

Perché eventualmente? Direi che è quasi scontato che andremo ad usare UDP o TCP :) A meno che qualcuno di noi non conosca ed abbia dei motivi per usare altri protocolli a livello di trasporto tipo AEP,AMTP,ATP,IL,NBP,NetBEUI,RTMP,SMB,SPX,SCTP,RTP...
(vi confesso, ho fatto copia-incolla da Wiki (http://it.wikipedia.org/wiki/Livello_di_trasporto), della maggior parte di questi protocolli non conoscevo manco la sigla.. :D)


- Sarebbe bello funzionare anche dietro ad una NAT...

Se uno dei due giocatori non è dietro ad un NAT, dovrebbe essere "semplice": basta che sia il giocatore dietro il NAT a contattare l'altro.
Altrimenti se sono entrambi nascosti dietro NAT servirebbe un 3o pc d'appoggio non dietro a NAT, che potrebbe essere permanente per tutto il gioco (soluzione "semplice", ma necessita di un pezzo di software sul 3o pc no?) oppure necessario solo alla connessione iniziale (più difficile, come ha detto cionci forse con IP spoofing oppure forse con alcune cose particolari del protocollo FTP con cui erano stati creati dei programmi per aggirare il problema NAT da parte degli utenti Fastweb... ma non sono per niente ferrato in questo campo :). Anche in quest'ultimo caso però servirebbe un software installato sul 3o pc..come minimo un finto server FTP :)).

^TiGeRShArK^
12-12-2005, 19:53
mmmm...non ho idea come funzionino i nat di fastweb...
ma ad esempio se la richiesta di connessione arrivasse DALLA macchina che è dietro il NAT all'altra non penso ci debbano essere grossi problemi....
o meglio... se i NAT di fastweb usano l'ip masquerading e qdi mappano ogni host su una particolare porta del server non ci dovrebbero essere problemi FINCHE' questi NAT accettino connessioni che non giungano dalle porte normali (HTTP, STMP, FTP)...
se non accettano queste connessioni... mi sa che ci dovremmo informare per vedere come superare il prob... :fagiano:

^TiGeRShArK^
12-12-2005, 19:58
A che ci serve il protocollo HTTP? Pensi che il netcode necessario per Diamonds sia affine?

me lo chiedevo anch'io...
penso che UDP sia + indicato visto ke è + snello...

Perché eventualmente? Direi che è quasi scontato che andremo ad usare UDP o TCP :) A meno che qualcuno di noi non conosca ed abbia dei motivi per usare altri protocolli a livello di trasporto tipo AEP,AMTP,ATP,IL,NBP,NetBEUI,RTMP,SMB,SPX,SCTP,RTP...
(vi confesso, ho fatto copia-incolla da Wiki (http://it.wikipedia.org/wiki/Livello_di_trasporto), della maggior parte di questi protocolli non conoscevo manco la sigla.. :D)
Se uno dei due giocatori non è dietro ad un NAT, dovrebbe essere "semplice": basta che sia il giocatore dietro il NAT a contattare l'altro.
Altrimenti se sono entrambi nascosti dietro NAT servirebbe un 3o pc d'appoggio non dietro a NAT, che potrebbe essere permanente per tutto il gioco (soluzione "semplice", ma necessita di un pezzo di software sul 3o pc no?) oppure necessario solo alla connessione iniziale (più difficile, come ha detto cionci forse con IP spoofing oppure forse con alcune cose particolari del protocollo FTP con cui erano stati creati dei programmi per aggirare il problema NAT da parte degli utenti Fastweb... ma non sono per niente ferrato in questo campo :). Anche in quest'ultimo caso però servirebbe un software installato sul 3o pc..come minimo un finto server FTP :)).
infatti... lo pensavo pure io...
ma se questi due utenti sono tutti e due dentro fastweb... non usano in quel caso il loro indirizzo privato senza passare dal NAT?

fek
12-12-2005, 20:09
me lo chiedevo anch'io...
penso che UDP sia + indicato visto ke è + snello...

Se non ci fossero grossi problemi di latenze, a me giocare anche dietro ad un proxy non dispiacerebbe affatto, sempre che fosse possibile :D

Ma e' una wishlist, ho buttato solo qualche idea, non conosco con precisione le implicazioni tecniche di tutto cio', ho giusto un'infarinatura sui vari protocolli.

Voi provate a farmi vedere il gioco che si connette ad un altro gioco e mostra la sua griglia e per ora e' gia' grasso che cola.

Ufo13
12-12-2005, 20:28
Bello questo spike!!! Mi ci metto pure io!!! Se cercate informazioni su questa storia del NAT e il tool che usava FTP vi consiglio di guardare qui: http://www.s0ftpj.org/bfi/bfi-it.html


C'è anche un programmino che si chiama mozzarella.c da qualche parte nel sito che dovrebbe tornare utile :)

BlueDragon
12-12-2005, 20:44
A che ci serve il protocollo HTTP? Pensi che il netcode necessario per Diamonds sia affine?
me lo chiedevo anch'io...
penso che UDP sia + indicato visto ke è + snello...

Allora, innanzitutto bisogna precisare che HTTP, TCP ed UDP sono 3 protocolli ma non sono intercambiabili tra di loro...
TCP ed UDP sono protocolli di trasporto (livello 4), e quindi puoi usare uno o l'altro, ma l'HTTP è un protocollo applicativo (livello 7) e non è sostitutivo di TCP ed UDP.
Esistono vari livelli per la comunicazione tra due PC ed ogni livello ha un suo protocollo che si occupa di una parte della comunicazione... si parte dal basso, con il livello fisico, che si occupa di come i singoli bit vengano trasmessi a livello fisico sulla fibra ottica o doppino o quel che sia, salendo poi verso l'alto con il livello di collegamento (Ethernet ad esempio), il livello di rete (IPv4, IPv6...), il livello di trasporto (UDP, TCP..) fino ad arrivare all'ultimo livello che è quello applicativo (protocolli HTTP, POP3, SMTP, SSH, FTP...).
I livelli sono 7 in tutto e c'è di che farsi una cultura..basta fare una ricerchina su Wikipedia :)

Quindi quando noi ci connettiamo ad un sito tramite HTTP stiamo automaticamente usando non solo il protocollo HTTP, ma anche tutti i protocolli che ci sono sotto, tra cui ad esempio TCP o UDP.

Per quanto riguarda la questione dei NAT, è vero gli utenti Fastweb tra di loro usano l'IP di rete interna Fastweb, ma hanno comunque dei problemi nell'utilizzare applicazioni che dialogano con utenti non Fastweb, in particolare quando devono fare da server :)

Vi racconto un po' quello che so, così magari qualcuno più esperto mi corregge se ho delle conoscenze errate :)

Gli utenti Fastweb fanno tutti parte della rete interna Fastweb, come se fossero collegati ad un enorme LAN. Per uscire su internet, devono attraversare i router NAT. Come conseguenza di ciò, gli utenti Fastweb non hanno un IP personale su internet ma vengono visti con l'IP del router NAT da cui sono usciti. I loro IP sono nascosti all'esterno, quindi se un utente FW decide di tirare su un server, dall'esterno della rete non si può accedere al suo server perché l'ip della rete interna su cui sta il server non è visibile da fuori.
Se un utente fosse padrone del proprio NAT, potrebbe semplicemente dire al NAT "tutte le connessioni che ti arrivano su una certa porta, ad esempio 9999, mandale verso il mio IP di rete interna alla porta 5555".
In questo modo ci si potrebbe collegare dall'esterno alla porta IP-interno:5555 semplicemente usando l'indirizzo IP-NAT:9999.
Purtroppo però gli utenti Fastweb non sono padroni dei router NAT né possono chiedere un forward personalizzato (cioé quel reindirizzamento di cui sopra).
Per cui, si sono messi alla ricerca di soluzioni alternative...
Una di queste soluzioni prevedeva l'uso di un programma particolare che si connetteva a ripetizione verso un server FTP esterno. Tramite l'uso di particolari comandi del protocollo FTP (che io non conosco), era possibile fare in modo che il server NAT in mezzo tra PC Fastweb e Server FTP, tenesse costantemente aperta una sua porta con reindirizzamento per il PC Fastweb, creando quindi una sorta di forward personale permanente (finché girava il programma).
Questa tecnica però aveva due brutti effetti collaterali:
1) Il programma in questione si connetteva a ripetizione verso un Server FTP. Se il server FTP è di una persona consenziente, tutto apposto.. ma se il server FTP è un server pubblico, connettercisi a ripetizione e per giunta per scopi non collegati al normale utilizzo FTP è quantomento sconveniente no? Se non proprio illegale.
2) Con questo programma si otteneva un forward al proprio interno che io ho definito "personale".... e se qualcun'altro avesse avuto bisogno della porta 9999 sul NAT? Con che diritto si può tenere occupata la porta di un server NAT che viene condiviso da più utenti?
Quest'ultima è una mia speculazione, non so se effettivamente usando quel programma il forward sul NAT escludesse totalmente l'uso di quella porta per gli altri utenti..... le mie conoscenze non vanno molto lontano in questo campo :)
Magari dopo lo spike di Natale ne saprò di più :P

Cmq nel nostro caso non si tratterebbe di un uso continuativo che potrebbe sfociare in abuso, ma di una breve apertura di pochi secondi per permettere ai due client che fossero dietro due NAT di reti diverse (non tutti e due FW quindi) di "vedersi" per il tempo necessario a stabilire una connessione permanente (TCP?) tra di loro.
Mi immagino quindi questo scenario, che non so se sia fattibile...

* PC A dietro Fastweb
* PC B dietro ProviderStraniero
Entrambi con problema NAT.
* PC C senza NAT di un loro amico.

il PC C contiene un software (magari Diamond stesso) che permette una connessione di tipo FTP o cmq che abbia la logica necessaria ad effettuare quel forward temporaneo di cui sopra.

1) PC A si connette a PC C e tramite FTP ottiene un forward dal suo NAT al suo indirizzo interno.
2) PC B si connette a PC C e tramite FTP ottiene un forward dal suo NAT al suo indirizzo interno.
3) il PC C comunica a PC A e PC B gli indirizzi NAT-A:Porta e NAT-B:Porta dei forward tramite cui si possono parlare.
4) PC A e PC B effettuano grazie ai forward una connessione TCP tra di loro
5) PC A e PC B lasciano la loro connessione "FTP" verso PC C, ringraziandolo :p

Cionci? Che ne dici?

BlueDragon
12-12-2005, 20:57
Aggiungo che mi sentirei abbastanza volontario da seguire il seguente tipo di Spike, da solo o in compagnia:

- protocollo di trasporto TCP
(da tramutare eventualmente in UDP..o forse direttamente UDP, ci devo pensare un po'/vedere cosa c'è di già pronto in Java)
- protocollo applicativo: DiamondsCrush (un protocollo tutto nostro :p)
- Soluzione al problema NAT: utilizzo permanente di un "Diamonds proxy", software integrato a Diamonds oppure separato (a scelta).

In pratica quando due PC si trovano entrambi dietro NAT di due LAN diversi, si connettono ad un 3o PC esterno non dietro a NAT che funge da ponte per tutta la durata del gioco :)

Ufo13
12-12-2005, 23:33
Per il protocollo applicativo posso darti una mano... Non ho mai lavorato con java in rete però mi pare che si possano serializzare oggetti facilmente ed inviarli ad un host... Penso che il protocollo, se fosse così, starebbe nel trovare il migliore oggetto da utilizzare per il trasporto delle informazioni di sincronizzazione delle griglie tra gli host... Inoltre sarebbe una buona cosa cercare di rendere sicuro il protocollo :)

cionci
13-12-2005, 02:11
Anche io anche io :)

Lo facciamo test driven ? Secondo me si evita di fare molti errori :)

Anche io non ho mai programmato queste cose su Java (anzi, a dirla tutta, non mai programmato in Java prima di Diamonds, se non nel lontano 1994)...

Concordo su TCP...visto che è orientato alla connessione è sicuramente preferibile rispetto ad UDP... In teoria la latenza introdotta da UDP dovrebbe essere leggermente minore, ma per ora possiamo fregarcene...

Direi che la prima cosa da fare sia un metodo per la stima del RTT...in questo modo possiamo anche sincronizzare i timer dei due giochi...

cdimauro
13-12-2005, 10:09
A lavoro uso questo: http://www.zeroc.com/ice.html per realizzare applicazioni client/server e mi trovo benissimo.
E' chiaro che, in questo caso, ognuno dovrebbe fare da server e client contemporaneamente, ma non c'è problema.

Tra l'altro server e client ICE si possono realizzare anche in Java, che dopo il C++ è la "piattaforma" più supportata.

fek
13-12-2005, 10:11
Anche io anche io :)

Lo facciamo test driven ? Secondo me si evita di fare molti errori :)

Anche io non ho mai programmato queste cose su Java (anzi, a dirla tutta, non mai programmato in Java prima di Diamonds, se non nel lontano 1994)...

Va benissimo scrivere lo spike test-driven ma tenete ben presente che tutto quello che scriverete nello spike sara' buttato e si ripartira' da zero per il codice di produzione. Quindi, come al solito, non attaccatevi troppo al codice che scriverete :)

Comunque il codice dello Spike non dev'essere robusto o privo di difetti, deve piu' o meno funzionare ed esplorare piu' soluzioni possibile ed incontrare piu' potenziali problemi possibile.

Direi che la prima cosa da fare sia un metodo per la stima del RTT...in questo modo possiamo anche sincronizzare i timer dei due giochi...

Assolutamente si', questo e' sicuramente il primo problema da affrontare.

DioBrando
13-12-2005, 10:15
cut

inrealtà i livelli sn 4 perchè si considera la suite TCP/IP, 7 per il modello OSI che però è troppo ridondante ( visto che suddivide inutilmente il livello applicativo in + sottolivelli) ed infatti n ha avuto successo :D

Se utilizzate il TCP, avrete la possibilità di maggiore affidabilità e del controllo degli errori, con l'UDP, mancando questa caratteristica ( e visto che il QoS viene implementato soprattutto a livello TCP), risulta un protocollo di trasporto + leggero ed infatti è quello che usano parecchi SW P2P decentralizzati ( Bit Torrent per es, nella connessione al tracker).

IMHO dovete provare a vedere quant'è l'effettiva larghezza di banda che occupate giocando in multiplayer e poi decidere se preferite qlc di + snello o qlc di + "reliable" come si dice :D


Cmq n mi scosterei tanto da questi due, che sn già supportati in tutti i SO ( ed il gioco nasce per essere portabile giusto?)...

cisc
13-12-2005, 13:14
ragazzi, per i giochi in java ho sentiito molto parlare di RMI, anche se sono abbastanza ignorante in materia, cerco di documentarmi e vi faccio sapere, cmq, sarei anche interessato a collabborare allo spike che usi udp....

^TiGeRShArK^
13-12-2005, 19:32
Allora, innanzitutto bisogna precisare che HTTP, TCP ed UDP sono 3 protocolli ma non sono intercambiabili tra di loro...

proprio per questo mi sembra un overhead inutile sia htttp ke tcp...
TCP è connection oriented mentre UDP è connection less...
quindi l'overhead di TCP è maggiore..
inoltre tutte le applicazioni che utilizzano scambi di dati in real-time (VoIP, videoconferenze) di solito usano il protocollo RTP che si appoggia a UDP proprio per evitare overhead ke sarebbe inutile e per gestire autonomamente la perdita di pacchetti...
cmq per il protocollo di livello 3 direi ke l'IP va + ke bene :D

I livelli sono 7 in tutto e c'è di che farsi una cultura..basta fare una ricerchina su Wikipedia :)

o ritrovare gli appunti di reti di telecomunicazioni :asd:

Quindi quando noi ci connettiamo ad un sito tramite HTTP stiamo automaticamente usando non solo il protocollo HTTP, ma anche tutti i protocolli che ci sono sotto, tra cui ad esempio TCP o UDP.

di solito si usa il TCP se non sbaglio perchè si instaura proprio una o + connessioni con il server web.

Gli utenti Fastweb fanno tutti parte della rete interna Fastweb, come se fossero collegati ad un enorme LAN. Per uscire su internet, devono attraversare i router NAT. Come conseguenza di ciò, gli utenti Fastweb non hanno un IP personale su internet ma vengono visti con l'IP del router NAT da cui sono usciti.

appunto ... dicesi ip masquerading ;)

I loro IP sono nascosti all'esterno, quindi se un utente FW decide di tirare su un server, dall'esterno della rete non si può accedere al suo server perché l'ip della rete interna su cui sta il server non è visibile da fuori.
Se un utente fosse padrone del proprio NAT, potrebbe semplicemente dire al NAT "tutte le connessioni che ti arrivano su una certa porta, ad esempio 9999, mandale verso il mio IP di rete interna alla porta 5555".
In questo modo ci si potrebbe collegare dall'esterno alla porta IP-interno:5555 semplicemente usando l'indirizzo IP-NAT:9999.
Purtroppo però gli utenti Fastweb non sono padroni dei router NAT né possono chiedere un forward personalizzato (cioé quel reindirizzamento di cui sopra).
Per cui, si sono messi alla ricerca di soluzioni alternative...
Una di queste soluzioni prevedeva l'uso di un programma particolare che si connetteva a ripetizione verso un server FTP esterno. Tramite l'uso di particolari comandi del protocollo FTP (che io non conosco), era possibile fare in modo che il server NAT in mezzo tra PC Fastweb e Server FTP, tenesse costantemente aperta una sua porta con reindirizzamento per il PC Fastweb, creando quindi una sorta di forward personale permanente (finché girava il programma).
Questa tecnica però aveva due brutti effetti collaterali:
1) Il programma in questione si connetteva a ripetizione verso un Server FTP. Se il server FTP è di una persona consenziente, tutto apposto.. ma se il server FTP è un server pubblico, connettercisi a ripetizione e per giunta per scopi non collegati al normale utilizzo FTP è quantomento sconveniente no? Se non proprio illegale.
2) Con questo programma si otteneva un forward al proprio interno che io ho definito "personale".... e se qualcun'altro avesse avuto bisogno della porta 9999 sul NAT? Con che diritto si può tenere occupata la porta di un server NAT che viene condiviso da più utenti?
Quest'ultima è una mia speculazione, non so se effettivamente usando quel programma il forward sul NAT escludesse totalmente l'uso di quella porta per gli altri utenti..... le mie conoscenze non vanno molto lontano in questo campo :)

si.. se un utente sta usando una connessione sul NAT quella porta resterà occupata fino alla caduta della connessione...
l'associazione 1 a 1 sarebbe km avevi detto prima
utente: porta <--> NAT: porta
non mi è chiaro perchè utilizzare questa tecnica...
non potremmo essere noi a sfruttare direttamente la porta 21 comunicando tramite questa col pc ke sta all'esterno???
in questo modo il pc esterno vedrà direttamente la connessione corrispondente del NAT che equivale alla porta 21 del nostro client fastweb....

Cmq nel nostro caso non si tratterebbe di un uso continuativo che potrebbe sfociare in abuso, ma di una breve apertura di pochi secondi per permettere ai due client che fossero dietro due NAT di reti diverse (non tutti e due FW quindi) di "vedersi" per il tempo necessario a stabilire una connessione permanente (TCP?) tra di loro.

finchè i due client si devono scambiare dati la porta sul NAT sarà occupata...... quindi in pratica per tutta la durata del gioco....

Mi immagino quindi questo scenario, che non so se sia fattibile...

* PC A dietro Fastweb
* PC B dietro ProviderStraniero
Entrambi con problema NAT.
* PC C senza NAT di un loro amico.

il PC C contiene un software (magari Diamond stesso) che permette una connessione di tipo FTP o cmq che abbia la logica necessaria ad effettuare quel forward temporaneo di cui sopra.

1) PC A si connette a PC C e tramite FTP ottiene un forward dal suo NAT al suo indirizzo interno.
2) PC B si connette a PC C e tramite FTP ottiene un forward dal suo NAT al suo indirizzo interno.
3) il PC C comunica a PC A e PC B gli indirizzi NAT-A:Porta e NAT-B:Porta dei forward tramite cui si possono parlare.
4) PC A e PC B effettuano grazie ai forward una connessione TCP tra di loro
5) PC A e PC B lasciano la loro connessione "FTP" verso PC C, ringraziandolo :p

Cionci? Che ne dici?
secondo me lo scenario sarebbe km detto sopra:
1)pc fastweb si connette a pc esterno tramite la porta 21
2)pc esterno vede ip: porta del pc fastweb e la usa per comunicare con lui
c'è però un ovvia controindicazione....
non sarò possibile utilizzare servizi FTP mentre si usa diamonds....

^TiGeRShArK^
13-12-2005, 19:41
ragazzi, per i giochi in java ho sentiito molto parlare di RMI, anche se sono abbastanza ignorante in materia, cerco di documentarmi e vi faccio sapere, cmq, sarei anche interessato a collabborare allo spike che usi udp....
RMI è il Remote Method Invocation utilizzato per chiamare dei metodi su una makkina remota....
in effetti potrebbe essere la scelta migliore... nn ci avevo pensato :Prrr:
non lo mai usato ancora... ma potrebbe essere una cosa buona da fare ora :D

cionci
13-12-2005, 19:43
Secondo me non è il caso di usare questi "trucchi" implementati in Diamonds. Gli utenti fastweb potranno continuare ad usare il loro trucco impostando una porta scelta da Diamonds.

cionci
13-12-2005, 19:47
inoltre tutte le applicazioni che utilizzano scambi di dati in real-time (VoIP, videoconferenze) di solito usano il protocollo RTP che si appoggia a UDP proprio per evitare overhead ke sarebbe inutile e per gestire autonomamente la perdita di pacchetti...
Sì ma RTP comporta notevoli "costi" di programmazione... E' un protocollo molto complesso...soprattutto se viene implementato completamente...

IMHO, ripeto...con la quantità di dati da scambiare che sarà minima TCP è la scelta migliore...

71104
13-12-2005, 19:51
proprio per questo mi sembra un overhead inutile sia htttp ke tcp...
TCP è connection oriented mentre UDP è connection less...
quindi l'overhead di TCP è maggiore.. ma UDP (da quanto ne so io) è inaffidabile: se un pacchetto non arriva per qualche motivo le due partite dei giocatori si sfasano... potremmo progettare il nostro protocollo in maniera tale che al pacchetto successivo si risincronizzino, ma non vedo che problema c'è ad usare il TCP visto che i pacchetti che spediremo saranno probabilmente di piccolissima dimensione...

fek
13-12-2005, 19:53
Sì ma RTP comporta notevoli "costi" di programmazione... E' un protocollo molto complesso...soprattutto se viene implementato completamente...

IMHO, ripeto...con la quantità di dati da scambiare che sarà minima TCP è la scelta migliore...

Provate un paio di soluzioni (TCP/UDP, RMI) e poi vediamo qual e' la migliore per noi, avendo ben presente che il nostro primo interesse e' la semplicita' di implementazione.

cionci
13-12-2005, 20:08
Di RMI non so un .h :stordita:

cionci
13-12-2005, 20:21
ma UDP (da quanto ne so io) è inaffidabile: se un pacchetto non arriva per qualche motivo le due partite dei giocatori si sfasano... potremmo progettare il nostro protocollo in maniera tale che al pacchetto successivo si risincronizzino, ma non vedo che problema c'è ad usare il TCP visto che i pacchetti che spediremo saranno probabilmente di piccolissima dimensione...
E' inaffidabile ma viene usato in praticamente tutti i giochi e sistemi P2P...
La gestione degli ACK e delle ritrasmissioni deve essere fatta tramite applicazione....

E non solo, è usato anche in tutti i sistemi realtime come audio/vido multicast e unicast...tutte applicazioni in cui la perdita di un frame non è fondamentale...ma è fondamentale rispettare delle deadline...

TCP è molto più complesso, ma tutto viene gestito dallo stack TCP/IP, e credo che per la minima quantità di dati trasferita sia preferibile...

DioBrando
13-12-2005, 20:52
E' inaffidabile ma viene usato in praticamente tutti i giochi e sistemi P2P...
La gestione degli ACK e delle ritrasmissioni deve essere fatta tramite applicazione....

E non solo, è usato anche in tutti i sistemi realtime come audio/vido multicast e unicast...tutte applicazioni in cui la perdita di un frame non è fondamentale...ma è fondamentale rispettare delle deadline...

TCP è molto più complesso, ma tutto viene gestito dallo stack TCP/IP, e credo che per la minima quantità di dati trasferita sia preferibile...

Esatto, in tutti i sistemi real-time siano streaming audio/video o altro è + importante la sincronizzazione dei vari flussi che la perdita di qlc pacchetto e quindi si utilizza l'RTP e l'RTSP ( come Windows Media o l'equivalente QuickTime) che si appoggiano sull'UDP per avere una trasmissione dati + leggera che non debba tenere conto del feedback che segnala se il pacchetto è arrivato al destinatario o meno.

L'RTP prevede cmq una sorta di controllo del flusso con l'RTCP che risulta cmq + leggero rispetto al TCP.
link (http://telemat.die.unifi.it/book/VideoConferencing/4rtp/rtp.htm)


Le Remote Method Invocations invece non dovrebbero essere nient'altro che un'evoluzione delle RPC, ma applicate a Java ed alla sua natura ad oggetti.
Mentre con le chiamate di procedura remote, viene invocato un processo su un host da remoto, con le RMI sfruttando la possibilità di chiamare all'interno di una singola applicazione e in locale + metodi per il funzionamento della stessa, si permette di invocare quegli stessi metodi ma da una macchina remota, attraverso un'interfaccia, ed ottenere poi un output di ritorno ( un pò quello che succede con un sito dinamico, quando l'output viene creato in base all'input immesso...giusto per rendere l'idea eh :p).
Quindi n sn un vero e proprio protocollo, quanto un insieme di specifiche utilizzate poi da protocolli o da standard e middleware + in generale come CORBA e WebSphere.


Nello specifico non sò come possano essere implementate in questo caso e n sò se sia così semplice...certo mettono a disposizione strumenti interessanti come la fault tolerance

^TiGeRShArK^
13-12-2005, 21:10
Sì ma RTP comporta notevoli "costi" di programmazione... E' un protocollo molto complesso...soprattutto se viene implementato completamente...

IMHO, ripeto...con la quantità di dati da scambiare che sarà minima TCP è la scelta migliore...
infatti nn dicevo d usare RTP ma UDP :p
cmq potremo saperlo solo facendo un confronto tra tcp e udp col codice secondo me :p

cionci
13-12-2005, 21:26
cmq potremo saperlo solo facendo un confronto tra tcp e udp col codice secondo me :p
Io sono a favore di TCP... Non ci possiamo permettere di perdere un pacchetto...

Ad esempio: con UDP dovremmo gestire le ritrasmissioni e gli ack (o i nack dipende dal protocollo)...e probabilmente anche un minimo di controllo di errore...

Chiaramente se TCP non si rivelasse adatto potremmo sempre ritornare su UDP... Dopo tutto gli spike servono a questo :)

Tutto ovviamente IMHO...

cisc
13-12-2005, 21:51
RMI è stato sviluppato da uno sviluppatore di CORBA, e in giro per internet si dice che i due sistemi convergano...poi, come dicevo, non sono molto ferrato in materia, però sembra che con il nat ci siano grossi problemi anche se è uno solo dei pc ad essere dietro nat

^TiGeRShArK^
13-12-2005, 22:11
ma nn ce l'ha nessuno fastweb per fare qualche prova??? :fagiano:

Ufo13
14-12-2005, 00:20
Io me la testerei con RMI se qualcuno vuole fare una collaborazione ci sto :)

thebol
14-12-2005, 06:57
Io me la testerei con RMI se qualcuno vuole fare una collaborazione ci sto :)

stavo pensando anche io allo spike su rmi.

come èfficenza non lo vedo molto vantaggioso, ma dovrebbe essere molto veloce da implementare(ho gia fatto esperimenti in passato, e con la 1.5 non cè piu manco bisogno di produrre gli skel e gli stu).

stasera esco presto, ma domani possiamo fare 2 chiacchere ;)

cdimauro
14-12-2005, 09:04
Beh, che ognuno faccia lo spike con la tecnologia che conosce/gradisce, e poi si vedrà quale adottare. :D

Jocchan
14-12-2005, 09:10
Accordatevi su MSN se volete cooperare (non è obbligatorio ma può essere utile).
Quindi, se non sbaglio, al momento abbiamo:

RMI - Ufo13 + thebol
TCP - BD + cionci

Chi si offre per UDP? cisc e TigerShark?

fek
14-12-2005, 09:18
Ragazzi, ma prima di iniziare con lo Spike, ricordatevi i task, hanno sempre la priorita'.

A me piace proporre gli Spike, ma se affliggono pesantemente lo sviluppo dei task normali, dovremmo abbandonarli e non voglio farlo. Quindi prima sempre i task :)

^TiGeRShArK^
14-12-2005, 14:50
io x ora sono out......
non ho nemmeno eclipse installato qui... :Prrr:

BlueDragon
14-12-2005, 22:15
Io sarò assente fino a lunedì sera, quindi niente spike né task fino alla prossima settimana :)
Venerdì sono qui: http://www.agileday.it/
C'è per caso qualcun'altro di noi? :)

cionci
14-12-2005, 22:52
No e mi dispiace non poterci essere :cry:

Ufo13
15-12-2005, 07:07
Manco io posso andarci...

Comunque thebol addami pure su MSN ma io prima di martedì sicuramente non potrò lavorarci...

^TiGeRShArK^
15-12-2005, 14:48
Io sarò assente fino a lunedì sera, quindi niente spike né task fino alla prossima settimana :)
Venerdì sono qui: http://www.agileday.it/
C'è per caso qualcun'altro di noi? :)
:cry:
a quando a quando c'è qualcosa di interessante cado malato!!!:cry:

Bonfo
04-01-2006, 00:39
Ho notato solo adesso questo spike...proverò a dire la mia, ora che finalmente sto cominciando a capire qualcosa del progetto !!! :sofico:

Cercherò di anadare per punti.
Il problema centrale, secondo me, è cosa dobbiamo comunicare? In che modo?
1)La prima domanda ci fa capire la quntità di dati che dobbiamo inviare per far funzionare il gioco. Se dobbiamo mandare 1 byte ogni ora ci va bene qualunque overhead...tanto qualsiasi banda riuscira a gestirlo. Se invece dobbiamo mandare 1 Mega ogni secondo...bhè allora il problema è già a livello fisico (livello 1) :cool:

2)Paradigmi di comunicazione: ovvero il problema dell'infrastuttura. Per spiegarmi meglio suddivido il problema su 2 livelli:
a)Da quale livello partiamo. ovvero cosa consideriamo come ABC: le socket,oppure a livello più alto HTTP e FTP, oppure saliamo ancora e usiamo "piattaforme" quali webservice o altro...
b)come vogliamo che si comporti il sitema durante la comunicazione: vogliamo che attenda la risposta, che invece vada avanti qualunque cosa sia successo alla rete, oppure che funzioni anche con il Wifi e anche su una pagina web.

Ora pongo esempi velocissimi per farvi capire quanto questo sciocche coconsiderazioni siano fondamentali (all'uni ci hanno talemte scassato...) :cry: :cry:

Pensiamo ad RMI...questa è un chiamata a procedure remota tra applicazioni java, chi fornisce il metodo remoto si registra ad un ente conosciuto, in modo tale che chi cerca quel servizio presso quell'ente, che deve conoscere, riceve le informazioni per trovare chi espone il metodo per invocarlo. A quel punto all'invocazione si serializza tutto, si manda dall'altra parte che deserializza, opera e poi fa l'operazione contraria per rispondere.
Ma se il "server" si blocca durante il metodo cosa succede...che la nostra applicazione rimane lì ad aspettare finchè il serve non risponde. Traduco: SI IMPALLA TUTTO. :muro: :muro: Da qui ci sono le varie gestioni di time out e cose varie.

Pensia ora invece di usare una infrastuttura a Message Passing (Per Java JMS, non la conosco ma ne ho sentito parlare :mc: ), bene si invia il dato e poi...arrivederci ( modalità asincrona). In questo modo quando arrivera la risposta la valuterò, ma intanto io non mi blocco e posso fare altre operazioni.
A questo punto si pongono i problemi di oggetti ATTIVi, ovvero con processi interni autonomi, che gestiscono le risposte o le richieste remote e/o l'invio di messaggi.

Non sto ancora proponendo soluzioni, ma solo problemi. :Prrr: :Prrr:


Io penso che possa essere utile pensare anche di utilizzare infrastutture a livello più alto che ci nascondano la rete, sempre che l'overhead prodotto sia gestibile. Financo i web service (ci permetterebbe di lavorare tranquillamente con quasiasi sistema di rete)
Secondo me un ottimo approccio potebbe essere di crearciun livello di "comunicazione" intercambiabile per poter usare UDP, TCP, RMI o qualsiai cosa.

Personamente, e finalmente mi scopro :D , io userei RMI o altrimenti un sistema a Message Passing come JMS.


Ora che ho finito il mio sproloquio dico:....non vedo l'ora di fare codice!!! :sofico: :sofico:

CIAO

PS.:non picchiatemi :ave: :ave:

Jocchan
07-02-2006, 11:41
Resuscito questo topic per fare il punto sulla situazione.
Come avrete notato, dopo averne discusso con Fek stamattina, ho modificato la storia per il ciclo 10, posticipando l'introduzione del netcode.
Per la first playable, avremo un multiplayer sullo stesso PC, ed il netcode lo implementeremo in seguito (così avremo già diversi elementi che ci potranno aiutare).
Questo però rende necessario, al più presto, il completamento dei vari spike per l'online, in modo da sapere perfettamente COSA e COME dobbiamo trasmettere.
Quindi, in questo ciclo avremo pochi task, di cui forse solo uno in pair, da completare rapidamente per poi dedicarvi anima e corpo allo spike.
Cerchiamo di terminarlo in tempi brevi, o non potremo iniziare la parte relativa al netcode.

VICIUS
07-02-2006, 17:42
Metto in rilievo il thread che senza uno spike decente non si può andare avanti e ci incagliamo.

ciao ;)

thebol
07-02-2006, 22:01
qualche settimana fa avevo giochicchiato con rmi, ma non ero mai riuscito a fare un vero e proprio spike(cercava di basarmi su diamonds).

ora ho risolto il problema della syncronizzazione fra i Cliente e Server(Semaphore rulez), e sto scrivendo una roba semplice, che mostri la connesione fra server e client, la comunicazione e sync fra i 2(faccio un ping), e il passaggio di un oggetto da una JVM all'altra :)

^TiGeRShArK^
07-02-2006, 22:06
ehm...secondo me la scelta basilare da fare è quale filosofia utilizzare.....
una "incrementale" in cui si suppone che ogni pacchetto arrivi a destinazione (e quindi sono necessarie ritrasmissioni, controllo di flusso ecc.. ecc...) ma che ci consente di inviare solo lo stretto necessario dei dati per aggiornare il gioco.
o una "totale" in cui in ogni pakketto si inviano TUTTE le informazioni per ricostruire solo lo stato del gioco, e quindi, anke se si perdesse un pakketto, con l'arrivo del pakketto successivo il gioco è di nuovo sincronizzato.
In base a questa scelta potremo decidere se indirizzarci verso una connessione connection oriented (quale il TCP o l'RMI) o una connection less (UDP).
Ovviamente potrebbero essere implementate anke soluzioni UDP con la filosofia "incrementale" e viceversa, però ci complicheremo molto la vita per gestire tutto il controllo di flusso come diceva cionci....
IMOH la prima cosa da fare è vedere la mole di dati che è in gioco sia per implementare le due filosofie...
se ci rendiamo conto che quella totale ad esempio richiede 8 KB/sec già potremo scartarla se vogliamo che si possa giocare anche con un normalissimo modem (in cui la comunicazione bidirezionale avviene ad un max di 4.2 KB/sec)....
Quindi tanto per concludere...
quali sono i dati che abbiamo intenzione di scambiare???
che tipo di meccanismo di sincronizzazione intendiamo implementare???
sulla base della risposta a queste domande imho avremo qualke dato in + per effettuare una scelta definitiva.....

EDIT: dimenticavo... da quello ke ho visto dell'RMI la mole di dati in gioco è sicuramente maggiore....se dovessimo fare diamonds per banda larga non avrei alcun dubbio se usare RMI oppure no, ma per un modem normale qualke dubbietto ce l'avrei onestamente....

thebol
08-02-2006, 07:03
rmi finche nn passi oggetti o molti parametri a una chiamata, nn penso occupi poi molto(sempre piu di una trasmissione codata ad HOC certo, ma se la nostra mole di dati di "business" non è alta allora puo essere trascurabile)

cmq nello spike faro qualche prova sulla bandwith consumata :)

^TiGeRShArK^
08-02-2006, 10:49
si infatti... sarebbe motlo utile... ;)
tieni conto che ad occhio non possiamo permetterci di inviare piu' di 3KB/sec x un modem (e già è un limite massimo) poikè dovrà inviare 3 KB/s e ricevere altrettanto per un totale di 6KB/s....
questi sono equivalenti ad una connessione a 48000 kbps sfruttata pienamente... ke mi pare già una situazione abbastanza rara x un 56K tipico.....
forse uno scenario piu' corretto sarebbe non superare i 2KB/s...
ah... e cmq stavo pensando che per una prova reale ci occorre considerare anche le latenze...
per implementare meccanismi di ritrasmissione queste cresceranno DI MOLTO nel caso di perdita di un pacchetto .... e mi sa che non ce lo potremo permettere durante il gioco...
Ad occhio, da quello ke ho pensato ieri sera la soluzione migliore sarebbe un approccio connection less con l'invio di tutte le informazioni necessarie per ricostruire lo stato dell'area di gioco dell'altro giocatore....

cionci
08-02-2006, 10:57
Se trasmettiamo gli eventi non possiamo permetterci di perdere nemmeno un pacchetto...se trasmettiamo le posizioni sì...

^TiGeRShArK^
08-02-2006, 11:41
Se trasmettiamo gli eventi non possiamo permetterci di perdere nemmeno un pacchetto...se trasmettiamo le posizioni sì...
si infatti...
ad esempio cosnidera il caso di un pacchetto perso trasmettendo gli eventi....
abbiamo ke ogni 20 ms parte un pakketto (nel caso in cui ad esempio l'utente tiene spinto un tasto di movimento) se perdiamo un pacchetto allora dovremo attendere che scada un timeout (che imho dovrebbe essere almeno il doppio del ping medio), e quindi inviarlo nuovamente, col risultato che arriverà in un'ordine diverso rispetto a quando è partito (con circa 200 ms di ritardo considerando un Round Trip Time di 200 ms)....
In questo modo avremo il pacchetto di un evento molto dopo rispetto alla sua generazione, e quindi perderemo cmq la sincronia degli stati delle due piattaforme di gioco.
Quindi IMHO l'unica soluzione accettabile è l'invio di informazioni globali (ad esempio le posizioni, ma non sono sicuro che siano sufficienti da sole) che permettano di ricostruire lo stato del gioco ad ogni istante fregandosene completamente dei parchetti persi ....

Jocchan
08-02-2006, 12:52
si infatti...
ad esempio cosnidera il caso di un pacchetto perso trasmettendo gli eventi....
abbiamo ke ogni 20 ms parte un pakketto (nel caso in cui ad esempio l'utente tiene spinto un tasto di movimento) se perdiamo un pacchetto allora dovremo attendere che scada un timeout (che imho dovrebbe essere almeno il doppio del ping medio), e quindi inviarlo nuovamente, col risultato che arriverà in un'ordine diverso rispetto a quando è partito (con circa 200 ms di ritardo considerando un Round Trip Time di 200 ms)....
In questo modo avremo il pacchetto di un evento molto dopo rispetto alla sua generazione, e quindi perderemo cmq la sincronia degli stati delle due piattaforme di gioco.
Quindi IMHO l'unica soluzione accettabile è l'invio di informazioni globali (ad esempio le posizioni, ma non sono sicuro che siano sufficienti da sole) che permettano di ricostruire lo stato del gioco ad ogni istante fregandosene completamente dei parchetti persi ....

E' un'ottima soluzione, Tiger. Vuoi lavorarci tu?

^TiGeRShArK^
08-02-2006, 13:08
E' un'ottima soluzione, Tiger. Vuoi lavorarci tu?
ehm....finito lo spike potrei provarci.... solo ke spero di finire prima del weekend perkè durante il weekend non ci sono :fagiano:
cmq come dicevo prima secondo me dovremo accordarci prima di iniziare lo spike sul formato delle informazioni da trasmettere...
ad esempio cioci prima parlava della posizione della gemma in movimento.... però oltre a queste imho ci vorrebbero delle informazioni necessarie a stabilire la velocità della gemma oltre alla posizione...
infatti se mandassimo ad esempio un informzaione di posizione ad ogni cambio di cella, l'utente collegato in rete vedrà il gioco andare "a scatti" poichè la gemma si muoverà di una cella alla volta in maniera "discretizzata"....
invece inserendo le informazioni sulla velocità potremo far muovere la gemma del secondo giocatore esattamente alla stessa velocità con cui si muove la gemma del primo (esempio caduta normale o caduta veloce) e quindi il secondo giocatore potrà vedere un comportamento + naturale e del tutto analogo a quello del suo gioco in locale.......
Cmq secondo me non è una cosa tanto facile da implementare... quando si ha a ke fare con la rete saltano sempre fuori i problemi + inaspettati.... e x risolverli imho l'unico modo è mettere da parte per una volta la filosofia e abbiamo sempre utilizzato e fare un'approfondita analisi prima di partire a scrivere codice sulla modellizzazione del comportamento della gemma ke vorremmo osservare e su come implementarlo.....
In pratica dovremo decidere come dicevo il formato esatto dei dati da scambiarci e solo dopo potremo affrontare le eventuali problematiche di rete basandoci su una simulazione effettiva di quello ke dovrà avvenire durante il gioco.....

P.S. ora arriva fek e mi spezza le ditine... :cry:
...ma a proposito... ke fine ha fatto??? :confused:

Bonfo
08-02-2006, 13:27
Da quello che ho capito, Fek è impegnatissimo: tra trasloco, preparazione del GDC (http://www.gdconf.com/) e altro....ha detto che per almeno un paio di settimane non lo vediamo.

Per ciò che riguarda lo spike, sono d'accordissimo con Tiger...finchè non sappiamo di cosa c'è bisogno, a livello di informazioni, non si può andare troppo avanti.

Per spezzare una lancia in favore di RMI, potrei dire che si dovrebbe riuscire ad andare avanti TDD, dovrebbe usare UDP e la gestione delle ritrasmissioni e sincronizzazioni, se opportunamente pensato, lo gestisce lui per noi. Inoltre risulterebbe molto più facile da implementare...basta remotizzare un paio di metodi (in particolare gli handler).

Io mi lancerei volentieri...ma queste settimane devo recuperare un po' di roba arretrata.
Non riesco nenanche a fare un TASK.... :cry: :cry:

...se riesco a portarmi abbastanza avanti, provo lo spike...sempre che non sia rimasto un task libero :Prrr:

Jocchan
08-02-2006, 14:11
Ricordiamoci che lo spike è importante, o non potremo andare oltre, ma i task hanno sempre priorità ;)

Ufo13
08-02-2006, 19:04
secondo me passare tutti i dati della tabella è troppo vulnerabile come sistema...

cionci
08-02-2006, 19:15
secondo me passare tutti i dati della tabella è troppo vulnerabile come sistema...
Ma è recuperabile in caso di perdita di messaggi...perchè l'informazione non è differenziale...

^TiGeRShArK^
08-02-2006, 19:46
secondo me passare tutti i dati della tabella è troppo vulnerabile come sistema...
ehm.. quale tabella???
mi sono perso qualkosa??? :fagiano:

Ufo13
08-02-2006, 22:15
Ma è recuperabile in caso di perdita di messaggi...perchè l'informazione non è differenziale...

con UDP implementato bene si risolve tutto a mio parere... Mandare tutta la griglia ogni volta è inutile... Al massimo si può fare una sincronizzazione...

Poi mandando tutta la griglia in chiaro si rischiano hack di ogni tipo... Per me è meglio di no...

^TiGeRShArK^
08-02-2006, 23:10
....
ma infatti ki ha parlato di mandare tutta la griglia? :fagiano:
io mi riferivo a inviare tutta le informazioni necessarie per ricreare il gioco dall'altra parte.. ovvero quelle necessarie a ricostruire la posizione e la velocità (l'accelerazione non ci serve per fortuna :D) della coppia di gemme ke in quel momento stanno scendendo...
se abbiamo gestito correttamente questa situazione le due griglie dovrebbero essere gestite correttamente dalla logica del gioco in teoria...

nihil84
09-02-2006, 10:50
ma nn ce l'ha nessuno fastweb per fare qualche prova??? :fagiano:

Io non ho fastweb ma sono dietro ad un NAT (anzi per essere precisi ne ho due... ). Tra l'altro di mia proprieta', quindi posso anche configurarli a piacere.

Mi rendo disponibile per le prove ma devo avanzare qualche dubbio:

Un NAT, grossomodo funziona cosi':
1) Per ogni pacchetto in uscita memorizza host di destinazione, porta di destinazione, host interno sorgente e porta sorgente.
2) Associa a questa quaterna di numeri una sua porta (+ o - a caso)
3) Sostituisce sul pacchetto host e porta sorgente con il suo indirizzo e la porta appena scelta
4) Ogni qualvolta riceve un pacchetto su quella porta proveniente da quell'host sulla porta di destinazione letta prima fa la sostituzione inversa dei campi che adesso sono host e porta destinatari

Quindi se riuscissimo a far comunicare due host attraverso una porta "instanziata" per un'altra comunicazione (con il fantomatico server esterno) credo che la cosa potrebbe essere catologata tra gli exploit :)

Credo che gli utenti di fastweb non abbiano fatto altro che reinventare l'ftp bounce attraverso i comandi ftp PORT e RETR (IMHO)
Un programma che faccia questo in automatico deve avere aperte 2 connessioni con il server ftp:
Per ogni pacchetto di dati da inviare al destinatario vero e proprio deve essere inviato al server ftp un file contenente questi dati (non importa se in codifica ascii o in binario raw) tramite una connessione ftp "standard" e poi tramite una connessione telnet (piu' versatile) allo stesso server ftp si inviano i comandi:

> PORT host:port
> RETR nomefile


Il comando PORT puo' essere inviato solo una volta all'inizio della sessione.

L'effetto pratico e' lo stesso di una connessione diretta ma lo scopo principale di questa tecnica (almeno quando la imparai) era quella di mantenere l'anonimato...
Funziona ma il server ftp deve essere sempre disponibile ad effettuare il tunneling.

Questo e' quello a cui penserei io ma potrebbero anche aver trovato delle soluzioni piu' efficienti e interessanti!

cionci
09-02-2006, 13:52
Secondo me ci dovremmo preoccupare dopo degli utenti dietro NAT...

Ufo13
09-02-2006, 15:01
Secondo me ci dovremmo preoccupare dopo degli utenti dietro NAT...

Mi trovo d'accordo... Ora bisogna pensare a COSA inviare per rendere il tutto stabile e sicuro...

cionci
09-02-2006, 15:11
Ora bisogna pensare a COSA inviare per rendere il tutto stabile e sicuro...
Anche perchè qualsiasi "cosa" invieremo i problemi sarebbero comunque i soliti...e quindi risolvibili in maniera comune in un secondo momento...

fek
10-02-2006, 10:02
Secondo me ci dovremmo preoccupare dopo degli utenti dietro NAT...

YAGNI. Se ne parla dopo. Se volete fare qualche test fate pure, ma non perdeteci troppo tempo (prima i task). C'e' un articolo interessante proprio su questo argomento (il passaggio attraverso i NAT) su un recente Game Programming Gems. Se riesco vi trovo una versione online.

^TiGeRShArK^
10-02-2006, 13:19
su un recente Game Programming Gems.
:rotfl:
ci hanno pure dedicato una rivista??? :D

^TiGeRShArK^
10-02-2006, 23:42
allora... ho fatto un pikkolo e semplice spike mandando 50 pakketti udp al secondo... il traffico generato esclusi gli header ethernet che non avremo via modem è pari a 47 byte a pacchetto....
in pratica verrà generato un traffico di 2350 byte al secondo...
imho è meglio ridurre un pò il campionamento intorno ai 30 pacchetti al secondo... ma questo lo potremo decidere solo con delle prove sul campo...
il traffico cmq è così suddiviso:

20 byte di header ip
8 byte di header udp
11 byte di dati
8 byte che non ho capito da dove spuntano...:confused:


ovviamente questi 36 byte saranno sempre fissi, quindi anke mandando un pakketto vuoto ci saranno sempre....
quindi.. supponendo l'invio di 36 byte di informazioni su diamonds 30 volte al secondo avremo in totale 2160 byte al secondo inviati... ke mi sembra abbastanza accettabile.....
qualcuno ha i dati riguardanti la dimensione dei pacchetti con TCP e con RMI così possiamo fare qualke confronto e pesare i pro e i contro delle varie scelte???

EDIT: l'occupazione di banda con l'ultima soluzione proposta (36 byte di info con UDP X 30 pakets/sec) considerando sia il traffico in upload ke in download (ke, ricordo, è condiviso) è pari a 34560 Kbps

VICIUS
11-02-2006, 00:26
Cosi a memoria mi sembra di ricordare che l'overhead minimo di un pacchetto tcp è di 24 byte ma può crescere.

^TiGeRShArK^
11-02-2006, 01:02
Cosi a memoria mi sembra di ricordare che l'overhead minimo di un pacchetto tcp è di 24 byte ma può crescere.
ehm..si + o -..
il pakketto TCP base SENZA alcuna options è di 20 byte contro gli 8 dell'UDP...
ma volevo piu' ke altro qualke dato derivante da un uso "reale" del TCP fatto in java + o - come ho fatto io sniffando il pakketto in modo da vedere nella realtà come vengono creati questi pakketti..
ank'io mi aspettavo ad esempio 20 byte di IP + 8 di UDP... ma poi mi sono ritrovato 8 byte catalogati come "dati" all'interno del payload del pakketto ke non mi spiego da dove vengano fuori....
In questo modo possiamo studiare i vari casi come vengono usati da java nella raltà ;)

cdimauro
11-02-2006, 05:55
Hai aggiunto anche un byte di checksum e uno di sequenza (ID del pacchetto spedito) ai dati?

Ufo13
11-02-2006, 07:39
gli UDP non credo abbiano ISN...

cionci
11-02-2006, 08:12
Edit: con riferimento a questo post: http://www.hwupgrade.it/forum/showpost.php?p=11245016&postcount=52

Sono arrivato alla conclusione che la soluzione sopra (vedi post linkato) sarebbe applicabile anche per il netgame...però bisogna aggiungere la gestione dei timer che avevo proposto diversi post sopra... Ovviamente non ci possiamo permettere di avere nemmeno una perdita di pacchetto... Inoltre potremmo stimare automaticamente il Ping, abbiamo già un timer, se un pacchetto arriva dopo la scadenza del tempo previsto per eseguire tale azione di può aumentare il lag del timer, che di conseguenza può essere una stima del ping...

cdimauro
11-02-2006, 09:32
Appunto per questo servirebbe un meccanismo del genere: l'UDP è un protocollo non affidabile per definizione. ;)

thebol
11-02-2006, 10:04
Sono arrivato alla conclusione che la soluzione sopra sarebbe applicabile anche per il netgame...però bisogna aggiungere la gestione dei timer che avevo proposto diversi post sopra... Ovviamente non ci possiamo permettere di avere nemmeno una perdita di pacchetto... Inoltre potremmo stimare automaticamente il Ping, abbiamo già un timer, se un pacchetto arriva dopo la scadenza del tempo previsto per eseguire tale azione di può aumentare il lag del timer, che di conseguenza può essere una stima del ping...
come lag del timer intendi il ritardo della griglia remota?

sono d'accordo che la griglia remota sia in ritardo rispetto a quella client(ping calcolato prima di incominciare) ma la variazione di questo ritardo puo essere molto complessa, visto che il gameTurn della griglia client e quella remota devono essere syncronizzati(intendo quelle che si vedranno nell'area gioco).

Direi cmq che idee per iniziare ce ne sono, manca il come gestire grossi lag ma ci si puo guardare sucessivamente.

^TiGeRShArK^
11-02-2006, 10:04
Appunto per questo servirebbe un meccanismo del genere: l'UDP è un protocollo non affidabile per definizione. ;)
no UDP non ha sequence number, ha solo il checksum...
ma cmq secondo me è inutile utilizzare protocolli piu' pesanti quando potremmo gestircelo noi il checksum in quanto dovremmo semplicemente scartare i pacchetti fuori sequenza...
RTP ad esempio utilizza un sequence number a 16 bit... che per i nostri scopi è già troppo...
mandando 30 pacchetti al secondo imho ci potrebbe bastare un byte di seqeunce number in quanto per completare il giro avremo bisogno di 8 secondi e mezzo ke è già abbastanza raro come caso...
se poi volessimo la certezza assoluta basterebbe utilizzare un sequence numer a 16 bit proprio come RTP;)

^TiGeRShArK^
11-02-2006, 10:28
Sono arrivato alla conclusione che la soluzione sopra sarebbe applicabile anche per il netgame...però bisogna aggiungere la gestione dei timer che avevo proposto diversi post sopra... Ovviamente non ci possiamo permettere di avere nemmeno una perdita di pacchetto... Inoltre potremmo stimare automaticamente il Ping, abbiamo già un timer, se un pacchetto arriva dopo la scadenza del tempo previsto per eseguire tale azione di può aumentare il lag del timer, che di conseguenza può essere una stima del ping...
ehm... non si può......
internet è per definizione una rete best-effort, non puoi avere alcuna garanzia sull'arrivo di tutti i pacchetti e soprattutto sull'arrivo nello stesso ordine in cui li hai inviati..
TCP tenta di superare queste limitazioni utilizzando dei buffer per la ricezione e implmentando dei meccanismi di ritrasmissione...
come ho già detto però non non ci possiamo permettere alcuna ritrasmissione...
Una piccola legenda per capire meglio quello ke scrivo in seguito....RTT = Round Trip Time ovvero il tempo medio impiegato da un sender per inviare un pakketto e ricevere una risposta dal receiver.
immagina un pò questa situazione:
0 Pack1 inviato ---> ricevuto all'istante 120
33 Pack2 inviato ---> ricevuto all'istante 153
66 Pack3 inviato ---> non viene ricevuto
99 Pack4 inviato ---> ricevuto all'istante 219
..........
546 scadenza del timeout (ke mi sa ke non è pari ad un RTT = 120 x 2 ma a 2-3 RTT, supponiamo il caso migliore di 2RTT = 480ms)
546 Pack3 reinviato ---> ricevuto all'istante 666

In questa situazione la nostra elaborazione è rimasta blokkata per ben 513ms....Invece utilizzando un meccanismo che non necessiti la sicurezza ke ogni pakketto arrivi potremo avere:
0 Pack1 inviato ---> ricevuto all'istante 120
33 Pack2 inviato ---> ricevuto all'istante 153
66 Pack3 inviato ---> ricevuto all'istante 225
99 Pack4 inviato ---> ricevuto all'istante 219

Come potete vedere ammettendo ke riceviamo il pakketto 3 fuori sequenza (o ancora meglio non lo riceviamo) ci basterà scartarlo e utilizzare le informazioni fornite dal pakketto successivo, ke nel nostro esempio è arrivato dopo altri 33ms...
in realtà le cose non stanno affatto così... ogni pakketto potrebbe prendere strate diverse all'interno dei vari router, e, anke se l'RTT medio potrebbe non cambiare di molto la sua varianza(o COvarianza:mbe: non mi ricordo +...:fagiano: ) è abbastanza elevata.
Concludendo...
secondo me la soluzione che prevede la sicurezza dell'arrivo di ogni pacchetto è da scartare...vedo molto + adatta al nostro caso un'implementazione basata su UDP....

EDIT: trovate le formule per il calcolo del timeout con TCP:
http://www.icar.cnr.it/cannataro/unical/SER-2002-2003/SER-Reti-Lezione05.pdf
Slide 5-36
Alpha viene solitamente posto ad 1/8 nella prima formula e ad 1/4 nella seconda se non erro...

cionci
11-02-2006, 10:50
Ok...ma le soluzioni UDP (senza contare ritrasmissioni e gestione della sequenza) e TCP partono da presupposti diversi:

- quella UDP non può funzionare a scambio di eventi, ma deve funzionare trasmettando la posizione corrente delle varie gemme nella griglia (ovviamente solo quelle che hanno variato la loro posizione)
- quella TCP invece può benissimo funzionare con la trasmissione degli eventi

^TiGeRShArK^
11-02-2006, 10:59
Ok...ma le soluzioni UDP (senza contare ritrasmissioni e gestione della sequenza) e TCP partono da presupposti diversi:

- quella UDP non può funzionare a scambio di eventi, ma deve funzionare trasmettando la posizione corrente delle varie gemme nella griglia (ovviamente solo quelle che hanno variato la loro posizione)
- quella TCP invece può benissimo funzionare con la trasmissione degli eventi
appunto... è proprio questo il problema...
secondo me non possiamo basarci sulla trasmissione di eventi proprio perchè saremmo troppo dipendenti dalla ricezione di tutti i pacchetti... e atraverso internet questo è tutt'altro ke scontato... fossimo in una LAN avremmo già potuto trascurare questo problema...
qdi secondo me ci dovremo concentrare nel cercare di capire quali sono le informazioni strettamente necessarie a sincronizzare le due griglie da inviare, possibilmente senza inviare la posizione di tutte le gemme....

cisc
11-02-2006, 11:37
sono d'accordo con ^TiGeRShArK^ sull'uso dell'udp e sull'invio delle gemme che hanno cambiato posizione, dobbiamo però stare attenti alla gestione dei pacchetti persi ed al problema che con udp i pacchetti non necessariamente arrivano nell'ordine in cui sono stati inviati, nei software voip si usa introdurre un ritardo al momento della ricezione, bufferizzando i pacchetti e scartando quelli che sono arrivati troppo tardi, dobbiamo studiare una soluzione simile a mio parere

cionci
11-02-2006, 11:44
Secondo me inviando gli eventi la quantità di pacchetti sarà bassissima (al contrario inviando la variazione di posizione dovremo inviare un pacchetto almeno ogni updaterate)... Ricordate che se non ci sono eventi non dobbiamo inviare niente !!!
Quindi confermo di essere tutt'ora orientato verso il TCP....

thebol
11-02-2006, 11:56
Secondo me inviando gli eventi la quantità di pacchetti sarà bassissima (al contrario inviando la variazione di posizione dovremo inviare un pacchetto almeno ogni updaterate)... Ricordate che se non ci sono eventi non dobbiamo inviare niente !!!
Quindi confermo di essere tutt'ora orientato verso il TCP....

*


se la bandwith usando tcp non ci creerà problemi, non vedo perche usare udp + altre logiche, quando tcp ce le fornisce tutte

cisc
11-02-2006, 12:28
a mio avviso però con il tcp avremmo problemi di ritardo

^TiGeRShArK^
11-02-2006, 12:37
*


se la bandwith usando tcp non ci creerà problemi, non vedo perche usare udp + altre logiche, quando tcp ce le fornisce tutte
xkè TCP ci fornisce la logica ma non ci garantisce assolutamente che i nostri pacchetti arrivino tutti..o meglio ... non ci garantisce ke arrivino SENZA latenze paurose che blokkerebbero l'elaborazione del nostro programma...
secondo me è abbastanza fastidioso ke quando si perde un pakketto si abbia MINIMO mezzo secondo di freeze (e in certi casi si può arrivare tranquillamente a qualke secondo) con subito dopo l'effetto di "accelerazione" che riporta lo stato a quello corrente....
se riuscissimo a trovare un modo con udp per inviare delle informazioni che ci consentano di ricostruire lo stato del gioco ad ogni pakketto sarebbe imho la soluzione migliore...
X rsp anke a cionci ... secondo me infatti non è importante inviare continuamente la posizione della gemma in movimento, quanto piuttosto la posizione E la velocità...
in questo modo, anke supponendo di perdere due pakketti di fila, non avremo alcun freeze, ma la nostra gemma continuerà a cadere o a muoversi nella stessa direzione in cui si stava muovendo per un max di 90 ms, al termine dei quali andrà ad occupare la posizione giusta, sempre ke sia diversa dalla posizione elaborata dal nostro programma con i dati ke aveva a disposizione in quel momento...
cmq forse la cosa migliore che ci tokkerà fare è astrarre completamente la logica del gioco del livello di rete e provare in ambedue i casi qual'è la situazione migliore...
poi starà a noi decidere una volta visti i due compartamenti...
probabilmente conviene implementare prima la soluzione TCP dato ke mi sembra la + facile da creare, e una volta provata CON DEI MODEM, potremo decidere se ci soddisfa o no, e altrimenti passare all'implementazione con UDP ke dovrebbe essere piu' robusta ai problemi di rete.....
cmq vada non la vedo tanto banale la gestione del multiplayer :fagiano:

cionci
11-02-2006, 12:42
a mio avviso però con il tcp avremmo problemi di ritardo
Come dicevo basta dimensionare dinamicamente il ritardo fra il timer della grglia remota e quelo della grglia locale...

Ad esempio una politica potrebbe essere:

- il ritardo può solo aumentare durante la discesa della gemma (per non avere brutti effetti ottici durante la caduta)
- il ritardo può diminuire solo durante le cancellazioni e l'attesa per la nuova coppia di gemme, in questo momento i due programmi si scambiano un pacchetto di sincronizzazione

Prima ho detto una ca@@ata...bisogna comunque scambiare un messaggio vuoto (con il solo contatore) ogni "InputRate", anche se non ci sono eventi...infatti questo ci serve per sincronizzare la discesa della gemma... Se il messaggio non arriva in tempo bisogna ritardare il timer fino all'arrivo del messaggio...

cionci
11-02-2006, 12:43
cmq vada non la vedo tanto banale la gestione del multiplayer :fagiano:
No per niente...ed è una cosa molto interessante...

^TiGeRShArK^
11-02-2006, 13:02
Prima ho detto una ca@@ata...bisogna comunque scambiare un messaggio vuoto (con il solo contatore) ogni "InputRate", anche se non ci sono eventi...infatti questo ci serve per sincronizzare la discesa della gemma... Se il messaggio non arriva in tempo bisogna ritardare il timer fino all'arrivo del messaggio...
appunto.. le problematike di rete sono MOLTO complesse ;)(e ne so qualcosa dopo 6 anni di ing telecomunicazioni :fagiano: )
imho è un problema ke dovremo affrontare con le molle....
la mia idea sapete qual'è però siamo sempre in tempo a provare le due strade

Bonfo
11-02-2006, 13:22
Fek mi ha fatto male....ha traviato la mia mente. :D
Anch'io prima mi sarei messo 1 mese a cercare di capire e pensare tutto...ma adesso mi veiene da dire:

proviamo uno spike per far funzionare il gioco in multiplayer su una stessa macchina. Stesso IP (127.0.0.1, localhost) e diversa porta...e vediamo se riusciamo a far comunicare le due istanze dell'applicazione.
Nel modo più semplice che viene, UDP, TCP, RMI, SMTP ( :Prrr: )...insomma quello che viene.
A quel punto sapremo perfettamente quali informazioni ci servono.

Poi si porta il tutto su 2 machine diverse, dove il parallelismo di esecuzione è reale, e vediamo che accade, se è un LAN è meglio...non vediamo problemi lag o NAT o PROXY o altro.

Poi siporta il tutto in remoto...e poi risolveremi i problemi di NAT e altro.

Penso che sia il modo migliore di procedere...incrementale.
Penso sia troppo difficile riuscire a mettere su carta tutti possibili problemi e variabili in gioco.

Se non siete d'accordo...va benissimo ;)

cionci
11-02-2006, 13:29
Se non siete d'accordo...va benissimo ;)
Ehm...mi sembrava che questa cosa fosse chiara :wtf:

comunque aspetterei la fine della storia 10.2, anche perchè fornisce gli strumenti per far funzionare la strada TCP che avevo proposto io...

^TiGeRShArK^
11-02-2006, 13:47
Fek mi ha fatto male....ha traviato la mia mente. :D
Anch'io prima mi sarei messo 1 mese a cercare di capire e pensare tutto...ma adesso mi veiene da dire:

proviamo uno spike per far funzionare il gioco in multiplayer su una stessa macchina. Stesso IP (127.0.0.1, localhost) e diversa porta...e vediamo se riusciamo a far comunicare le due istanze dell'applicazione.
Nel modo più semplice che viene, UDP, TCP, RMI, SMTP ( :Prrr: )...insomma quello che viene.
A quel punto sapremo perfettamente quali informazioni ci servono.

Poi si porta il tutto su 2 machine diverse, dove il parallelismo di esecuzione è reale, e vediamo che accade, se è un LAN è meglio...non vediamo problemi lag o NAT o PROXY o altro.

Poi siporta il tutto in remoto...e poi risolveremi i problemi di NAT e altro.

Penso che sia il modo migliore di procedere...incrementale.
Penso sia troppo difficile riuscire a mettere su carta tutti possibili problemi e variabili in gioco.

Se non siete d'accordo...va benissimo ;)
infetto era quello ke intendevo con la mia proposta di astrarre lo strato di rete e di implementare la soluzione piu' semplice ;)

cionci
11-02-2006, 13:52
infetto era quello ke intendevo con la mia proposta di astrarre lo strato di rete e di implementare la soluzione piu' semplice ;)
Non è tanto semplice un'astrazione di questo tipo... Pensa che con UDP trasferiamo mele e con TCP pere...quindi è nettamente diverso...

thebol
11-02-2006, 14:10
xkè TCP ci fornisce la logica ma non ci garantisce assolutamente che i nostri pacchetti arrivino tutti..o meglio ... non ci garantisce ke arrivino SENZA latenze paurose che blokkerebbero l'elaborazione del nostro programma...
secondo me è abbastanza fastidioso ke quando si perde un pakketto si abbia MINIMO mezzo secondo di freeze (e in certi casi si può arrivare tranquillamente a qualke secondo) con subito dopo l'effetto di "accelerazione" che riporta lo stato a quello corrente....

si, ma anche no ( :) ) visto che la maggior attenzione del giocatore non sara rivolta verso la griglia avversaria ma verso la propria(e cmq una cosa da valutare col customer)


se riuscissimo a trovare un modo con udp per inviare delle informazioni che ci consentano di ricostruire lo stato del gioco ad ogni pakketto sarebbe imho la soluzione migliore...
X rsp anke a cionci ... secondo me infatti non è importante inviare continuamente la posizione della gemma in movimento, quanto piuttosto la posizione E la velocità...
in questo modo, anke supponendo di perdere due pakketti di fila, non avremo alcun freeze, ma la nostra gemma continuerà a cadere o a muoversi nella stessa direzione in cui si stava muovendo per un max di 90 ms, al termine dei quali andrà ad occupare la posizione giusta, sempre ke sia diversa dalla posizione elaborata dal nostro programma con i dati ke aveva a disposizione in quel momento...
cmq forse la cosa migliore che ci tokkerà fare è astrarre completamente la logica del gioco del livello di rete e provare in ambedue i casi qual'è la situazione migliore...

e se perdiamo le info in una situazione con gemme "quasi atterrate"?
verrebbero scatenate tutte le logiche di bigGem, etc da cui sarebbe difficile rollbackare

cionci
11-02-2006, 14:12
e se perdiamo le info in una situazione con gemme "quasi atterrate"?
verrebbero scatenate tutte le logiche di bigGem, etc da cui sarebbe difficile rollbackare
Infatti...

Ufo13
11-02-2006, 19:26
Non sono assolutamente d'accordo riguardo il TCP...

è vero che garantisce l'arrivo dei pacchetti nell'ordine prestabilito ma non ci aiuta assolutamente in questo caso... Con UDP possiamo tranquillamente numerare gli eventi ed avere questa gestione...

Poi il TCP è decisamente scarso per quanto riguarda questo genere di applicazione per la quale UDP si presta meglio... Infatti videogiochi ed applicazioni realtime usano UDP.

cionci
11-02-2006, 19:34
Poi il TCP è decisamente scarso per quanto riguarda questo genere di applicazione per la quale UDP si presta meglio... Infatti videogiochi ed applicazioni realtime usano UDP.
Ma gli altri videogiochi hanno una quantità di informazioni da scambiare nettamente più grande... Doversi mettere a gestire le ritrasmissioni e la gestione della sequenza su UDP non è affatto una cosa semplice...

Ufo13
11-02-2006, 20:26
Non la vedo così ostica... Basta numerare i pacchetti ed usiamo una window per gestire la ricostruzione...

thebol
11-02-2006, 21:47
Non la vedo così ostica... Basta numerare i pacchetti ed usiamo una window per gestire la ricostruzione...

e se si perde un pacchetto/evento?

^TiGeRShArK^
11-02-2006, 22:02
ma xkè il tcp ke fa??? :D
usa le logike appena descritte da ufo13 implementando un protocollo di ricezione a finestra ed usa dei timeout per gestire la ritrasmissione calcolati con la formula ke avevo postato prima :D
cmq secondo me senza fare delle prove pratike non potremo decidere...
fino ad allora potremo solo ammazzarci i neuroni a seghe mentali :sofico:

Ufo13
11-02-2006, 22:08
e se si perde un pacchetto/evento?

La window non procede finchè non abbiamo la sequenza corretta... Ora non ho link da porti ma se cerchi il meccanismo della (sliding?) window in TCP capisci subito :)

Tigershark non c'entra il fatto che TCP faccia la stessa cosa... UDP non è connection oriented ed instrada ogni pacchetto scegliendo il routing migliore cosa che TCP non fa :)

Ufo13
11-02-2006, 22:09
La window non procede finchè non abbiamo la sequenza corretta... Ora non ho link da porti ma se cerchi il meccanismo della (sliding?) window in TCP capisci subito :)

Tigershark non c'entra il fatto che TCP faccia la stessa cosa... UDP non è connection oriented ed instrada ogni pacchetto scegliendo il routing migliore cosa che TCP non fa :)

Comunque se si perdono eventi i client possono chiedere la ri-sincronizzazione degli stati... Cosa che va gestita al meglio per evitare hacks :)

^TiGeRShArK^
11-02-2006, 22:23
La window non procede finchè non abbiamo la sequenza corretta... Ora non ho link da porti ma se cerchi il meccanismo della (sliding?) window in TCP capisci subito :)

Tigershark non c'entra il fatto che TCP faccia la stessa cosa... UDP non è connection oriented ed instrada ogni pacchetto scegliendo il routing migliore cosa che TCP non fa :)
ehm...ora non ricordo di preciso...
ma sicuro ke i router su internet rispettino tutti l'instradamento specificato da TCP???
se non sbaglio quella era solo un'indicazione di massima, ma poi sta al singolo routere decidere se seguire quell'indicazione....
o no??? :fagiano:
Da uqello ke mi ricordavo io le unike reti connection oriented "reali" erano ATM e l'FDDI (ks si kiama?:confused: ) su fibra...

Ufo13
11-02-2006, 22:42
Ma non so... Non credo abbia così importanza... Comunque provate con quello che preferite... Io andrei di UDP...

Purtroppo non potrò iniziare il mio spike prima di metà marzo quindi buon lavoro :p

^TiGeRShArK^
11-02-2006, 23:08
Ma non so... Non credo abbia così importanza... Comunque provate con quello che preferite... Io andrei di UDP...

Purtroppo non potrò iniziare il mio spike prima di metà marzo quindi buon lavoro :p
esami? :asd:
cmq ora vediamo kosa fare :D

Ufo13
12-02-2006, 08:26
laurea... :p

thebol
12-02-2006, 09:52
La window non procede finchè non abbiamo la sequenza corretta... Ora non ho link da porti ma se cerchi il meccanismo della (sliding?) window in TCP capisci subito :)

Tigershark non c'entra il fatto che TCP faccia la stessa cosa... UDP non è connection oriented ed instrada ogni pacchetto scegliendo il routing migliore cosa che TCP non fa :)

conosco la sliding windows, non capisco perche inmplementarla su udp quando tcp ce la da gratis. Problemi di bandwith non ci sono(ancora), cmq direi di lasciare la parola al dopo-spike udp vs tcp :cool:

Ufo13
12-02-2006, 10:15
conosco la sliding windows, non capisco perche inmplementarla su udp quando tcp ce la da gratis. Problemi di bandwith non ci sono(ancora), cmq direi di lasciare la parola al dopo-spike udp vs tcp :cool:

Per ragioni di routing e priorità. Inoltre il TCP aggiunge un payload maggiore...

Comunque procedete con gli spike... Al massimo poi con qualche modifica si fanno le prove :)

buon lavoro

^TiGeRShArK^
12-02-2006, 16:45
laurea... :p
ah ecco....
so i kasini ke stai passando allora :D
:vicini:

nihil84
13-02-2006, 11:55
UDP non è connection oriented ed instrada ogni pacchetto scegliendo il routing migliore cosa che TCP non fa :)

L'instradamento e' delegato a IP, infatti i router non implementano il protocollo di trasporto ma arrivano solo al livello di rete.
Quindi non c'e' alcuna differenzatra tcp e udp a questo livello: il canale di connessione sicuro e' solo _virtuale_, niente vieta ai pacchetti tcp di arrivare per strade diverse e non in ordine. E' compito degli strati tcp, implementati solo nel mittente e nel destinatario, gestire attese e ritrasmissioni.

In My Humble Opinion:
E' inutile usare udp se avete intenzione di utilizzare sliding windows e timeout di ritrasmissione, perche' e' esattamente quello che fa tcp.
TCP inoltre implementa il controllo di congestione che solo apparentemente negativo (diminuisce il byterate se la rete e' congestionata), perche' continuare a inviare pacchetti a frame rate costanti in una rete a rischio di congestione non fa altro che aumentare la possibilita' che tali pacchetti vengano scartati dai router con buffer pieni

paolo

Ufo13
13-02-2006, 13:09
Non sono d'accordo... Prometto di dare motivazioni piu` valide non appena trovo il tempo pero` se molti giochi usano UDP una motivazione c'e`...

In ogni caso con UDP hai la liberta` di perdere dei pacchetti senza bloccare tutta la coda (cosa che in TCP avviene per forza di cose) e puoi gestire il tutto semplicemente con una risincronizzazione dello stato delle griglie.

Jocchan
13-02-2006, 14:17
Ok, chi si offre per fare delle prove concrete con TCP, e chi per farne con UDP?
Già i task finora completati in questo ciclo possono dare una mano.

cionci
13-02-2006, 15:22
Io posso fare una prova con TCP, ma solo dopo il completamento della storia 10.2, perchè è utile se vogliamo riprodurre gli eventi...

cionci
13-02-2006, 15:24
In ogni caso con UDP hai la liberta` di perdere dei pacchetti senza bloccare tutta la coda (cosa che in TCP avviene per forza di cose) e puoi gestire il tutto semplicemente con una risincronizzazione dello stato delle griglie.
Però ti devi "rendere" conto che li hai persi...dopo quanto tempo ?!?!? I dati trasmessi per "risincronizzare" le griglie non solo sono di più, ma nemmeno costanti in quantità...

Ufo13
13-02-2006, 18:06
Però ti devi "rendere" conto che li hai persi...dopo quanto tempo ?!?!? I dati trasmessi per "risincronizzare" le griglie non solo sono di più, ma nemmeno costanti in quantità...

Il timeout è impostabile manualmente.

Il packet loss generalmente per connessioni così lente è bassissimo...

Anche in TCP si deve rendere conto di averli persi (a livello transport) e poi la risincronizzazione delle griglie mi sa che dovremo gestirla comunque...

Per il fatto dei dati "variabili" non vedo il problema :)

cionci
13-02-2006, 18:15
Per il fatto dei dati "variabili" non vedo il problema :)
Il problema è che hai una quantità di dati notevole...e che aumenta sempre...con il rischio di perdere tempo proprio nelle siutazioni più concitate del gioco...

Ufo13
14-02-2006, 07:52
Il problema è che hai una quantità di dati notevole...e che aumenta sempre...con il rischio di perdere tempo proprio nelle siutazioni più concitate del gioco...

notevole non direi proprio...

Alla peggio invii tutto lo stato della griglia (che sono un centinaio circa)...

Metti un byte a cella per dire il tipo... 100 byte? :)

^TiGeRShArK^
14-02-2006, 11:42
io mi potrei offrire per la prova con udp...
però cosa dovrei fare??? :fagiano:
un client ed un server UDP già li avevo creati per fare le misurazioni di cui sopra...
non avrei idea di quali altre prove effettuare se non speifichiamo quali informazioni dovremmo scambiarci....:fagiano:

Ufo13
14-02-2006, 11:59
è uno spike spazio all'inventiva :p

fek
14-02-2006, 16:34
Vedete se questo puo' tornarvi utile:

http://www.answers.com/topic/udp-hole-punching

(Grazie a jumpermax per il link)

fek
14-02-2006, 16:37
Non sono d'accordo... Prometto di dare motivazioni piu` valide non appena trovo il tempo pero` se molti giochi usano UDP una motivazione c'e`...

Probabilmente hanno esigenze diverse di banda e latenze da quelle che abbiamo noi :)

"Se quell'applicazione usa questo algoritmo ci sara' un perche'" non e' mai un buon argomento. Il fatto che una soluzione sia buona per un determinato problema in determinate condizioni non la rende automaticamente buona per un altro problema in condizioni diverse.

Noi useremo la soluzione piu' semplice per il nostro problema nelle nostre condizioni. Questa soluzione potra' essere TCP o UDP o HTTP o quant'altro e lo Spike serve proprio a chiarirci le idee in proposito.

jumpermax
14-02-2006, 16:48
ho letto veloce e aggiungo i my 2 cent da persona che sta per schiattare su reti di calcolatori.... se quanto vi offre tcp vi basta usate quello, se invece avete bisogno di vostre caratteristiche specifiche di trasporto allora è più sensato implementarle sopra udp . Non credo ci voglia molto, specie se usate java.

^TiGeRShArK^
16-02-2006, 10:59
intanto un grazie a jumper :D
poi stanotte (:D) mi è venuto in mente ke forse la cosa migliore da fare potrebbe essere di usare la tecnica impiegata nell'MPEG...
mi spiego meglio....
nell'MPEG vengono inviati dei frame di tipo I che contengono informazioni complete su un frame intero, seguite da frame di tipo P che in pratica non sono altro che indicazioni per ricomporre il frame corrente partendo dalle informazioni precedenti...
in questo modo potremmo inviare ad esempio un pacchetto ogni 10 contenente le informazioni totali della griglia e negli altri 9 frame inviamo solo gli eventi necessari per una ricomposizione dell'area di gioco "incrementale".
Così facendo avremo risolto sia il problema di eccessivo consumo di bandwidth che quello dell'attesa dovuta alle ritrasmissioni in caso di perdita di un pakketto....
cmq questa è una soluzione da vagliare nel caso in cui il metodo piu' semplice non sia sufficiente ovviamente :p

VICIUS
16-02-2006, 11:35
intanto un grazie a jumper :D
poi stanotte (:D) mi è venuto in mente ke forse la cosa migliore da fare potrebbe essere di usare la tecnica impiegata nell'MPEG...
mi spiego meglio....
nell'MPEG vengono inviati dei frame di tipo I che contengono informazioni complete su un frame intero, seguite da frame di tipo P che in pratica non sono altro che indicazioni per ricomporre il frame corrente partendo dalle informazioni precedenti...
in questo modo potremmo inviare ad esempio un pacchetto ogni 10 contenente le informazioni totali della griglia e negli altri 9 frame inviamo solo gli eventi necessari per una ricomposizione dell'area di gioco "incrementale".
Così facendo avremo risolto sia il problema di eccessivo consumo di bandwidth che quello dell'attesa dovuta alle ritrasmissioni in caso di perdita di un pakketto....
cmq questa è una soluzione da vagliare nel caso in cui il metodo piu' semplice non sia sufficiente ovviamente :p
L'idea è carina e mi piace. :)

Potremmo trasmettere un pacchetto I ogni volta che si sta per creare una nuova gemsPair per sincronizzare lo stato di tutta la griglia. E trasmettere dei pacchetti P ogni volta che una gemma cambia cella.

ciao ;)

Ufo13
16-02-2006, 18:47
il problema consiste nel controllare che la griglia sia valida... Altrimenti si può falsificare il contenuto e cheattare...

Inviando gli eventi per forza la griglia deve essere valida (vengono ripetuti in locale)

thebol
26-02-2006, 10:55
ho fatto qualche prova(che a breve mettero sul repository fra gli spike) su RMI....

con un metodo remoto, a cui passavo un long(il turno di input) e uno short(codifica dell'informazione), la bandwithd era > 5kb/s per cui inutilizzabile per il ns scopo. Si potrebbe al limite togliere lo short, ma nn penso che la situazione migliori di molto...

cmq lo pubblichero, cosi potrete fare le vs prove, nn si sa mai abbia sbagliato qualcosa o contato male :doh:


ps.le prove le ho fatte con un inputrate di 60ms(simulato con una sleep) iterando 100 volte(circa 6 sec) in cui il traffico generato è stato 30Kb.

Ufo13
26-02-2006, 11:23
ho fatto qualche prova(che a breve mettero sul repository fra gli spike) su RMI....

con un metodo remoto, a cui passavo un long(il turno di input) e uno short(codifica dell'informazione), la bandwithd era > 5kb/s per cui inutilizzabile per il ns scopo. Si potrebbe al limite togliere lo short, ma nn penso che la situazione migliori di molto...

cmq lo pubblichero, cosi potrete fare le vs prove, nn si sa mai abbia sbagliato qualcosa o contato male :doh:


ps.le prove le ho fatte con un inputrate di 60ms(simulato con una sleep) iterando 100 volte(circa 6 sec) in cui il traffico generato è stato 30Kb.

Non puoi trasferire solo i cambiamenti?

thebol
26-02-2006, 12:00
Non puoi trasferire solo i cambiamenti?
certo, questa è cmq la situazione "limite" raggiungibile. In effetti e difficile che ci sia un cambiamento di tasti ogni 60ms...ma non so se è accettabile.

Ufo13
26-02-2006, 12:43
puoi dare una soglia di N ms. Mandi al + un messaggio ogni N ms e nel caso ce ne fossero di + in coda ne raggruppi un po' in uno solo...

thebol
26-02-2006, 12:51
puoi dare una soglia di N ms. Mandi al + un messaggio ogni N ms e nel caso ce ne fossero di + in coda ne raggruppi un po' in uno solo...
in questa maniera l'overhead dell'rmi scenderebbe...certo con 2 messaggia per coda si rischierebbe di ottenere un effetto "velocita doppia" ogni 120 msec, ma la probabilità dell evento sarebbe bassa.

E la bandwith dovrebbe scendere sui 2,5kb/s, che diverrebbe accettabile.

Ufo13
26-02-2006, 16:14
in questa maniera l'overhead dell'rmi scenderebbe...certo con 2 messaggia per coda si rischierebbe di ottenere un effetto "velocita doppia" ogni 120 msec, ma la probabilità dell evento sarebbe bassa.

E la bandwith dovrebbe scendere sui 2,5kb/s, che diverrebbe accettabile.

L'effetto accadrebbe solo in casi di ripetizioni velocissime e comunque è possibile fare uno smoothing client-side...

Mi sembra un po' tanto 2.5kb/s per hmmm 8 messaggi circa?

thebol
26-02-2006, 22:13
L'effetto accadrebbe solo in casi di ripetizioni velocissime e comunque è possibile fare uno smoothing client-side...

ho guardato l'ultimo log che avevo su diamonds, ed è una situazione che capita(puoi provare tu stesso). Lo smothing comporta cmq un aumento di velocità(ma magari viene a malapena percepito, si possono fare delle prove)


Mi sembra un po' tanto 2.5kb/s per hmmm 8 messaggi circa?
di dovrebbero essere 8, ma ce anche la risposta per i messaggi ricevuti

thebol
05-03-2006, 21:57
svn://spartacus.dnsalias.net/diamonds/extras/Spikes/Thebol

ho commitato lo spike su RMI. Se ci volete fare un giro :cool:

VICIUS
05-03-2006, 23:32
svn://spartacus.dnsalias.net/diamonds/extras/Spikes/Thebol

ho commitato lo spike su RMI. Se ci volete fare un giro :cool:
Magnifico. Era ora che ci fosse uno spike concreto sul repository. Faccio partire subito un checkout cosi seguo i cambiamenti.

ciao ;)

cionci
06-03-2006, 06:59
Io per fare lo spike sto aspettando che sia riproducibile il log... Volevo sfruttare lo stesso motore per il netcode con TCP...

thebol
06-03-2006, 17:39
Io per fare lo spike sto aspettando che sia riproducibile il log... Volevo sfruttare lo stesso motore per il netcode con TCP...

si possono cmq incominciare a far delle prove, il mio spike nn utilizza nulla di diamonds(apparte timer per far durare la prova 10 secondi), ma simula una partita di 10 secondi(anche troppo, visto che è difficile che entrambi faccianoq ualcosa ogni 60ms ;) )

^TiGeRShArK^
06-03-2006, 23:27
ehm....
io avrei fatto a suo tempo il netSpike con UDP, ma mi sa che mi sono dimenticato di committarlo:fagiano:
se lo committo in un file zip sotto trunk qualcuno che ha tutto l'albero di directory lo può committare nel posto giusto perchè io ho fatto il checkout solo di trunk e se dovessi fare un altro checkout con 'sto cell non finisco +....
fatemi sapere ks domani lo committo...

(x stasera sono distrutto....:fagiano: )

dnarod
07-03-2006, 00:11
x stasera sono distrutto....

chissa perche :)

nexusventuri
07-03-2006, 03:01
Ho letto i vari post abbastanza velocemente(chiedo scusa)
per quello che so io rmi non è la soluzione ottimale, in quanto si dovrebbe avere attivo l'rmi registry che per quanto riguarda la versione che avevo utilizzato arrivava a pesare 15 M una volta attivo.
Inoltre l'invocazione blocca il thread del processo chiamante (data la sementica al piu' una volta).
Non mi ricordo il comportamento dell'oggetto chiamato dal punto di vista dei thread.
Riguado a quanto descritto qui sopra:

Sementica al piu' una volta:
http://java.sun.com/j2se/1.5.0/docs/guide/rmi/spec/rmi-arch2.html

Per una specifica generale rmi:
http://java.sun.com/j2se/1.5.0/docs/guide/rmi/spec/rmiTOC.html

Bloccando il thread chimante l'applicazione si ferma fintanto che non si ha risposta(se single thread).

Quindi in un implementazione (single-thread) del tipo:
-A manda i messaggi usando B.InsertGrid(grid)
-InsertGrid va a modificare una classe per valuare lo spostamento
Blocca A fintanto che non è stato eseguito tutto il codice di insert grid.

UnicastRemoteObject si poggia su tcp (overhead rispetto a udp).


Per i NAT -> su rmi non ci sono molti problemi, sul sito della sun ho trovato alcune soluzioni a problemi gia affrontati (da altri):

Questa è la ricerca fatta:
http://onesearch.sun.com/search/onesearch/index.jsp?qt=rmi+nat&subCat=&site=dev&dftab=&chooseCat=javaall&col=developer-forums
Nel caso si potrebbe utilizzare questo supporto
https://cajo.dev.java.net

Questo è un documento riguardante la possibilità di utilizzare tcp o udp attraverso i nat, postato inizialmente da jumpe (grande!)
http://www.brynosaurus.com/pub/net/p2pnat/

Secondo me la scelta piu' opportuna sarebbe utilizzare udp eventualmente con la possibilita' di creare una soluzione che possa andare bene sia per connessioni lente che per ADSL etc..
l'approccio "grezzo" che mi viene al momento consite nello scambiare i messaggi solamente dopo un determinato numero di mosse (a seconda della connessione dall'altra parte) in questo modo si utilizza al meglio il pacchetto (ovvero la % di dati utili è di dimensioni maggiori rispetto agli header udp).

Nei casi di perdite di pacchetti(purtroppo le wireless contribuirebbero a questa parte del problema) si puo scambiare anche l'id della gemma, in modo tale che se l'id non corrispondesse a quella attesa si richieda un aggiornamento della griglia avversaria (la famosa windows).

Mi scuso se alcune nozioni sono ridondanti rispetto ai messaggi precedenti forse ho letto tutti i topic un po' troppo velocemente... :cry:

Ken

Ufo13
07-03-2006, 08:44
Secondo me la scelta piu' opportuna sarebbe utilizzare udp eventualmente con la possibilita' di creare una soluzione che possa andare bene sia per connessioni lente che per ADSL etc..
l'approccio "grezzo" che mi viene al momento consite nello scambiare i messaggi solamente dopo un determinato numero di mosse (a seconda della connessione dall'altra parte) in questo modo si utilizza al meglio il pacchetto (ovvero la % di dati utili è di dimensioni maggiori rispetto agli header udp).

Ken

Appoggio in pieno questa soluzione cosi` chi ha la connessione piu` veloce la puo` sfruttare appieno e chi ha una 56k non subira` un grosso danno...

Appena finita la tesi tiriamo su uno spike :)

Bonfo
30-03-2006, 13:32
Seguendo il corso di reti ho sentito parlare dell' RTP : Real-Time Transfert Protocol

Si basa su UDP e dovrebbe garantire il real-time di cui abbiamo bisogno.

Non l'ho ancora studiato...non so proprio come funzioni, però può essere uno spunto. :D :D

VICIUS
30-03-2006, 18:04
Seguendo il corso di reti ho sentito parlare dell' RTP : Real-Time Transfert Protocol

Si basa su UDP e dovrebbe garantire il real-time di cui abbiamo bisogno.

Non l'ho ancora studiato...non so proprio come funzioni, però può essere uno spunto. :D :D
Ho ricordi veramente vaghi di rtp ma se non sbaglio era piuttosto complesso da implementare ed era specializzato per il trasferimento di contenuti multimediali in real-time in cui si poteva avere una piccola perdita di dati.

Non mi sembra l'ideale ma potrei anche sbagliarmi. Tienici informati :)

ciao ;)

cionci
30-03-2006, 18:14
Io me lo ricordo un po'... RTP e RTCP... Sono molto complessi e sono dedicate appunto al trasferimento di flussi audi-video... IMHO YAGNI...

redcloud
30-03-2006, 18:45
Mmm ma tutti questi YAGNI non dovrebbero essere spostati in una apposita sezione per non perderli nell'oblio?

Bonfo
30-03-2006, 23:39
Non lo conosco e quindi mi fido di voi...

...se è veramente così complesso e dedicato completamente allo streaming ....YAGNI :D

cionci
31-03-2006, 07:53
Mmm ma tutti questi YAGNI non dovrebbero essere spostati in una apposita sezione per non perderli nell'oblio?
Resta tutto qui...in ogni caso questo non è uno YAGNI da implementare in futuro :)

Ufo13
09-04-2006, 21:43
Ragazzi questo spike è qui da quattro mesi ed i risultati non sono stati molti...

Che ne dite se apriamo un branch dopo la first playable (così iniziamo a testare seriamente il gioco) con l'implementazione del netcode? Intendo dire niente test ma proprio il gioco funzionante con due griglie :)

thebol
20-04-2006, 12:35
http://www.gamedev.net/reference/articles/article1138.asp

Ufo13
25-04-2006, 13:46
Mi han suggerito questa libreria

http://www.jxta.org/

http://instantp2p.jxta.org/

Confesso che non ho ancora guardato... Per ora segnalo :)

fek
26-05-2006, 11:32
http://bunkandrambling.com/images/blog/yagni060524b.png

cionci
26-05-2006, 11:42
Io aspetto il playback del log per farlo...

Bonfo
26-05-2006, 11:44
http://bunkandrambling.com/images/blog/yagni060524b.png

STRALOL

:rotfl: :rotfl: :rotfl: :rotfl:

Comunque è vero emi preoccupa un po'...non sarà affatto facile :cry: :cry:

thebol
26-05-2006, 11:49
http://bunkandrambling.com/images/blog/yagni060524b.png

il proxy non me la passa, che è?

71104
26-05-2006, 12:33
LOOOOOOOOOOOOOOOOOOOOOOL IL SIGNOR YAGNI!! HUWAHZUHWUAHWUAHAUHZHHWZAHWWUAHZAUWAHZWUHZWUHAZ
:rotfl::rotfl::rotfl::rotfl::rotfl::rotfl:

DanieleC88
26-05-2006, 17:28
LOOOOOOOOOOOOOOOOOOOOOOL IL SIGNOR YAGNI!! HUWAHZUHWUAHWUAHAUHZHHWZAHWWUAHZAUWAHZWUHZWUHAZ
:rotfl::rotfl::rotfl::rotfl::rotfl::rotfl:
Non è stupendo? :D

Rubberick
28-05-2006, 19:10
Sono arrivato fino a pagina 4 purtroppo nn ho tempo per leggere tutto cmq butto la mia...

Gioco da parecchio a Warcraft III gioco blizzard che tutti voi conoscerete, l' RTS non World of Warcraft :P

Ho notato che il gioco fa uso di una miriade di pacchetti udp molto leggeri, non arriva mai a consumare + di 1.5-2kB/s e vi faccio presente che su war3 ci si ammazza in termini di azioni molto + che su diamonds...

Tuttavia c'e' una cosa molto interessante che viene fatta... la sincronizzazione (consideriamo che war3 arriva fino a 12 players in contemporanea) e' fatta al livello globale agendo entro un certo limite sulla velocita' di gioco.. (ecco perche' quando si gioca in lan il gioco risponde sempre meglio...)

In pratica un giocatore prima di essere droppato su war ha i seguenti passaggi...

Frazione di lag bassa [da 0ms di differenza a tot ms o tot tempo di dissincronia da recuperare]: La velocita' del gioco e' tarata dinamicamente in base alla velocita' del giocatore con connessione peggiore...

Frazione di lag alta [da tot ms a infinito]: Parte un timer pubblico di tot tempo nel quale il gioco viene messo fisicamente in pausa... l'unica cosa disponibile e' la chat e in quel tempo si spera che il giocatore riesca a recuperare cio' che manca... (con un adeguato skipping fatto per evitare che debba recuperare tonnellate di cose)... Alla fine del timer diventa disponibile il tasto Caccia Giocatore e il giocatore puo' essere bannato pubblicamente dagli altri (questo a voi non interessa ma e' per farvi capire come vanno le cose)...

vabbe poi il timer non riparte sempre da zero... ogni giocatore in game ha un tot di secondi ad es 60.. se le laggate sono molto vicine il valore viene mantenuto man mano e recuperato, se uno fa una laggata all'inzio del game e ad es un'altra a 10 min di distanza il timer e' riazzerato.. (quest'ultima cosa l'ho aggiunta per completezza)

VABBE SONO LOGORROICO XD cmq in sostanza regolare la velocita' del gioco dinamicamente per apparare la lag? parliamo di lag di pochi ms :)

In ultimo aggiungo... sicuro non utilizzerei un ping esterno, ma basatevi sugli udp che sono i + veloci a passare a meno di tcp non configurati diversamente...

PS: Perche' complicarvi la vita? Vedete come hanno risolto altri giochi come appunto warcraft e riadattate il tutto a diamonds :) la soluz per me rimane udp veloci e pratici, il controllo di risincronia e le altre cosette le vedete al livello applicazione.. se la velox del gioco viene modificata in modo dinamico avreste anche meno frameskipping :P

Ufo13
28-05-2006, 19:13
Sì ho giocato a WC3 online a suo tempo (ora mi sto finendo Frozen Throne :D) non è che mi piacesse così tanto la storia della pausa automatica...

Comunque effettivamente l'opzione della pausa tra le griglie potrebbe anche essere valutata :)

Rubberick
28-05-2006, 19:54
la pausa tu la hai nel momento in cui la differenza in termini di tempo e' troppo forte, oltre un certo limite!

se la differenza non e' sostanziale... c'e' la regolazione dinamica della velocita'...

Ah nn so se l'ho detto ma cmq lo ripeto =) non usate il ping come metro di giudizio ma usate un ping interno... i pacchetti imcp sono generalmente considerati a bassa priorita' dai routers intermedi e vi forniranno dei valori spesso + alti del normale oppure infiniti (se nn arrivano :P)

cionci
28-05-2006, 19:57
Ah nn so se l'ho detto ma cmq lo ripeto =) non usate il ping come metro di giudizio ma usate un ping interno... i pacchetti imcp sono generalmente considerati a bassa priorita' dai routers intermedi e vi forniranno dei valori spesso + alti del normale oppure infiniti (se nn arrivano :P)
Direi...non solo, spesso vengono anche filtrati da alcuni provider...inoltre dietro ai proxy non terrebbero conto degli hop successivi...

Rubberick
28-05-2006, 20:05
siccome anche joccha nn aveva capito riassumo molto brevemente...

In riferimento al distacco temporale tra i due players:

FASE 1 - LATENZE BASSE (da 0ms a TOTms) - Il gioco regola dinamicamenta la sua velocita'... i giocatori sono sempre due quindi si parla di velocita' complessiva (se fossero stati + d'uno come su war3 avreste fatto riferimento al delay del tizio con latenza peggiore)

FASE 2 - LATENZE ALTE (da TOTms a VALORE GROSSO) - Il gioco si rende conto che non puo' rallentarsi + di un tanto... a questo punto entra in gioco un frameskipping...

FASE 3 - LATENZE INFINITE (estensione del concetto latenze alte) - Il gioco dice al player... ao' ma vedi che sto tizio con cui stai giocando e' popo morto... che vuoi fare...? abbandoni la partita o ti fai na grattata sperando che ricompare e resti col gioco aperto? (ovviamente sia chiaro... messaggio di un certo colore e titolo del tipo "Partita in Conclusione") per far capire bene al player che nn e' + cosa...

O in alternativa direttamente... caro ragazzo il tuo avversario si e' andato a fare 2 birre, qualche tiro a stecca e un paio di bionde mentre te stai come un fesso qui davanti... hai vinto... percio' a te la gloria e a lui il resto :D :D :D

E' chiaro in questi termini? :D

71104
29-05-2006, 00:20
la regolazione dinamica della velocità del gioco è un discorso interessantissimo!! :eek:

questo spike sta diventando troppo complesso per essere uno solo, dovrebbero essere più d'uno.

aggiungo i miei 2 cent: i parametri che regolano il meccanismo per il quale il gioco decide se rallentare o se frameskippare o se dire "bella pe' te, l'avversario è più furbo e ha perso ma si sta facendo due bionde, e non si tratta di birre" non devono essere messi in Config ma devono essere hardcoded o meglio ancora comunicati dal protocollo in fase iniziale; questo perché se stessero in config esisterebbe la possibilità che i giocatori li abbiano diversi, e uno potrebbe tweakkarli apposta per giocare più veloce e sconfiggere l'avversario... ^^
dunque possono essere hardcoded, ma così se decidiamo di cambiarli in versioni future giocatori con versioni diverse del gioco non potrebbero giocare, o potrebbero farlo ma uno si potrebbe trovare avvantaggiato...
quindi la cosa migliore è stabilirli ad ogni partita; ciascuno dei peer potrebbe stabilire i valori da lui consigliati secondo uno schema hardcoded, e poi si opterebbero i migliori secondo un algoritmo che li scelga a seconda del tipo di valore.

EDIT: certo però che pure inserire la possibilità di tweakkare i valori sarebbe no tamarro, deppiù... :D :D :D

thebol
29-05-2006, 07:07
secondo me ci conviene lavorare un passo alla volte, e incominciare a regolare la sincronia con il frameskipping della griglia del giocatore remoto. Poi se vediamo che è troppo fastidioso, si puo pensare di di introdurre anche il rallentamento.

Questo non vuol dire pero che ci possano essere 2 spike separati :)

Rubberick
29-05-2006, 09:46
quindi la cosa migliore è stabilirli ad ogni partita; ciascuno dei peer potrebbe stabilire i valori da lui consigliati secondo uno schema hardcoded, e poi si opterebbero i migliori secondo un algoritmo che li scelga a seconda del tipo di valore.

EDIT: certo però che pure inserire la possibilità di tweakkare i valori sarebbe no tamarro, deppiù... :D :D :D

Veramente trovo che quest'ultima soluzione possa rivelarsi un po' strampalata... e' vero come e' vero che ovunque uno si trovi, se in cina, o in america o in italia un ping 50 e' veloce, un 100 e' cosi' cosi' e 200 risulta laggoso... (consideraz media per un rpg/rts quei valori gia' sono alti per un fps)

Indubbiamente questi valori devono essere hardcoded nel programma, la blizz non li ha certo messi all'esterno anche perche' sono troppo tecnici e trascendono da una semplice configurazione... inoltre come scritto sopra bastera' trovarli una volta ed utilizzarli in eterno, non sono soggetti a variazioni una volta che tu quantifichi un ritardo e dei valori di soglia quelli sono e quelli saranno...

A mente fresca, riedito il topic, cominciate a leggere qui, se poi volete perdervi in maggiori info leggete il quotato

-----------------------------------------------------------------------
- si realizza un intero aggiornato sempre "int latency" (la sua utilita' ha a che fare con la GetFullState e la vedete se vi leggete il topic intero)
- i pacchetti inviati meno che i ping sono tutti indispensabili! invece di mandare ogni tot secondi un aggiornamento si mandano le azioni eseguite (all'altro giocatore) solo ad ogni EVENT da parte del giocatore locale (un umano medio penso non faccia + di un tot di azioni al sec :D)
- siccome non sappiamo se questi pacchetti si sono persi per strada faremo un controllo... se ci sono tutti non facciamo nulla, se ne manca anche solo uno... il giocatore remoto chiedera' al locale una GetFullState... (aggiornamento di griglia completo) per poi andare avanti continuando con le azioni alla solita maniera
- penso sia tutto
-----------------------------------------------------------------------

Credo che prima di mettervi al lavoro dovreste provare a puntare verso una strada e poi man mano ritornare al bivio e vedere magari di espandere la cosa ma qui voi siete mille volte + preparato di me... pero' provo a buttare una falsariga da seguire...

Protocollo a Basso Livello Scelto: UDP
Frammentazione dei Pacchetti a Livello Trasporto: Automatico
Periodicita' nel Lancio dei Pacchetti all'altro Host: Variabile
Mi spiego, invece di effettuare una connessione continua e cadenzata dei pacchetti inviati si puo' fare che ad ogni input o evento lato client di un giocatore corrispondano l'invio di pacchetti di aggiornamento all'avversario sulla situazione... a questo si aggiungono possibili richieste lato server (l'altro giocatore) in situazioni particolari

[risposta gioco in base alla latenza]

Due sono le cose, o ci si basa su una funzione derivata da latenza + altri kakki (+ complessa e bisogna vedere quanto e' YAGNI) oppure ci si basa solamente sulla latenza (si potrebbe cominciare ad implementare quella come test per poi passare a qualcosa di + complesso se necessario).

Dunque, "costruzione di una variabile" int latency[/] (espressa in ms) aggiornata di continuo... (si potrebbe realizzare mediante un pacchetto microscopico ad hoc lanciato ogni x ms, + e' basso questo tempo, maggiore e' il fine tuning di regolazione fattibile)...

In base al valore di questa variabile il gioco evolve dinamicamente.. (non sto parlando di implementare da subito la variaz dinamica della velocita', ma la variabile latency serve comunque anche per il frameskipping e il drop per latenza eccessiva, insomma funge anche da keep alive)

Una mia proposta sarebbe questa... anche per cercare di tenere il gioco quanto + possibile "leggero" in termini di rete... vengono trasferite sempre e solo le azioni.. se pero' c'e' qualcosa che non va allora il diamonds remoto mandera' una pacchetto funzione speciale (ecco a cosa mi riferivo prima) [B]GetFullState e il diamonds locale gli mandera' un pacchetto formattato in un certo modo (per pacchetto intendo il pacchetto immaginario, magari nella realta' sara' frammentato in auto in + pezzi)

A questo punto il diamonds remoto sara' in grado di ricostruire la griglia al completo... e far si che le prossime azioni mandategli saranno "fattibili" in quanto riferite ad una situazione aggiornata...

[Come Detectare il Qualcosa che NON va]
Siccome a questo punto tutti i pacchetti inviati saranno "indispensabili", facendo semplicemente un conto di questi si vedra' se c'e' qualcosa che non va :)

----------------------------------------------------------------------
Es:
----------------------------------------------------------------------

diamonds1 a diamonds2 ti ho inviato 300 pacchetti in questo frangente di tempo... a te quanti te ne sono arrivati?

diamonds2: tutto apposto tutti e 300 vai tranquillo...

diamonds1: ok...

----------------------------------------------------------------------
passarono X secondi...
----------------------------------------------------------------------

diamonds1 a diamonds2 ti ho inviato 300 pacchetti in questo frangente di tempo... a te quanti te ne sono arrivati?

diamonds2: eh me ne sono arrivati 298! 298 < 300 !!! GetFullState perfavore!

diamonds1: eccoti la griglia completa!

----------------------------------------------------------------------
(pacchetti si intendono tutti eccetto i pings che non sono "essenziali")
----------------------------------------------------------------------

La realizzazione di questo check sui pacchetti si puo' fare in svariati modi, lascio a voi quello + piacevole...

[Considerazioni Finali]
Questa impostazione ha un forte vantaggio sulle reti a bassa latenza, utilizza un controllo "degli errori" integrato ed e' in grado di gestire (se ben impostata) tutte le possibili problematiche... in + fa si che il frameskipping venga attivato solo quando necessario (vedi GetFullState) e solo quando i due clients se l'aspettano (prevent hacking)

Puo' non funzionare bene nel momento in cui:

- le reti sono a latenza alta
- la GetFullState e' pesante in termini di banda (ecco il perche' di farla quanto + leggera possibile e lasciare che passi veramente solo le pos delle gemme e quali gemme sono ad es identificate ognuna con un numero..)
- il controllo sui pacchetti persi viene effettuato con un valore troppo basso rispetto alla latenza della rete.. provocando troppi GetFullState che a quanto pare sono il tipo di pacchetto + grande che abbiamo...

Bastera' variare il tempo di controllo pacchetti persi in base alla latenza che riconosciamo dinamicamente =P se vediamo che la latenza comincia a salire troppo aumentiamo questo tempo di controllo errori per evitare che partano millemila GetFullState a saturare la banda in una situazione gia' penosa...





Arrivando al Pratico
========================================================
- Potreste cominciare a creare una funzione ping basata su udp costruendo il pacchetto + piccolo possibile per i vostri scopi... (stavolta al livello trasporto forzando un pacchetto non in auto ma manuale e microscopico)

- Creare la variabile int latency e mantenerla aggiornata man mano grazie ad un ping/keep alive periodico..

- Pensare a come codificare la griglia in bits per mandarla con la GetFullState... ipotizzando un numero di bit + alto per i tipi di gemme riservando "tipi" per gemme future nel caso vogliate implementarle...
=========================================================





:D :D :D :D :D :D
1) sono logorroico
2) il lato net di un'app probabilmente e' uno dei + scassapalle e va discusso molto... non parlandone in real cerco sempre di approfondire quanto + possibile per dare una visione piena...
3) spero di esservi stato utile :oink:
:D :D :D :D :D :D

cisc
29-05-2006, 17:58
sono d'accordo con Rubberick in TOTO..aggiungerei solo l'invio del fullstate ogni tot secondo...

Rubberick
29-05-2006, 18:57
sono d'accordo con Rubberick in TOTO..aggiungerei solo l'invio del fullstate ogni tot secondo...
per avere una sicurezza ulteriore che la griglia sia perfetta?

cisc
29-05-2006, 19:16
per avere una sicurezza ulteriore che la griglia sia perfetta?

beh, forse non è così utile, anzi, potrebbe essere anche + dannosa, infatti avevo pensato che sarebbe stato utile nel caso di tentativi di cracking nell'invio degli eventi, ma crackare gli eventi è molto meno grave che crackare la grid intera, ed introdurre l'invio di tutto lo stato periodicamente sarebbe quindi peggio dal punto di vista della sicurezza...

Rubberick
29-05-2006, 19:32
infatti riquoto il mio esempio:
----------------------------------------------------------------------
Es:
----------------------------------------------------------------------

diamonds1 a diamonds2 ti ho inviato 300 pacchetti in questo frangente di tempo... a te quanti te ne sono arrivati?

diamonds2: tutto apposto tutti e 300 vai tranquillo...

diamonds1: ok...

----------------------------------------------------------------------
passarono X secondi...
----------------------------------------------------------------------

diamonds1 a diamonds2 ti ho inviato 300 pacchetti in questo frangente di tempo... a te quanti te ne sono arrivati?

diamonds2: eh me ne sono arrivati 298! 298 < 300 !!! GetFullState perfavore!

diamonds1: eccoti la griglia completa!

----------------------------------------------------------------------
(pacchetti si intendono tutti eccetto i pings che non sono "essenziali")
----------------------------------------------------------------------


in quest'ottica se tutto e' fatto come si deve, i due si mettono daccordo su ricevere ed inviare la get full state :D se cio' non succede anche che ad uno dei due arriva un pacchetto fullstate completo l'altro lo guarda cosi' O_o' e nn fa nulla perche' non l'aveva richiesto ^^

Questo e' veramente un casino difficile da hackerare... penso ^^'

cionci
29-05-2006, 19:36
E se perdi il pacchetto di getFullState ?

Rubberick
29-05-2006, 20:31
:D e' vero ti confesso che non ne ho parlato perche' stavo cercando una soluzione...quello non puo' essere perso... un controllo anche li? o diventa troppo pesante...? allo stesso modo se si perde il pacchetto per la richiesta del get full state... hum...

un pacchetto tcp? nah.. uff ^^

argh, bozza molto brutta di risoluzione:

se si verifica una problematica full state:
- il remoto invia al locale di continuo richieste getfullstate
(una richiesta getfullstate e' piccola paragonabile ad un ping, la fullstate e' grossa perche' contiene tutta la griglia)
- sotto questo situazione (il bombardamento di get) il locale inviara' periodicamente (nn tanto da avere problemi di saturaz della banda) pacchetti full (quelli grossi) finche' non vedra' che il remoto nn la finisce con i get
- il remoto ovviamente al primo full che gli arriva la smette con sto bombardamento (e direi anche perke' ha rotto i cogl... :sofico: )

Ribadisco la mia proposta puo' essere tanto brutta quanto cattiva pero' credo che funzioni bene in ambito a basse latenze... il problema e' quando si sale che non si riesce a capire granche'... e' anche una questione di :ciapet:

Alla fine... se si riuscisse ad implementare in modo molto basso un Pacchetto FULL tutta la mia logica nn avrebbe granche' senso pero' andrebbero risolti 2 problemi:

- 1 la sicurezza
- 2 la gestione delle velocita' (non usando le azioni e facendo un semplice aggiornamento di griglia o il tizio vede discretizzato o va implementato un gestore delle velocita')

nexusventuri
30-05-2006, 14:57
hummm....
mettiamo che su diamonds1 ci sia un cheater

---------------------------------------------------
diamonds1 a diamonds2 ti ho inviato 400 pacchetti, ti sono arrivati? (informazione falsa)
diamonds2: no veramente me ne sono arrivate 290... getFullState
diamonds1: eccoti la griglia completa!
---------------------------------------------------
in questo modo diamonds1 invia una griglia completamente vuota o come vuole lui(es gemme tutte rosse ma in questo caso basta fare un riscontro sulla % di gemme di un determinato colore che possono arrvare fino a quel punto del gioco, invalidare la risposta e segnalare il cheater).
non so forse ho capito male il protocollo...

thebol
30-05-2006, 16:18
hummm....
mettiamo che su diamonds1 ci sia un cheater

---------------------------------------------------
diamonds1 a diamonds2 ti ho inviato 400 pacchetti, ti sono arrivati? (informazione falsa)
diamonds2: no veramente me ne sono arrivate 290... getFullState
diamonds1: eccoti la griglia completa!
---------------------------------------------------
in questo modo diamonds1 invia una griglia completamente vuota o come vuole lui(es gemme tutte rosse ma in questo caso basta fare un riscontro sulla % di gemme di un determinato colore che possono arrvare fino a quel punto del gioco, invalidare la risposta e segnalare il cheater).
non so forse ho capito male il protocollo...

invece di spedire la griglia, poterbbe inserire gli ultimi eventi importanti(tipo dovo sono finite le gemsPair, oppure a che turno ha esploso la dinamite).

In questa maniera si avrebbe un maggior controllo

Rubberick
30-05-2006, 16:59
hummm....
mettiamo che su diamonds1 ci sia un cheater

---------------------------------------------------
diamonds1 a diamonds2 ti ho inviato 400 pacchetti, ti sono arrivati? (informazione falsa)
diamonds2: no veramente me ne sono arrivate 290... getFullState
diamonds1: eccoti la griglia completa!
---------------------------------------------------
in questo modo diamonds1 invia una griglia completamente vuota o come vuole lui(es gemme tutte rosse ma in questo caso basta fare un riscontro sulla % di gemme di un determinato colore che possono arrvare fino a quel punto del gioco, invalidare la risposta e segnalare il cheater).
non so forse ho capito male il protocollo...

Eh.. brutta storia... :D

In pratica mi sembra di capire che a questo punto in nessuna situazione potremo mai mandare una griglia completa... in quanto essendo diamonds pubblico chi volesse hackerarlo potrebbe... (capirai che sfizio c'e' xo'...)

Nulla nn mi viene in mente nient'altro che un server intermedio di controllo annullando quella che e' la logica del p2p :\

Tale server pero' permetterebbe anche a gente come fw di connettersi... le solite due facce della medaglia...

Rubberick
30-05-2006, 17:11
Eh no... ci sono cambiamo un po' di carte in tavola...

Basiamo tutto sulle azioni, ne + ne - i controlli vengono fatti sulle azioni sincronizzate... da una e dall'altra parte ci sono azioni inviate e azioni ricevute... qualora si sia persa qualche azione il diamonds remoto chiedera' al locale il rinvio dell'azione...

le azioni fatte dal locale quindi dovranno essere in un array disponibile per l'invio...

ogni pacchetto in riferimento all'azione dovra' avere un unico codice identificativo... basta un intero molto grosso che si azzera e torna daccapo e la lista delle azioni secondo me si puo' settare a 100 di dimensione... e' una lista a scorrimento... array LocalActions[100]

si forse cosi' dovrebbe andare e teniamo sempre il consumo in termini di banda minimo!

:sofico: :sofico: :sofico: il diamonds remoto che riceve le azioni man mano chiedera' in modo identificativo al diamonds locale una GetActionID(23) ad es pero' magari continua ad accumulare azioni la 24, la 25, la 27 (chiedera' la 26) - le richieste funzionano con la stessa logica del bombardamento di quella che era la vecchia getfullstate e processa le azioni a partire da un array che potremmo definire RemoteActions[100].. man mano che le usa le svuota e passa appresso... sisi cosi' potrebbe andare...

ora scappo se nn e' chiaro a qualcuno rispiego in termini diversi poi...

cmq in sostanza tutto il modello di networking si ricalibra su un buffer delle azioni con controllo degli errori, gestendo adeguatamente le informazioni sui pacchetti persi e quelle sulla latenza e' possibile anche regolare dinamicamente la velocita' del gioco in modo da rendere + fluido il tutto senza effetti di frameskipping....

a questo punto la sicurezza e' massima perche' l'unico modo di hackerare diamonds sarbbe che uno dei due utilizza una versione tarokka in grado di lanciare delle azioni non consentite nella realta'... ad esempio distruggere una gemma e muoverne una sola... cambiare il tipo di gemma piazzando un forziere al posto di una gemma e cosi' via...

MA e sottolineo ma se il diamonds locale fa un check se l'azione e' corretta o meno anche sul RemoteActions buffer, (le controlla prima di processarle) il problema e' risolto! :D

Se ovviamente trova un hacking mette in pausa il gioco e scatta un allarme hacking =) dando la vittoria a quello che giocava pulito...

Abbiamo risolto? :D :sofico: :sofico:

Rubberick
30-05-2006, 17:41
Ancora ancora... stavo pensando possiamo fare una cosa molto bella e astrarre il tutto come piace a voi programmatori xD

[nuova e si spera definitiva teoria]
- Il protocollo a basso livello e' costituito da pacchetti UDP
- Ipotizziamo una dimensione fissa e lavoriamo sempre con quella, o al meglio dei casi con dimensione minore ma non superiamo mai una certa dim, anche per meglio quantificare il consumo di banda.
- Dividiamo i pacchetti in due categorie:
--- Indispensabili
--- Non Indispensabili
(ad es potrebbe essere il primo bit utile del pacchetto, [0 non indisp.] - [1 indisp])

Indispensabili: Ogni pacchetto e' identificato ulteriormente ed in modo univoco da un numero intero, tocchera' vedere quanto grande... si potrebbe fare un 15 bit unsigned in modo che con quello iniziale arriviamo a 16, 1 identificativo del fatto che e' indisp e 15 che ci riservano un totale di 32767 identificatori...

Ho sbagliato a dire univoco perche' sara' a rotazione la cosa (nn rotazione in senso stretto altrimenti ci metteremmo nei casini)... dopo che la lista si e' riempita, la prox azione andra' a prendere l'id 0 e tornera' a riempire di nuovo blocchi gia' usati 32767 azioni fa :P

Non Indispensabili: Pacchetti come il ping :) per il quale non c'e' bisogno del re-invio in caso di errore... non contenendo l'identificatore ed essendo semplici in partenza questi pacchetti saranno leggeri e veloci limitandosi a poco + della dimensione dell'udp base

---------------------------------------------------------------------------

Il funzionamento del resto della baracca e' semplice.

Il lato gaming del gioco locale bufferizza una lista di pacchetti contenenti le azioni o altro (si puo' estendere il concetto associando priorita' e classe del pacchetto, le azioni potrebbero avere priorita' media e classe 1 identificativa ma qui entriamo molto nella specifica del protocollo) concentriamoci cmq sulle azioni.

Il lato networking del gioco locale provvede ad inviarle...

Il lato networking del gioco remoto provvede a riceverle e ricostruire una lista nel suo locale di quella che era del primo... se ce ne sono di mancanti cerca di far andare avanti la lista delle azioni ( nel caso ideale, prevedendo quella chicca rallentandola ;) ;) ;) ) e nel frattempo invia richieste al locale dicendo hey mi manca l'azione 31551...

Il lato gaming del gioco remoto provvede a fare effettivamente le azioni come richiesto e nel momento che le fa gia' che c'e' controlla se possono essere fatte... se non possono essere fatte etichetta il gioco come hackato e vabbe qui decidete voi il cosa...

Soddisfatti? :P

Se serve posso dare una mano nella stesura del protocollo =)

cionci
30-05-2006, 17:44
Il problema di spedire lo stato dell'intera griglia è che questo NON E' sufficiente per ricostruire la partita, ma servono per forza gli eventi, perchè glie venti vanno ad influire sulla griglia avversaria (inserimento delle stone) !!!

jappilas
30-05-2006, 17:49
e mandare: lo snapshot della griglia quando questa e' alterata da una qualche azione, aggregata al timestamp e a un codice di descrizione dell' ultimo evento (crush, esplosione...) che l' ha modificata? :stordita:

cionci
30-05-2006, 18:03
A questo punto penso che sia più semplice implementare un protocollo con ACK...

Ogni ACK in attesa ha un timer (che in teoria può essere anche un numero di ACK per i pacchetti successivi arrivati), se il timer scade il pacchetto il cui ACK è mancante viene rispedito...

Il client comunque per ogni pacchetto ricevuto invia un ACK (anche se l'ha già inviato)...

Quindi di fatto l'attesa di un pacchetto non blocca server e client... Sicuramente blocca la griglia avversaria sul client, ma non dipendendo più dal timer possiamo anche permettercelo...le stone magari arriveranno più tardi sul campo avversario, ma questa cosa non possiamo impedirla (a meno che non vogliamo far passare comunque i pacchetti con stone da mettere nel campo avversario che di fatto sono le informazioni di sincronizzazione più importanti)...

La perdita di un ACK non comporta alcun aumento del lag...solo un po' di traffico in più...

Niente full state ed il protocollo è possibile renderlo con semplicità duale, infatti supponendo entrambi i lati client e server e possibile inglobare un ACK nel prossimo pacchetto eventi inviato...

Inoltre il ping è misurabile direttamente dagli ACK come differenza fra ACK del gameturn più alto ricevuto e pacchetto degli eventi con gameturn più alto spedito...

cionci
30-05-2006, 18:14
Ah...mi dimenticavo di fare qualche considerazione sugli errori di trasmissione... Nei pacchetti ci dovrà essere un CRC... Un pacchetto con CRC errato viene semplicemente scartato...

Rubberick
30-05-2006, 18:14
scusa cionci una question... ma con il discorso degli ack per ogni azione, non aumenti il traffico sulla rete? col sistema mio viene fatta invece una richiesta solo quando si vede che il pacchetto e' mancante.. o danneggiato (hai ragione mi ero scordato il crc)

Sto parlando dell'ultima proposta :D ne sono state fatte mille ^^, l'ultima non prevede nemmeno i fullstate...

cionci
30-05-2006, 18:28
Sì, ma se perdi il pacchetto della richiesta di rispedizione come te ne accorgi ?

Gli ACK come dicevo sono a costo quasi nullo perchè vengono inglobati nei pacchetti eventi...devono contenere solo un identificativo del gameturn per cui si invia l'ACK... Di fatto 4 byte (se lo facciamo di 4 byte) in più per ogni pacchetto...

Senza contare che nella mia proposta non c'è bisogno dei pacchetti di ping...

Bonfo
30-05-2006, 18:54
Soddisfatti? :P


Mi pare fantastica!!!
Penso che sia la cosa più realizzabile proposta per adesso.


Sì, ma se perdi il pacchetto della richiesta di rispedizione come te ne accorgi ?


Hai ragione.
In ogni caso si possono inviare lo stesso gli ACK piggyBacking ( :oink: ) aggiungendo un campo di soli 16 bit ( seguendo la proposta di Rubberick) che indicando l'ultimo pacchetto in ordine arrivato.

Inoltre il timer può essere anche lato richiedente...ovvero:
-sto aspettando il 16
-mi vedo arrivare il 18
-richiedo il 17
-setto un timer
-se scade il timer richiedo il pacchetto 17 e risetto il timer

In questo modo ci risparmiamo pure gli ACK ;)

cionci
30-05-2006, 18:57
Faccio un piccolo esempio: supponendo per entrambi i protocolli un tempo di attesa pari a 1,5 volte il Round Trip Time, tempo che chiamo Ta (per ora usiamo il timer per semplificare tutto)...


Perdita di un pacchetto eventi...

Rubberick:

non arriva un pacchetto (cioè arriva il successivo, ricordati che possono anche arrivare fuori sequenza), quindi si fa partire il timer... Trascorso Ta si fa la richiesta del pacchetto mancante, quindi il pacchetto ritorna in un tempo RTT (approssimiamo)...

In RTT + Ta hai il pacchetto mancante, cioè in 2.5 RTT...

Cionci:

non arriva un pacchetto (cioè arriva il successivo), il client non fa niente e continua a lavorare beatamente... Al server non arriva l'ACK (quindi se ne accorge dopo circa RTT/2 rispetto a quando avrebbe dovuto arrivare al client)...
Viene fatto partire il timer e dopo Ta viene inviato un nuovo pacchetto che arriva in RTT/2...

Quindi RTT/2 + RTT/2 + Ta = 2.5 RTT...uguale a quello sopra...


Perdita di una richiesta di pacchetto mancante (solo Rubberick):

ti aspetti il pacchetto mancante sicuramente dopo RTT...se non arriva aspetti Ta ed invii una nuova richiesta che arriva al server che ti risponde in RTT...

Quindi 2*RTT + Ta = 3.5 RTT


Perdita di una rispedizione (sia Cionci che Rubberick):

Rubberick:

situazione identica a quella sopra (non puoi sapere se hai perso il pacchetto di richiesta o quello in risposta alal richiesta)

Quindi 2*RTT + Ta = 3.5 RTT

Cionci:

viene persa la rispedizione quindi il server si aspetta un ACK entro RTT...ma non arriva e aspetta Ta per eseguire una rispedizione... La rispedizione arriva in RTT/2 al client...

Quindi RTT + RTT/2 + Ta = 3 RTT

cionci
30-05-2006, 19:06
In questo modo ci risparmiamo pure gli ACK ;)
L'uso degli accumulative ACK è una soluzione, ma bisogna aggiungerci anche il ping, che con il protocollo che avevo proposto speravo di eliminare...

Solitamente gli accumulative ACK funzionano in altra maniera... Arrivano N pacchetti, mi manca l'N-5, invio ACK N-6 e dopo devo inviare nuovamente ACK N-6....quando il server riceve il doppio ACK sa che deve mandare il pacchetto mancante... Il problema principale di questo sistema è che può essere fatto per un pacchetto mancante alla volta perchè la sequenza degli ACK non avanza !!! Invece sia con la richiesta dei pacchetti mancanti di rubberick che con il protocollo che avevo proposto io possono essere gestiti più pacchetti mancanti contemporaneamente...

Bonfo
30-05-2006, 19:19
Belli i conti...mi sono un attimo perso in alcuni e adesso me li rifaccio con carta e penn a :fagiano:

Comuqnue nel nostro caso ci interessa sottolineare che ci manca il pacchetto N-5, quindi anche dall'altra parte la concentrazione deve essere nell'inviare il pacchetto N-5, che nel mio caso richiedo esplicitamente.
Anche perchè senza quello cose me ne faccio di ricevere N-3 e N-1 che avevo perso prima negli N pacchetti???

Poi appena ricevo N-5, posso mandare l'ACK relativo a N se già li ho tutti tra N-5 e N.

cionci
30-05-2006, 19:25
Appunto...in tal caso l'ack cumulativo non ti serve a niente... Che senso ha confermare i pacchetti fino a N-6... Non basta richiedere l'N-5 e tutti gli altri pacchetti che mancano ?

Bonfo
30-05-2006, 19:44
Sì...l'ACK non serve. ;)
Volevo solo dire che l'ACK in piggybacking è una complicazione, che a basso costo, può darci sicurezze in più. :stordita:

Rubberick
30-05-2006, 20:24
Direi che a parte la scelta del metodo che implica latenza minore stiamo arrivando ad un accordo... la cosa mi fa molto piacere =)

Considerando che questo spike e' up da una vita e' una cosa bella ^^

Cionci io i calcoli ammetto nn li ho fatti, la teoria delle due liste operative mirrorate tra un'app e un'altra l'ho partorita in pochissimo... cmq si possono fare dei test pratici sia con l'uno che con l'altro sistema a questo punto...

Una cosa forse non e' stata considerata xo' nel conto... il diamonds 2 non manda un singolo pacchetto per avvertirgli mi manca il 7320, ne manda un bombardamento a qualche ms di distanza...

+ che altro si potrebbe fare una best-of dei due ragionamenti, al livello basso di correzione errori etc si potrebbe fare come hai detto tu, al livello alto io avevo fatto la proposta delle "actions" da processare con rallentamento del gioco se manca roba e il controllo della validita' degli eventi trasmessi..

A questo punto ci vedrei bene una codificazione in id di tutti i possibili eventi gestibili da diamonds... =)

I pacchetti ping nn sono obbligatori... ma era un esempio di quella che poteva essere un'implementazione needed/not needed in pratica... nonostante usiamo l'udp avremmo un qualcosa simile a tcp (i pacchetti indispensabili) e udp (i pacchetti non indispensabili) :D

cionci
30-05-2006, 21:05
Il problema è che secondo me non ci sono eventi non indispensabili... Sono tutti indispensabili...

Secondo me è ancora presto per sapere cosa dobbiamo e cosa non dobbiamo mandare e l'implementazione...

I ping (o l'alternativa proposta da me) sono indispensabili perchè bisogna stimare volta volta il RTT certo che nella tua proposta potrebbero lavorare ad un livello più basso del protocollo principale e non rientrare nemmeno nel "computo" dei pacchetti del protocollo...

Gli host si rimbalzerebbero all'infinito un token con il timestamp aggiornato...se va perso se ne genera un altro...

thebol
30-05-2006, 21:38
io partirei da una cosa semplice.

spedire unicamente dove va a finire la gemsPair, al tale turno.
Quando la gemsPair si ferma lo si spedisce.

Naturalmente sarebbe da valutare se questa soluzione puo essere usata al posto di rispedire tutta la griglia.

Altra cosa da considerare, e che le 2 griglie non potranno essere perfettamente sincronizzate...per cui le stone a che gameTurn le inseriamo quando la crush avviene poco prima dell'inserimento nella griglia avversaria?

Rubberick
30-05-2006, 23:44
? come impostazione non e' un tantino sbagliata ?

con la velocita' degli udp e la latenza bassa pure in situazione estrema con un modem penso ci possiamo ampiamente permettere di mandare un'info ad ogni movimento del tipo tasto destro, tasto sinistro, tasto giu'... specificando magari anche il tempo per il quale viene tenuto premuto :P

cioe'... capiscimi... nn e' che non voglio partire da una base semplice... e' che se voi fate in modo che arrivati ad un certo punto del codice networking...

la rete si sostituisce semplicemente alla tastiera del 2° player vi basta far si come se l'altro giocatore stesse effettivamente premendo quei tasti... non dovet riscrivere nulla agite a mo di controllo e usate tutta la gestione degli eventi classica che avete gia' fatto :P - questo ovviamente di base fa un prevent assoluto dell'hacking...

codificate i tasti in un array binario e passate quelli sottoforma di pacchetti leggeri... se il gioco va come deve non dovete scrivere una riga di codice in +, vi basta quello che avete fatto per il secondo player :P

cionci
31-05-2006, 00:09
la rete si sostituisce semplicemente alla tastiera del 2° player vi basta far si come se l'altro giocatore stesse effettivamente premendo quei tasti... non dovet riscrivere nulla agite a mo di controllo e usate tutta la gestione degli eventi classica che avete gia' fatto :P - questo ovviamente di base fa un prevent assoluto dell'hacking...
Questa soluzione è già stata scartata... Bisogna codificare tutti gli eventi, come i crush e gli aggiornamenti della posizione delle gemme...

Bonfo
31-05-2006, 00:24
Questa soluzione è già stata scartata... Bisogna codificare tutti gli eventi, come i crush e gli aggiornamenti della posizione delle gemme...


scartata :eek: !!!
Mi devo essere perso qualcosa :mc: :mc:

Chi me lo spiega?? :flower:

thebol
31-05-2006, 06:58
? come impostazione non e' un tantino sbagliata ?

con la velocita' degli udp e la latenza bassa pure in situazione estrema con un modem penso ci possiamo ampiamente permettere di mandare un'info ad ogni movimento del tipo tasto destro, tasto sinistro, tasto giu'... specificando magari anche il tempo per il quale viene tenuto premuto :P

cioe'... capiscimi... nn e' che non voglio partire da una base semplice... e' che se voi fate in modo che arrivati ad un certo punto del codice networking...

la rete si sostituisce semplicemente alla tastiera del 2° player vi basta far si come se l'altro giocatore stesse effettivamente premendo quei tasti... non dovet riscrivere nulla agite a mo di controllo e usate tutta la gestione degli eventi classica che avete gia' fatto :P - questo ovviamente di base fa un prevent assoluto dell'hacking...

codificate i tasti in un array binario e passate quelli sottoforma di pacchetti leggeri... se il gioco va come deve non dovete scrivere una riga di codice in +, vi basta quello che avete fatto per il secondo player :P
bisognerebbe fare delle prove di carico, ma la vedo dura ottenere in questa maniera un consumo di banda sull'ordine dei 2k/s, dovendo potenzialmente spedire a ritmo dell'inputRate queste informazioni.

La mia idea, era per partire dal caso base(info minime per ricostruire una griglia dopo una botta di lag, senza dover rispedire l'intera griglia), e poi affinare(spedizione di tutte le n action, spedizioni di n/10 action con interpolazione, etc)

Cosi si potrebbe gia valutare, ma in un implementazione piu semplice, i vari problemi di lag

cionci
31-05-2006, 08:16
scartata :eek: !!!
Mi devo essere perso qualcosa :mc: :mc:

Chi me lo spiega?? :flower:
Scusa, ma non si era detto di usare il motore che riproduce i log anche per riprodurre i dati che arrivano dalla rete ?

Quale significato avrebbe usare due tipi di log delle azioni diversi ?!!?

thebol
31-05-2006, 08:30
Scusa, ma non si era detto di usare il motore che riproduce i log anche per riprodurre i dati che arrivano dalla rete ?

Quale significato avrebbe usare due tipi di log delle azioni diversi ?!!?
il motore attuale come specifiche non è temporizzato.

Pero con il gameTurn si puo riuscire a fare qualcosa.


ps.secondo me il motore di log attuale e un po troppo ridondante per il gioco online, cmq si vedra :)

cionci
31-05-2006, 08:31
Pero con il gameTurn si puo riuscire a fare qualcosa.
Infatti basta il gameturn...
ps.secondo me il motore di log attuale e un po troppo ridondante per il gioco online, cmq si vedra :)

Secondo me il motore di log DEVE essere lo stesso del motore di rete....per un semplice motivo... Quello che viene riprodotto sullo schermo del giocatore remote deve essere tanto completo quanto il log...
Chiaramente non dico che l'informazioen che viaggia sulla rete debba essere il contenuto del file di log, ma con un layer intermedio le informazioni potrebbero essere adattate in un struttura fissa...

Ad esempio (indico fra parentesi il numero di bit):

gameturn(16), stone(16), pointsToAdd(24),
fallingGemsPair(8), fallingGemsPairHorizontalCell(4), fallingGemsPairVerticalPixel(12),
destroyedGemsListCount(8), destroyedGemCellCoordinates(8), destroyedGemCellCoordinates(8),
destroyedGemCellCoordinates(8) fino ad arrivare al Count,
CRC(16)

Totale 104 bit + la lista di gemme distrutte (mettiamo una media di 1 a gameturn, mi sembra anche abbondante come media)...

Un media di 14 byte a pacchetto non mi sembra poi esagerata...
Da notare che ci possiamo permettere anche di non inviare sempre i pacchetti... Durante la caduta della gemspair possiamo permetterci di inviare anche un pacchetto ogni due gameturn...ed in caso di particolari problemi di banda (da calcolare) possiamo ancora scendere... L'importante, dal punto di vista visuale è inviare pacchetti quando c'è la ditruzione delle gemme, quando c'è l'inserimento di una nuova gemspair e quando la gemspair si ferma (questo non l'ho tenuto in conto nell'esempio sopra, comunque basterebbe aggiungere un byte per riconoscere il tipo di pacchetto di ognuno di questi eventi, quindi si poterbbe scendere ancora come numero di byte)...

Insomma sotto i 16 byte a gameturn che ora mi pare che sia intorno ai 60ms, quidni con un frequenza di circa 17 pacchetti al secondo sono circa 272 byte al secondo...e ci stiamo non alla grande, ma alla grandissima...

thebol
31-05-2006, 08:49
Secondo me il motore di log DEVE essere lo stesso del motore di rete....per un semplice motivo... Quello che viene riprodotto sullos chermo del giocatore remote deve essere tanto completo quanto il log...

le info necessarie sono imho molte meno (il seed, gli input generati, e forse le stone).

E gli input si potrebbero generalizzare ancora di piu con la posizione della gemsPair(mancherebbe la dinamite & company)

Il log ha in piu che logga quello che succede all'interno del engine :O di gioco

cionci
31-05-2006, 09:04
Il log ha in piu che logga quello che succede all'interno del engine :O di gioco
Vebbè, se si decide di ritornare al log degli input (per la rete) per me non ci sono problemi...

Comuqnue il problema principale del protocollo di rete sarà il counter attack...

fek
31-05-2006, 09:21
le info necessarie sono imho molte meno (il seed, gli input generati, e forse le stone).

E gli input si potrebbero generalizzare ancora di piu con la posizione della gemsPair(mancherebbe la dinamite & company)

Il log ha in piu che logga quello che succede all'interno del engine :O di gioco

In realta' il log deve contenere il minimo di informazioni possibile per ricreare il gioco, quindi non deve loggare l'interno dell'engine, ma sedersi sopra l'engine ad un livello piu' alto. Deve loggare il risultato dell'engine di gioco.

thebol
31-05-2006, 09:54
In realta' il log deve contenere il minimo di informazioni possibile per ricreare il gioco, quindi non deve loggare l'interno dell'engine, ma sedersi sopra l'engine ad un livello piu' alto. Deve loggare il risultato dell'engine di gioco.

contiene il minimo di info possibili per riprodurlo senza timer, anche perche se no (a occhio..), basterebbero gli input da utente.

Ufo13
31-05-2006, 10:49
Io eviterei di inviare una qualunque lista di Droppable... Servono solo gli input dei due giocatori :)

Bonfo
31-05-2006, 11:24
Scusa, ma non si era detto di usare il motore che riproduce i log anche per riprodurre i dati che arrivano dalla rete ?

Quale significato avrebbe usare due tipi di log delle azioni diversi ?!!?

aaahhh...ok.
Ma infatti io sono ancora convinto che il log della azioni di input delle due tastiere permetterebbero di risolvere tutti i problemi anche relativi alle azioni da loggare e da riprodurre.

Infatti, dato il motore di gioco, come si sviluppa dipende tutto dagli input delle due tastiere...quindi basterebbe quello.

Quindi anche data la sequenza dei tasti locali e la sequenza dei tasti remoti, che è quello che proponeva rubbe ;)

cionci
31-05-2006, 11:29
Io eviterei di inviare una qualunque lista di Droppable... Servono solo gli input dei due giocatori :)
Allora il motore di log non avrà niente a che fare con il networking... Ok...almeno questo punto che a me non sembrava chiaro mi è stato chiarito...

Di fatto abbiamo due "motori" per riprodurre le azioni di un giocatore... Io lo vedo un tantinello ridondante...però fate voi...

Bonfo
31-05-2006, 11:31
Ho letto adesso tutti i post :D
Vedo che siamo tutti d'accordo...bsatano gli input dei due giocatori.
Quindi, per il remoto basta inviare i propri input e per il log bisogna loggare entrambi gli input...

...anche perchè diamnods giocato da solo non ha senso :D :D

Ripeto: l'idea di Rubbe di aver un buffer di azioni di input remote è bellissima.
Bisogna riuscire a fare in modo di riprodurre il gioco con tali informazioni e senza il timer.
Ma direi che con i gameTurn :D

cionci
31-05-2006, 11:51
Quindi, per il remoto basta inviare i propri input e per il log bisogna loggare entrambi gli input...
Mi sembra che sia chiaro che per il log si sia scelto non di loggare gli input, ma gli eventi...

Ufo13
31-05-2006, 12:06
Allora il motore di log non avrà niente a che fare con il networking... Ok...almeno questo punto che a me non sembrava chiaro mi è stato chiarito...

Di fatto abbiamo due "motori" per riprodurre le azioni di un giocatore... Io lo vedo un tantinello ridondante...però fate voi...

In realtà secondo me è presto per parlarne... I requisiti del sistema di logging e del networking sono potenzialmente differenti...

Inoltre ho sbagliato a parlare di Input... Io parlere di eventi... Insomma quello che succede nella griglia e non il suo contenuto :)

Bonfo
31-05-2006, 12:32
Allora il motore di log non avrà niente a che fare con il networking... Ok...almeno questo punto che a me non sembrava chiaro mi è stato chiarito...

Di fatto abbiamo due "motori" per riprodurre le azioni di un giocatore... Io lo vedo un tantinello ridondante...però fate voi...

Anche per me sono ridondanti.
Pe rme una volta che abbiamo un motore ingrado di riprodurre uno momento del gioco dato un'inisme di informazioni, può essere usato sia per il log che per il networking.

Inoltre io insisto.
Dato l'elenco delle gemme (il seed iniziale), i timestamp degli input (proprio i tasti) e le informazioni sugli inputRate e updateRate di entrambe le griglie è possibile ricotruire una partita.
Queste sono le informazioni FONDAMENTALI. Con queste si ottine tutto. :sofico:

Poi per il logging o per il networking, per comodità di realizzazione, per efficenza o perchè ci piace, ci possiamo mettere quello che vogliamo. :D

Inviando solo i tasti premuti sarà sicuramente un po' più difficile il motore di riproduzione, ma almeno risparmiamo lo scambio di un sacco dinformazioni e gameLog di MB :D

VICIUS
31-05-2006, 12:46
Inviando solo i tasti premuti sarà sicuramente un po' più difficile il motore di riproduzione, ma almeno risparmiamo lo scambio di un sacco dinformazioni e gameLog di MB :D
In effetti da quando logghiamo gli stati il log è di dimensioni inumane. Non basta un un intero da 8 bit al posto di una stringa di una cinquantina di caratteri ?

ciao ;)

Bonfo
31-05-2006, 12:47
Mi sembra che sia chiaro che per il log si sia scelto non di loggare gli input, ma gli eventi...

Dipende cosa deve fare il log.

Domanda: ma il log nn è già stato realizzato il ciclo scorso??
Siamo riusciti a riprodurre un game??
Se no. ma il log cosa deve fare ...ovvero quali sonoi suoi requisiti.
Deve essere solo la base per la riproduzione del gioco per "vederlo" come se fosse un filmato, ovvero con la possibiltà di andare avanti e indietro e poi fare play, oppure ha altre specifiche??

Inoltre: il motore di riproduzione di log e il motore della griglia remota devono essere diversi, devono essere ugauli, possono essere uguali come diversi??

Il fatto è che finchè non abbiamo un logging funzionante (Writer, Reader e Palyer) nonpotremmo mai capire quali informazioni sono fondamentali e quali no e quindi nenache fare il tuning del protocollo in base a queste.

Comunque il buffer di ricezione di informazioni gestito a sliding-window mi sembra applicabile in ogni caso, bisogna solo capire con cosa riempirlo ;)
Sta idea, anche se da libri di storia delle reti, mi piace un sacco :Prrr:
Chissà se senza rubbe ci sarebbe venuta mai in mente :D

VICIUS
31-05-2006, 13:04
Domanda: ma il log nn è già stato realizzato il ciclo scorso??
Siamo riusciti a riprodurre un game??
No i lavori non sono neanche cominciati :mad:

ciao ;)

Bonfo
31-05-2006, 13:10
Allora STOP alle telefonate. :D

Ogni volta che ci mettiamo a parlare del networking ci mettiamo a discutere su che cosa dobbiamo inviare più che sulla natura del protocollo.
Quindi finchè non abbiamo scoperto quello, mi sa che non abbiamo il pane da mangiare ;)

Adesso apriamo un thread per discutere delle stesse cose per il logging :D :D

cionci
31-05-2006, 13:33
Comunque il buffer di ricezione di informazioni gestito a sliding-window mi sembra applicabile in ogni caso, bisogna solo capire con cosa riempirlo ;)
IMHO è una complicazione inutile per il protocollo... Praticamente se implementiamo accumulative ACK e sliding-window in pratica stiamo facendo il TCP ;)

IMHO il protocollo deve essere KISS...

Rubberick
31-05-2006, 16:13
IMHO è una complicazione inutile per il protocollo... Praticamente se implementiamo accumulative ACK e sliding-window in pratica stiamo facendo il TCP ;)

IMHO il protocollo deve essere KISS...
Credo di capire che bonfo non si riferisse ad accumulative acks...

In merito alla proposta che facevo io la lista non era proprio a scorrimento, bensi' a chiamiamola cosi' "sovrascrittura degli indici"... cmq anche nel tuo modo devi implementare una lista se non fosse anche solo una lista dei timers ma lo e' :P
Quello cmq e' fatto al livello locale e non centra una mazza con la rete...

Il tcp non lo fai nemmeno se gonfi i pacchetti udp grossi quanto una casa... io cmq continuo a suggerire un ping (a valore certo) a basso livello per la misurazione della latenza (per averlo di comodo da usare)..

bisognerebbe fare delle prove di carico, ma la vedo dura ottenere in questa maniera un consumo di banda sull'ordine dei 2k/s, dovendo potenzialmente spedire a ritmo dell'inputRate queste informazioni.

Per input rate intendi il minimo tempo per il riconoscimento dei tasti? Basterebbe associare il send del pacchetto solo all'atto effettivo del "click" sul tasto e tanti saluti dubito che un utente medio arrivi a cliccare un tasto + di 10 volte in un secondo :D e mandare pacchetti ogni 100ms nn mi sembra una tragedia.. le info poi sarebbero ristrettissime..

Quanti tasti usate in totale? penso siamo ben sotto i 16 o forse anche solo 8 ^^

Cmq... se poi dovete necessariamente implementare le azioni in un certo modo e vi serve che vengano passate quelle al posto dei tasti e' tutto un'altro discorso chiaro... ad es se dovete far scoppiare la dinamite o chessoio e se questo non puo' essere visto passando un semplice tasto...

In effetti la teoria del send dei tasti nn si puo' applicare nel momento in cui per una qualsiasi cosa dall'altro lato il tizio nn sa come regolarsi anche se gli si mandano le info da "tastiera"...

(solo che mi domando... e come e' possibile cio' visto che il gioco e' fatto per 2 player? anche in locale nn bastano solo le keys? c'e' qualche var random che fa le bizze?)

thebol
31-05-2006, 18:15
Per input rate intendi il minimo tempo per il riconoscimento dei tasti? Basterebbe associare il send del pacchetto solo all'atto effettivo del "click" sul tasto e tanti saluti dubito che un utente medio arrivi a cliccare un tasto + di 10 volte in un secondo :D e mandare pacchetti ogni 100ms nn mi sembra una tragedia.. le info poi sarebbero ristrettissime..



l'input rate è a 20ms, ed è possibile(ma non frequente) riuscire a spingere 2 tasti fra un input rate e l'altro.

Questo si potrebbe risolvere, spedendo magari gli input degli ultimi 100ms(si rischerebbe di andare un po a scatti, ma forse neanche troppo...)

jappilas
02-11-2006, 17:09
mia semplice idea di protocollo di rete e dati da scambiare
Si assume che nell' ambito della sessione di gioco , i due endpoint diamonds debbano apparire il più possibile simmetrici , e che al lato pratico una sessione si possa trovare in essenzialmente due stati, gioco in corso e gioco in terminazione,
Quindi ipotizzerei (anche per riallacciarmi alla domanda "cosa bisogna inviare" in un altro thread ) che il pacchetto inviato da una delle due griglie all' altra sia composto da campi

1 identificazione temporale - timestamp
2 dichiarazione del tipo dei dati
3 dati che possono essere
- 3a opcode per gli eventi in "mandata"
- 3b opcode per eventuali grid action in feedback
- 3c grid configuration data

a Partita in corso
si invierebbero all' altro gli opcode degli eventi (3a) corrispondenti alle mosse sulla gemspair [rot cw, rot ccw, move left, move right, drop, POS UPDATE + data, dynamite blow + mode]
E/O agli altri tipi di evento di "sistema" ( che si presuppongono asincroni): [Turn start, Resync Request, GAME OVER INIT, GAME OVER ACK, Game START, Game QUIT]
E
si riceverebbero (eventualmente) dall' altro gli eventi (3b) corrispondenti alle grid action generate in conseguenza delle mosse sul proprio campo

Se il DC remoto applica le mosse sulla propria versione del campo avversario, e constata che non si verificano le stesse action, invia resync request e l'altro rispnderà con uno stato completo della griglia (400 B circa)

in fase game over
si potrebbe applicare un semplice handshake: il primo sistema che marca la propria perdita (griglia piena) in locale notifica all' avversario tramite l' evento GAME OVER INIT
L' avversario a sua volta applicherà le mosse in sospeso, se rileva che la griglia avversaria si riempie al timestamp T minore di un eventuale T1 di riempimento della propria, notificherà un GAME OVER ACK all'altro, e dichiarerà vinta la partita dalla propria parte
il perdente chiuderà effettivamente dopo la ricezione dell' acknowledge
Per input rate intendi il minimo tempo per il riconoscimento dei tasti? Basterebbe associare il send del pacchetto solo all'atto effettivo del "click" sul tasto e tanti saluti dubito che un utente medio arrivi a cliccare un tasto + di 10 volte in un secondo :D
però uno può tenere premuto un certo tasto, generando comunque eventi <codice_tasto, pressed> con frequenza data dall' intervallo di poll della coda di ingresso
e mandare pacchetti ogni 100ms nn mi sembra una tragedia.. le info poi sarebbero ristrettissime..per conciliare la minimizzazione dei pacchetti con la necessità di inviare dati necessari e sufficienti per comunicare all' avversario cosa succede sulla griglia locale, penserei di attuare una forma di event merging : invece di inviare ad ogni pressione di un tasto l' opcode di tipo 3a corrspondente, si invierebbe l' opcode del tipo "position update", a una frequenza più bassa (magari i 100 ms di cui si parlava prima) e solo se non si son avuti ambiamenti nella posizione della gempair attiva
questo dovrebbe avere il beneficio di tenere basso l' overhead
Cmq... se poi dovete necessariamente implementare le azioni in un certo modo e vi serve che vengano passate quelle al posto dei tasti e' tutto un'altro discorso chiaro... ad es se dovete far scoppiare la dinamite o chessoio e se questo non puo' essere visto passando un semplice tasto...
In effetti la teoria del send dei tasti nn si puo' applicare nel momento in cui per una qualsiasi cosa dall'altro lato il tizio nn sa come regolarsi anche se gli si mandano le info da "tastiera"...motivo per cui io ipotizzavo l' invio non del codice del tasto, ma di un codice relativo agli "eventi" consequenziali rispetto alle decisioni dell' utente
lo scoppio di una dinamite, sarebbe uno di questi , insieme eventualmente al modo in cui è scoppiata (croce/qudrato) che occuperebbe un bit in più nel pacchetto ;)

Ufo13
03-11-2006, 23:57
Io farei un'implementazione client-server, se il client è laggato rispetto al server amen, quasi tutti i giochi funzionano così ed è più semplice da implementare. Comunque ci pensiamo più avanti, per ora bisogna finire la modalita versus e bisogna finire tutti i refactoring necessari

Bonfo
04-11-2006, 03:20
Io insisto...faccimaolo XP questo net code.
Esempio:
task 1: far vedere il tasto premuto all'avversario con collegamento statico (ovvero mi passi l'IP)
task 2: far muovere un agemma nello schermo avversario
task 3: .....
task ..:...
task N: net code fatto :sofico:

cionci
04-11-2006, 08:23
Concordo, ma bisogna simulare anche la perdita di pacchetti...

thebol
04-11-2006, 10:37
altra ipotesi:

il tempo di gioco è diviso in tick
Il client deve spedire all'altro client(o al server) le info sui suoi spostamenti.
Queste info possono essere i tasti(o meglio l'evento associato alla pressione e al rilascio), che saranno spedite legate al tick.
[fare il logging con tasto-evento ci potrebbe aiutare a capire se questo è realizzabile o no e con quali eccezioni, basterebbe in teoria uno spike]
Il tutto tramite udp.


il pacchetto che il client spedisce contiene tutti gli eventi per un tick. Per ottimizzare la cosa si potrebbero spedire in un pacchetto piu tick(un pacchetto ogni 100ms ad esempio).

Fin qua nulla di nuovo...
Il problema è naturlamente che udp non garantisce l'ordine di arrivo dei pacchetti, ne che questi arrivino.

Per quanto riguarda l'ordine, è un problema minore visto che abbiamo il tick che ce li ordina già.

Per quanto riguarda i pacchetti persi invece il problema rimane.

La mia idea è che ogni 100ms(periodo poi da verificare e tunizzare) il server spedisca al client fino a quale tick ha le informazioni.

Il client userebbe quest'informazione per spedire tutti i tick dal tick richiesto fino a dove è realmente arrivato.



Vantaggi di quest'ipotesi: la coerenza delle azioni fatte è garantita(non posso spedire al server una griglia cittata). Possibilità di tunizare i periodi di spedizione dei pacchetti e richieste a runtime a seconda di come va la connesione


Svantaggi:Se il server rimane troppo indietro (botta di lag momentanea)riesce a recuperare la situazione richiedendo i tick arretrati?
Quando si fa una crush e si spediscono le stone da aggiungere all'altra griglia, come gestire questa situazioni in mezzo a una botta di lag(A spedisce delle stone a B, questo ha una botta di lag e riceve l'informazione dopo che ha droppato la pair e fatto altre cose:ritorna indietro?)
i tick riescono a rimanere sincronizzati (compreso un margine di tolleranza) sulle 2 macchine?

Ufo13
04-11-2006, 11:18
Svantaggi:Se il server rimane troppo indietro (botta di lag momentanea)riesce a recuperare la situazione richiedendo i tick arretrati?
Quando si fa una crush e si spediscono le stone da aggiungere all'altra griglia, come gestire questa situazioni in mezzo a una botta di lag(A spedisce delle stone a B, questo ha una botta di lag e riceve l'informazione dopo che ha droppato la pair e fatto altre cose:ritorna indietro?)
i tick riescono a rimanere sincronizzati (compreso un margine di tolleranza) sulle 2 macchine?

Per questo pensavo ad un modello client-server. Il server ha sempre ragione, se il client è rimasto indietro... Azzi sua!! :P
Nel 90% dei videogiochi online funziona così :P

thebol
04-11-2006, 13:32
Per questo pensavo ad un modello client-server. Il server ha sempre ragione, se il client è rimasto indietro... Azzi sua!! :P
Nel 90% dei videogiochi online funziona così :P
si potrebbe far fare a uno dei 2 client il server...

jappilas
05-11-2006, 15:34
Per quanto riguarda i pacchetti persi invece il problema rimane.

La mia idea è che ogni 100ms(periodo poi da verificare e tunizzare) il server spedisca al client fino a quale tick ha le informazioni.
secondo me è leggermente vulnerabile, perchè nell' intervallo tra due "Tick" si può essere perso un messaggio su N, o i messaggi possono non essere tutti arrivati nell' ordine giusto: in quest' ultimo caso il sistema dovrebbe funzionare ugualmente, tramite accodamento e sequenziazione a destinazione
per il primo, imporrei una forma di merging degli eventi generati fino allo scadere del tick, arrivando quindi alla stessa granularità del tick, e un acknowledge come per gli i eventi e messaggi di tipo asincrono (come l' invio delle stone, la rigenerazione forzata dello stato, il gameover, lo start di turno,... )
Quando si fa una crush e si spediscono le stone da aggiungere all'altra griglia, come gestire questa situazioni in mezzo a una botta di lag
secondo me si potrebbe vincolare l' invio delle stone al numero di turno (che sarebbe tenuto da un contatore interno triggerato da eventi tipo TURN START inviato dall' avversario per la propria griglia) a cui si trova la griglia dell' avversario, nello stato conosciuto dalla postazione che ha generato le stone stesse
e inviare un pacchetto che sarà a destinazione accodato come magari tutti ed eseguito prima della fine del turno
(A spedisce delle stone a B, questo ha una botta di lag e riceve l'informazione dopo che ha droppato la pair e fatto altre cose:ritorna indietro?)
se A si accorge che B ha iniziato un nuovo turno senza confermare la ricezione delle STONE, A invierebbe un messaggio contenente
il codice di forzata rigenerazione della griglia
il timestamp/numero di turno uguale a quello del messaggio delle stone notificate (**)
i dati della grid aggiornata (o magari una sua variante approssimata, ad es la "minigrid" che ai tempi studiai per l' artificial player)
(**) questo perchè c'è il rischio che il pacchetto non sia andato perso, ma si sia solo scombinato l' ordine di arrivo e si sia aggiunto il lag: nel caso arrivi prima il pacchetto delle stone, un' eventuale messaggio di forzatura generato a sua volta asincroncamente, dovrebbe essere ignorato; nel caso arrivi dopo sarebbe lui a dover essere scartato: avere lo stesso timestamp/turn number servirebbe a questo

se poi si pone il TURN START come il modo più diretto ma non unico per incrementare il contatore (ad, se un messaggio di inizio turno è ricevuto dopo quelli di alcune mosse relative a quel turno già effettuate, verrà aggiornato il contatore oltre che applicati gli effetti delle mosse avversarie) il sistema dovrebbe essere abbastanza immune da discrepanze..

Ufo13
05-11-2006, 15:53
si potrebbe far fare a uno dei 2 client il server...

Sì chiaro la mia idea è:

Network menu -> Host game / Join game

Syst3m Crash3r 480
13-11-2006, 18:49
Scusate se mi intrometto, ma questa discussione è particolarmente interessante per me visto che sono un perito informatico e un sistemista di rete. Premetto che non ho letto tutto il thread, ma comunque penso di poter dare qualche piccolo aiuto:


Ribadisco l'importanza di usare il TCP, per avere una comunicazione affidabile. L'overhead di questo protocollo è irrilevante in questo caso, visto che non bisogna trasferire moltissimi dati.
Ho realizzato una semplicissima classe in C# per stimare il carico di un host: l'avevo creata per altri scopi, ma penso che si possa adattare e arricchire facilmente.
Potrei ideare una gerarchia di classi per il gioco in rete, magari.

Ufo13
13-11-2006, 19:59
Scusate se mi intrometto, ma questa discussione è particolarmente interessante per me visto che sono un perito informatico e un sistemista di rete. Premetto che non ho letto tutto il thread, ma comunque penso di poter dare qualche piccolo aiuto:


Ribadisco l'importanza di usare il TCP, per avere una comunicazione affidabile. L'overhead di questo protocollo è irrilevante in questo caso, visto che non bisogna trasferire moltissimi dati.
Ho realizzato una semplicissima classe in C# per stimare il carico di un host: l'avevo creata per altri scopi, ma penso che si possa adattare e arricchire facilmente.
Potrei ideare una gerarchia di classi per il gioco in rete, magari.


Scaricati pure il codice e proponi :D

Syst3m Crash3r 480
22-11-2006, 18:59
Scusate se ci ho messo tanto a rispondere, ma sono sempre molto impegnato... :muro:
Ecco qua la classe ServerLoadLimiter (è da adattare, ma è un buon inizio):

class ServerLoadLimiter
{
/// <summary>
/// This is class permits to evaluate if a server is overloaded.
/// You can decide to not send data to it, then. ;-)
/// </summary>

private IPHostEntry iheServer;

public ServerLoadLimiter(IPHostEntry iheServer)
{
this.iheServer = iheServer;
}

public ServerLoadResponse EvaluateLoad(int iMaxLoadLevel)
{
ServerLoadResponse slrResponse;
iMaxLoadLevel = Math.Abs(iMaxLoadLevel);
// Get a page from the server...
HttpWebRequest hwrRequest = (HttpWebRequest)HttpWebRequest.Create("http://" + iheServer.HostName + "//glogin.shtml");
DateTime dtBeforePageRequest = DateTime.Now;
HttpWebResponse hwrResponse = (HttpWebResponse)hwrRequest.GetResponse();
TimeSpan tsTimeForAPage = DateTime.Now - dtBeforePageRequest;
slrResponse.RTTTimeForAPage = tsTimeForAPage.Milliseconds;
//// 1) Ping 3 times www.google.com and calculate the average RTT.
Ping ping = new Ping();
PingReply prReply = null;
//double dGoogleRTT = 0;
//for (int i = 0; i < 3; i++)
//{
// prReply = ping.Send("www.google.com");
// dGoogleRTT += prReply.RoundtripTime;
//}
//dGoogleRTT /= 3;
// 2) Ping the target server.
prReply = ping.Send(iheServer.AddressList[0]);
double dTargetRTT = prReply.RoundtripTime;
slrResponse.RTTPing = dTargetRTT;
// 3) Calculate the time load.
double dLoad = double.Parse(tsTimeForAPage.Milliseconds.ToString()) - dTargetRTT;
// 4) Evaluate the load.
if (dLoad > iMaxLoadLevel)
{
// We suppose that the server is quite busy...
slrResponse.IsOverloaded = true;
}
else
{
slrResponse.IsOverloaded = false;
}
return slrResponse;
}
public bool IsOverloaded(int iMaxLoadLevel)
{
ServerLoadResponse slr = EvaluateLoad(iMaxLoadLevel);
return slr.IsOverloaded;
}
}

public struct ServerLoadResponse
{
public bool IsOverloaded;
public double RTTPing;
public double RTTTimeForAPage;
}

jappilas
22-11-2006, 19:47
suggerimenti , nonchè coding guidelines

metodi il più possibile brevi
il codice dovebbe essere sempre autoesplicativo , quindi nessun commento in mezzo al codice, se mai in testa al corpo della funzione, per dichiarare bug, idiosincrasie, TODO ecc ;)
se possibile niente struct, finchè si tratta solo di ottenere dei valori o delle flag usa dei metodi getter
in questo caso ad esempio aggiungerei due variabili private, un metodo pubblico public boolean isOverloaded(int maxLoadLevel)
{
return (evaluateLoad() > maxLoadLevel);
} con evaluateLoad() trasformata in private
nei nomi delle variabili non inserire l' abbreviazione del tipo che istanziano, e non aver paura di scriverli per esteso (ad es PingRoundTripTime piuttosto che RTTPing )

questo per il codice che si intende aggiungere a diamonds (e a prescindere dal tuo in particolare e dalla sua funzione)
ma se ti capita prova ad applicare questi criteri sempre (io l' ho fatto e la qualità e leggibilità del mio codice è aumentata) ;)

Syst3m Crash3r 480
23-11-2006, 16:38
Ho fatto un po' di modifiche. Ecco qua la nuova versione:

class ServerLoadLimiter
{
/// <summary>
/// This is class permits to evaluate if a server is overloaded.
/// You can decide to not send data to it, then. ;-)
/// </summary>

private IPHostEntry iheServer;
private bool bIsOverloaded;
private double dRTTPing;
private double dRTTTimeForAPage;

public ServerLoadLimiter(IPHostEntry iheServer)
{
this.iheServer = iheServer;
}

private void EvaluateLoad(int iMaxLoadLevel)
{
iMaxLoadLevel = Math.Abs(iMaxLoadLevel);
HttpWebRequest hwrRequest = (HttpWebRequest)HttpWebRequest.Create("http://" + iheServer.HostName);
DateTime dtBeforePageRequest = DateTime.Now;
HttpWebResponse hwrResponse = (HttpWebResponse)hwrRequest.GetResponse();
TimeSpan tsTimeForAPage = DateTime.Now - dtBeforePageRequest;
dRTTTimeForAPage = tsTimeForAPage.Milliseconds;
Ping ping = new Ping();
PingReply prReply = null;
prReply = ping.Send(iheServer.AddressList[0]);
dRTTPing = prReply.RoundtripTime;
double dLoad = double.Parse(tsTimeForAPage.Milliseconds.ToString()) - dRTTPing;
if (dLoad > iMaxLoadLevel)
{
bIsOverloaded = true;
}
else
{
bIsOverloaded = false;
}
}
public bool IsOverloaded(int iMaxLoadLevel)
{
EvaluateLoad(iMaxLoadLevel);
return IsOverloaded;
}
public double RTTPing
{
get
{
return dRTTPing;
}
}
public double RTTPage
{
get
{
return dRTTTimeForAPage;
}
}
}


L'unico tuo consiglio che non ho applicato è quello sul nome delle variabili... :Prrr:

jappilas
23-11-2006, 17:54
public double RTTPing
{
get
{
return dRTTPing;
}
}ti chiedo scusa, ma il get in quella posizione non l' avevo mai visto :stordita: :mbe:
pensavo una cosa molto semplice, del tipo (tenendo il tuo codice ma riorganizzandolo - a parte che alcuni elementi sintattici non mi sembrano Java :mbe: ):
private void EvaluateLoad()
{
iMaxLoadLevel = Math.Abs(iMaxLoadLevel);
HttpWebRequest hwrRequest = (HttpWebRequest)HttpWebRequest.Create("http://" + iheServer.HostName);
DateTime dtBeforePageRequest = DateTime.Now;
HttpWebResponse hwrResponse = (HttpWebResponse)hwrRequest.GetResponse();
TimeSpan tsTimeForAPage = DateTime.Now - dtBeforePageRequest;
dRTTTimeForAPage = tsTimeForAPage.Milliseconds;
Ping ping = new Ping();
PingReply prReply = null;
prReply = ping.Send(iheServer.AddressList[0]);
dRTTPing = prReply.RoundtripTime;
}

public void update ( long timer )
{
if (timer - lastEvaluationTimestamp > updateInterval)
{
lastEvaluationTimestamp = timer;
EvaluateLoad();
}
}

public double getRoundTripTimeForPing()
{
return dRTTPing;
}

public bool IsOverloaded(int iMaxLoadLevel)
{
double timeForAPage = double.Parse(tsTimeForAPage.Milliseconds.ToString();
return ( timeForAPage - dRTTPing) > iMaxLoadLevel ) ;
} con l' update utile nel caso volessi assicurare che il controllo sia fatto su base periodica e avessi l' engine a chiamare la funzione passandogli il timestamp (come molte classi di DC) , con updateInterval variabile settata nel costruttore e/o presa dal config
E il chiamante ("client" dell' oggetto LoadEvaluator) o chiamerà direttamente
serverLoadEvaluator.update();
if (serverLoadEvaluator.isOverloaded())
....o userà solo i metodi getRoundTripTime() e isOverloaded() contando sul fatto che i dati siano attendibili in quanto l' update si stato forzato direttamente dall' engine ( che se non erro, "polla" buona parte delle entità istanziate tramite propagazione del timer e delle chiamate di aggiornamento tra le varie classi)

tieni conto di due cose comunque:
questo è uno spike, ma per aggiungere qualunque pezzo di codice a /trunk è necessario che sia corredato di test case
Non si dovrebbe imho dimenticare che Diamonds è nato come terreno di prova per le pratiche di sviluppo XP e test driven... anche se ora non si procede in TDD puro * (perchè il tempo scarseggia ed anche perchè la code base si è fatta un po' troppo intricata, necessitando quindi refactoring e bug fix vari) il refactoring del codice e dei test, è teso proprio ad aumentare l' utilità dei test e la loro copertura e limare la possibilità d' insorgenza di bug che i test attuali non intercetterebbero ... quindi dei test che descrivano la relazione corretta tra le tue classi e il resto del codice, nonchè il giusto comportamento osservabile sulla/e tua/e classe/i, sono indispensabili
* per inciso, tempo fa, quando si procedeva per TDD puro, la prassi era prima scrivere un test minimo, dopo scrivere il codice minimo (anche solo una riga di codice) che lo facesse passare

Inoltre, sempre quando ti capiterà di inserire del codice, dovrà armonizzarsi col resto della code base senza risaltare (in pratica uno che legga il codice non dovrebbe capire chi lo ha scritto)

Ufo13
23-11-2006, 20:15
public double RTTPing
{
get
{
return dRTTPing;
}
}


Ma non sarà C# questo? :D

cionci
24-11-2006, 10:40
Ho fatto un po' di modifiche. Ecco qua la nuova versione:
Lo sai che se la comunciazione è TCP è perfettamente inutile una cosa del genere ? Il TCP gestisce già il controllo della congestione...

Syst3m Crash3r 480
24-11-2006, 16:00
Allora, devo ricordare alcune cose:

1) Avevo detto che avrei provveduto una classe scritta in C# che avreste dovuto provvedere ad adattare e così ho fatto. :read:
2) cionci, la mia classe ha uno scopo un tantino diverso dal modo in cui il TCP gestisce la connessione: se un host è sovvraccaricato per qualsiasi ragione, non bisognerebbe disturbarlo più, o almeno per un certo tempo. Questa è una cosa che TCP non fa... :rolleyes:
3) Non chiedetemi, almeno per ora, di programmare in TDD: non l'ho mai fatto e dovrei imparare, cosa che forse farò in futuro (tempo permettendo). La classe era già pronta, perciò valeva la pena sottoporvela almeno come cose snippet... :D

jappilas
24-11-2006, 16:33
1) Avevo detto che avrei provveduto una classe scritta in C# che avreste dovuto provvedere ad adattare e così ho fatto. :read:ok, è che personalmente conosco C, C++ e Java ma codice C# non ne avevo visto molto :D
2) cionci, la mia classe ha uno scopo un tantino diverso dal modo in cui il TCP gestisce la connessione: se un host è sovvraccaricato per qualsiasi ragione, non bisognerebbe disturbarlo più, o almeno per un certo tempo. Questa è una cosa che TCP non fa... :rolleyes: può darsi che quella classe finirà con qualche modifica e adeguato testing nel codice di diamonds, come può darsi che non ve ne sia bisogno ... afaik, allo stato attuale è ancora in via di definizione il protocollo di comunicazione tra le due "griglie" remote :p
3) Non chiedetemi, almeno per ora, di programmare in TDD: non l'ho mai fatto e dovrei imparare, cosa che forse farò in futuro (tempo permettendo). La classe era già pronta, perciò valeva la pena sottoporvela almeno come cose snippet... :Dguarda code snippet, algoritmi, proposte, idee di design.... tutto serve in qualche modo, anche se del codice non lo si usa, averlo letto arricchisce comunque il bagaglio culturale (almeno il mio), quindi per me sono sempre bene accetti, a maggior ragione qui e quandunque si tratti di spike ;)
Poi, (a tutti) causa impegni, esami, e mille altre cose, sono tra i primi a dire che il tempo è tiranno e a dover ridurre l' impegno sul forum e sui task...
però visto che apparentemente il modo migliore per entrare in confidenza con il TDD era fare un task accessibile in pair con qualcuno dei membri di vecchia data, e non si tratta del primo caso di persona interessata ma intimidita o non pratica del test driven, proporrei come già in un altro thread, di agevolare la ripulitura e avviare una documentazione comprensiva del codice
Questo in vista di un' occasione in cui si troverà un po' di tempo tutti per delle sessioni di pair introduttive :)

cionci
24-11-2006, 17:05
2) cionci, la mia classe ha uno scopo un tantino diverso dal modo in cui il TCP gestisce la connessione: se un host è sovvraccaricato per qualsiasi ragione, non bisognerebbe disturbarlo più, o almeno per un certo tempo. Questa è una cosa che TCP non fa... :rolleyes:
Il TCP Vegas ha il congestion control e il flow control del TCP Reno, in più ha il congestion avoidance...
Esiste proprio una grandezza chiamata Congestion Window che determina quanti segmenti posso inviare in uscita... Questa finestra è regolata in base ad una stima del RTT e agli ACK duplicati o non ricevuti con gli algoritmi Slow Start, Fast Retrasmit e Fast Recovery.
Inoltre se la congestione è su un nodo intermedio c'è il Random Early Detection: man mano che ci si avvicina alla congestione (si piena la coda in ingresso) i router scartano volontariamente con una certa probabilità i pacchetti, in questo modo inducono i peer della connessione TCP ad abbassare la Congestion Window.

http://www.ietf.org/rfc/rfc2581.txt

In sostanza con TCP bisogna preoccuparsi solamente di spedire i pacchetti in burst...non serve assolutamente controllare la congestione perchè ci pensa il TCP stesso...

Syst3m Crash3r 480
28-11-2006, 12:41
jappilas -> Cosa intendi per "sessioni in pair"? Ripeto, non è che abbia molto tempo... :rolleyes:

cionci -> Non impedirebbe comunque a dei nodi di perdere inutilmente del tempo aspettando risposte di nodi "morti" o molto lenti... :mbe:

jappilas
28-11-2006, 13:38
jappilas -> Cosa intendi per "sessioni in pair"?Quello che si faceva un po' di tempo fa su msn o sul forum, due persone che per uno stesso task: studiano assieme la test list, e scrivono rispettivamente e alternativamente test e relativa soluzione, fino al soddisfacimento di tutte le specifiche
Questi sono alcuni dei più recenti thread di pair programming, buona lettura :)
http://www.hwupgrade.it/forum/showthread.php?t=1163417
http://www.hwupgrade.it/forum/showthread.php?t=1137234
http://www.hwupgrade.it/forum/showthread.php?t=1121469
http://www.hwupgrade.it/forum/showthread.php?t=1109317
Ripeto, non è che abbia molto tempo... :rolleyes: Per quello nemmeno io e mi pare di capire nemmeno gli altri, infatti dicevo bisognerebbe fissare qualche data e nel frattempo magari preparare il terreno... ma cmq il pair mi pareva la cosa migliore per introdurre chi davvero con il TDD desidera prendere confidenza :)

cionci
30-11-2006, 01:36
cionci -> Non impedirebbe comunque a dei nodi di perdere inutilmente del tempo aspettando risposte di nodi "morti" o molto lenti... :mbe:
La gestione che abbiamo in mente comunque non è centralizzata, ma la connessione avviene fra i due giocatori...
In ogni caso il TCP dopo un tot di timeout consecutivi sullo stesso pacchetto "resetta" la connessione...
Con il ping non hai invece garanzia di ricezione del pacchetto (si appoggia direttamente su IP) quindi se un pacchetto di ping viene scartato da un router intermedio siamo punto e a capo ;)

Syst3m Crash3r 480
08-12-2006, 10:29
jappilas -> Non ho proprio tempo per delle "sessioni in pair". Al limite potrei (e sottolineo il condizionale) codare da solo. :rolleyes:

cionci -> Va be', come non detto. :mbe:

jappilas
16-06-2007, 21:41
avendo ripensato a questa funzionalità che entro qualche ciclo si dovrà in un modo o nell'altro implementare, e ad alcune idee per farlo, ho riesumato la discussione - e nel farlo ho notato come questa fosse affetta da overdesign (rileggendolo ora, noto che anche un mio vecchio post soffriva).. e anche pesante, se per valutare cosa trasmettere via rete si è pensato di introdurre un complesso sistema di logging totale ( come se si dovesse debuggare l' intera code base :p) e ci si è complicati la vita con timestamp, "ticks", finestre temporali , ecc, prima di aver esaminato e ridotto ai minimi termini i requisiti nell' ottica "della partita" e creato un' implementazione il più semplice possibile per il caso di rete affidabile e basso delay ...
eventuali problemi si sarebbero potuti affrontare in un secondo tempo, ma almeno si poteva pensare al gioco in rete locale :O
I requisiti del sistema di logging e del networking sono potenzialmente differentiinfatti, il problema è ricostruire nemmeno tutto quello che fa internamente l' engine del gioco, ma lo stato della griglia che A controlla in locale, che B osserva e imita da remoto

e lo stato della griglia dipende essenzialmente da quali gemme vengono introdotte, dalla posizione in cui si trovano al termine della caduta, dalle crush (che anche la griglia remota è in grado di ricostruire correttamente, fintantoche la posizione finale della gempair è corretta) e dalle stone (che a questo punto si potrebbero descrivere come una sequenza di <colore, numero di turni, posizione di caduta> da inviare ) e in modalità avanzata ( se mai verrà reimplementata), dall' esplosione di una Dynamite (che non dovrebbe dare problemi fintantoche non si inverta l' ordine dell' evento "attivazione" rispetto agli altri)
Inoltre ho sbagliato a parlare di Input... Io parlere di eventi... Insomma quello che succede nella griglia e non il suo contenuto :)esattamente, mandare solo gli eventi tradotti (move_left/move_right/rotate_clockwise/rotate_counterclockwise/drop/...) sicuramente risparmierebbe banda e overhead rispetto all' invio di eventi input alla frequenza di scansione della tastiera
e numerandoli con un loro numero di sequenza intero trasmesso con l' opcode dell' evento dovrebbe permettere di accorgersi di pacchetti persi e gestirli senza ricorrere a "tick" periodici, finestre di vulnerabilità o altro (se l' ultimo evento sicuramente ricevuto è N e viene ricevuto il pacchetto N -1, semplicemente si scarta quest' ultimo, se arriva l' N + 2, lo si scarta e in più si fa richiesta di ritrasmissione di quelli da N+1 in avanti ...)
Sì chiaro la mia idea è:

Network menu -> Host game / Join gameinfatti...
- che uno dei due giocatori faccia partire il gioco per primo e resti in attesa che anche l'altro si connetta, oppure
- che uno inizi una partita per conto proprio e improvvisamente gli si presenti un menu in game "CHALLENGED BY REMOTE PLAYER - ACCEPT ? Y/N",
il modello è sempre quello...
Io farei un'implementazione client-server, io sarei per un' implementazione simmetrica p2p :O
se il client è laggato rispetto al server amen, quasi tutti i giochi funzionano così ed è più semplice da implementare.anche perchè può esserci il caso che il lag sia approssimativamente costante e/o la perdita di pacchetti sia limitata
entrambe situazioni gestibli a livello del gridcontroller in modo abbastanza semplice
per ora bisogna finire la modalita versus e bisogna finire tutti i refactoring necessari*:O Io insisto...faccimaolo XP questo net code.
Esempio:
task 1: far vedere il tasto premuto all'avversario con collegamento statico (ovvero mi passi l'IP)
task 2: far muovere un agemma nello schermo avversario
task 3: .....
task ..:...
task N: net code fatto :sofico:sì ma se un test dipende da un "agente" esterno all' indirizzo statico, fallirà quasi sempre se prima non si avvia quest' ultimo :stordita:

BlueDragon
14-05-2008, 16:22
Ciao a tutti,
scrivo questo post per "spiegare" come ho fatto lo spike del Netplay, visto che il codice non è molto leggibile.
Inanzitutto ho eliminato dall'update delle griglie il riferimento al timestamp (vedi GridController metodo update)...in questo modo ero sicuro che l'update non fosse dipendente dal tempo reale ma solo dal numero di update chiamati...1 update = 1 turno di gioco.
Poi ho modificato gli handler in modo che in caso di netplay fossero capaci di inviare le mosse del giocatore tramite l'oggetto NetGame. Da notare che non vengono inviati i tasti premuti, ma direttamente i risultati, in modo che dalla parte che riceve i dati non ci sia bisogno di ricalcolare tramite timestamp se il tasto aveva effetto o meno, vengono inviati solo i risultati sicuri, es: la gemma è stata spostata a sinistra.
Sincronizzare il gioco è quindi una questione di applicare gli eventi accaduti nell'ordine e nel turno di gioco corretto.
A questo proposito, ho messo un contatore nel loop di GameLoop-updateState() ed un if che controlla se il Netplayer ha già giocato il suo turno: se non l'ha ancora giocato (perché non ha ricevuto ancora gli eventi), la griglia rimane ferma in attesa.
Gli eventi vengono tradotti in semplici lettere: R, L, 1, 2, D, U...ossia spostamento a destra, sinistra, orario, antiorario, tasto giù, fine del tasto giù.
Ad ogni turno vengono inviate tutte le lettere degli eventi oppure se non è successo nulla in quel turno un "-".
Ogni turno di gioco viene quindi codificato in una stringa che finisce sempre con un ritorno a capo in quanto viene scritta nello stream di rete tramite writeLn e letta tramite readLine.
Per quanto riguarda il discorso client-server, peer to peer, etc... la logica, una volta premuto NetPlay nel menù, è la seguente:
1) Il gioco prova a connettersi all'IP/porta del file di configurazione
2) Se sei il primo a premere Netplay, la connessione fallirà perché l'altro gioco non è ancora pronto e quindi la tua copia passa in modalità passiva, ossia apre la porta e rimane in attesa che sia l'altro a connettersi.
3) l'altro giocatore preme netplay e riesce a connettersi perché la tua copia è già in ascolto.
Una volta stabilita la connessione, che è con Socket TCP/IP, non c'è più differenza tra chi è client e chi è server. Entrambi procedono allo stesso modo, inviando i dati degli eventi successi nella griglia locale e leggendo quelli da applicare sulla griglia "remota".

Nel fare i vari cambiamenti al codice ho rotto la possibilità di tenere premuto LEFT/RIGHT... la logica non mi era chiara in quel punto e sul momento non sono riuscito a ripararlo... per fortuna non era fondamentale :)

Non è ancora presente la codifica dell'evento "invio delle stone", quindi le due copie del gioco si desincronizzano perché le stone vengono applicate subito sulla griglia dell'avversario che hai in locale, che però è ovviamente "vecchia" rispetto alla realtà (anche una lag di pochi decimi cambia le cose). In realtà bisognerebbe inviare l'evento in remoto attendere che l'evento sia avvenuto in remoto ed applicarlo sulla griglia dell'avversario solo quando da remoto ti dicono in che turno di gioco è avvenuto.

Al momento sono un po' impegnato, comunque magari nel weekend riesco a completarlo e fare anche questa parte.

Ah, un'ultima nota...quando premete su Netplay il gioco si "impalla" finché non riesce a connettersi, in quanto rimane fermo in attesa senza far proseguire il loop del rendering mentre attende :)

Ci sarebbero poi un altro po' di dettagli da dire ma ho un po' da fare quindi concludo qui e spero che questo primo post sia sufficiente per chi vuole dare un primo sguardo allo spike :)

BlueDragon

PS: Riporto una cosa già scritta nell'altro thread:

tu come hai risolto il problema di avere la stessa sequenza di Droppable da entrambe le parti? ;)
La prima cosa che viene inviata da un gioco all'altro è il randomSeed che inizializza la sequenza "casuale" di gemme (vedi variable randomSeed in GameLoop). Da notare che attualmente il Pattern delle stone viene generato con un seed diverso, istanziato al volo la prima volta che vengono create delle stone...io l'ho modificato affinché sia sempre lo stesso seed delle gemme, altrimenti andrebbe inviato anche quello :)

PS2: Lo spike è disponibile su SVN, in una cartella a parte: svn://fcarucci.homeip.net/diamonds/Spike

Bonfo
15-05-2008, 08:27
Fantastico.
Solo un appunto: gli spike vanno sotto la cartella "branch" ;)

BlueDragon
15-05-2008, 08:50
Fantastico.
Solo un appunto: gli spike vanno sotto la cartella "branch" ;)
Argh, non avevo fatto caso che nel repository c'era già la cartella branch con anche tutti gli spike precedenti.... più tardi lo sposto :)
Una volta spostato però chi ne aveva già fatto checkout dovrebbe usare switch per sincronizzarsi sulla nuova posizione...:)

jappilas
15-05-2008, 13:20
Ciao a tutti,
scrivo questo post per "spiegare" come ho fatto lo spike del Netplay, visto che il codice non è molto leggibile.ciao, me lo sono studiato ieri e in effetti è per molti versi interessante :)
però ehm, ci sono un po' tante flag :stordita:
Inanzitutto ho eliminato dall'update delle griglie il riferimento al timestamp (vedi GridController metodo update)...in questo modo ero sicuro che l'update non fosse dipendente dal tempo reale ma solo dal numero di update chiamati...1 update = 1 turno di gioco.piccolo chiarimento terminologico ;)
quello che per me è un "turno" di gioco inizia dall' ingresso della gempair corrente e finisce quando terminano le crush dopo che la gempair è droppata - ma mi pare di capire ( anche da quello che ho visto ieri studiandomi il tuo codice per estrapolarne algoritmo e scaletta di task equivalenti) che tu invece ti riferisci a un singolo update, svolto durante una esecuzione di GameLoop.loopstep - però un "turno" durerebbe parecchi loopstep :O
Poi ho modificato gli handler in modo che in caso di netplay fossero capaci di inviare le mosse del giocatore tramite l'oggetto NetGame.
Da notare che non vengono inviati i tasti premuti, ma direttamente i risultati in modo che dalla parte che riceve i dati non ci sia bisogno di ricalcolare tramite timestamp se il tasto aveva effetto o meno, vengono inviati solo i risultati sicuri, es: la gemma è stata spostata a sinistra.
Sincronizzare il gioco è quindi una questione di applicare gli eventi accaduti nell'ordine e nel turno di gioco corretto.sono felice di non essere stato il solo a ragionare in questo modo :)
Non è ancora presente la codifica dell'evento "invio delle stone", quindi le due copie del gioco si desincronizzano perché le stone vengono applicate subito sulla griglia dell'avversario che hai in locale, che però è ovviamente "vecchia" rispetto alla realtà (anche una lag di pochi decimi cambia le cose).
In realtà bisognerebbe inviare l'evento in remoto attendere che l'evento sia avvenuto in remoto ed applicarlo sulla griglia dell'avversario solo quando da remoto ti dicono in che turno di gioco è avvenuto.io lo farei in modo leggermente diverso - cioè senza nessuna attesa, semplicemente inviando un messaggio contenente il numero (rilevato in locale) del turno a cui è giunta la griglia *avversaria* nel momento dell' invio
il giocatore remoto, ricevuto questo messaggio, confronta il valore con quello del proprio contatore interno -
se corrisponde esegue l' immissione delle Stone senza generare risposta, se non corrisponde vuol dire che è andato troppo avanti, è avvenuta una desincronizzazione - e potrebbe reagire inviando al gridcontroller "proxy" remoto un messaggio di RESYNC contenente lo stato *effettivo* della griglia risultante dall' applicazione delle stone al proprio turno corrente

entrambe le soluzioni sono però un po' troppo complesse per essere implementate ora imho... meglio secondo me mettersi a reimplementare la funzionalità base di "join", "setup" ( di gameloop e playfield) e "mirroring" (delle mosse) in TDD (vedi dopo) ;)
Al momento sono un po' impegnato, comunque magari nel weekend riesco a completarlo e fare anche questa parte.quello che già hai fatto non è poco :)
forse si potrebbe fare un feature freeze temporaneo e mettersi tutti assieme a stendere i task e reimplementare in tdd puro e in codice pulito e integrato con il resto della code base, quanto finora hai ottenuto con lo spike, ti va? ;)
Ah, un'ultima nota...quando premete su Netplay il gioco si "impalla" finché non riesce a connettersi, in quanto rimane fermo in attesa senza far proseguire il loop del rendering mentre attende :)mia idea personale, improntata alla semplicità e gradualità: un paio di nuovi "Loop" frapposti al menuloop e al gameloop in caso di netplay ( uno creerebbe prima il socket server e si porrebbe in attesa di un messaggio "join", ricevuto quello invierebbe il seed - l' altro creerebbe prima il socket client e invierebbe un messaggio "join" per restare in attesa del seed) - comportamento polimorfico, nessuna flag, ottenimento del seed più chiaro che non il dump il socket appena dopo averlo creato

downsides ( ma a questo punto credo più caratteristiche inerenti): necessità di avere: due voci di menu e due menu action separate Host Game / Join Game;
e dei "messaggi" costituiti da un opcode più un campo dati opzionale, per il seed come, ad esempio, per il turno di invio stones, per la sincronizzazione - si perderebbe l' uniformità semantica con gli Event usati per l' input da tastiera - ma non è detto che sia un male, giacchè si operebbe a un livello diverso - inoltre si tratta di un meccanismo che in prospettiva non avrebbe un solo utilizzo)

BlueDragon
15-05-2008, 17:15
ciao, me lo sono studiato ieri e in effetti è per molti versi interessante :)
però ehm, ci sono un po' tante flag :stordita:

Sì, è abbastanza orrendo..per fortuna è uno spike o mi sarei dovuto spezzare le ditine da solo :D


piccolo chiarimento terminologico ;)
quello che per me è un "turno" di gioco inizia dall' ingresso della gempair corrente e finisce quando terminano le crush dopo che la gempair è droppata - ma mi pare di capire ( anche da quello che ho visto ieri studiandomi il tuo codice per estrapolarne algoritmo e scaletta di task equivalenti) che tu invece ti riferisci a un singolo update, svolto durante una esecuzione di GameLoop.loopstep

Esatto, il mio "turno" in realtà è "1 update" :)
All'inizio avevo visto che esiste una classe GameTurn e speravo fosse quello che mi serviva, poi invece era diverso... :)


io lo farei in modo leggermente diverso - cioè senza nessuna attesa, semplicemente inviando un messaggio contenente il numero (rilevato in locale) del turno a cui è giunta la griglia *avversaria* nel momento dell' invio
il giocatore remoto, ricevuto questo messaggio, confronta il valore con quello del proprio contatore interno -
se corrisponde esegue l' immissione delle Stone senza generare risposta, se non corrisponde vuol dire che è andato troppo avanti, è avvenuta una desincronizzazione - e potrebbe reagire inviando al gridcontroller "proxy" remoto un messaggio di RESYNC contenente lo stato *effettivo* della griglia risultante dall' applicazione delle stone al proprio turno corrente

Uhm... nel caso che hai menzionato bisogna mandare indietro nel tempo la griglia su cui l'altro giocatore sta giocando (!) e trovare quindi un metodo per inviare l'intera griglia che da te è remota e usarla per sostituire la griglia locale dell'altro giocatore...! Cosa un po' strana visto che le griglie locali dovrebbero essere "master", ossia sorgenti dell'informazione sullo stato delle griglie e non essere comandate da quelle remote. Inoltre, per come è fatto lo spike, 1 update (10 msec circa) può già essere troppo avanti, quindi il resync averrebbe praticamente sempre :)


entrambe le soluzioni sono però un po' troppo complesse per essere implementate ora imho... meglio secondo me mettersi a reimplementare la funzionalità base di "join", "setup" ( di gameloop e playfield) e "mirroring" (delle mosse) in TDD (vedi dopo) ;)

Ho già una soluzione in mente e dovrebbe essere semplice...appena possibile tento di applicarla così siamo sicuri che è fattibile, altrimenti lo spike senza invio delle stone non vale moltissimo...pensa se scoprissimo che non è assolutamente possibile inviare stones con quel design! Il valore dello spike crollerebbe a zero visto che senza sincronizzazione delle stones non si riesce a fare una vera partita online.. finirebbe come tra me e Jocchan, dove ognuno aveva vinto "in locale" :)


forse si potrebbe fare un feature freeze temporaneo e mettersi tutti assieme a stendere i task e reimplementare in tdd puro e in codice pulito e integrato con il resto della code base, quanto finora hai ottenuto con lo spike, ti va? ;)

Se implementiamo lo spike non è più un feature freeze :D Comunque sta a Jocchan decidere :) Io proverò a liberarmi il più possibile in modo da essere attivo ed affidabile finché non abbiamo ben decollato con il netplay :)


mia idea personale, improntata alla semplicità e gradualità: un paio di nuovi "Loop" frapposti al menuloop e al gameloop in caso di netplay ( uno creerebbe prima il socket server e si porrebbe in attesa di un messaggio "join", ricevuto quello invierebbe il seed - l' altro creerebbe prima il socket client e invierebbe un messaggio "join" per restare in attesa del seed) - comportamento polimorfico, nessuna flag, ottenimento del seed più chiaro che non il dump il socket appena dopo averlo creato

downsides ( ma a questo punto credo più caratteristiche inerenti): necessità di avere: due voci di menu e due menu action separate Host Game / Join Game;
e dei "messaggi" costituiti da un opcode più un campo dati opzionale, per il seed come, ad esempio, per il turno di invio stones, per la sincronizzazione - si perderebbe l' uniformità semantica con gli Event usati per l' input da tastiera - ma non è detto che sia un male, giacchè si operebbe a un livello diverso - inoltre si tratta di un meccanismo che in prospettiva non avrebbe un solo utilizzo)
Ehm....mi sono perso!!! Per quanto riguarda il codice...creiamolo piano piano e ci dirà lui cosa serve...per il menù invece: Jocchan :D

BlueDragon

jappilas
15-05-2008, 18:29
Sì, è abbastanza orrendo..per fortuna è uno spike o mi sarei dovuto spezzare le ditine da solo :De meno male che non ho più spedito a fek il regalo che pensavo di fargli (http://www.spazioro.it/ita/scheda.asp?p=148) ... :D
Esatto, il mio "turno" in realtà è "1 update" :)
All'inizio avevo visto che esiste una classe GameTurn e speravo fosse quello che mi serviva, poi invece era diverso... :)ok, lo dicevo perchè per me era in effetti più chiaro usare la nozione di "gameturn" - per un motivo
l' invio delle stone sarebbe "validato" senza richiedere risincronizzazione, per la durata del gameturn corrente in cui avviene
ma lo stesso non si può dire per i cicli di esecuzione di loopStep() ( i tuoi turni) perchè un GameTurn si estende sicuramente per un certo numero di cicli...

sbaglierò ma mi sembra che usare i cicli come turni, complichi un po' un problema che potrebbe essere più semplice :wtf:
Uhm... nel caso che hai menzionato bisogna mandare indietro nel tempo la griglia su cui l'altro giocatore sta giocando (!) perchè ?
se non vado errato il resync dovrebbe poter essere comandato da un messaggio che la griglia remota può ricevere ed eseguire in locale senza accodamenti, o particolari meccanismi - a patto che il turno in cui è eseguito corrisponda a quello in cui dall' altra parte è generato lo snaphot della griglia ( tenendo conto del fatto che le gemme nella griglia non si muovono e non cambiano durante un gameturn se non alla fine, con le crush)
e trovare quindi un metodo per inviare l'intera griglia che da te è remota e usarla per sostituire la griglia locale dell'altro giocatore...! nel gioco locale, l' input reactor e gli EventHandler in esso contenuti sono più o meno onnipotenti, in quanto hanno accesso al gridcontroller e da qui alla grid
non dovrebbe essere molto difficile crearne un equivalente apposito per il netplay (che già in effetti esiste, nell' ottica della code base il tuo netplayer è sovrapponibile all' input reactor, con la differenza che quello si appoggia a un altro oggetto il quale a sua volta riceve gli aventi dalla tastiera, e il netplayer legge da un soscket e parsa i caratteri ricevuti), che inserisca nella griglia le gemme deserializzate dal messaggio ricevuto ( come hai serializzato i comandi non dovrebbe essere difficile farlo con le gemme - per serializzarle potresti implementare una iteration che per ogni droppable genera un carattere per il tipo seguito dai valori interi di riga e colonna)
Cosa un po' strana visto che le griglie locali dovrebbero essere "master", ossia sorgenti dell'informazione sullo stato delle griglie e non essere comandate da quelle remote. qui secondo me ci starebbe un' importante chiarificazione a beneficio di tutti

per come la vedo io ( non necessariamente il modo "corretto", solo come mi appare da quando ho provato a ragionare sul netplay per conto mio ) le entità in gioco, complessivamente, sono 4 ( campo locale e campo remoto sia sulla macchina locale "A" che su quella remota "B") ma essendovi simmetria sia nella comunicazione tra le due sia nel fatto che il gridcontroller del 2o giocatore può e deve sia ricevere che inviare all' avversario delle Stones, quelle da considerare sono 3, cioè i giocatori ( o GridController):

locale sulla macchina A -> "A local"
locale sulla macchina B (remota rispetto ad A) -> "B- local"
remoto sulla macchina A -> "A - remote"

ora, in ottica di GridController, dal momento che "A-remote" controlla la 2a griglia (locale) imitando le mosse "B-local" e ricevendo le stones inviate dal controller di A- local per poi ( in propspettiva) comunicarlo a B - local con un messaggio apposito, A - remote è sostazialmente un proxy di , o "B- proxy"

ed è anche quello a cui mi riferisco quando nomino la "griglia remota" , non il giocatore remoto ( cioè B- local) ma il suo proxy locale ( aka A- remote)

chiedo scusa per la verbosità ma mi sembrava un chiarimento necessario , altrimenti si richia più avanti di non capirsi :O
Inoltre, per come è fatto lo spike, 1 update (10 msec circa) può già essere troppo avanti, quindi il resync averrebbe praticamente sempre :)anche per quello pensavo ai gameturn - se un gameturn dura tipicamente qualche secondo , tranne quando si approssima il gameover, il gridcontroller "proxy" di cui sopra può "respirare", e ci si può permettere la presenza e gestione di un messaggio (asincrono rispetto al gameturn stesso ) che sarebbe effettivamente una misura d' emergenza

IMHO , ovviamente ;)
Ho già una soluzione in mente e dovrebbe essere semplice...appena possibile tento di applicarla così siamo sicuri che è fattibile, altrimenti lo spike senza invio delle stone non vale moltissimo...pensa se scoprissimo che non è assolutamente possibile inviare stones con quel design! Il valore dello spike crollerebbe a zero proprio zero no, perchè algoritmi e idee sono comunque entrati
per quanto mi riguarda ad esempio mi sono fatto un' idea di una possibile scaletta di task per replicare in tdd la funzionalità attuale ;)
task uno per uno molto semplici, ad esempio introdurre la nuova menuaction, introdurre Config.getString(), usare Environment per memorizzare e poi recuperare il gameseed eccetera eccetera
inoltre qualora venisse fuori che un problema non viene risolto dal codice di uno spike, anche in questo caso il valore dello spike è non nullo, perchè comunque si sa cosa non ha funzionato, quindi cosa eventualmente tenere per buono e cosa evitare durate un task o un refactoring futuro ;)
tieni conto comunque che in tdd uscirà del codice che non è detto essere uguale a quello scritto da te nello spike, anzi con buona probabilità ci saranno notevoli differenze anche qualora gli algoritmi usati siano gli stessi ;)
visto che senza sincronizzazione delle stones non si riesce a fare una vera partita online.. finirebbe come tra me e Jocchan, dove ognuno aveva vinto "in locale" :)se non ricordo male era uscito che il gameover costituirebbe un ulteriore problema di suo, in certe condizioni motivo per cui probabilmente andrà sincronizzato anche quello
ma un problema alla volta ;)
Se implementiamo lo spike non è più un feature freeze :D Comunque sta a Jocchan decidere :) Io proverò a liberarmi il più possibile in modo da essere attivo ed affidabile finché non abbiamo ben decollato con il netplay :)ok :)
Ehm....mi sono perso!!! semplicemente , mi sono detto: sia nel caso di "Host" che di "Join" di un avversario remoto, instaurare la connessione è un busy loop che una volta terminato cede il posto al GameLoop, e che ( imho) non avrebbe molto senso di stare in MenuLoop... e siccome abbiamo già in place una struttura ad oggetti "*Loop" polimorfici fatti apposta per avvicendarsi gli uni agli altri, partivo dal presupposto di estendere (in tdd) tale struttura... :D
Per quanto riguarda il codice...creiamolo piano piano e ci dirà lui cosa serve...per il menù invece: Jocchan :Dof course :)

BlueDragon
15-05-2008, 23:02
Ho appena committato la versione 2944 nello Spike.....codename: "StonesSincronizzate" :D
Ho provato con Jocchan e sembra funzionare bene...ci siamo divertiti a fare un po' di partite, vi allego un paio di screenshot di confronto :D

Una volta vinco io....
http://img179.imageshack.us/img179/5139/synch01wk2.jpg (http://imageshack.us)
...ed una volta vince Jocchan.. :)
http://img137.imageshack.us/img137/6767/synch02wc2.jpg (http://imageshack.us)

Nel secondo screenshot la griglia del giocatore vincente sembra meno sincronizzata ma è solo perché gli screenshot non li abbiamo presi allo stesso secondo :)


Per sincronizzare le stones ho seguito queste 3 regole:
1) La griglia locale *non* può agire sulla griglia accanto (in quanto è una griglia remota)
2) La griglia remota quando replica la tua crush può inviare le stones alla griglia locale dell'avversario
3) La griglia locale, quando subisce delle stones avverte la sua copia in remoto in modo che vengano applicate anche lì.

Ho anche pulito un pochino il codice in GameLoop, ora è più semplice :)
Sempre dentro GameLoop ho lasciato un commento in quanto non ero sicuro che le stones fossero applicate in ordine corretto, ma in realtà dovrebbe funzionare....ci penserò un altro po' magari :)

Faccio un piccolo riepilogo del "vocabolario" usato dallo stream di rete tra i due pc:
- ogni riga è un turno
- ogni turno inizia con un trattino "-" (questo mi sa che non serve più)
- se il player muove con successo la gemma, possono essere aggiunti alla riga i seguenti caratteri:
L = gemma mossa a sinistra
R = gemma mossa a destra
W = rotazione oraria
N = rotazione antioraria
M = rotazione 180°
D = tasto giù premuto, gemma accelerata
U = tasto giù rilasciato
- CXXXXC dove XXXX è un numero intero qualsiasi che indica il numero di stone subite dalla griglia.

BlueDragon

thebol
16-05-2008, 08:41
Ho appena committato la versione 2944 nello Spike.....codename: "StonesSincronizzate" :D
Ho provato con Jocchan e sembra funzionare bene...ci siamo divertiti a fare un po' di partite, vi allego un paio di screenshot di confronto :D

Una volta vinco io....
http://img179.imageshack.us/img179/5139/synch01wk2.jpg (http://imageshack.us)
...ed una volta vince Jocchan.. :)
http://img137.imageshack.us/img137/6767/synch02wc2.jpg (http://imageshack.us)

Nel secondo screenshot la griglia del giocatore vincente sembra meno sincronizzata ma è solo perché gli screenshot non li abbiamo presi allo stesso secondo :)


Per sincronizzare le stones ho seguito queste 3 regole:
1) La griglia locale *non* può agire sulla griglia accanto (in quanto è una griglia remota)
2) La griglia remota quando replica la tua crush può inviare le stones alla griglia locale dell'avversario
3) La griglia locale, quando subisce delle stones avverte la sua copia in remoto in modo che vengano applicate anche lì.

Ho anche pulito un pochino il codice in GameLoop, ora è più semplice :)
Sempre dentro GameLoop ho lasciato un commento in quanto non ero sicuro che le stones fossero applicate in ordine corretto, ma in realtà dovrebbe funzionare....ci penserò un altro po' magari :)

Faccio un piccolo riepilogo del "vocabolario" usato dallo stream di rete tra i due pc:
- ogni riga è un turno
- ogni turno inizia con un trattino "-" (questo mi sa che non serve più)
- se il player muove con successo la gemma, possono essere aggiunti alla riga i seguenti caratteri:
L = gemma mossa a sinistra
R = gemma mossa a destra
W = rotazione oraria
N = rotazione antioraria
M = rotazione 180°
D = tasto giù premuto, gemma accelerata
U = tasto giù rilasciato
- CXXXXC dove XXXX è un numero intero qualsiasi che indica il numero di stone subite dalla griglia.

BlueDragon

una figata veramente

complimenti per il lavoro fatto!!!

Bonfo
16-05-2008, 09:01
WOW!!! :mano: :cincin:

Sono d'accordo con BlueDragon: sarà il codice a dirci che cosa vuole ;)
Non facciamo l'errore di pensare tutto adesso... altrimenti facciamo lo svilupppo UML e passiamo una settimana a fare il modello statico, quello dinamico, i diagrammi di stato e di sequenza e poi facciamo anche del psuedo codice per essere sicuri che la soluzone sia corretta. Dopo anche la mia scimmia sa implementarlo ;)

jappilas
16-05-2008, 10:33
WOW!!! :mano: :cincin:

Sono d'accordo con BlueDragon: sarà il codice a dirci che cosa vuole ;)ma guarda che su questo sono perfettamente d' accordo anch' io - e d' altra visto che lo si dovrà rifare in tdd non potrà che essere così ;)
Non facciamo l'errore di pensare tutto adesso... altrimenti facciamo lo svilupppo UML e passiamo una settimana a fare il modello statico, quello dinamico, i diagrammi di stato e di sequenza e poi facciamo anche del psuedo codice per essere sicuri che la soluzone sia corretta. :sofico: :sofico:
ma no... quello che volevo era solo esporre delle constatazioni che ho fatto durante le mie sperimentazioni sul sistema di input ed eventi ( che oramai purtroppo posso dire di conoscere fin troppo bene :stordita: ) nella speranza che siano utili in futuro nella stesura dei task e soprattutto per evitare gli errori che facevo io una volta ;)

se le cose funzionano anche senza, tanto meglio ;)

jappilas
16-05-2008, 10:36
Ho appena committato la versione 2944 nello Spike.....codename: "StonesSincronizzate" :D

< CUT>

BlueDragonfantastico, davvero, complimenti anche da parte mia :)

BlueDragon
16-05-2008, 17:40
Grazie dei complimenti :)
Comunque con rammarico devo annunciare che la sincronizzazione non è ancora perfetta, mi è capitato di fare un paio di partite contro me stesso in cui il gioco si è desincronizzato, credo in prossimità di un gameover (non so se sia correlato)...
Ora sto facendo ulteriori prove con un po' di lag artificiale... vediamo cosa esce fuori ;)

BlueDragon

Ufo13
17-05-2008, 14:06
Davvero gran lavoro Blue :)

Io direi che se funziona ed e` semplice possiamo cominciare riscrivend oquesta implementazione in TDD. Una volta completata possiamo cominciare a raffinare il codice e la gestione di LAG e Firewall partendo da li`.

Potresti mica fare una lista delle classi coinvolte ed i cambiamenti piu` importanti (vedi: input, grid, gridcontroller etc...) che dovremmo fare per implementarlo?