Database
 sql >> Database >  >> RDS >> Database

Giochi MMO e progettazione di database

Siamo onesti:tutti noi amiamo giocare, specialmente sui nostri computer. Fino a quando Internet non si è diffuso, la maggior parte di noi giocava da soli ai giochi per computer, di solito contro avversari IA. È stato divertente, ma non appena ti sei reso conto di come funzionavano le meccaniche di gioco, il gioco ha perso gran parte della sua magia.

Lo sviluppo di Internet ha spostato i giochi online. Ora possiamo giocare contro avversari umani e mettere alla prova le nostre abilità contro le loro. Niente più meccaniche di gioco!

Poi sono emersi enormi giochi multiplayer online (MMO) che hanno cambiato tutto. Migliaia di giocatori si sono trovati negli stessi universi di gioco, in competizione per le risorse, negoziando, scambiando e combattendo. Per rendere possibili tali giochi, era necessaria una struttura di database in grado di memorizzare tutte le informazioni rilevanti.

In questo articolo, progetteremo un modello che incorpora gli elementi più comuni che si trovano nei giochi MMO. Discuteremo come usarlo, i suoi limiti e i suoi possibili miglioramenti.

Un'introduzione ai modelli di dati per i giochi MMO

Ci sono molti giochi MMO molto popolari oggi e coinvolgono tutti i tipi di scenari. Mi concentrerò qui su giochi di strategia come Ogame , Travian , Sparta :Guerra degli imperi e Imperia Online . Questi giochi riguardano più la pianificazione, la costruzione e la strategia e meno l'azione diretta.

I giochi MMO sono ambientati in universi diversi, sono visivamente diversi e utilizzano opzioni di gioco più o meno diverse. Tuttavia, alcune idee sono le stesse. I giocatori competono per le posizioni, combattono per loro e formano alleanze con (e contro) altri giocatori. Costruiscono strutture, raccolgono risorse e ricercano tecnologie. Costruiscono unità (come guerrieri, carri armati, mercanti, ecc.) e le usano per commerciare con gli alleati o per combattere con gli avversari. Tutto ciò deve essere supportato nel nostro database.

Possiamo pensare a questi giochi come a giochi da tavolo online con molti quadrati indicizzati. Ogni quadrato può avere molte azioni diverse associate; alcune azioni includeranno più quadrati, ad es. quando spostiamo unità o risorse da un luogo all'altro.




Il database è suddiviso in cinque aree principali:

  • Players / Users
  • Alliances
  • Locations and Structures
  • Research and Resources
  • Units

Le restanti sette tabelle non raggruppate sono relative alle unità e descrivono la posizione delle unità e i movimenti nel gioco. Analizzeremo ciascuna di queste aree in modo molto più dettagliato, a cominciare dai Giocatori e Alleanze .

Giocatori e alleanze

Senza dubbio, i giocatori sono la parte più importante di qualsiasi gioco.

Il player tabella contiene un elenco di tutti i giocatori registrati che prendono parte a un'istanza di gioco. Conserveremo i nomi utente, le password e i nomi delle schermate dei giocatori. Questi verranno memorizzati nel user_name , password e nickname rispettivamente gli attributi.

I nuovi utenti dovranno fornire un indirizzo email durante la registrazione. Verrà generato e inviato loro un codice di conferma, al quale risponderanno. Aggiorneremo il confirmation_date attributo quando l'utente verifica il proprio indirizzo email. Quindi, questa tabella ha tre chiavi univoche:user_name , nickname e email .

Ogni volta che un utente effettua l'accesso, viene aggiunto un nuovo record nella login_history tavolo. Tutti gli attributi in questa tabella sono autoesplicativi. Il logout_time è specifico. Può essere NULL quando la sessione corrente dell'utente è attiva o quando gli utenti escono dal gioco (senza disconnettersi) a causa di problemi tecnici. Nel login_data attributo, memorizzeremo i dettagli di accesso come la posizione geografica di un giocatore, l'indirizzo IP e il dispositivo e il browser che utilizza.

