Ich werde mit allen leicht anderer Meinung sein und sagen, dass der relationale Ansatz hier vernünftig ist. Interessant ist hier, dass Elemente mehrere Rollen haben können. Das Hauptproblem wird sein, dass sich die Zuordnung zwischen diesem relationalen Layout und einem OO-Layout im Code nicht "natürlich" anfühlt, aber ich denke, auf der Datenbankseite können mehrere Rollen sauber ausgedrückt werden (ohne seltsame Codierungen oder Redundanz, nur Verknüpfungen). .
Als Erstes müssen Sie entscheiden, wie viele Daten objektspezifisch sind und wie viele von allen Elementen eines bestimmten Typs gemeinsam genutzt werden.
Folgendes würde ich tun, wenn alle Daten artikelspezifisch sind:
// ITEMS table: attributes common to all items
item_id | name | owner | location | sprite_id | ...
1 | Light Saber | 14 (Tchalvek) | 381 (Tchalvek house) | 5663 | ...
// WEAPONS table: attributes for items that are weapons
item_id | damage | damage_type | durability | ...
1 | 5 | sharp | 13 | ...
// LIGHTING table: attributes for items that serve as lights
item_id | radius | brightness | duration | ...
1 | 3 meters | 50 | 8 hours | ...
In diesem Design befindet sich jedes Element in der Elementtabelle, zusammen mit Attributen, die alle (oder die meisten) Elemente haben. Jede zusätzliche Rolle, die ein Gegenstand spielen kann, ist eine separate Tabelle.
Wenn Sie es als Waffe verwenden möchten, schlagen Sie es in der Waffentabelle nach. Wenn es da ist, kann es als Waffe verwendet werden. Wenn es nicht da ist, kann es nicht als Waffe verwendet werden. Die Existenz der Aufzeichnung sagt Ihnen, ob es sich um eine Waffe handelt. Und wenn es da ist, werden alle seine waffenspezifischen Attribute dort gespeichert. Da diese Attribute direkt anstatt in einer codierten Form gespeichert werden, können Sie Abfragen / Filter mit ihnen ausführen. (Für die Metrikseite Ihres Spiels möchten Sie beispielsweise Spieler nach Waffenschadenart aggregieren, und dies können Sie mit einigen Verknüpfungen und einem Gruppentyp nach Schadenstyp tun.)
Ein Gegenstand kann mehrere Rollen haben und in mehr als einer rollenspezifischen Tabelle vorhanden sein (in diesem Beispiel sowohl Waffe als auch Beleuchtung).
Wenn es nur ein Boolescher Wert wie "Ist das haltbar?" Ist, würde ich ihn in die Tabelle "Elemente" einfügen. Es kann sich lohnen, "Ist dies eine Waffe" usw. zwischenzuspeichern, damit Sie die Waffen und andere Rollentabellen nicht nachschlagen müssen. Es fügt jedoch Redundanz hinzu, sodass Sie darauf achten müssen, dass es synchron bleibt.
Die Empfehlung von Ari, eine zusätzliche Tabelle pro Typ zu erstellen, kann auch bei diesem Ansatz verwendet werden, wenn einige Daten nicht pro Element variieren. Wenn beispielsweise der Waffenschaden nicht pro Gegenstand variiert, die Rollen jedoch immer noch pro Gegenstand variieren, können Sie gemeinsam genutzte Waffenattribute in einer Tabelle zusammenfassen:
// WEAPONS table: attributes for items that are weapons
item_id | durability | weapon_type
1 | 13 | light_saber
// WEAPONTYPES table: attributes for classes of weapons
weapon_type_id | damage | damage_type
light_saber | 5 | energy
Ein anderer Ansatz wäre, wenn die Rollen, die von Elementen gespielt werden, nicht nach Element, sondern nur nach Elementtyp variieren. In diesem Fall würden Sie den item_type in die Items-Tabelle einfügen und die Eigenschaften wie "Ist es eine Waffe?" Und "Ist es haltbar?" Und "Ist es ein Licht?" In einer ItemTypes-Tabelle speichern. In diesem Beispiel mache ich auch, dass Artikelnamen nicht pro Artikel variieren:
// ITEMS table: attributes per item
item_id | item_type | owner | location
1 | light_saber | 14 (Tchalvek) | 381 (Tchalvek house)
// ITEMTYPES table: attributes shared by all items of a type
item_type | name | sprite_id | is_holdable | is_weapon | is_light
light_saber | Light Saber | 5663 | true | true | true
// WEAPONTYPES table: attributes for item types that are also weapons
item_type | damage | damage_type
light_saber | 5 | energy
Es ist wahrscheinlich, dass sich Gegenstandstypen und Waffentypen während des Spiels nicht ändern. Sie können diese Tabellen also nur einmal in den Speicher laden und diese Attribute in einer Hash-Tabelle anstatt mit einem Datenbank-Join nachschlagen.