Attribute für ein Rollenspiel speichern: Wie am Besten?

Hallo liebe Community,

nach langer Abstinenz melde ich mich auch mal wieder zu Wort.

Und zwar geht es um Folgendes:
Ein Kumpel und ich arbeiten zur Zeit an seinem Browsergame, und wir sind dort auf ein Problem gestoßen. Bevor ich aber zu meiner Frage komme, muss ich wohl kurz erklären worum es geht. :D

Und zwar wird es ein Rollenspiel im Stil von DSA, also man erstellt sich einen Charakter mit verschiedenen Attributen, wie z.B. Stärke, Willenskraft, ...
Von diesen Hauptattributen werden jedoch weitere Attribute abgeleitet Initiative, Lebenspunkte, ...

Wir fragen uns schon seit einigen Tagen, wie wir das datebank-seitig realisieren könnten.

Sollen wir nur die Grundattribute speichern und alle abgeleiteten Werte on-the-fly berechnen? Wie speichert man in so einem Falle die Werte die sich ständig gegen den Maximalwert ändern, z.B. die Lebenspunkte?

Erschwerend kommt noch hinzu, dass verschiedene Faktoren die Werte modifizieren, wie z.B. Wunden oder Zauber oder ähnliches.

Wir sind gerade echt ziemlich ratlos.

Ich dachte mir wir speichern die Grundattribute in einer Tabelle und in einer anderen Tabelle die Modifkationen der Werte so nach dem Prinzip: WertID - Modifikation - Priorität - Dauer

Bei der Attributsabfrage wird dann mit getAttributeValue() das Grundattribut und die Modifikationen abgefragt und berechnet. Wäre das praktikabel?

Ich bin für Vorschläge und Kritik jederzeit offen. :)

P.S.: Entschuldigt bitte, aber mir ist kein treffender Titel für den Thread eingefallen. :(
 
Zuletzt bearbeitet:
Hi,
also ich würde es wahrscheinlich so machen, dass die Grundattribute in der Datenbank abgespeichert werden und die anderen (abgeleiteten) Werte/Attribute dann on-the-fly berechnet werden. Da das nicht so viel Aufwand ist diese zu berechnen, als ständig eine neue DB-Abfrage zu machen. Das würde meiner Meinung nach sonst nur zu viel Performance kosten.

Gruß

Fabio
 
Hi,
also ich würde es wahrscheinlich so machen, dass die Grundattribute in der Datenbank abgespeichert werden und die anderen (abgeleiteten) Werte/Attribute dann on-the-fly berechnet werden. Da das nicht so viel Aufwand ist diese zu berechnen, als ständig eine neue DB-Abfrage zu machen.

Das Problem ist, dass halt auch die abgeleiteten Werte modifiziert werden können, also selbst wenn ich sie on-the-fly berechne müsste ich Abfragen ob irgendwelche Modifikationen in der Datenbank stehen.
 
Kommt drauf an, von welchen Modifizierungen wir hier reden. Sind es dauerhafte Modifizierungen oder sind es temporäre? Wenn sie dauerhaft sind, macht es natürlich schon Sinn, sie mit in der DB abzuspeichern.
 
Es wird verschiedene Modifikatoren geben.
Bedingt durch angelegte Ausrüstung (gelten so lang man die Ausrüstung trägt),
durch Zauber die eine gewisse Zeit laufen (Ticks!) beispielsweise.

Das ich z.B. nicht die Änderungen der Initiative im Kampf speichern muss, die nach dem Kampf eh wieder auf den Grundwert (abgeleitet von den Attributen) gesetzt wird, ist mir klar. :)

Ich denke an Folgendes:
Jedes Attribut erhält eine ID => Mut ID 0, Stärke ID 1, usw.

Wir machen eine Tabelle in der wir folgendes speichern:
CharakterID - Die ID des entsprechenden Charakters
AttributID - Die ID des entsprechenden Charakters
AttributModifikation - z.b. +2 oder -20% oder was auch immer.
ModifikationDauer - z.B. die Tickanzahl, oder "ausgerüstet" oder "aura" oder was auch immer
ModifikationPriorität - Eine Zahl die festlegt, in welcher Reihenfolge abgerechnet wird, falls für ein Attribut mehrere Modifikatoren gelten.