La maggior parte dei giochi MMO ci consente di collaborare con altri giocatori. Una delle forme standard di cooperazione tra giocatori è l'alleanza. I giocatori condividono i loro "dati privati" di gioco (stato online, piani, posizione delle loro città e colonie, ecc.) con gli altri per beneficiare delle azioni alleate e per puro divertimento.

L'alliance la tabella memorizza le informazioni di base sulle alleanze di gioco. Ognuno ha un alliance_name univoco che memorizzeremo. Avremo anche un campo, date_founded , che immagazzina quando è stata fondata l'alleanza. Se un'alleanza viene sciolta, memorizzeremo tali informazioni nel date_disbanded attributo.

Il alliance_member tabella mette in relazione i giocatori con alleanze. I giocatori possono unirsi e lasciare la stessa alleanza più di una volta. Per questo motivo, il player_idalliance_id la coppia non è una chiave univoca. Conserveremo le informazioni su quando un giocatore si unisce all'alleanza e quando (se) se ne va nel date_from e date_to campi. Il membership_type_id l'attributo è un riferimento al membership_type dizionario; memorizza il livello attuale dei diritti dei giocatori nell'alleanza.

I diritti dei giocatori in un'alleanza possono cambiare nel tempo. Le membership_actions , membership_type e actions_allowed le tabelle insieme definiscono tutti i diritti possibili per i membri dell'alleanza. Questo modello non consente ai giocatori di definire i propri livelli di diritti in un'alleanza, ma ciò potrebbe essere ottenuto abbastanza facilmente aggiungendo nuovi record nel membership_type dizionario e memorizzazione di informazioni su quali alleanze sono correlate.

Riassumendo:i valori memorizzati in queste tabelle sono da noi definiti durante la configurazione iniziale; cambieranno solo se introduciamo nuove opzioni.

La membership_history la tabella memorizza tutti i dati relativi ai ruoli o ai diritti dei giocatori all'interno di un'alleanza, incluso l'intervallo in cui questi diritti erano validi. (Ad esempio, potrebbe avere i permessi da "principiante" per un mese, e poi "l'abbonamento completo" da quel momento in poi.) Il date_to l'attributo è NULLable perché i diritti attualmente attivi non sono ancora terminati.

Le membership_actions il dizionario contiene un elenco di tutte le azioni che i giocatori possono fare in un'alleanza. Ogni azione ha il proprio action_name e la logica del gioco è costruita attorno a questi nomi. Possiamo aspettarci valori come "visualizza elenco membri" , "visualizza gli stati dei membri" e "invia messaggio" qui.

Il membership_type dizionario contiene i nomi univoci dei gruppi di azioni utilizzati nel gioco. Le actions_allowed la tabella assegna le azioni ai tipi di appartenenza. Ogni azione può essere assegnata a un tipo solo una volta. Pertanto, il membership_action - membership_type coppia costituisce la chiave univoca per questa tabella.

Località e strutture

I luoghi di gioco sono aree in cui i giocatori raccolgono risorse e costruiscono strutture e unità. Alcuni giochi hanno una gamma predefinita di possibili posizioni, mentre altri possono consentire agli utenti di definire le proprie posizioni.

In uno spazio 3D, le posizioni possono essere definite con le coordinate [x:y:z]. Se un gioco ha un intervallo predefinito, potrebbe non consentire ai giocatori di utilizzare qualsiasi posizione al di fuori dell'intervallo [0:1000] per tutti e tre gli assi, quindi siamo limitati a uno spazio di 1000 * 1000 * 1000.

D'altra parte, forse vogliamo consentire ai giocatori di inserire le coordinate esatte della loro nuova posizione, ad es. [1001:2073:4] – e vogliamo che il gioco lo elabori per loro.

