Al CitizenCon 2951 abbiamo approfondito tecnologie radicali quali il Server Meshing e lo Streaming della Persistenza (Persistent Streaming) con Paul Reindell (Director of Engineering, Online Technology) e Benoit Beausejour (Chief Technology Officer di Turbulent). Dopo il panel, abbiamo visto che molti avevano domande aggiuntive per i nostri ragazzi e vogliamo assicurarci di rispondere. Questo è il Q&A con Paul, Benoit, Roger Godfrey (Lead Producer) e Clive Johnson (Lead Network Programmer).

Quando vedremo lo Streaming della Persistenza e il Server Meshing nel PU?

Il nostro obiettivo attuale è rilasciare lo Streaming della Persistenza e la prima versione del Replication Layer – idealmente – tra il Q1 e il Q2 del prossimo anno. Seguirà quindi la prima versione del Server Meshing Statico, salvo imprevisti tecnici, tra il Q3 e il Q4 del prossimo anno.

Qual è lo stato attuale del Server Meshing e quali sono i maggiori problemi che ne impediscono il rilascio?

La maggior parte delle persone, quando si parla di Server Meshing, di solito pensa al passaggio finale di questa tecnologia in cui “colleghiamo i server”. La verità è che, prima di questo passaggio finale, è necessario realizzare una serie molto lunga di prerequisiti e cambiamenti alle fondamenta tecnologiche del nostro motore di gioco. Tenuto conto di ciò, cercherò di rispondere a questa domanda tenendo presente il quadro completo.

La risposta breve è che in realtà siamo in uno stato molto avanzato.

Ora la versione lunga. La strada verso il Server Meshing è iniziata nel 2017/2018:

Object Container Streaming

Per rendere possibile il Server Meshing era necessario avere una tecnologia per vincolare e svincolare dinamicamente le entità tramite un sistema di streaming, e ciò non era supportato dall’Engine inizialmente. Quindi, quando abbiamo rilasciato il “Client Side Object Container Streaming” (OCS) nel 2018, abbiamo anche fatto il primo passo verso il Server Meshing!

Una volta completato questo trampolino di lancio, abbiamo dovuto abilitare questa tecnologia per vincolare e svincolare entità sul client anche per il server (poiché alla fine i nodi server nel server meshing dovranno ricevere e trasmettere entità dinamicamente). Questa tecnologia si chiama “Server Side Object Container Streaming” (S-OCS) e la prima versione del S-OCS è stata rilasciata alla fine del 2019. Questo è stato il grande passo successivo verso il Server Meshing.

Entity Authority & Trasferimento di Authority

Sebbene avessimo la tecnologia per gestire dinamicamente le entità sul server, è ancora un solo server a “possedere” tutte le entità simulate. In un Server Meshing in cui più nodi server condividono la simulazione, avevamo bisogno del concetto di “Entity Authority”. Ciò significa che una determinata entità non è più di proprietà di un singolo server di gioco dedicato, poiché ci sono più nodi server nel Server Meshing. Quindi ci sarà un nodo server che controlla l’entità e altri nodi server che possono avere una visione “client” di questa entità. Questa Authority ha anche bisogno della capacità di poter essere trasferita tra i nodi server. Nella prima metà del 2020 abbiamo dedicato diverso tempo di sviluppo al concetto di “Entity Authority” e “Trasferimento di Authority”. Questa è stata la prima volta che l’intera compagnia ha dovuto lavorare sul Server Meshing, poiché molto del codice di gioco doveva essere cambiato per funzionare con il nuovo concetto di entità-autorità. Entro la fine del 2020 la maggior parte del codice (di gioco) è stato modificato per supportare il concetto, quindi è stato fatto un altro grande passo, ma il Server Meshing non era ancora raggiungibile.

Replication Layer & Streaming della Persistenza

Il passo successivo è stato spostare la replica delle entità in un luogo centrale in cui potremo controllare lo streaming e la logica di collegamento alla rete (Network-bind Logic). Questo ci permetterà di replicare lo stato di rete su più nodi server. Per raggiungere questo obiettivo, abbiamo dovuto spostare lo streaming e la logica di replica dal server dedicato al ”Replication Layer”, che ora ospita la replica di rete e il codice per lo streaming delle entità.

Allo stesso tempo abbiamo anche implementato lo Streaming della Persistenza, che permette al Replication Layer di mantenere lo stato dell’entità in un database a grafo (graph database) che conserva lo stato di ogni singola entità di rete replicata. Il 2021 è stato dedicato al lavoro sul Replication Layer e sull’EntityGraph, che ci consente di controllare lo streaming e la replica delle entità da un processo separato (separato dal tradizionale server di gioco dedicato). Questo lavoro è quasi finito ed è nella sua fase finale.

Server Meshing Statico e Dinamico

