Il modo più efficiente per archiviare i dati del giocatore multiplayer?

0

problema :

Fare un videogioco presenta le seguenti sfide sullo storage variabile:

  • invia gli stati del player ogni 50-200ms, quindi memorizza la posizione / rotazione nel modo più efficiente possibile.
  • memorizza grandi blocchi di dati per ciascun giocatore in merito ai loro cooldown, abilità e loadout
  • tutte le variabili devono ruotare attorno all'ID di connessione assegnato quando si connettono al server, non a chi dicono di essere

soluzioni considerate finora:

  • utilizza un numero intero come " ID giocatore " che ricerca i dati su dozzine di matrici . Informare il cliente di questo numero relativo a ciascun giocatore affinché possa utilizzarlo nell'API back-end. Inconveniente - brutto e ingombrante sul lato server.
  • mappa ogni " ID giocatore " in una classe . Rifinitura: è necessario iterare solo per ottenere le posizioni / rotazioni ogni 50-200 ms.
  • crea nuovamente una matrice di strutture utilizzando " ID giocatore " come indice. Inconveniente, come sopra.

Tuttavia, ognuna di queste soluzioni che utilizzano "l'id del giocatore" come indice non funziona bene quando la concorrenza è instabile, con i giocatori che vanno e vengono. Esistono tre approcci (alla struttura effettiva dei dati inviati):

  • rispecchia la lista / matrice sui client, quindi notifica i client quando è necessario apportare una modifica (ad esempio: giocatore x a sinistra, tutti i player > x down iterate). Questo ha una locazione per rompere le cose tra il ritardo.
  • collega l'id del giocatore a ciascun aggiornamento posizionale anziché inferire che i client possono dedurlo dall'indice dell'array.
  • invia un array statico con un numero invariato di slot, tutte le posizioni non occupate vengono inviate comunque. Ci dovrebbe essere un punto di crossover in cui questo è più efficiente di includere gli id se stai utilizzando una certa quantità di esso.

Quale sarebbe la soluzione migliore per questo scenario?

    
posta hydrix 03.01.2017 - 01:33
fonte

1 risposta

1

Le mie nozioni sono troppo grandi per un commento.

L'accesso diretto all'array con l'indice del giocatore sembra porre alcune domande sulla memoria se int è > 32Bits. E anche su 32 bit sprecherai tonnellate di memoria solo per contenere un array per lo più vuoto. L'uso di una hashmap sul numero intero sembra l'approccio corretto qui.

Per datastructure: usa una classe contenente tutti i dati dei giocatori. Il tuo costo di accesso sarà

  • c per accedere al giocatore dall'hash (si suppone che abbia un costo di accesso costante)
  • n * c2 per aggiornare n valori dal client nella classe giocatore. c2 è il costo di accesso alla proprietà (dovrebbe essere trascurabile).

  • Vorrei provare a mantenere una rete di giocatori nelle vicinanze, in modo da poter limitare facilmente i giocatori ad essere aggiornati su ciascuna modifica.

  • Mantieni i giocatori che devono essere aggiornati in una coda sporca. Aggiorna solo i client che si trovano nelle vicinanze di un giocatore sporco.

L'iterazione non è malvagia per definizione. Alla fine, dovrai lavorare su ogni giocatore dal vivo là fuori. Se trovi che i tuoi aggiornamenti non escono abbastanza velocemente, devi lanciare più discussioni sull'attività. Se si inviano gli aggiornamenti da inviare in una coda, è possibile attivare dinamicamente più thread di trasmissione per prelevare dalla coda e inviare i dati ai client.

  • Per quanto riguarda la struttura di trasmissione: il costo di NetIO è di magnitudo maggiore del costo della CPU o dell'accesso alla memoria. Pertanto, la tua infrastruttura dati non dovrebbe sprecare alcun byte per "spazi vuoti". Se sei sotto l'intervallo di 1k con una struttura dati, il tuo messaggio sarà in un frame sulla rete. Cerca di mantenerlo in questo modo. Prenderò in considerazione anche la compressione per restare al di sotto.
  • Non trasferire su testo, inviare un formato binario. Il client dovrà commutare i bit nel giusto ordine per la deserializzazione - non importa: il client ha molto più CPU / Player rispetto al server: -)
risposta data 03.01.2017 - 03:28
fonte

Leggi altre domande sui tag