Conserveremo un elenco di tutte le posizioni utilizzate in un'istanza del nostro gioco nella location tavolo. Ogni località ha il proprio nome, ma i nomi non sono univoci. D'altra parte, le coordinates l'attributo deve contenere solo valori univoci. Le coordinate della posizione vengono memorizzate come valori di testo, quindi possiamo memorizzare le coordinate per i giochi 3D come [112:72:235]. Le coordinate per i giochi 2D possono essere memorizzate come <1102:98>.

In alcuni giochi, le posizioni avranno un numero di quadrati che vengono utilizzati per ospitare strutture o unità. Conserveremo tali informazioni nella dimension attributo, che è un campo di testo. Una dimensione può essere semplicemente il numero di quadrati in una griglia 2D o 3D. Il player_id l'attributo memorizza le informazioni sull'attuale proprietario di quella posizione. Può essere NULL quando le posizioni sono predefinite ei giocatori competono per occuparle.

La structure la tabella contiene un elenco di tutte le strutture che possiamo costruire in vari luoghi di gioco. Le strutture rappresentano miglioramenti che ci consentono di produrre unità migliori, eseguire nuovi tipi di ricerca, produrre più risorse, ecc. Ogni struttura utilizzata nel gioco ha il suo structure_name univoco . Qualche possibile structure_name i valori sono “fattoria”, “miniera”, “impianto solare” e “centro ricerche”.

Possiamo aspettarci che ogni struttura venga aggiornata più volte, quindi memorizzeremo anche le informazioni sul suo livello attuale. Ogni aggiornamento migliora l'output delle strutture, quindi produce più risorse o ci consente di utilizzare nuove funzionalità nel gioco. Non possiamo conoscere in anticipo il livello massimo di aggiornamento, quindi definiremo tutte le cose relative al livello (costi, tempo di aggiornamento e produzione) con delle formule. Tutte le formule memorizzate nel database sono il fulcro delle meccaniche di gioco e la loro regolazione è fondamentale per l'equilibrio del gioco e il gameplay in generale.

Questo è anche il caso della upgrade_time_formula attributo. Un valore di esempio per questo campo è " * 30 min" , dove rappresenta il livello a cui vogliamo passare.

Nella maggior parte dei casi, ci sono requisiti che devono essere soddisfatti prima che i giocatori compiano determinate azioni. Forse abbiamo bisogno di completare una quantità definita di ricerca prima di poter costruire nuove strutture o viceversa. Conserveremo il livello di ricerca necessario per costruire strutture nel prerequisite_research tavolo. Le relazioni e il livello di struttura necessario per avviare le varie ricerche sono mantenuti nella prerequisite_structure tavolo. In entrambe le tabelle, le chiavi esterne research_id e structure_id sono accoppiati per formare una chiave univoca. Il level_required l'attributo è l'unico valore.

Queste due tabelle, prerequisite_research e prerequisite_structure , costituiscono anche il fulcro del gioco.

Per ogni struttura definiremo un elenco di prerequisiti:altre strutture e i loro livelli minimi che i giocatori devono avere per iniziare a costruire. Conserveremo questi dati nella structure_required tavolo. Qui, structure_id rappresenta la struttura che vogliamo costruire; structure_required_id è un riferimento alle strutture dei prerequisiti e al level è il livello richiesto.

La structure_built la tabella memorizza le informazioni sui livelli di struttura correnti in una determinata posizione. Il upgrade_ongoing l'attributo verrà impostato solo se è attualmente in corso un aggiornamento, mentre il upgrade_end_time l'attributo conterrà un timestamp una volta completato l'aggiornamento.

La structure_formula la tabella mette in relazione strutture e risorse. La coppia di chiavi esterne di questa tabella costituisce la sua chiave univoca. Questa tabella ha anche due attributi di testo contenenti formule con come parametro. Definiremo queste formule, una per i costi e l'altra per la generazione di risorse, nel database. Saranno simili alla upgrade_time_formula . Ne abbiamo bisogno perché dobbiamo definire le risorse spese per costruire ogni struttura. Dobbiamo anche definire la produzione di risorse dopo l'aggiornamento, se la struttura genera risorse (ad es. la miniera produrrà * 20 minerale al giorno).