Tuttavia, non siamo ancora arrivati al Server Meshing. Il lavoro sul Server Meshing vero e proprio è iniziato e richiederà buona parte del prossimo anno per essere completato, e tutti i prerequisiti che ho delineato sopra erano necessari anche solo per arrivare a questo punto. La prima versione di questa tecnologia sarà un Server Meshing Statico ed è il prossimo grande trampolino di lancio. Tuttavia, non sarà nemmeno l’ultimo! Con il Server Meshing Statico, avremo la prima versione di un Server Meshing ma, come indica il nome “Statico”, la capacità di scalare con questo Server Meshing è molto limitata.

Prima di poter veramente dire di aver completato questa feature, dovremo compiere un altro grande passo, che abbiamo chiamato “Server Meshing Dinamico”. Questo passaggio ci consentirà di mescolare dinamicamente i nodi server e quindi scalare il tutto in modo dinamico in base alla domanda. Gran parte del lavoro su questa parte avviene in parallelo. Ad esempio, il Fleet Manager che controlla la parte dinamica del Server Meshing è già in fase di sviluppo, così come i requisiti di matchmaking che derivano dalla nuova aggiunta degli “shard”.

Nel frattempo, molti team che si occupano del codice di gioco devono anche lavorare per adattare il codice esistente per farlo funzionare completamente con il Server Meshing (e, cosa più importante, trovare tutti i casi limite che emergeranno solo una volta che avremo un vero Server Meshing). Sebbene il lavoro sull’Entity Authority sia stato completato nel 2020, l’Entity Authority è attualmente trasferita solo tra il client e un solo server, quindi del codice potrebbe richiedere ulteriori modifiche.

Come pensate di gestire una nave grande, tipo una Javelin? Avrebbe un suo server insieme alle navi circostanti*?

*(Would that be it’s own dedicated resource with ships around it?)

Con il Server Meshing Dinamico, è possibile che navi di grandi dimensioni come una Javelin possano avere un proprio server dedicato per eseguire il controllo della simulazione per quella nave e tutto ciò che contiene. Tuttavia, stiamo cercando di evitare regole rigide su come le entità vengono assegnate alle risorse di elaborazione, quindi potrebbe non essere sempre così. Si tratta di trovare la quadra tra velocità di elaborazione e costi per i server. Se avessimo una regola rigida per cui dedichiamo un server ad ogni Javelin e tutto ciò che contiene, non sarebbe molto conveniente se alcune Javelin contenessero solo una manciata di giocatori. Inoltre, la stessa regola non sarebbe ottimale in termini di velocità di elaborazione del server se ci fossero centinaia di giocatori tutti ammassati nella stessa Javelin, poiché la regola ci impedirebbe di distribuire il carico di elaborazione su più server.

Il Server Meshing Dinamico sarà leggermente diverso in quanto valuterà costantemente il modo migliore per distribuire la simulazione, mirando a trovare il giusto equilibrio in modo che nessun server sia sovraccaricato o sottoutilizzato. Man mano che i giocatori si spostano nel ‘Verse, la distribuzione ideale delle risorse di elaborazione cambierà. Per reagire a tali modifiche, avremo bisogno della capacità di trasferire l’Authority sulle entità da un server a un altro, nonché di portare nuovi server online e spegnere quelli vecchi. Questo ci consentirà di spostare il carico di elaborazione da un server che rischia di sovraccaricarsi a uno attualmente sottoutilizzato. Se nessuno dei server esistenti ha una capacità di riserva sufficiente per gestire un aumento del carico, potremo semplicemente noleggiare più server dal nostro cloud platform provider. E quando alcuni server non avranno un carico sufficiente per renderli convenienti, alcuni di loro potranno trasferire le loro parti della simulazione agli altri e potremo spegnere quelli che non ci servono più.

Quanti giocatori saranno capaci di vedersi in un luogo? Qual è il massimo che state pianificando?

Questa è una domanda dalla risposta difficile e la risposta migliore che possiamo dare al momento è che dipende.

Supponendo che la domanda riguardi il limite di quanti giocatori potranno vedersi lato client, sarà principalmente dettata dal client di gioco. Ciò è dovuto alla simulazione lato client, come fisica e codice di gioco, nonché ai costi di rendering.

Inoltre, dipende anche molto dallo scenario; 100 giocatori in combattimento FPS sono più economici da simulare e renderizzare sul client rispetto a 100 giocatori che combattono in astronavi monoposto, sparando missili e laser l’uno contro l’altro.

Il Team Grafico sta lavorando attivamente su Vulkan, che ci consentirà di aumentare Draw Call e dovrebbe migliorare il numero di giocatori/navi che possiamo renderizzare contemporaneamente, mentre il Team Engine è fortemente concentrato sull’ottimizzazione del codice di gioco per aumentare il numero di oggetti di gioco che possiamo simulare contemporaneamente.

Il nostro obiettivo è aumentare il numero di giocatori e la nostra aspettativa è che supporteremo scenari in cui 100 giocatori possono vedersi a framerate ragionevoli. Tuttavia, quando inizieremo a ridimensionare i nostri shard per supportare un numero maggiore di giocatori, le probabilità che ogni singolo giocatore all’interno di uno shard possa andare nello stesso luogo e vedersi senza problemi di prestazioni diminuirà.

