sql >> Databasteknik >  >> RDS >> Database

MMO-spel och databasdesign

Låt oss vara ärliga:vi älskar alla att spela spel, särskilt på våra datorer. Tills internet blev utbrett spelade de flesta av oss datorspel själva, vanligtvis mot AI-motståndare. Det var kul, men så fort du insåg hur spelmekaniken fungerade förlorade spelet det mesta av sin magi.

Utvecklingen av Internet flyttade spel online. Nu kan vi spela mot mänskliga motståndare och testa våra färdigheter mot deras. Inget mer rote-spel!

Sedan uppstod massiva multiplayer online-spel (MMO) och förändrade allt. Tusentals spelare befann sig i samma speluniversum, där de konkurrerade om resurser, förhandlade, handlade och slogs. För att göra sådana spel möjliga behövdes en databasstruktur som kunde lagra all relevant information.

I den här artikeln kommer vi att designa en modell som innehåller de vanligaste elementen som finns i MMO-spel. Vi kommer att diskutera hur man använder den, dess begränsningar och möjliga förbättringar.

En introduktion till datamodeller för MMO-spel

Det finns gott om mycket populära MMO-spel idag, och de involverar alla typer av scenarier. Jag kommer att fokusera här på strategispel som Ogame , Travian , Sparta :War of Empires och Imperia Online . Dessa spel handlar mer om att planera, bygga och lägga strategier, och mindre om direkta åtgärder.

MMO-spel utspelar sig i olika universum, är visuellt olika och använder mer eller mindre olika spelalternativ. Ändå är vissa idéer desamma. Spelare tävlar om platser, slåss för dem och bildar allians med (och mot) andra spelare. De bygger strukturer, samlar resurser och forskar om teknik. De bygger enheter (som krigare, stridsvagnar, handlare, etc.) och använder dem för att handla med allierade eller för att slåss med motståndare. Allt detta måste stödjas i vår databas.

Vi kan se dessa spel som brädspel online med många indexerade rutor. Varje ruta kan ha många olika åtgärder associerade med sig; vissa åtgärder kommer att innehålla flera rutor – t.ex. när vi flyttar enheter eller resurser från en plats till en annan.




Databasen är indelad i fem huvudområden:

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

De återstående sju ogrupperade borden är relaterade till enheter och beskriver enhetens position och rörelser i spelet. Vi kommer att titta på vart och ett av dessa områden i mycket mer detalj, med början med Spelare och Allianser .

Spelare och allianser

Utan tvekan är spelare den viktigaste delen av alla spel.

player Tabellen innehåller en lista över alla registrerade spelare som deltar i en spelinstans. Vi kommer att lagra spelarnas användarnamn, lösenord och skärmnamn. Dessa kommer att lagras i user_name , password och nickname attribut respektive.

Nya användare måste ange en e-postadress under registreringen. En bekräftelsekod kommer att genereras och skickas till dem, som de kommer att svara på. Vi kommer att uppdatera confirmation_date attribut när användaren verifierar sin e-postadress. Så den här tabellen har tre unika nycklar:user_name , nickname och email .

Varje gång en användare loggar in läggs en ny post till i login_history tabell. Alla attribut i denna tabell är självförklarande. logout_time är specifik. Den kan vara NULL när användarens nuvarande session är aktiv eller när användare avslutar spelet (utan att logga ut) på grund av tekniska problem. I login_data attribut lagrar vi inloggningsuppgifter som en spelares geografiska plats, IP-adress och enheten och webbläsaren de använder.

De flesta MMO-spel låter oss samarbeta med andra spelare. En av standardformerna för spelarsamarbete är alliansen. Spelare delar sina "privata data" i spelet (onlinestatus, planer, platsen för deras städer och kolonier, etc.) med andra för att dra nytta av allierade handlingar och för det rena nöjet.

alliance tabellen lagrar grundläggande information om spelallianser. Var och en har ett unikt alliance_name som vi lagrar. Vi kommer också att ha ett fält, date_founded , som lagras när alliansen grundades. Om en allians upplöses lagrar vi den informationen i date_disbanded attribut.

alliance_member tabellen relaterar spelare med allianser. Spelare kan gå med och lämna samma allians mer än en gång. På grund av detta, player_idalliance_id par är inte en unik nyckel. Vi sparar information om när en spelare går med i alliansen och när (om) de lämnar i date_from och date_to fält. membership_type_id attribut är en referens till membership_type lexikon; den lagrar den nuvarande nivån på spelarnas rättigheter i alliansen.