Ricerca e risorse

La ricerca (o le tecnologie) nei giochi sono solitamente richieste per la creazione di altre funzionalità. Senza determinati livelli di ricerca, non è possibile costruire nuove strutture o tipi di unità. Anche la ricerca può avere i suoi requisiti. Uno dei più comuni è il livello di una data struttura, solitamente chiamata “laboratorio di ricerca”. O forse i giocatori devono completare un certo livello di ricerca prima di poter iniziare una nuova ricerca. Tutti questi requisiti saranno trattati in questa sezione. Di seguito, possiamo trovare il modello dati per Ricerca e Risorse:

La research la tabella contiene un elenco di tutte le possibili azioni di ricerca nel nostro gioco. Utilizza la stessa logica della structure tavolo. Il research_name l'attributo è la chiave univoca della tabella, mentre la upgrade_time_formula contiene una rappresentazione testuale della formula dei requisiti di tempo di ricerca, con come parametro. Eventuali risorse necessarie per gli aggiornamenti sono definite nella upgrade_formula memorizzato nella research_formula tabella.

Come per le strutture, definiremo l'elenco di tutte le altre ricerche e dei loro livelli che devono essere completati prima di poter iniziare un altro tipo di ricerca. Conserveremo questi dati nel research_required tabella, dove research_id rappresenta la ricerca desiderata; research_required_id è un riferimento alla ricerca dei prerequisiti e al level è il livello richiesto.

La ricerca è relativa ai singoli giocatori e per ogni giocatore – ricerca ch coppia dobbiamo memorizzare il livello di ricerca corrente di un giocatore e qualsiasi stato di aggiornamento in corso. Conserveremo queste informazioni utilizzando il research_level tabella nello stesso modo in cui abbiamo usato structure_built tabella.

Risorse come legno, minerali, gemme ed energia vengono estratte o raccolte e utilizzate in seguito per costruire strutture e altri miglioramenti. Conserveremo un elenco di tutte le risorse di gioco nella resource dizionario. L'unico attributo qui è il resource_name campo, ed è anche la chiave univoca della tabella.

Per tenere traccia della quantità attuale di risorse in ciascuna località, utilizzeremo il resources_on_location tavolo. Ancora una volta, una coppia di chiavi esterne (resource_id e location_id ) costituisce la chiave univoca della tabella, mentre il number l'attributo memorizza i valori delle risorse correnti.

Unità e movimenti

Le risorse vengono utilizzate per produrre unità. Le unità possono essere utilizzate per trasportare risorse, attaccare altri giocatori o in generale saccheggiare e bruciare.

L'elenco dei tipi di unità utilizzati nel nostro gioco è archiviato in unit dizionario con un solo valore, unit_name; quell'attributo è la chiave univoca di questa tabella. Alcune unità di gioco comuni sono "spadaccino", "incrociatore da battaglia", "grifone", "caccia a reazione", "carro armato", ecc.

Dobbiamo descrivere ogni unità con caratteristiche specifiche. Un elenco di tutte le possibili caratteristiche è memorizzato nella characteristic dizionario. Il characteristic_name campo contiene un valore univoco. I valori in questo campo potrebbero includere:"attacco", "difesa" e "punti ferita". Assegneremo le caratteristiche alle unità utilizzando il unit_characteristic relazione. La coppia di chiavi esterne di unit_id e characteristic_id formano la chiave univoca della tabella. Useremo un solo attributo, value , per memorizzare il valore desiderato.