È qui che dovremo iniziare a implementare meccaniche di gioco che impediscano che questi scenari si verifichino troppo frequentemente.

Il limite assoluto è difficile da prevedere fino a quando parte della nuova tecnologia non sarà online e non potremo iniziare a misurare le prestazioni.

Se creerò una base su una luna, la mia base si rifletterà suGLI altri shard su cui non sono?

Il Planet Tech Team prevede di implementare la creazione delle basi ragionando in ottica server shard. Rivendicare un terreno per la vostra base rivendicherà questo terreno su tutti gli shard e abbiamo in programma di replicare la tua base su tutti gli shard.

Tuttavia, solo uno shard avrà una versione “attiva” della base, con gli altri shard che genereranno una versione “ad accesso limitato/sola lettura” di quella stessa base. Ad esempio, una base darà pieno accesso e la possibilità di espandersi nello shard su cui il proprietario sta attualmente giocando, mentre su tutti gli altri shard questa base potrebbe generarsi con porte bloccate in uno stato immutabile. Il design completo non è ancora stabilito al 100% e potrebbe cambiare.

Il vero obiettivo finale è un singolo shard per tutti i giocatori?

Questa è la nostra ambizione, ma a questo punto non è possibile dare una risposta definitiva.

Inizieremo con molti piccoli shard per regione e ridurremo lentamente il numero di shard. Il primo principale obiettivo sarà quello di ridurre il tutto ad un solo shard per regione. Per arrivarci, il nostro piano è aumentare gradualmente il numero di giocatori per shard e migliorare costantemente il backend e la tecnologia lato client per supportare sempre più giocatori.

Non sono solo necessari cambiamenti tecnologici per raggiungere questo obiettivo: sono necessari anche nuovi design e meccaniche di gioco. Senza meccanismi per impedire a ogni singolo giocatore di andare nella stessa posizione, un mega-shard di grandi dimensioni sarà molto difficile da ottenere, specialmente per il client. Ad esempio, potrebbe esserci un meccanismo per chiudere temporaneamente i Jump Point in luoghi affollati o creare nuovi layer per determinati luoghi.

Mentre il backend è progettato per scalare orizzontalmente, il client di gioco viene eseguito su una singola macchina ed è limitato a un numero definito di core CPU/GPU e dalla memoria.

Solo una volta superati questi ostacoli e realizzato un mega-shard per regione, saremo in grado di affrontare il boss finale: unire gli shard regionali in un mega-shard globale.

Questo comporta una serie di problemi, poiché la località gioca un ruolo importante nell’esperienza del giocatore. Ad esempio, la latenza tra i servizi di backend all’interno dello stesso data center è molto inferiore rispetto alla latenza tra i servizi di backend ospitati in due data center distanti geograficamente. E sebbene abbiamo progettato il backend per supportare uno shard globale, è una sfida reale distribuire il backend in modo che non favorisca un gruppo di giocatori rispetto a un altro.

L’economia dell’universo sarà globale o indipendente in ogni shard?

L’economia sarà globale e si rifletterà in ogni shard.

Ad esempio, prendiamo i negozi. Sebbene ogni negozio abbia un inventario locale (articoli che sono attualmente in mostra), i negozi vengono riforniti da un inventario globale condiviso tra tutti gli shard. Se molti giocatori iniziano a comprare un’arma specifica nel negozio di armi di Port Olisar, il prezzo di quell’arma aumenterà in questo negozio su tutti gli Shard. Ad un certo punto tutte le scorte di tale pistola si esauriranno e quindi tutti i negozi in tutti gli shard non potranno rifornirsi di questa pistola.

Cosa impedirà a grossi gruppi di “blu” e grossi gruppi di “rossi” di creare shard echo-chamber? Le dinamiche sociali implicano grandi concentrazioni di persone con gli stessi interessi, sia lato amici che lato organizzazioni. Ci sarà una soluzione che assicurerà un corretto mix di buono, cattivo e misto?

I giocatori non verranno assegnati in modo permanente agli shard poiché il sistema di matchmaking assegna un nuovo shard per la regione selezionata a ogni login. All’inizio ciò causerà una distribuzione naturale, poiché inizieremo con molti piccoli shard in parallelo.

Quando inizieremo a ridimensionare i nostri shard (e quindi a ridurre il numero di shard paralleli), questa domanda diventerà più rilevante. Abbiamo in programma di affrontare questo problema con il nostro nuovo sistema di matchmaking.

Il nuovo sistema di matchmaking attualmente in sviluppo insieme al Server Meshing ci consente di abbinare i giocatori agli shard in base a più parametri. Questi sono usati per abbinare i giocatori in shard con i loro amici, o dove hanno lasciato la maggior parte dei loro oggetti nel gioco. Tuttavia, ci consente anche di utilizzare parametri più avanzati, come la reputazione e altre statistiche nascoste del giocatore di cui teniamo traccia.