PHP-seitig sähe es dann so aus:
charakter->getAttribute(charakterid, attributeArray()

es werden die grundattribute abgefragt,
davon werden die anderen attribute abgeleitet (ganz simple Mathematik)
danach werden alle modifikatoren aus der DB ausgelesen und angerechnet

die methode liefert das array zurück mit den angeforderten attributen


Wäre das praktikabel? Lohnt sich da eventuell Caching? => Wenn ein Modifikator dazu kommt, oder geändert wird, wird gespeichert in wieviel Ticks sich das nächste mal die Werte ändern. (Wenn beispielsweise die kleinste Tickdauer 5 beträgt, braucht auch erst in 5 Ticks neu berechnet werden.) Sollten in der Zwischenzeit Attribute abgefragt werden, werden sie aus dem Cache (andere sql-tabelle?) geladen.
 
Also ich würde das dann doch eher so machen (wenn du das nicht schon meinst), dass ich in der DB die Grundattribute (z.B.: Stärke, Willenskraft, etc.) in der Tabelle Character abspeichere. Zudem kommt zu dieser Tabelle noch eine Untertabelle mit der Ausrüstung (z.B.: Hut, Gewand, Schuhe, Waffe, etc.). Die Ausrüstungsgegenstände musst du dann natürlich noch in einer anderen Tabelle mit ihren Eigenschaften (welche fest sind z.B.: Verteidigung, Bonis, etc.) abspeichern, sodass du in der Untertabelle von der Character-Tabelle nur eine Referenzid speichern musst. Wenn du dann eine Abfrage machst zu der Ausrüstung, bekommst du gleich alle relevanten Daten.

Hier mal als Beispiel, wie ich mir das momentan vorstelle:
Code:
+ Character
   ID
   Stärke
   Willenskraft
   ...
   + Ausrüstung
      HelmID
      RüstungID
      SchuheID
      HandschuheID
      WaffeID
      SchildID

+ Objekte
   Schild1
   Schild2
   Rüstung1
   Rüstung2
   ...

So kannst du die Modifizierungen zum Teil Clientseitig berechnen lassen und auf der DB speichern. Weil du die Modifizierung von z.B. einem Ausrüstungsgegenstand in der Tabelle für diesen Gegenstand abspeichern und abfragen kannst.

Ich hoffe ich konnte dir damit weiterhelfen und es war nicht all zu verwirrend. :)
 
Mich würde noch der Punkt Player-vs-Player interessieren ...
Nehmen wir mal an du geräts in einen Kampf ... und innerhalb dieses Kampfes wird für den Gegner ein anderen on-the-fly - Wert berechnet als für dich. Daher wäre es alleine auch schon des PvP wegen sinnvoller komplett alles in der Datenbank zu speichern und die Berechnung nicht etwa Zeitgesteuert zu machen sondern bei jedem Zugriff auf diese Daten.
Du wirst jetzt denken : das kostet doch Performance ...
Nun ... teilweise ... denn der Vorteil den du bekommst wenn du alles in der Datenbank speicherst ist einfach der das du dann innerhalb der Abfrage mit den Werten rechnen kannst und als Result nur noch die fertigen Ergebnisse bekommst die du dann nur noch anzeigen musst ...
 
Ich hoffe ich konnte dir damit weiterhelfen und es war nicht all zu verwirrend. :)

Ja konntest du, was hälst du denn trotzdem von der Idee mit dem Caching?
Meinst du, das ist eine gute Idee?

Da es tickbasiert ist, kann es eigentlich nicht sein, dass ein Spieler während eines Kampfes andere Werte bekommt.

Denn, entgegen dem Realismus muss man an die Spieler denken: Das Ergebnis eines Kampfes wird sofort berechnet.

Ich fände längere Kämpfe zwar auch super, aber man stelle sich vor, jemand plant in der Mittagspause XYZ im Spiel zu machen und kann nicht weil er einen Tick vor der Pause angegriffen wurde und jetzt mittem im Kampf ist.
 
Was genau willst du denn cachen? Die ausgerechneten Modifikationen? Wenn ja, dann würde ich auch schauen welche sich am häufigsten verändern und diese on-the-fly zu berechnen und alles andere zu cachen.

Was darf man denn unter einem Tick verstehen? Welche Zeitabstände hast du, um die Spielstände zu aktualisieren?
 
Ich dachte das mit dem Caching so:

Wenn Charakterdaten abgefragt werden, werden die Grundattribute aus der DB gelesen, dann die anderen Werte abgeleitet, und zuletzt werden diese Werte (mit den Modifikatoren aus der DB) verrechnet.
Da ja jeder Modifikator eine Dauer hat, z.B. 6 Ticks, könnte man den niedrigsten dieser Werte speichern.
(denn vorher ändern sich ja keine Werte mehr, ausser es kommt ein neuer Modifkator dazu)
Dann könnte man die berechneten Charakterwerte speichern.
Bei einer Attributsabfrage muss dann nur überprüft werden ob diese "6 Ticks" bereits abgelaufen sind und wenn nicht dann können die Daten aus dem Cache geholt werden, ansonsten wird neu berechnet und gecachet.


Ticks dachten wir so je 15 Minuten.
 
Zurück