È possibile che un server non invii altro che un'area basata su un riquadro a un client?


8

Per iniziare, ho un buon background nel networking (hardware, router, ex.) Ma pochissime conoscenze oltre le basi della programmazione di rete. Potrebbe sembrare una domanda stupida, ma voglio sapere in cosa mi sto cacciando mentre immagino l'implementazione del multiplayer nel mio gioco.

Sto creando un mondo basato su piastrelle, che viene generato attraverso un semplice array 2D. Diciamo qualcosa come World [100] [100], per semplicità.

Attualmente, il metodo di rendering esegue il rendering delle tessere solo in base alla risoluzione della finestra, più una tessera (per un rendering uniforme durante il movimento.) Non importa quanto sia grande il mondo (10x10, 1 milione x 1 milione) il rendering è impeccabile nelle prestazioni.

Il gameplay non ha bisogno di altro che sapere cosa è attualmente visibile (renderizzato sullo schermo +1) e, nella maggior parte dei casi, ALCUNE informazioni sulle tessere in un'area intorno al giocatore.

Quindi qualsiasi altra cosa inviata dal Server non sarebbe l'informazione completa sul riquadro. Ex. Gli oggetti distesi sul terreno, il tipo di terreno, gli alberi, ecc. Non sarebbero importanti nell'area al di fuori della vista del giocatore, ma sarebbero solo ciò che il Cliente / Giocatore deve sapere in quelle tessere. (Es. I "nomi in arrivo" di Ultima Online in cui i giocatori potevano conoscere un personaggio [giocatore o mostro] erano appena oltre le tessere nella loro vista renderizzata.)

Non so molto sulla rete, quindi forse, quando apprenderò, potrebbe rispondere alla mia domanda. Tuttavia, sono curioso di sapere se questa è una soluzione fattibile o se l'idea è semplicemente ridicola.

Le informazioni inviate riguarderebbero un'area di tessere 10x15 e ogni tessera contiene informazioni su ciò che si trova sulla tessera. Più efficacemente, tutto sarebbe un oggetto, in cui la tessera contiene tutti gli oggetti sulla tessera. Ex. Tile [4] [4] contiene Sword # 23452, Rock2, Tree5, Player3, Monster4.