Questo ci permetterà di provare e garantire che ogni shard abbia una composizione semi-diversificata di individui. Ad esempio, potremmo assicurarci di non caricare inavvertitamente uno shard solo con giocatori non criminali, il che potrebbe non essere molto divertente se parte di ciò che vogliono fare è dare la caccia a giocatori criminali.

Il nostro personaggio e la nostra nave saranno sempre nel gioco quando ce ne saremo andati? Cioè, se mi disconnettessi su un pianeta dal lettino della mia nave, la mia nave sarà ancora lì, e le persone potranno tentare di entrare o di distruggere la mia nave?

Quando un’entità viene “caricata” in uno shard (ovvero esiste fisicamente nello shard), esiste permanentemente all’interno di quello shard finché il giocatore non “ripone” l’entità in un inventario. Questo può essere fatto raccogliendo una pistola e mettendola nello zaino, o facendo atterrare una nave su un landing pad, che stiva la nave in un inventario specifico del landing pad. Una volta che un’entità si trova all’interno di un inventario, viene archiviata nel database globale e può essere caricata in qualsiasi shard. Ciò consente ai giocatori di spostare gli oggetti tra gli shard.

Abbiamo anche in programma una meccanica chiamata “Conserva/Rimuovi Oggetti Principali”. Ciò prenderà tutti gli oggetti principali di proprietà del giocatore e li riporrà automaticamente in un inventario specifico per giocatore per la transizione tra shard. Lo stoccaggio automatico di solito si verifica quando non ci sono altri giocatori in giro e l’entità viene rimossa dal server. Gli oggetti in questo inventario di transizione tra shard seguiranno automaticamente il giocatore, quindi quando il giocatore accede a uno shard diverso, prenderemo le entità e le riposeremo nel nuovo shard nella posizione in cui il giocatore le ha lasciate.

Quando atterri la tua nave su una luna e ti disconnetti, la nave sarà rimossa dal server e verrà automaticamente conservata se non ci sono altri giocatori in quel momento. Ora, quando accedi a un altro shard, la tua nave verrà spostata nel nuovo shard. Se, per qualche motivo, la nave è rimasta più a lungo nel vecchio shard e viene distrutta mentre eri disconnesso, potresti svegliarti in un letto medico.

Quanti nuovi contenuti dipendono dal Server Meshing?

Se da una parte il Server Meshing ci consentirà di iniziare ad aumentare il numero di giocatori che possono giocare insieme a Star Citizen, ci consentirà anche di iniziare ad aggiungere nuovi contenuti. In questo momento, siamo concentrati sullo sfruttare ciò per aggiungere nuovi sistemi planetari. Il Server Meshing è una delle tecnologie chiave per far funzionare i Jump Point nel gioco, consentendo ai sistemi planetari di muoversi senza problemi dentro e fuori dalla memoria senza la necessità di schermate di caricamento. I giocatori lo vedranno per la prima volta il prossimo anno con l’introduzione del sistema Pyro quando la prima versione del Server Meshing sarà attiva.

Mentre perfezioniamo la tecnologia e ci spostiamo dal Server Meshing Statico a quello Dinamico, i designer possono utilizzare questa tecnologia per avere aree più grandi e più interessanti (come insediamenti più grandi o interni di navi di grandi dimensioni) con un numero più denso di IA e giocatori. Il Server Meshing potrebbe aprire le porte a esperienze di gameplay a cui i nostri designer non hanno ancora pensato!

Lato prestazioni, che miglioramenti possiamo aspettarci?

I miglioramenti maggiori si vedranno nelle prestazioni dei server. Al momento, le prestazioni dei nostri server sono piuttosto limitate a causa del numero di entità che dobbiamo simulare su ogni server. Ciò si traduce in un framerate molto basso e un degrado dei server, causando per i client lag e rubber banding e altri problemi di desync. Una volta che il Server Meshing Statico sarà funzionante, ci aspettiamo un framerate lato server considerevolmente più alto, riducendo tali sintomi.

Lato client, il Server Meshing avrà in realtà un minimo impatto sugli FPS. Il client già carica solo le entità che si trovano a distanza di vista. Potrebbero esserci dei piccoli miglioramenti, in quanto potremo essere un po’ più aggressivi sulla rimozione delle entità con la distanza, poiché in questo momento alcuni oggetti hanno un raggio di caricamento gonfiato per far funzionare elementi come radar e missili. Con il Server Meshing, possiamo sganciare il raggio di caricamento tra client e server. Tuttavia, questi miglioramenti saranno minimi sul client. In ogni caso, un server con maggiore framerate migliorerà l’esperienza complessiva poiché il ritardo di rete sarà ridotto considerevolmente.

So che potreste non esserci ancora una risposta a questa domanda, ma al momento del rilascio iniziale del Server Meshing quanti shard prevedete di creare? 10, 100, 1000 o di più? Sappiamo che la transizione dal DGS (SERVER DI GIOCO DEDICATO) significa più giocatori per area di gioco, ma non siamo sicuri sul grado di miglioramento in cui sperate.

