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

MMO-spil og databasedesign

Lad os være ærlige:Vi elsker alle at spille spil, især på vores computere. Indtil internettet blev udbredt, spillede de fleste af os computerspil alene, normalt mod AI-modstandere. Det var sjovt, men så snart du indså, hvordan gameplay-mekanikken fungerede, mistede spillet det meste af sin magi.

Udviklingen af ​​internettet flyttede spil online. Nu kan vi spille mod menneskelige modstandere og teste vores færdigheder mod deres. Ikke mere løst gameplay!

Så dukkede massive multiplayer online (MMO) spil op og ændrede alt. Tusindvis af spillere befandt sig i de samme spiluniverser, hvor de konkurrerede om ressourcer, forhandlede, handlede og kæmpede. For at gøre sådanne spil mulige var der behov for en databasestruktur, der kunne gemme alle relevante oplysninger.

I denne artikel vil vi designe en model, der inkorporerer de mest almindelige elementer, der findes i MMO-spil. Vi vil diskutere, hvordan man bruger det, dets begrænsninger og dets mulige forbedringer.

En introduktion til datamodeller til MMO-spil

Der er masser af meget populære MMO-spil i dag, og de involverer alle slags scenarier. Jeg vil her fokusere på strategispil som Ogame , Travian , Sparta :War of Empires og Imperia Online . Disse spil handler mere om planlægning, opbygning og strategilægning og mindre om direkte handling.

MMO-spil foregår i forskellige universer, er visuelt forskellige og bruger mere eller mindre forskellige spilmuligheder. Alligevel er nogle ideer de samme. Spillere konkurrerer om placeringer, kæmper for dem og danner alliance med (og mod) andre spillere. De bygger strukturer, indsamler ressourcer og forsker i teknologier. De bygger enheder (såsom krigere, kampvogne, handlende osv.) og bruger dem til at handle med allierede eller til at kæmpe med modstandere. Alt dette skal understøttes i vores database.

Vi kan tænke på disse spil som online brætspil med mange indekserede firkanter. Hver firkant kan have mange forskellige handlinger forbundet med sig; nogle handlinger vil omfatte flere firkanter – f.eks. når vi flytter enheder eller ressourcer fra et sted til et andet.




Databasen er opdelt i fem hovedområder:

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

De resterende syv ugrupperede borde er relateret til enheder og beskriver enhedsposition og bevægelser i spillet. Vi vil se meget mere detaljeret på hvert af disse områder, begyndende med Spillere og Alliancer .

Spillere og alliancer

Uden tvivl er spillere den vigtigste del af ethvert spil.

player tabellen indeholder en liste over alle registrerede spillere, der deltager i en spilinstans. Vi gemmer spillernes brugernavne, adgangskoder og skærmnavne. Disse vil blive gemt i user_name , password og nickname hhv.

Nye brugere skal angive en e-mailadresse under registreringen. En bekræftelseskode vil blive genereret og sendt til dem, som de vil svare på. Vi opdaterer confirmation_date attribut, når brugeren bekræfter sin e-mailadresse. Så denne tabel har tre unikke nøgler:user_name , nickname og email .

Hver gang en bruger logger ind, tilføjes en ny post i login_history bord. Alle egenskaberne i denne tabel er selvforklarende. logout_time er specifik. Den kan være NULL, når brugerens aktuelle session er aktiv, eller når brugere afslutter spillet (uden at logge ud) på grund af tekniske problemer. I login_data attribut, gemmer vi loginoplysninger såsom en spillers geografiske placering, IP-adresse og den enhed og browser, de bruger.

De fleste MMO-spil lader os samarbejde med andre spillere. En af standardformerne for spillersamarbejde er alliancen. Spillere deler deres "private data" i spillet (onlinestatus, planer, placering af deres byer og kolonier osv.) med andre for at drage fordel af allierede handlinger og bare for sjov.

alliance tabel gemmer grundlæggende oplysninger om spil alliancer. Hver enkelt har et unikt alliance_name som vi gemmer. Vi har også et felt, date_founded , der gemmer, da alliancen blev grundlagt. Hvis en alliance opløses, gemmer vi disse oplysninger i date_disbanded attribut.

alliance_member tabel forbinder spillere med alliancer. Spillere kan tilslutte sig og forlade den samme alliance mere end én gang. På grund af dette er player_idalliance_id par er ikke en unik nøgle. Vi gemmer oplysninger om, hvornår en spiller slutter sig til alliancen, og hvornår (hvis) de forlader i date_from og date_to felter. membership_type_id attribut er en reference til membership_type ordbog; den gemmer det aktuelle niveau for spillernes rettigheder i alliancen.

