Namensprobleme bei der komponentenbasierten Entity-System-API

7

Meine Engine verwendet intern ein komponentenbasiertes Entitätssystem, und ich möchte es für die Skripterstellung an Lua binden.

Jetzt möchte ich Leute retten, die Skripte für die Schreibarbeit schreiben. In C ++ gehen Sie wie folgt vor, um die Position einer Entität festzulegen:

pEntity->GetComponent< CPoint >()->SetPos( Vector( X, Y ) );

Das heißt, wenn ich es an Lua 1: 1 binden würde, müssten Sie auch:

ent:GetComponent( CP_POINT ):SetPos( 123, 456 )

Aber seien wir ehrlich, möchten Sie so viel eingeben, nur um die Position eines Unternehmens festzulegen?

Ich glaube nicht, deshalb habe ich das Komponentensystem vor Lua "versteckt":

Was Sie jetzt tun, ist

ent:SetPos( 123, 456 )

Das Komponentenmaterial wird intern behandelt. Sie können Lua weiterhin manuell mit ent: AddComponent und ent: RemoveComponent usw. zu Lua hinzufügen und daraus entfernen.

Das scheint auch nicht perfekt zu sein:

  • Das Entity-Metatable wird unübersichtlich, da es alle Funktionen aller Komponenten übernehmen muss

  • Namensprobleme: Auch hier ent:SetJointMotorEnabled()scheint es irgendwie schlecht

Haben Sie Ideen, wie ich ein besseres Benennungsschema für Komponentenfunktionen finden könnte, ohne die Bequemlichkeit der Skripterstellung zu gefährden?

Eine Katze
quelle
Ich glaube nicht, dass Sie eine Option haben. Sie könnten es entweder explizit (Ihr erster Weg) oder implizit (der zweite) tun, aber ich bezweifle, dass Sie einen Mittelpunkt finden werden. Es sei denn, Sie haben eine Art von ent:"Point":SetPos(...)... was fast wieder die erste Methode ist. Verwenden Sie möglicherweise die zweite Methode für allgemeine Komponenten?
Die kommunistische Ente
Ich denke, Sie finden möglicherweise Verwendung auf gamedev.stackexchange.com/questions/12529/… Ich habe versucht, mein System so benutzerfreundlich und kompakt wie möglich zu gestalten :)
The Communist Duck

Antworten:

11

Wir haben eine ähnliche Situation in unserem Projekt und haben das Problem gelöst, indem wir Komponenten (keine Funktionen) in LUA-Metatabellen gespeichert haben. Grundsätzlich sieht Code beim Erstellen einer Entität (oder eines Spielobjekts, wie wir sie nennen) auf der LUA-Seite ungefähr so ​​aus:

function createShip()
    ...

    self.transform = registerToComponent("transform")
    self.sprite = registerToComponent("sprite")

    ...
end

Jetzt können wir einfach verwenden

entity.transform:setPosition(5.2, 4.8)
entity.sprite:setTexture("ship.png")

Position (und Textur) einstellen. Und wir sind total zufrieden damit!

(Und tatsächlich denke ich, dass dies besser ist, als nur Entity: SetPosition und Entity: SetTexture zu haben, da die resultierende Entity-API nur ein großes Durcheinander wäre, wenn Sie viele Komponenten haben.)

user4241
quelle
4

Das grundlegende Problem hierbei ist, dass Sie das Komponentensystem der API ausgesetzt haben. Sie müssen das Zeug hinter Ihrer Schnittstelle kapseln.

DeadMG
quelle
0

Ich habe eine Weile nicht mehr mit Lua gearbeitet, aber konnten Sie nicht zulassen, dass Ihre Komponenten selbst die Entitätsschnittstelle über den Lua-Wrapper ändern (das letzte Mal, als ich Lua in einem Spiel im Jahr 2005 verwendet habe, müssen sich die Wrapper seitdem weiterentwickelt haben)?

Wenn Sie es auf Komponentenebene haben, kann Ihre Positionskomponente eine "SetPos" -Funktion für die Entität registrieren, die die Komponente direkt aufruft, und eine JointMotor-Komponente kann ein Objekt in einer Entität mit der Funktion "SetEnabled" registrieren, auf diese Weise sind es "Daten" gefahren "und unterstützen sowohl ent: SetPos (123, 456) als auch ent: JointMotor: SetEnabled ()?

Solange die Registrierung von Unterobjekten und Funktionen bestätigt, dass kein Namenskonflikt vorliegt, sollten Sie in Ordnung sein.

Emartel
quelle