La risposta breve è che non possiamo avanzare un numero.

Il concetto di shard è la parte “malleabile” dell’architettura del Server Meshing e saremo in grado di dire il numero di shard richiesti solo una volta che tutti i componenti saranno al loro posto e prevediamo di arrivarci un passo alla volta.

Con il primo rilascio dello Streaming della Persistenza (che non è il Server Meshing), vogliamo iniziare imitando l’attuale situazione che vedete online dove c’è uno shard per istanza del server e una replica (chiamata hybrid). L’unica differenza è che tutte le entità in quegli shard saranno ancora persistenti. Questo ci consentirà di affrontare lo scenario peggiore avendo un numero davvero elevato di shard persistenti e repliche molto grandi per testare i meccanismi di creazione/diffusione (seeding), la simulazione con giocatori attivi, e il rallentamento per il riciclaggio o la distruzione (NdT: credo intenda il riavvio/spegnimento dei server). Vogliamo che la creazione e la distruzione degli shard in questa prima fase siano ottimali, veloci e senza aumenti di costo.

Questo approccio ha diversi vantaggi, in quanto possiamo testare la persistenza degli shard prima e cosa più importante possiamo misurare le statistiche attive su molti shard.

Ad esempio (non esaustivo!):

  • Quante entità rimangono in uno shard persistente nel tempo (tasso di crescita dello shard);
  • Dimensione del grafo globale (tasso di crescita globale);
  • Quanti giocatori può gestire un singolo database di shard (gestione del giocatore);
  • Effetto di diverse meccaniche di gameplay sugli aggiornamenti delle entità nel database di shard (effetti di gameplay);
  • Profilo delle prestazioni nelle code di scrittura, ovvero tempi medi di query dei cluster di database degli shard (metriche del database degli shard);
  • Profilo delle prestazioni nelle code di scrittura, ovvero tempi medi di query del cluster di database globale (metriche del database globale);
  • Efficienza dello sharding del database (un altro livello di sharding!) del grafo.

Sebbene disponiamo di effettive stime e misurazioni interne per queste cose, nulla sostituisce i giocatori reali che generano un carico rappresentativo sul sistema.

Man mano che mettiamo in campo gli altri componenti del Server Meshing, principalmente il Server Meshing Statico, abbiamo in programma di ridurre gradualmente il numero di shard, raggruppando i giocatori in shard sempre più grandi finché non ci sentiremo a nostro agio con le prestazioni delle repliche, dei DGS e del grafo delle entità (EntityGraph). Ovviamente, il Server Meshing Statico soffrirà di problemi di congregazione e saremo in grado continuare verso shard molto più grandi solo una volta che il Server Meshing Dinamico sarà pronto.

In definitiva, con il Server Meshing Dinamico, miriamo a supportare shard molto grandi.

Può un elemento piccolo come un proiettile viaggiare attraverso i server shard?

La risposta breve è no.

Potete immaginare gli shard come un’istanza completamente isolata dell’universo simulato, molto simile a come attualmente abbiamo diverse istanze isolate per server dedicato. Affinché gli elementi vengano trasferiti tra le istanze, questi elementi devono essere riposti in un inventario prima di poter essere spostati in uno shard diverso. Ad esempio, se un giocatore raccoglie una pistola in uno shard e la mette nello zaino. Ora, quando il giocatore si connette a un altro shard, può estrarre la pistola dallo zaino, che arriverà nel nuovo shard.

All’interno di uno shard, un’entità come un missile sarà in grado di viaggiare attraverso più nodi server se questi nodi server hanno il missile all’interno dell’area di caricamento del server. Solo un nodo server avrà il controllo (l’Authority) su quel missile, mentre gli altri nodi server vedranno quel missile come se fossero dei client.

I proiettili sono in realtà presenti lato client. Quindi, una versione unica del proiettile viene generata su ciascun nodo client e server, motivo per cui ho usato un’entità con una replica nel network – come un missile – nell’esempio sopra.

Per la gestione delle diverse regioni del mondo, avete intenzione di avere quattro server farm principali, tipo USA, UE, Cina e Oceania? O avete intenzione di realizzare un “Universo Globale”? Se fosse globale, come gestireste l’equilibrio tra giocatori con estreme variazioni di ping?

Abbiamo ancora intenzione di mantenere la distribuzione regionale dei sistemi di rete. Nella distribuzione iniziale dello Streaming della Persistenza, il database globale sarà veramente globale. Gli shard stessi saranno distribuiti a livello regionale, quindi un client di gioco che si connette alla regione UE sarebbe preferibilmente abbinato a uno shard UE. Man mano che gli shard cresceranno di dimensioni (sia per i giocatori che per le entità), abbiamo in programma di rivedere questo modello e introdurre anche sistemi (di backend) a livello regionale per trasmettere i dati ad una minore distanza.

