The problem I see with this approach is that the AI module cannot be easily decoupled from the components attached to the entities. To evaluate a tree or run a state machine, it needs to know information from the entity being used so it actually needs to pull information like the inventory, the weapons available, the position, etc from the actual components.
Beobachten Sie jedes Tier: Sein Nervensystem ist auf seine Aufgaben zugeschnitten. Vögel haben ein scharfes Sehvermögen, um nach Nahrung und Bedrohungen zu suchen, und die Fähigkeit, ihre Haltung zu korrigieren und beim Sturz instinktiv Auftrieb zu erlangen. Und ein menschlicher Geist ist dazu verdrahtet, sich der Fähigkeiten seines eigenen Körpers, seines Gesundheitszustands, seines Hungers, seiner Kälte und der Anwesenheit oder Abwesenheit von Gliedmaßen sehr bewusst zu sein. Wenn wir RL als Grundlage für die Objektmodellierung verwenden, ist es kein Fehler, wenn der Verstand / die KI Aspekte wie Ort, Haltung, Gesundheit, gehaltene Gegenstände, Fähigkeiten usw. kennt. Was Sie könnten tun abstrakte Raketenwaffen behandelt werden als generischer Typ. Dies führt zu einer schönen abstrakten KI-Logik wieif holding missile weapon in hand, attempt to fire
. Ein Gehirn in einem Glas, OTOH, ist genau das - vorausgesetzt, es weiß, dass es körperlos ist, weiß es auch, dass der Versuch, aus dem Glas herauszuklettern, vergeblich ist. Das heißt: Lassen Sie AI auf null
Komponenten prüfen und fahren Sie entsprechend fort.
I thought about diverging from the pure ECS pattern of keeping components as data containers only and actually implement those methods in the components themselves so that I can have a base AIControlledComponent
I thought I could refactor the code splitting it up based on the kind of enemy (aka an enemy that has a Weapon won't be able to Charge and vice versa) but then I'd have to have a base AIControlSystem and inherit from that and specialize it based on the components attached to the entities. This would result in pretty much one new system per enemy kind and it doesn't really look like a good solution.
Es ist nicht das entscheidende Problem, sie als reine Datenelemente beizubehalten oder nicht. Aber Ihre Kontrollhierarchie ist, und in dieser Hinsicht wird der "reine" Ansatz oft als "gesunde Praxis" bezeichnet. In Wahrheit macht es kaum einen Unterschied, ob die Logik eingeschaltet ist this
oder auf etwas anderem (wie einem Controller höherer Ebene). Lassen Sie sich von der nicht reinen Methode nur nicht in Spaghetti verwandeln. (Meiner Erfahrung nach hat der reine Ansatz mehr monolithischen Code und macht es schwieriger, Fehler im lokalen Objekt zu machen, die nicht mit globalen Kontrollmechanismen übereinstimmen. Ich finde immer klare Top-Down-Ansätze am besten.)
Einige werden anderer Meinung sein, aber im Allgemeinen ist die gesamte Idee hinter ECS Objektzusammensetzung vs. Vererbung. Ich sage nicht, dass Sie die Vererbung für einige Ihrer Komponententypen nicht verwenden konnten, aber ich würde sie so weit wie möglich vermeiden.
Based on the mental state, this systems adds a set of actions to a queue. Then the queue is being consumed and evaluated. An action like "Attack" is actually calling a method of the system that checks whether the entity has a WeaponComponent attached and fires, or if there's a ChargeComponent it charges at the player.
Ich denke, das ist von zentraler Bedeutung für Ihre Krise. Ihre KI-Geisteskomponente sollte, wenn sie den vollständigen Zustand ihres eigenen Körpers und der relevanten Teile der äußeren Umgebung kennt, niemals "Angriff" in die Warteschlange gestellt haben, es sei denn, die Umstände waren überhaupt ideal. Stellen Sie sich zum Beispiel vor, Sie hätten plötzlich gemerkt, dass Sie doch kein Gewehr in der Hand hatten, sondern ein Stiftmesser. Würden Sie immer noch angreifen und angreifen, besonders wenn der Feind alle mit Waffen bewaffnet wäre? Ich bezweifle das. Es ist taktisch sehr unterschiedlich und in Ihrem aktuellen Code wird diese Unterscheidung von Ihrer KI-Komponente nicht getroffen, bevor die betreffende Aktion in die Warteschlange gestellt wird.
whether the entity has a WeaponComponent attached and fires, or if there's a ChargeComponent it charges at the player
Das ist auch völlig falsch für mich. Warum ist Charge
ein Component
? Sicher ist es nur ein Verb, eine Art von Aktion, die jede KI ausführen kann, selbst wenn sie eine Raketenwaffe in der Hand hat? Sicherlich ist das einzige, was eine Ladung verhindern würde, Geschwindigkeit / Belastung, und dies sollten Faktoren sein, die bei der Entscheidung des KI-Geistes berücksichtigt werden, welche Maßnahmen auf der Grundlage des eigenen physischen Status des Unternehmens zu ergreifen sind. Aber ok.
Die letzten beiden Absätze geben Ihnen einen Überblick über Ihre Probleme: Sie verlassen die entscheidenden KI- Entscheidungen (!) Der ersten Klasse, die vor dem Anstehen getroffen werden, und werden in letzter Minute zu Entscheidungen zweiter Klasse, die in dem Moment getroffen werden, in dem Ihre Entität dies auch tun sollte den Abzug betätigen oder um sein Leben rennen. Klingt für mich nicht sehr entscheidend und ich kann mir vorstellen, was mit echten Soldaten passiert, die auf diese Weise kämpfen. Darüber hinaus bin ich mir nicht einmal sicher, ob die KI überhaupt in Ihre "zweite Vermutungs" -Phase involviert ist oder ob dies nur andere Komponenten sind, die diese endgültigen Entscheidungen darüber treffen, ob sie handeln sollen oder nicht ... wenn letztere müssen Sie dies in einphasige AI-Entscheidungsabwicklung ändern und Aktionen basierend auf Gewissheiten in die Warteschlange stellen.
Schlagen Sie vor, dass Sie Ihre KI-Verarbeitung vollständig konsolidieren, bevor diese Warteschlange beginnt. Die Probleme hier liegen alle in Ihrer KI-Strategie und nicht in Ihrer ECS-Nutzung, soweit ich sehen kann.