Spelarnas rättigheter i en allians kan förändras över tiden. membership_actions , membership_type och actions_allowed tabeller tillsammans definierar alla möjliga rättigheter för alliansmedlemmar. Den här modellen tillåter inte spelare att definiera sina egna rättigheter i en allians, men det skulle kunna åstadkommas tillräckligt enkelt genom att lägga till nya poster i membership_type ordbok och lagra information om vilka allianser de är relaterade till.

Sammanfattningsvis:värdena som lagras i dessa tabeller definieras av oss under den första installationen; de ändras bara om vi introducerar nya alternativ.

membership_history tabellen lagrar all data om spelarnas roller eller rättigheter inom en allians, inklusive intervallet när dessa rättigheter var giltiga. (Till exempel kan han ha "nybörjare"-behörigheter i en månad och sedan "fullständigt medlemskap" från den tidpunkten.) date_to attributet är NULL-bart eftersom för närvarande aktiva rättigheter inte har upphört än.

membership_actions ordboken innehåller en lista över alla åtgärder som spelare kan göra i en allians. Varje åtgärd har sin egen action_name och spellogik är uppbyggd kring dessa namn. Vi kan förvänta oss värden som "visa medlemslista" , "visa medlemmars status" och "skicka meddelande" här.

membership_type ordboken innehåller de unika namnen på de actiongrupper som används i spelet. actions_allowed Tabellen tilldelar åtgärder till medlemstyper. Varje åtgärd kan endast tilldelas en typ en gång. Därför är membership_action - membership_type paret utgör den unika nyckeln för denna tabell.

Platser och strukturer

Spelplatser är områden där spelare samlar resurser och bygger strukturer och enheter. Vissa spel har ett fördefinierat utbud av möjliga platser, medan andra kan tillåta användare att definiera sina egna platser.

I ett 3D-utrymme kan platser definieras med [x:y:z]-koordinater. Om ett spel har ett fördefinierat intervall kanske det inte tillåter spelare att använda någon plats utanför intervallet [0:1000] för alla tre axlarna, så vi är begränsade till ett 1000 * 1000 * 1000 utrymme.

Å andra sidan kanske vi vill tillåta spelare att ange de exakta koordinaterna för sin nya plats – t.ex. [1001:2073:4] – och vi vill att spelet ska bearbeta det åt dem.

Vi kommer att hålla en lista över alla platser som används i en instans av vårt spel på location tabell. Varje plats har sitt eget namn, men namnen är inte unika. Å andra sidan, coordinates attribut får endast innehålla unika värden. Platskoordinater lagras som textvärden, så vi kan lagra koordinater för 3D-spel som [112:72:235]. Koordinater för 2D-spel kan lagras som <1102:98>.

I vissa spel kommer platser att ha ett antal rutor som används för att hysa strukturer eller enheter. Vi behåller den informationen i dimension attribut, som är ett textfält. En dimension kan helt enkelt vara antalet rutor i ett 2D- eller 3D-rutnät. player_id attribut lagrar information om den aktuella ägaren av den platsen. Det kan vara NULL när platser är fördefinierade och spelare tävlar om att ockupera dem.

structure Tabellen innehåller en lista över alla strukturer vi kan bygga på olika spelplatser. Strukturer representerar förbättringar som gör att vi kan producera bättre enheter, utföra nya typer av forskning, producera mer resurser etc. Varje struktur som används i spelet har sitt eget unika structure_name . Några möjliga structure_name värden är "gård", "malmgruva", "solkraftverk" och "forskningscenter".

Vi kan förvänta oss att varje struktur kommer att uppgraderas flera gånger, så vi kommer också att lagra information om dess nuvarande nivå. Varje uppgradering förbättrar strukturernas produktion, så den producerar mer resurser eller tillåter oss att använda nya funktioner i spelet. Vi kan inte veta den maximala uppgraderingsnivån i förväg, så vi kommer att definiera alla nivårelaterade saker (kostnader, uppgraderingstid och produktion) med formler. Alla formler som lagras i databasen är kärnan i spelets mekanik, och deras justering är avgörande för spelbalansen och spelet i allmänhet.

Det är också fallet med upgrade_time_formula attribut. Ett exempelvärde för detta fält är * 30 min” , där representerar den nivå vi vill uppgradera till.