Vivo nell’Europa dell’Est. Quando sarà introdotto il Server Meshing, potrò giocare con gli amici statunitensi?

Non prevediamo di limitare la scelta del giocatore per shard o regione.

Un giocatore sarà libero di scegliere qualsiasi regione in cui giocare e, all’interno di tale regione, consentiremo una selezione limitata di shard. Ad esempio, lo shard dove ci sono i tuoi amici o l’ultimo shard in cui hai giocato l’ultima volta.

Poiché tutti i dati dei giocatori sono archiviati nel database globale, i giocatori possono passare da uno shard all’altro in modo simile a come possono passare da un’istanza all’altra oggi. Gli oggetti nell’inventario (stowed) verranno trasferiti con il giocatore e saranno sempre accessibili indipendentemente dallo shard.

Morte del Replication Layer: Cosa succede ai giocatori se un Replication Layer viene spento o “muore”? Sappiamo che l’EntityGraph raccoglierà le informazioni seminate e le reindirizzerà in un nuovo Replication Layer, ma torneremo al menu principale se il Replication Layer muore rispetto a se un nodo server muore, o avremo una sorta di caricamento che parte automaticamente e ci trasporta nel nuovo Replication Layer?

Per rispondere correttamente, devo prima fornire qualche dettaglio in più su come sarà la nostra architettura finale. In definitiva, il Replication Layer non sarà un singolo nodo server. Sarà invece costituito da più istanze di un insieme di microservizi  chiamati Replicant, Atlas e Scribe. Questo ci dà il vantaggio di poter scalare il Replication Layer. Un altro vantaggio, più rilevante per questa domanda, è che sebbene un singolo nodo/istanza nel Replication Layer possa fallire, è molto improbabile che l’intero Replication Layer fallisca contemporaneamente. Dal punto di vista del client, i nodi di Replicant sono i più importanti in quanto sono quelli che gestiranno il flusso di caricamento delle entità e lo stato di replica tra i client e il gioco. Il Replicant è progettato per non eseguire alcun elemento logico del gioco e, in effetti, eseguirà pochissimo codice; nessuna animazione, nessuna fisica, solo netcode. Il fatto che sia costruito su così poco codice dovrebbe significare meno bug in generale. Quindi, dopo alcuni inevitabili problemi iniziali, ci aspettiamo che i Replicant siano abbastanza stabili. È anche importante sapere che – in qualsiasi momento – un singolo client può essere gestito da più Replicant (ma quei Replicant gestiranno anche altri client contemporaneamente). L’ultimo pezzo del puzzle è il Gateway Layer: i client non si connetteranno direttamente ai Replication Layer ma invece a un nodo gateway nel Gateway Layer. Il sistema Gateway serve solo per indirizzare i pacchetti tra i client e i vari Replicant con cui stanno comunicando. Il sistema Gateway utilizzerà una base di codice ancora più piccola rispetto al Replicant, quindi dovrebbe avere ancora meno probabilità di crashare.

Quindi, cosa succederà ad un client se uno dei Replicant che lo gestisce crasha improvvisamente?

Il client rimarrà connesso allo shard ma parte o tutta la sua simulazione si freezerà temporaneamente. Il Replication Layer avvierà un nuovo nodo Replicant per sostituire quello che si è bloccato e recupererà lo stato delle entità perse dalla persistenza tramite l’EntityGraph. I Gateway client e i nodi DGS che erano connessi al vecchio Replicant ristabiliranno la connessione con quello nuovo. Una volta ricollegato tutto, il gioco si sbloccherà per i client interessati. A questo punto il client potrebbe sperimentare scatti o teletrasporto delle entità. Speriamo che l’intero processo richieda meno di un minuto.

Cosa accadrà al client se il Gateway che lo gestisce crasha improvvisamente?

Il sistema Gateway non tiene traccia di alcuno stato di gioco e avrà una propria forma di ripristino in caso di arresto anomalo. Poiché si tratta di un servizio molto più semplice di un Replicant, il tempo di ripristino dovrebbe essere molto più rapido, più vicino ai secondi. Mentre il ripristino è in corso, il client sperimenterà un blocco temporaneo seguito da alcuni scatti o teletrasporto delle entità.

E il sistema Hybrid?