Il research_unit la tabella contiene un elenco di tutte le attività di ricerca che devono essere terminate prima di poter avviare la produzione di un determinato tipo di unità. Il unit_cost tabella definisce le risorse necessarie per produrre una singola unità. Entrambe le tabelle hanno chiavi univoche composte dalla coppia di chiavi esterne (research_id o resources_id combinato con unit_id ) e un campo valore (cost e level_required ).

E ora, la parte divertente. La produzione è divertente, ma spostare le unità e agire è ancora meglio. Abbiamo già introdotto l'unit tabella, ma la terremo qui a causa della relazione con le altre tabelle.

O le unità sono di stanza in una posizione o si stanno spostando da una posizione all'altra. Aggiunta del player_id campo determina chi possiede la sede o il gruppo che si sta spostando tra le sedi.

Se le unità sono solo di stanza in una determinata posizione, memorizzeremo quella posizione e il numero di unità lì stazionate. Per farlo, utilizzeremo units_on_location tabella.

Quando le unità non sono di stanza, si muovono. Avremo bisogno di memorizzare il loro punto di partenza e la loro destinazione. Inoltre, dobbiamo definire possibili azioni durante i movimenti. Tutte queste azioni sono memorizzate nel movement_type dizionario. Il type_name l'attributo è univoco mentre allows_wait attributo determina se un'azione consente l'attesa nel punto di destinazione.

Possiamo spostare un singolo tipo di unità, ma in quasi tutti i casi sposteremo molte unità di diversi tipi di unità. Quel gruppo condividerà dati comuni e li memorizzeremo nel group_movement tavolo. In questa tabella definiremo i seguenti elementi:

  • il giocatore che ha avviato quell'azione
  • il tipo di azione
  • il punto di partenza
  • il punto di destinazione
  • il arrival_time a destinazione
  • il return_time al punto di partenza
  • il wait_time a destinazione

Il return_time l'attributo può essere NULL se si tratta di un viaggio di sola andata e wait_time è definito dal giocatore. Le unità appartenenti a un gruppo sono definite da valori archiviati in units_in_group tavolo. La coppia di chiavi esterne di units_id e group_moving_id costituisce la chiave univoca della tavola. Il numero delle unità dello stesso tipo all'interno di un gruppo è definito nel number attributo.

Ogni movimento può trasportare risorse da un luogo all'altro. Pertanto, definiremo una relazione molti-a-molti tra il group_movement e le resources tavoli. Oltre alle chiavi primarie ed esterne, il resources_in_group la tabella contiene solo il number attributo. Questo campo memorizza la quantità di risorse che i giocatori spostano dal punto di partenza alla loro destinazione.

Nella maggior parte dei casi, i giocatori possono chiamare altri per unirsi alla loro avventura. Per supportarlo utilizzeremo due tabelle:allied_movement e allied_groups . Un giocatore avvierà un'azione congiunta e ciò creerà un nuovo record nel allied_movement tavolo. Tutti i gruppi di unità che prendono parte a un'azione alleata sono definiti da valori archiviati in allied_groups tavolo. Ogni gruppo può essere assegnato a un'azione alleata solo una volta, quindi le chiavi esterne formano la chiave univoca di questa tabella.

Questo modello ci fornisce la struttura di base necessaria per costruire un gioco di strategia MMO. Contiene le caratteristiche di gioco più importanti:posizioni, strutture, risorse, ricerca e unità. Inoltre li mette in relazione, ci consente di definire i prerequisiti nel database e memorizza anche la maggior parte della logica di gioco nel database.

Dopo che queste tabelle sono state popolate, la maggior parte della logica di gioco è definita e non ci aspetteremmo che vengano aggiunti nuovi valori. Quasi ogni tabella ha un valore di chiave univoco, un nome di funzionalità o una coppia di chiavi esterne. La modifica delle caratteristiche delle unità e delle formule di produzione/costo ci consentirà di modificare il bilanciamento del gioco nel livello del database.

Come cambieresti questo modello? Cosa ti piace e cosa faresti di diverso? Diccelo nella sezione commenti!