Spillernes rettigheder i en alliance kan ændre sig over tid. membership_actions , membership_type og actions_allowed tabeller definerer tilsammen alle mulige rettigheder for alliancens medlemmer. Denne model tillader ikke spillere at definere deres egne niveauer af rettigheder i en alliance, men det kunne opnås nemt nok ved at tilføje nye poster i membership_type ordbog og lagring af information om, hvilke alliancer de er relateret til.

For at opsummere:Værdierne gemt i disse tabeller er defineret af os under den indledende opsætning; de ændrer sig kun, hvis vi introducerer nye muligheder.

membership_history tabellen gemmer alle data vedrørende spillernes roller eller rettigheder inden for en alliance, inklusive området, hvor disse rettigheder var gyldige. (Han kunne f.eks. have "nybegyndere"-tilladelser i en måned og derefter "fuldt medlemskab" fra det tidspunkt.) date_to attributten er NULLbar, fordi de aktive rettigheder endnu ikke er afsluttet.

membership_actions ordbogen indeholder en liste over alle handlinger, som spillere kan foretage i en alliance. Hver handling har sin egen action_name og spillogik er bygget op omkring disse navne. Vi kan forvente værdier som "se medlemsliste" , "se medlemmers status" og "send besked" her.

membership_type ordbogen indeholder de unikke navne på de handlingsgrupper, der bruges i spillet. actions_allowed tabel tildeler handlinger til medlemstyper. Hver handling kan kun tildeles en type én gang. Derfor er membership_action - membership_type par danner den unikke nøgle til denne tabel.

Placeringer og strukturer

Spilplaceringer er områder, hvor spillere samler ressourcer og bygger strukturer og enheder. Nogle spil har et foruddefineret udvalg af mulige placeringer, mens andre kan tillade brugere at definere deres egne placeringer.

I et 3D-rum kan placeringer defineres med [x:y:z]-koordinater. Hvis et spil har en foruddefineret rækkevidde, tillader det muligvis ikke spillere at bruge nogen placering uden for området [0:1000] for alle tre akser, så vi er begrænset til en plads på 1000 * 1000 * 1000.

På den anden side vil vi måske give spillerne mulighed for at indtaste de nøjagtige koordinater for deres nye placering – f.eks. [1001:2073:4] – og vi ønsker, at spillet skal behandle det for dem.

Vi gemmer en liste over alle placeringer, der bruges i en forekomst af vores spil på location bord. Hvert sted har sit eget navn, men navnene er ikke unikke. På den anden side er coordinates attribut må kun indeholde unikke værdier. Lokationskoordinater gemmes som tekstværdier, så vi kan gemme koordinater for 3D-spil som [112:72:235]. Koordinater for 2D-spil kan gemmes som <1102:98>.

I nogle spil vil steder have et antal firkanter, der bruges til at huse strukturer eller enheder. Vi beholder disse oplysninger i dimension attribut, som er et tekstfelt. En dimension kan simpelthen være antallet af kvadrater i et 2D- eller 3D-gitter. player_id attribut gemmer oplysninger om den aktuelle ejer af det pågældende sted. Den kan være NULL, når placeringer er foruddefinerede, og spillere konkurrerer om at besætte dem.

structure tabel indeholder en liste over alle strukturer, vi kan bygge på forskellige spilsteder. Strukturer repræsenterer forbedringer, der giver os mulighed for at producere bedre enheder, udføre nye typer forskning, producere flere ressourcer osv. Hver struktur, der bruges i spillet har sit eget unikke structure_name . Nogle mulige structure_name værdier er "gård", "malmmine", "solcelleanlæg" og "forskningscenter".

Vi kan forvente, at hver struktur bliver opgraderet flere gange, så vi gemmer også oplysninger om dens nuværende niveau. Hver opgradering forbedrer strukturernes output, så det producerer flere ressourcer eller giver os mulighed for at bruge nye funktioner i spillet. Vi kan ikke kende det maksimale niveau for opgradering på forhånd, så vi definerer alle niveaurelaterede ting (omkostninger, opgraderingstid og produktion) med formler. Alle formler gemt i databasen er kernen i spillets mekanik, og deres justering er afgørende for spillets balance og gameplay generelt.

Det er også tilfældet med upgrade_time_formula attribut. Et eksempel på værdi for dette felt er * 30 min” , hvor repræsenterer det niveau, vi ønsker at opgradere til.