Durante il panel del CitizenCon sullo Streaming di Persistenza e sul Server Meshing, Paul e Benoit hanno parlato del Replication Layer in termini di sistema Hybrid. Il sistema Hybrid è – come suggerisce il nome – un ibrido dei sistemi Replicant, Atlas, Scribe e Gateway che ho menzionato sopra (ma non dell’EntityGraph), nonché una manciata di altri servizi non ancora discussi. Abbiamo scelto di svilupparlo prima di dividerlo nei suoi servizi componenti in quanto riduce il numero di parti mobili che stiamo cercando di gestire contemporaneamente. Inoltre, ci consente di concentrarci sulla dimostrazione di tutte queste grandi idee piuttosto che sul semplice fatto che tutti quei singoli servizi comunichino correttamente. In questa implementazione iniziale, il Replication Layer sarà un singolo nodo server di Hybrid. Se questo nodo ibrido si arresta in modo anomalo, la situazione sarà simile a quella che i client sperimentano ora quando un server di gioco dedicato si arresta in modo anomalo. Tutti i client verranno rimandati al menu front-end con il famigerato errore 30k. Una volta avviato l’Hybrid sostitutivo, i client saranno in grado di ricongiungersi allo shard e continuare da dove erano stati interrotti. Speriamo di essere in grado di implementarlo in modo tale che i client ricevano una notifica sullo schermo quando lo shard è di nuovo disponibile e che basti poi la singola pressione di un tasto per tornare nello shard (in modo simile a come funziona per il ripristino in caso di crash anomalo del client).

Abbiamo visto molto parlare nel panel su quali nodi hanno l’autorità di scrittura all’interno di uno shard, ma per quanto riguarda l’autorità di scrittura tra shard separati? Vengono mantenuti database di persistenza separati per shard separati o gli stati degli elementi del mondo alla fine verranno sincronizzati tra gli shard anche se sono stati lasciati in stati diversi (cioè, una porta viene lasciata aperta su uno SHARD e lasciata chiusa su un altro – uno shard alla fine scriverà il suo stato nel database, aggiornando lo stato della porta sull’altro shard?)

In generale, ogni shard è la sua copia univoca dell’universo e qualsiasi elemento all’interno dello shard non condividerà lo stato con un elemento di un shard diverso poiché ogni shard ha il proprio database. D’altra parte, abbiamo un database globale per i dati dell’inventario dei giocatori. Questo database viene utilizzato per memorizzare qualsiasi oggetto nell’inventario di un giocatore e gli oggetti possono essere trasferiti tra gli shard se vengono prima messi da uno shard in un inventario e poi lasciati in un altro shard.

Alcune funzionalità, come gli avamposti dei giocatori o le risorse minabili, implementano un codice speciale che replicherà uno stato globale su tutti gli shard, quindi un avamposto può esistere in più shard in parallelo e lentamente (rispetto alla velocità del gioco in tempo reale) replicare il suo stato tra gli shard. Questa non è una replica istantanea (una porta che si apre/chiude non verrà replicata), tuttavia, uno stato persistente come una porta bloccata o sbloccata potrà essere replicato tra gli shard.

È simile per le risorse minabili: mentre ogni shard ha una versione unica di una roccia minabile, la quantità complessiva verrà replicata tra gli shard, quindi quando i giocatori inizieranno ad estrarre in una determinata area, la mappa delle risorse globali per quest’area verrà modificata e il numero di rocce minabili in quella posizione sarà modificato su tutti gli shard.

Quando hai un gruppo che si sposta (in Quantum o altro) da un punto a un altro e quell’altro nodo, oggetto o istanza DGS sono pieni, la versione T0 / Server Meshing Statico creerà preventivamente un altro nodo DGS? O come sarà gestito?

Con il Server Meshing Statico, tutto è fissato in anticipo, incluso il numero di nodi server per shard e quale server di gioco è responsabile della simulazione di quali luoghi. Ciò significa che se tutti nello shard decidono di andare nella stessa posizione, finiranno per essere tutti simulati dallo stesso nodo del server.

In realtà, il caso peggiore è se tutti i giocatori decidono di sparpagliarsi tra tutte le posizioni assegnate a un singolo nodo del server. In questo modo, il povero server cercherà di trattare non solo con tutti i giocatori, ma dovrà anche caricare tutte le sue località. La risposta ovvia è inserire più server per shard, quindi ogni nodo server ha meno luoghi in cui potrebbe essere necessario eseguire il caricamento. Tuttavia, poiché si tratta di un Server Meshing Statico e tutto è fissato in anticipo, avere più nodi server per shard aumenta anche i costi di gestione . Ma dobbiamo iniziare da qualche parte, quindi il piano per la prima versione del Server Meshing Statico è di iniziare con il minor numero possibile di nodi server per shard, pur continuando a testare che la tecnologia funzioni effettivamente. Chiaramente questo sarà un problema se permettiamo agli shard di avere molto più degli attuali 50 giocatori per istanza.

Quindi, non aspettatevi che il numero di giocatori aumenti molto con la prima versione. Ciò eviterà il problema che un singolo nodo server si riempia prima che i giocatori arrivino, poiché limiteremo il numero massimo di giocatori per shard in base al caso peggiore. Una volta che il sistema funzionerà, esamineremo lo stato delle prestazioni e dei costi e vedremo fino a che punto possiamo spingerci. Ma per rendere economicamente fattibile un’ulteriore espansione, dovremo cercare di arrivare al Server Meshing Dinamico il prima possibile.

Con l’enorme volume di dati che viaggiano tra i client e i nodi server e la necessità di una latenza estremamente bassa, potete descrivere o approfondire come lo state gestendo o quali tecnologie state utilizzando per accelerare il traffico, o – piuttosto – evitare che rallenti?

