Cerca di mantenerlo il più semplice possibile e interfacce ben definite e documentate. Il mantenimento e il debug di un sistema complesso in produzione si trasforma facilmente in un inferno. Quindi, se esiste un approccio semplice e complesso, pensaci due volte prima di procedere con quello complesso.
Definizione dei servizi
Penso che il primo passo sia identificare i servizi e le loro dipendenze : Contenuto statico, Autenticazione, Chat locale, Canali di chat globali, Canali di chat regionali, Elenco amici, Gilde, Borsa / Inventario, Casa d'aste, Mappa globale, Mondo, ...
Quindi per ciascuno di questi servizi ha deciso se il client può parlare direttamente con loro. Ad esempio, è abbastanza facile lasciare che il client parli direttamente con i server responsabili dei canali di chat globali. I server del mondo non devono essere coinvolti nei messaggi di chat. La chat regionale può essere implementata allo stesso modo, ma i server del mondo devono comunicare ai server di chat quando i giocatori cambiano regione. Ancora una volta, non devono preoccuparsi dei messaggi.
Il terzo passo è pensare al bilanciamento del carico all'interno di un servizio . Ad esempio, i canali di chat globali e regionali possono essere suddivisi su più server in base al loro nome. È probabilmente una buona idea non codificare in modo rigido questa suddivisione nel client, ma fornire un servizio di ricerca.
Server mondiali
La parte più difficile di solito sono i server del mondo , quindi sto iniziando con un approccio semplice. Probabilmente è una buona idea lasciare che il client parli direttamente con il server responsabile della regione in cui si trova. Pertanto, al momento del login o della regione che attraversa il client, deve essere detto a quale server connettersi.
L'approccio semplice è quello di dividere il mondo in regioni indipendenti . Con regioni indipendenti intendo che un giocatore non può guardare da una parte all'altra e i mostri non possono attraversare le parti. Quelle regioni sono diverse da quelle che il giocatore vede in base al paesaggio e alla storia del mondo esterno. Di solito la maggior parte dei mostri si trova nei sotterranei e i giocatori tendono ad accettare che devono attraversare un gateway per entrare in un sotterraneo. Soprattutto se quei sotterranei vengono istanziati in base al gruppo di giocatori. Altri esempi nel mondo esterno sono i diversi continenti e valli racchiusi da alte montagne.
Un approccio al mondo continuo diventa complesso molto rapidamente, quindi ha senso pianificarlo bene: di quali informazioni ha bisogno il cliente? Quali informazioni devono condividere i server? Il giocatore interagirà principalmente solo con gli oggetti (inclusi mostri e NPC) nella stessa regione. Puoi imbrogliare posizionando gli oggetti al di fuori dell'intervallo di clic dal bordo della zona. Ciò significa che il cliente è principalmente interessato a leggere solo informazioni per le zone vicine. In questi casi i server di zona non devono coordinare nulla tranne che per il controllo delle autorizzazioni che il giocatore è abbastanza vicino per connettersi a una zona vicina.
Questo lascia solo un numero molto piccolo di casi difficili in cui oggetti o azioni devono attraversare un bordo del server. Il che è positivo perché quei casi come frecce e incantesimi sono fondamentali per le prestazioni. Potrebbe essere una buona idea dividere il combattimento in attacco e difesa. Quindi il server di un incantatore definirà i parametri di attacco inclusa la posizione dell'incantatore. Il server del difensore riceverà il messaggio sull'attacco e calcolerà l'impatto. Il server dell'attaccante non ha bisogno di conoscere l'impatto; il cliente lo imparerà usando la sua connessione di sola lettura.
A seconda della complessità del modello del tuo lettore, potrebbero essere necessari alcuni secondi per trasferirlo su un altro server (Second Life ha un grosso problema con questo). Il problema può essere mitigato preparando il trasferimento in anticipo quando il giocatore si avvicina a un bordo virtuale. In modo che la maggior parte dei dati del giocatore sia già memorizzata nella cache sul server di destinazione quando si verifica la consegna effettiva.
Sommario
Dividi il problema definendo diversi servizi che possono essere suddivisi tra server con piccole dipendenze. Come passo successivo, guarda come fare il bilanciamento del carico all'interno dei servizi critici. Delegare il lavoro di bilanciamento al client istruendolo a connettersi direttamente ai server pertinenti (ovviamente i server devono verificare le autorizzazioni). Mantenerlo il più semplice possibile, documentare bene le responsabilità dei vari servizi e server, fornire l'opzione per abilitare l'output di debug.
PS: alcune di queste tecniche possono essere utilizzate per migliorare l'affidabilità. E dovresti tenerlo a mente perché l'uso di molti server implica un rischio molto più elevato di rottura delle cose; non solo nel software ma anche a livello hardware.