Le tessere vuote invierebbero nient'altro che il tipo di terreno [Erba, Sabbia, Acqua] se non già caricato durante l'inizializzazione / caricamento. Alcune tessere avrebbero una manciata di oggetti [Tree2, Sword # 924, Gold, Corpse, Rock3].

Quindi non riesco a immaginare che un riquadro avrebbe molte informazioni da inviare al client dal server, poiché il client deve solo conoscere la trama che deve essere caricata e posizionarla per posizionarla sullo schermo. Posizione essendo solo due numeri interi e Texture come un numero intero per un elenco di file per indicare al client di eseguire il rendering.

Nel modo più folle, il Server dovrebbe inviare 150 tessere con le informazioni di solo una manciata di Oggetti OnLOAD, e da quel momento in poi si aggiornano solo le modifiche alle tessere (se presenti) e tutte le nuove tessere (da 10 a 15 ogni volta che un giocatore si muove in una direzione ) e la direzione del movimento per i personaggi sullo schermo (in modo che il cliente possa simulare movimenti fluidi tra le tessere).

Presumo di aver ragione nel pensare che si tratti di una quantità incredibilmente bassa di informazioni inviate su Internet o tra pari, quindi dovrebbe avere piccoli problemi con le prestazioni anche su connessioni ritardate? O sono così ignorante del networking che la mia mente sarà sbalordita quando finalmente riesco ad aprire il mio libro sul networking multiplayer?

Se si tratta di una quantità molto bassa di informazioni inviate tra client / server, avrebbe più senso caricare semplicemente l'intero mondo all'inizializzazione? O 'Mappa' se il mondo è eccessivamente grande. E poi dopo LOAD, invia solo i riquadri che vengono aggiornati?

Sto ancora riflettendo su come dovrei trattare in modo specifico i dati. Il libro che sto usando come riferimento vuole che io abbia un Elenco collegato, in cui aggiungo e rimuovo oggetti, quindi tutto è un bool. "C'è un personaggio? C'è un albero?"

Stavo pensando a un approccio diverso, come un contenitore che contiene oggetti e la logica del server che invia solo ciò che è necessario per dire al client cosa rendere. Forse con oggetti che contengono al suo interno informazioni di rete, che vengono inviate quando richiesto dal Server.


Ti suggerisco di dare un'occhiata a freemmorpgmaker.com, questo motore mi ha aiutato molto quando ho appena iniziato. La sceneggiatura è relativamente semplice e molto divertente con cui lavorare. Il codice mi ha insegnato tutto ciò che avevo bisogno di sapere per creare il mio motore / gioco 2D. Quello che non dovresti imparare da loro è come proteggere il tuo server / client.
Nick,

Risposte:


6

Sei sulla strada giusta.

Prendi in considerazione Minecraft. Minecraft carica solo le aree (chiamate anche blocchi) che circondano immediatamente i giocatori. Ecco come il server è in grado di funzionare senza esaurire la memoria e perché i client non si impantanano dal traffico di rete.

Se si tratta di una quantità molto bassa di informazioni inviate tra client / server, avrebbe più senso caricare semplicemente l'intero mondo all'inizializzazione? O 'Mappa' se il mondo è eccessivamente grande. E poi dopo LOAD, invia solo i riquadri che vengono aggiornati?

Questo è esattamente ciò che dovresti fare. Invia solo i dati che devi inviare.

  1. Quando un cliente si unisce, inviagli un pezzo della mappa delle tessere (o tutto se, se hai a che fare con piccole aree)
  2. Quando il giocatore prova a modificare una tessera, invia quei dati al server.
  3. Quando un riquadro cambia stato, invia un pacchetto con tali informazioni a tutti i client rilevanti.

Se stai semplicemente inviando un array 2D di ID tessere, la dimensione dei dati può essere molto bassa, specialmente se hai meno di 256 tipi di tessere diversi. In tal caso, è possibile utilizzare un singolo byte (o carattere senza segno). Quindi, se stai inviando tessere 100x100 al giocatore, e ogni tessera è composta da un solo byte ... L'idea ti viene. Non sono molti dati.

La comunità di Minecraft ha fatto un ottimo lavoro documentando il suo protocollo: http://mc.kev009.com/Protocol

http://www.minecraftwiki.net/wiki/Classic_server_protocol


1
wow, grazie mille! Questa è una grande spinta di fiducia che mi è stato detto che sono sulla strada giusta, quando ne so così poco. Mi dice che sto capendo le cose correttamente e che ingegnerizzo al meglio che posso. Sono fiducioso che se continuo a imparare, farò abbastanza adeguatamente. È così soddisfacente ricevere consigli positivi e non "Stai sbagliando!" lol :)

Mi ci è voluto molto tempo prima che raccogliessi il coraggio di giocare a giochi multiplayer e 3D. :)
Nick Caplinger,

Inoltre, un consiglio positivo è ciò su cui questa comunità prospera. Incoraggio tutti a contribuire in ogni modo possibile!
Nick Caplinger,

3

È generalmente una buona idea inviare al cliente le informazioni che dovrebbero essere mostrate al giocatore. Seguire questo principio riduce il traffico di rete e previene gli imbrogli.

Ma tieni presente che quando il giocatore sposta il proprio personaggio, sicuramente vorrai iniziare la mossa sul lato client prima di ricevere la conferma dal server per rendere il gioco meno lento e più reattivo. Ciò significa probabilmente che si desidera anche iniziare a scorrere lo schermo in un'area che non è ancora stata caricata. Questo ti costringe a lasciare vuota questa parte della mappa e sostituirla con il mondo reale quando è stata caricata. Sarebbe piuttosto un interruttore di immersione. Per questo motivo dovresti precaricare l'area in un certo raggio attorno allo schermo dei giocatori.

La dimensione dell'area precaricata dipende dalla velocità con cui i tuoi giocatori possono muoversi e da quanto tempo sarà la loro latenza media.


-1

La quantità di dati che invii dal server al client può essere INCREDIBILMENTE insignificante. Se questo è tutto ciò che devi inviare, suggerirei con veemenza di caricare il più possibile su Load, quindi sono necessari ancora meno dati. L'importo inviato al caricamento sarà abbastanza piccolo da giustificare il tempo di caricamento, l'utilizzo della memoria sarà quasi inesistente a meno che il tuo mondo non sia ridicolmente sovradimensionato e non dovrai aggiornare quasi nessun dato.

Immagino che potresti anche fare alcuni trucchi accurati per ottimizzare la previsione del ritardo che compensa il ritardo medio che un utente sperimenta, consentendo movimenti prevedibili con i personaggi.

Anche dare la priorità ai dati insignificanti con il movimento del personaggio e le azioni / reazioni del personaggio con la massima priorità può aiutare a garantire che anche i giocatori in ritardo sentano pochissimo ritardo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.