I de fleste tilfælde er der krav, der skal opfyldes, før spillere foretager bestemte handlinger. Måske skal vi gennemføre en defineret mængde forskning, før vi kan bygge nye strukturer eller omvendt. Vi gemmer det forskningsniveau, der er nødvendigt for at bygge strukturer i prerequisite_research bord. Relationer og det strukturniveau, der er nødvendigt for at starte forskellige undersøgelser, opbevares i prerequisite_structure bord. I begge tabeller er fremmednøglerne research_id og structure_id er parret for at danne en unik nøgle. level_required attribut er den eneste værdi.

Disse to tabeller, prerequisite_research og prerequisite_structure , udgør også kernen i spillet.

For hver struktur vil vi definere en liste over forudsætninger:andre strukturer og deres minimumsniveauer, som spillere skal have for at begynde at bygge. Vi gemmer disse data i structure_required bord. Her, structure_id repræsenterer den struktur, vi ønsker at bygge; structure_required_id er en reference til forudsætningsstruktur(er) og level er det nødvendige niveau.

structure_built tabel gemmer information om aktuelle strukturniveauer på en given placering. upgrade_ongoing Attributten indstilles kun, hvis en opgradering i øjeblikket er i gang, mens upgrade_end_time attribut vil indeholde et tidsstempel, når opgraderingen er fuldført.

structure_formula tabel relaterer strukturer og ressourcer. Fremmednøgleparret til denne tabel danner dens unikke nøgle. Denne tabel har også to tekstattributter, der indeholder formler med som parameter. Vi definerer disse formler, den ene for omkostninger og den anden til ressourcegenerering, i databasen. De vil ligne upgrade_time_formula . Vi har brug for dem, fordi vi skal definere de ressourcer, der bruges på at bygge hver enkelt struktur. Vi er også nødt til at definere ressourceproduktion efter opgradering, hvis struktur genererer nogen ressourcer (dvs. malmmine vil producere * 20 malm om dagen).

Forskning og ressourcer

Forskning (eller teknologier) i spil er normalt nødvendige for at skabe andre funktioner. Uden visse niveauer af forskning kan nye strukturer eller enhedstyper ikke bygges. Forskning kan også have sine egne krav. En af de mest almindelige er niveauet af en given struktur, normalt kaldet et "forskningslaboratorium". Eller måske skal spillere gennemføre et vist niveau af forskning, før de kan starte ny forskning. Alle disse krav vil blive behandlet i dette afsnit. Nedenfor kan vi finde datamodellen for forskning og ressourcer:

research tabel indeholder en liste over alle mulige forskningshandlinger i vores spil. Den bruger samme logik som structure bord. research_name attribut er tabellens unikke nøgle, mens upgrade_time_formula feltet indeholder en tekstrepræsentation af formlen for forskningstidskrav med som parameter. Alle nødvendige ressourcer til opgraderinger er defineret i upgrade_formula gemt i research_formula tabel.

Som med strukturer, vil vi definere listen over alle andre undersøgelser og deres niveauer, der skal afsluttes, før vi kan starte en anden type forskning. Vi gemmer disse data i research_required tabel, hvor research_id repræsenterer den ønskede forskning; research_required_id er en reference til forudsætningen for forskning og level er det nødvendige niveau.

Forskning er relateret til individuelle spillere, og for hver spiller – research ch-par skal vi gemme en spillers aktuelle forskningsniveau og eventuelle igangværende opgraderingsstatusser. Vi gemmer disse oplysninger ved hjælp af research_level tabellen på samme måde, som vi brugte structure_built tabel.

Ressourcer som træ, malm, ædelstene og energi udvindes eller indsamles og bruges senere til at bygge strukturer og andre forbedringer. Vi gemmer en liste over alle ressourcer i spillet i resource ordbog. Den eneste attribut her er resource_name felt, og det er også tabellens unikke nøgle.

For at holde styr på den aktuelle mængde ressourcer på hver lokation bruger vi resources_on_location bord. Igen et fremmednøglepar (resource_id og location_id ) danner tabellens unikke nøgle, mens number attribut gemmer de aktuelle ressourceværdier.

Enheder og bevægelser

Ressourcer bruges til at producere enheder. Enheder kan bruges til at transportere ressourcer, angribe andre spillere eller generelt plyndre og brænde.

Listen over enhedstyper, der bruges i vores spil, er gemt i unit ordbog med kun én værdi, unit_name; denne attribut er den unikke nøgle til denne tabel. Nogle almindelige spilenheder er "sværdkæmper", "battlecruiser", "griffin", "jetjager", "tank" osv.

