Ich entwickle ein Rollenspiel und bin an dem Punkt angelangt, an dem ich mit dem Aufbau einer feindlichen Datenbank beginnen muss. Damit sind einige Herausforderungen verbunden und einige Lösungen, über die ich nachgedacht habe.
Folgendes muss ich in meiner feindlichen Datenbank tun:
Ich habe zwei primäre Feindklassen, über die ich Daten darstellen muss:
Eine Basis-Feindklasse, die Folgendes umfasst:
Base Stats
Status Resistance Table
Elemental Resistance Table
Steal Table
Drop Table
Level
Unique ID
Base XP
AI Hook
Name
Display Name
Und eine abgeleitete Klasse, die die Möglichkeit zum Hinzufügen von Ausrüstung hinzufügt und die folgenden Felder hinzufügt:
Main Weapon
Secondary Weapon/Equipment
Armor
Accessories
Ich kann in Zukunft weitere Felder oder zusätzliche Klassen hinzufügen, wenn dies sinnvoll ist. Ich habe zwei mögliche Formate für Datenbank-Feinde in Betracht gezogen.
XML-Dateien
Ich würde es im Grunde so machen:
<?xml version="1.0" encoding="utf-8"?>
<Enemies>
<Enemy name="Red Dragon" type="BaseEnemy" level="56" displayname="Red Dragon">
<Stats HP="55000" MP="2500" SP="2500" Strength="212" Vitality="125" Magic="200" Spirit="162" Skill="111" Speed="109" Evasion="100" MgEvasion="100" Accuracy="100" Luck="55"/>
<StatusResistances>
<Resistance name="Sleep" value="100" />
<Resistance name="Stop" value="100" />
</StatusResistances>
<ElementResistances>
<Resistance name="Fire" value="75" />
</ElementResistances>
<LootTable>
<Item name="Elixir" rate="0.03" count="1"/>
</LootTable>
<DropTable>
<Item name="Elixir" rate="0.03" count="1"/>
</DropTable>
<AIScript value="BasicBehaviour.py" />
<BaseXP value="4800"/>
</Enemy>
<Enemy name="Gaverick 1" type="HumanoidEnemy" level="33" displayname="Gaverick">
<!--Same Stuff as above here-->
<Equipment>
<Weapon name="Dark Eclipse"/>
<Armor name="Terra Defense"/>
<Accessory name="Ribbon"/>
</Equipment>
</Enemy>
</Enemies>
Vorteile:
- Einfach zu erweitern, wenn ich Parameter hinzufügen / neu anordnen muss
- einfach Standardwerte zuzuweisen
- Ich habe bereits einen XML-Parser (pugixml) für Konfigurationsdateien, gekachelte Karten und das Laden von Ressourcenbeschreibungen
Nachteile:
- möglicherweise langsam (meine Datenbank wird wahrscheinlich mehrere hundert Feinde treffen)
- kann nicht nach beliebigen Feinden abfragen, muss also wahrscheinlich alle Feinde im Speicher behalten.
- Dies würde bedeuten, dass ich das Spiel neu starten muss, um auch geänderte feindliche Daten zu laden
SQLite
Dazu würde ich im Grunde eine Tabelle mit Spalten erstellen, die alle benötigten Daten darstellen, und die unnötigen Felder leer lassen
Vorteile
- Durch willkürliches Abfragen können unnötige feindliche Daten nicht mehr gespeichert werden
- Fühlt sich strukturierter an
- Kleinere Dateigröße
Nachteile
- Schwieriger, Parameterreihenfolgen zu erweitern / neu anzuordnen
- Unnötiger Aufwand für nicht verwendete Felder
- Muss einen Datenbankschnittstellen-Wrapper für SQLite schreiben
Vor diesem Hintergrund war ich neugierig darauf, Erfahrungen von außen darüber zu sammeln, was andere Leute getan haben. Ich denke vielleicht völlig falsch darüber nach, und wenn ja, schlagen Sie bitte eine Alternative zu den beiden Möglichkeiten vor, die ich hier habe.
Darüber hinaus sind Vorschläge zur Verbesserung einer dieser Möglichkeiten willkommen. Wirklich, ich möchte nur wissen, ob ich auf dem richtigen Weg bin.
Ich bin offen für die Nutzung jeder kostenlosen Bibliothek und baue bereits Boost ein
quelle
Ich bin nicht davon überzeugt, dass Sie dafür zwei Klassen benötigen. ein einziger sollte ausreichen. Sie können dies genauso gut mit Komposition und nicht mit Vererbung modellieren . Moderne Software-Design-Techniken tendieren weg von tiefen Klassenhierarchien, weil sie dazu neigen, spröde und schwer zu pflegen zu sein. Ihre vorgeschlagene Hierarchie ist zwar nicht sehr tief, aber unnötig (was ein erster Schritt in Richtung "tief" ist). Ihre abgeleitete Klasse fügt nur Eigenschaften hinzu, die genauso gut in der Basisklasse verbleiben können, aber leer bleiben.
Auf diese Weise können Sie nicht nur das Verhalten und die Eigenschaften Ihrer einzelnen Feinde später besser iterieren und optimieren, sondern Ihren Code auch einfacher gestalten, da Sie nur mit einer einzigen öffentlichen API und deren Verarbeitung arbeiten.
Von diesen beiden würde ich XML wählen. Im Allgemeinen sollten Sie sich JSON ansehen . Ich denke nicht, dass die Verwendung einer tatsächlichen relationalen Datenbank hier gerechtfertigt ist. In dieser Frage finden Sie eine Diskussion darüber, warum: Die Kurzversion ist komplex und weniger direkt zugänglich oder bearbeitbar. Da Sie keinen der Vorteile benötigen, die eine relationale Datenbank bietet, sollten Sie sich besser an etwas Ähnliches halten.
Sowohl XML als auch JSON haben den großen Vorteil, dass sie trivial von Menschen gelesen und bearbeitet werden können, ohne dass spezielle Tools erforderlich sind, die Ihre Iterationszeiten erheblich verlängern können. Mit XML können Sie XSLT verwenden , um Ihre Daten in großen Mengen zu transformieren, falls Sie das Schema jemals drastisch ändern oder eine andere Art der Migration in großem Maßstab durchführen müssen.
Speziell für Ihre drei "Vorteile" für SQLite:
quelle
Hier ist eine andere Möglichkeit, es zu betrachten, eine Datenstruktur zu erstellen, sie mit Ihren Monsterwerten zu füllen, dann die Datenstruktur in einer Binärdatei zu speichern und diese in eine Pak-Datei zu legen, wie:
Laden Sie dann das Paket in den Speicher, analysieren Sie die npcdat-Dateien und analysieren Sie auf Anfrage die darin enthaltenen Daten. Es ist schneller als XML und SQLLite und nimmt viel weniger Platz ein.
quelle
Der einzige Vorteil von SQLite, den ich mir vorstellen kann, ist die Reduzierung von Duplikaten, dh wenn Sie in den Vorteilsbereich "Fühlt sich strukturierter an" fallen.
Sie können XML jedoch mit XPath abfragen, wenn Sie dies wünschen. Aber ich denke, für Hunderte (und sogar Tausende) ist das Speichern aller Daten im Speicher nicht kritisch. Bei dieser Datenmenge ist die Größe der Datenbank- oder XML-Datei nicht kritisch.
Ich stimme für XML.
quelle