I de flesta fall finns det krav som måste uppfyllas innan spelare vidtar vissa åtgärder. Kanske behöver vi slutföra en definierad mängd forskning innan vi kan bygga nya strukturer eller vice versa. Vi lagrar den forskningsnivå som behövs för att bygga strukturer i prerequisite_research tabell. Relationer och strukturnivån som behövs för att starta olika undersökningar finns i prerequisite_structure tabell. I båda tabellerna är de främmande nycklarna research_id och structure_id är ihopparade för att bilda en unik nyckel. level_required attribut är det enda värdet.

Dessa två tabeller, prerequisite_research och prerequisite_structure , utgör också kärnan i spelet.

För varje struktur kommer vi att definiera en lista med förutsättningar:andra strukturer och deras miniminivåer som spelare måste ha för att börja bygga. Vi lagrar denna data i structure_required tabell. Här, structure_id representerar den struktur vi vill bygga; structure_required_id är en referens till förutsättningsstruktur(er) och level är den nivå som krävs.

structure_built Tabell lagrar information om nuvarande strukturnivåer på en given plats. upgrade_ongoing attribut kommer endast att ställas in om en uppgradering för närvarande pågår, medan upgrade_end_time attribut kommer att innehålla en tidsstämpel när uppgraderingen är klar.

structure_formula tabell relaterar strukturer och resurser. Det främmande nyckelparet till denna tabell bildar dess unika nyckel. Den här tabellen har också två textattribut som innehåller formler med som parameter. Vi kommer att definiera dessa formler, en för kostnader och den andra för resursgenerering, i databasen. De kommer att likna upgrade_time_formula . Vi behöver dem eftersom vi måste definiera de resurser som används för att bygga varje struktur. Vi måste också definiera resursproduktion efter uppgradering, om struktur genererar några resurser (dvs malmgruvan kommer att producera * 20 malm per dag).

Forskning och resurser

Forskning (eller teknologier) i spel är vanligtvis nödvändiga för att skapa andra funktioner. Utan vissa nivåer av forskning kan nya strukturer eller enhetstyper inte byggas. Forskning kan också ha sina egna krav. En av de vanligaste är nivån på en given struktur, vanligtvis kallad ett "forskningslabb". Eller kanske spelarna behöver slutföra en viss nivå av forskning innan de kan påbörja ny forskning. Alla dessa krav kommer att hanteras i detta avsnitt. Nedan kan vi hitta datamodellen för forskning och resurser:

research Tabellen innehåller en lista över alla möjliga forskningsåtgärder i vårt spel. Den använder samma logik som structure tabell. research_name attribut är tabellens unika nyckel, medan upgrade_time_formula fältet innehåller en textrepresentation av formeln för forskningstidskrav, med som parameter. Alla resurser som krävs för uppgraderingar definieras i upgrade_formula lagras i research_formula bord.

Precis som med strukturer kommer vi att definiera listan över alla andra undersökningar och deras nivåer som måste slutföras innan vi kan påbörja en annan typ av forskning. Vi lagrar denna data i research_required tabell, där research_id representerar den önskade forskningen; research_required_id är en referens till förutsättningen forskning och level är den nivå som krävs.

Forskning är relaterad till individuella spelare, och för varje spelare – forska ch-par måste vi lagra en spelares aktuella forskningsnivå och eventuella pågående uppgraderingsstatusar. Vi lagrar denna information med hjälp av research_level tabellen på samma sätt som vi använde structure_built bord.

Resurser som trä, malm, ädelstenar och energi bryts eller samlas in och används senare för att bygga strukturer och andra förbättringar. Vi lagrar en lista över alla resurser i spelet i resource lexikon. Det enda attributet här är resource_name fältet, och det är också den unika nyckeln i tabellen.

För att hålla reda på den aktuella mängden resurser på varje plats använder vi resources_on_location tabell. Återigen, ett främmande nyckelpar (resource_id och location_id ) bildar den unika nyckeln för tabellen, medan number attribut lagrar de aktuella resursvärdena.

Enheter och rörelser

Resurser används för att producera enheter. Enheter kan användas för att transportera resurser, attackera andra spelare eller i allmänhet plundring och bränning.

Listan över enhetstyper som används i vårt spel lagras i unit ordbok med bara ett värde, unit_name; det attributet är den unika nyckeln för denna tabell. Några vanliga spelenheter är "svärdsman", "battlecruiser", "griffin", "jet fighter", "tank" etc.