Vi skal beskrive hver enhed med specifikke egenskaber. En liste over alle mulige egenskaber er gemt i characteristic ordbog. characteristic_name feltet indeholder en unik værdi. Værdier i dette felt kan omfatte:"angreb", "forsvar" og "hitpunkter". Vi vil tildele karakteristika til enheder ved hjælp af unit_characteristic forhold. Det fremmede nøglepar unit_id og characteristic_id danner tabellens unikke nøgle. Vi bruger kun én egenskab, value , for at gemme den ønskede værdi.

research_unit tabel indeholder en liste over alle forskningsaktiviteter, der skal afsluttes, før vi kan starte produktionen af ​​en given enhedstype. unit_cost tabel definerer de ressourcer, der er nødvendige for at producere en enkelt enhed. Begge tabeller har unikke nøgler sammensat af det fremmede nøglepar (research_id eller resources_id kombineret med unit_id ) og ét værdifelt (cost og level_required ).

Og nu den sjove del. Produktion er sjovt, men det er endnu bedre at flytte enheder rundt og handle. Vi har allerede introduceret unit tabel, men vi beholder den her på grund af, hvordan den hænger sammen med andre tabeller.

Enten er enheder stationeret på et sted, eller også bevæger de sig mellem lokationer. Tilføjelse af player_id feltet bestemmer, hvem der ejer enten lokationen eller gruppen, der flytter mellem lokationerne.

Hvis enheder netop er stationeret på den givne placering, gemmer vi denne placering og antallet af enheder, der er stationeret der. For at gøre det bruger vi units_on_location tabel.

Når enheder ikke er stationeret, bevæger de sig rundt. Vi bliver nødt til at gemme deres afgangssted og deres destination. Derudover skal vi definere mulige handlinger under bevægelser. Alle sådanne handlinger er gemt i movement_type ordbog. type_name attributten er unik, mens allows_wait attribut bestemmer, om en handling tillader at vente på destinationspunktet.

Vi kan flytte en enkelt enhedstype, men i næsten alle tilfælde flytter vi mange enheder af flere forskellige enhedstyper. Denne gruppe deler fælles data, og vi gemmer dem i group_movement bord. I denne tabel definerer vi følgende elementer:

  • den spiller, der påbegyndte handlingen
  • handlingstypen
  • udgangspunktet
  • destinationspunktet
  • arrival_time på destinationen
  • return_time til udgangspunktet
  • wait_time på destinationen

return_time attribut kan være NULL, hvis dette er en envejsrejse, og wait_time er defineret af spilleren. Enheder, der tilhører en gruppe, er defineret af værdier gemt i units_in_group bord. Det fremmede nøglepar units_id og group_moving_id danner bordets unikke nøgle. Antallet af enheder af samme type inden for en gruppe er defineret i number attribut.

Hver bevægelse kan transportere ressourcer fra et sted til et andet. Derfor definerer vi et mange-til-mange forhold mellem group_movement og resources tabeller. Udover de primære og fremmede nøgler, resources_in_group tabel indeholder kun number attribut. Dette felt gemmer mængden af ​​ressourcer, som spillere flytter fra startpunktet til deres destination.

I de fleste tilfælde kan spillere ringe til andre for at deltage i deres eventyr. For at understøtte det bruger vi to tabeller:allied_movement og allied_groups . Én spiller vil indlede fælles handling, og det vil skabe en ny rekord i allied_movement bord. Alle grupper af enheder, der deltager i en allieret handling, er defineret af værdier gemt i allied_groups bord. Hver gruppe kan kun tildeles en allieret handling én gang, så fremmednøgler udgør den unikke nøgle til denne tabel.

Denne model giver os den grundlæggende struktur, der er nødvendig for at bygge et MMO-strategispil. Det indeholder de vigtigste spilfunktioner:placeringer, strukturer, ressourcer, forskning og enheder. Det relaterer dem også, lader os definere forudsætninger i databasen og gemmer også det meste af spillogikken i databasen.

Efter at disse tabeller er udfyldt, er det meste af spillogikken defineret, og vi ville ikke forvente, at der tilføjes nye værdier. Næsten hver tabel har en unik nøgleværdi, enten et funktionsnavn eller et fremmednøglepar. Ændring af enhedernes karakteristika og produktions-/omkostningsformler vil give os mulighed for at ændre spilbalancen i databaselaget.

Hvordan ville du ændre denne model? Hvad kan du lide, og hvad ville du gøre anderledes? Fortæl os i kommentarfeltet!


  1. ændre tabel ændre kolonne i Oracle database

  2. Brug af vinduesfunktioner i en opdateringserklæring

  3. Hvordan kan jeg sætte en database under git (versionskontrol)?

  4. SQL Ydeevne UNION vs. OR