I maggiori fattori che attualmente influenzano la latenza sono il tickrate del server, il ping del client, lo spawn di entità e la latenza dei sistemi di persistenza.

Il tickrate del server è quello più impattante tra questi ed è correlato al numero di luoghi che il server di gioco sta simulando. Il Server Meshing dovrebbe aiutare in questo, riducendo il numero di luoghi che ogni server di gioco deve caricare e simulare. Un minor numero di luoghi significherà un numero medio di entità per server molto più basso e i risparmi possono essere utilizzati per aumentare il numero di giocatori per server.

Il ping del client è dominato dalla distanza dal server. Vediamo molti giocatori che scelgono di giocare in regioni da continenti completamente diversi. Parte del nostro codice di gioco è ancora client-authoritative, il che significa che i giocatori con un ping elevato possono influire negativamente sull’esperienza di gioco per tutti gli altri. Non c’è molto che possiamo fare al riguardo nel breve termine, ma è un qualcosa che vogliamo migliorare dopo che il Server Meshing sarà implementato.

Lo spawn lento delle entità può causare latenza ritardando il flusso delle entità sui client. Ciò può causare effetti indesiderati, come luoghi che non appaiono completamente fino a pochi minuti dopo il viaggio in quantum in un luogo, cadere tra i piani dopo essere respawnati in un luogo, navi che impiegano molto tempo ad apparire ai terminali ASOP, modifica dell’equipaggiamento del giocatore, ecc. I colli di bottiglia di queste cose sono principalmente sul server. Innanzitutto, le entità non vengono replicate sui client finché non sono state completamente generate sul server. In secondo luogo, il server ha una singola coda di spawn che deve elaborare in ordine. In terzo luogo, più luoghi un server deve caricare, più elementi deve far spawnare. Per migliorare le cose, abbiamo modificato il codice di spawn del server per utilizzare code parallele di spawn. Anche il Server Meshing aiuterà, non solo riducendo il carico sulle code di spawn ( riducendo il numero di luoghi che il server deve caricare), ma anche perché il Replication Layer replica le entità su client e server contemporaneamente, consentendo loro di generarsi in parallelo.

Stiamo ancora utilizzando alcuni dei nostri vecchi sistemi di persistenza, che andavano bene come design ma noti per avere problemi di prestazioni e scalabilità per le nostre necessità. Ciò può comportare lunghe attese durante il recupero di dati della persistenza dai sistemi per sapere cosa spawnare, cose come generare una nave da un terminale ASOP, esaminare un inventario, modificare l’equipaggiamento del giocatore, ecc. Poiché il completo Streaming della Persistenza e il Server Meshing andranno entrambi ad aumentare drasticamente la quantità di dati da gestire per far funzionare il tutto, sapevamo di dover fare qualcosa al riguardo. Questo è il motivo per cui Benoit e il suo team di Turbulent hanno completamente reinventato il modo in cui manterremo i dati, ovvero l’EntityGraph, un sistema altamente scalabile costruito su un database altamente scalabile che è ottimizzato esattamente per il tipo di operazioni sui dati che eseguiamo. Inoltre, stiamo sviluppando anche il Replication Layer, che agisce come una cache in memoria – altamente scalabile – dello stato corrente di tutte le entità in uno shard, eliminando la necessità della maggior parte delle query che abbiamo usato nei vecchi sistemi di persistenza. Esatto, saranno sistemi altamente scalabili fino in fondo!

Per aiutare a ridurre/eliminare qualsiasi latenza aggiuntiva che il Replication Layer potrebbe introdurre, lo stiamo costruendo in modo che sia guidato dagli eventi piuttosto che su un tickrate come un server di gioco tradizionale. Ciò significa che quando arrivano i pacchetti, li elaborerà immediatamente e invierà la risposta e/o inoltrerà le informazioni ai client e ai server di gioco relativi. Una volta completato il lavoro sulla versione iniziale del Replication Layer (l’Hybrid Service), faremo un passaggio di ottimizzazione per assicurarci che sia il più reattivo possibile. E, sebbene questa sia in definitiva una decisione per il team DevOps, li distribuiremo negli stessi data center dei server di gioco in modo che la latenza della rete on-the-wire dovuta al salto extra tra il Replication Layer e il server di gioco sia inferiore al millisecondo. Oh, e ho detto che il Replication Layer sarà altamente scalabile? Ciò significa che se per caso il Replication Layer causerà dei problemi di latenza in particolari punti del ‘Verse, saremo in grado di riconfigurarlo per rimediare al problema.

AVVISO
Le risposte riflettono le intenzioni dello sviluppatore nel momento in cui scrive, ma la compagnia e il team di sviluppo si riserva il diritto di adattare, migliorare o cambiare funzionalità e design delle navi in risposta a feedback, testing, revisioni di design o altre considerazioni per migliorare il bilanciamento o la qualità del gioco nel suo insieme.