Vi måste beskriva varje enhet med specifika egenskaper. En lista över alla möjliga egenskaper lagras i characteristic lexikon. characteristic_name fältet innehåller ett unikt värde. Värden i detta fält kan inkludera:"attack", "försvar" och "träffpunkter". Vi kommer att tilldela egenskaper till enheter med unit_characteristic relation. Det främmande nyckelparet för unit_id och characteristic_id utgör tabellens unika nyckel. Vi kommer bara att använda ett attribut, value , för att lagra önskat värde.

research_unit Tabellen innehåller en lista över alla forskningsaktiviteter som måste avslutas innan vi kan starta produktion av en given enhetstyp. unit_cost tabellen definierar de resurser som behövs för att producera en enda enhet. Båda tabellerna har unika nycklar som består av det främmande nyckelparet (research_id eller resources_id kombinerat med unit_id ) och ett värdefält (cost och level_required ).

Och nu, den roliga delen. Produktion är kul, men att flytta runt enheter och agera är ännu bättre. Vi har redan introducerat unit tabell, men vi kommer att behålla den här på grund av hur den relaterar till andra tabeller.

Antingen är enheterna stationerade på en plats eller så flyttar de mellan platser. Lägger till player_id fältet avgör vem som äger antingen platsen eller gruppen som flyttar mellan platserna.

Om enheter bara är stationerade på den angivna platsen, lagrar vi den platsen och antalet enheter som är stationerade där. För att göra det använder vi units_on_location bord.

När enheter inte är stationerade flyttar de runt. Vi måste lagra deras avgångspunkt och deras destination. Dessutom måste vi definiera möjliga handlingar under rörelser. Alla sådana åtgärder lagras i movement_type lexikon. type_name attributet är unikt medan allows_wait attribut bestämmer om en åtgärd tillåter väntan vid destinationspunkten.

Vi kan flytta en enda enhetstyp, men i nästan alla fall flyttar vi många enheter av flera olika enhetstyper. Den gruppen delar gemensam data och vi lagrar dem i group_movement tabell. I den här tabellen kommer vi att definiera följande objekt:

  • spelaren som initierade åtgärden
  • åtgärdstypen
  • utgångspunkten
  • målpunkten
  • arrival_time vid destinationen
  • return_time till startpunkten
  • wait_time vid destinationen

return_time attribut kan vara NULL om detta är en enkel resa och wait_time definieras av spelaren. Enheter som tillhör en grupp definieras av värden lagrade i units_in_group tabell. Det främmande nyckelparet för units_id och group_moving_id bildar tabellens unika nyckel. Antalet enheter av samma typ inom en grupp definieras i number attribut.

Varje rörelse kan transportera resurser från en plats till en annan. Därför kommer vi att definiera en många-till-många-relation mellan group_movement och resources tabeller. Förutom de primära och främmande nycklarna, resources_in_group Tabellen innehåller endast number attribut. Detta fält lagrar mängden resurser som spelarna flyttar från startpunkten till sin destination.

I de flesta fall kan spelare ringa andra för att delta i deras äventyr. För att stödja det kommer vi att använda två tabeller:allied_movement och allied_groups . En spelare kommer att initiera gemensam åtgärd, och det kommer att skapa ett nytt rekord i allied_movement tabell. Alla grupper av enheter som deltar i en allierad åtgärd definieras av värden lagrade i allied_groups tabell. Varje grupp kan bara tilldelas en allierad handling en gång, så främmande nycklar utgör den unika nyckeln för denna tabell.

Denna modell ger oss den grundläggande strukturen som behövs för att bygga ett MMO-strategispel. Det innehåller de viktigaste spelfunktionerna:platser, strukturer, resurser, forskning och enheter. Den relaterar dem också, låter oss definiera förutsättningar i databasen och lagrar också det mesta av spellogiken i databasen.

Efter att dessa tabeller har fyllts i, är det mesta av spelets logik definierad och vi förväntar oss inte att nya värden läggs till. Nästan varje tabell har ett unikt nyckelvärde, antingen ett funktionsnamn eller ett främmande nyckelpar. Genom att ändra enheternas egenskaper och produktions-/kostnadsformler kan vi ändra spelbalansen i databaslagret.

Hur skulle du ändra denna modell? Vad gillar du och vad skulle du göra annorlunda? Berätta för oss i kommentarsfältet!


  1. Uppdatera kolumner med nollvärden

  2. Exportera MySQL-databas med PHP

  3. Hur man importerar/återställer MySql-tabeller med PHP

  4. Korrekt infogning av tabellnamn