Jump to content
Unity Insider Forum
Cxyda83

System Architektur frage :thinking_face:

Recommended Posts

Moin zusammen!

ich arbeite zur zeit an einem recht aufwändigen WiSim game und habe bereits eine recht saubere Architektur implementiert. Im prinzip geht es in die MicroServices Architektur in der sich jeder Service im genau 1 Feature oder 1 "Problem" innerhalb meines games kümmert (Siehe Architektur Diagramm unten). Ich habe also

  • View Layer der Daten mithilfe des DataProviders (readOnly) abfragen und Commands über den MessageHub publishen
  • Services subscriben auf die Commands, führen dann Logik aus und publishen dann Events
  • Jedes Model verwealtet alle DatenObjekte genau eines typs, führt logik aus und schreibt die Daten zurück.

In der aktuellen Implementieren publishen Models auch Events je nach dem ob sie (nach meiner ansicht) atomare Änderungen vornehmen von denen jeder wissen solle wie z.B. das hinzufügen / entfernen / ändern von Items im Inventar.

Jetzt bekomme ich jedoch langsam das Problem das wenn ein Service eine komplexere Operation ausführt, mehrere Events hintereinander gepublished werden und meine Views durcheinander bringt... ein Beispiel:

Der Trading Service kümmert sich darum das Items von NPCs gekauft und verkauft werden können. Für diese Aufgabe braucht er folgende Systeme:

  • Market (read/write), um die aktuellen Preise der Items zu ermitteln und anschließend neue Marktpreise zu berechnen
  • Reputation (read/write), um das Ansehen des jeweiligen Characters herauszubekommen, was dann einfluss auf den Preis hat
  • Inventory (read/write), für menge / verfügbarkeit der Items und änderungen bei erfolgreichem handel
  • ...

Da das Trading System bei erfolgreichem / gescheitertem Handel Änderungen in einigen anderen Systeme vornimmt ist nun meine Frage ob

option 1) : das Trading Model mit den anderen System Models arbeitet um so direkt read / write operationen durchzuführen

option 2) : das TradingModel ausschließlich mit anderen Services kommuniziert um schreib operationen durchzuführen und ausschließlich mit dem DataProvider kommuniziert um Daten anderer Systeme zu lesen

option 3 ) weitere vorschläge ?

Beide optionen haben Vor- und Nachteile vorallem wenn man darüber nachdenkt wer (services oder models) Events nach durchführung einer operation published.

Bei option 2 würden eine ganze menge events gepublished werden z.B.

  • InventoryChangedEvent (NPC Inventory)
  • InventoryChangedEvent (Player Inventory)
  • ReputationChangedEvent (NPC)
  • MoneyChanged (Player Money)
  • MoneyChanged (NPC Money)
  • TradeSuccessfulEvent

Würden die Models untereinander alle nötigen Operationen ausführen könnte am ende nur 1 event gepublished werden (TradeSuccessfulEvent) aber hier besteht das große Risiko das irgendwelche Views / Systeme änderungen nicht mitbekommt da sie nicht einfach nur auf 1 event hören müssen sondern auf ALLE events von Systemen die ein SubSystem ändern.

Aus diesem Grund hätte ich gerne einmal eure Meinung dazu gehört 🙂 Im moment sind bei mir beide optionen am Start aber ich bin jedes mal hin und her gerissen welchen weg ich gehen soll und das würde ich gerne abstellen.

 

Besten dank schon mal im vorraus!

 

untitled(1).jpg

Share this post


Link to post
Share on other sites

Hmm.... niemand ? ^^ Hat keiner eine Meinung dazu ?

Liegt das daran das ich völlig auf dem Holzweg bin oder das Problem völlig over-engineered habe ? 🤔 Ich gebe zu das ist nicht die typische Frage die man hier so findet^^ aber vielleicht will sich ja doch jemand äußern 🙂

 

 

Share this post


Link to post
Share on other sites

Eine Meinung dazu habe ich schon, aber was soll ich sagen.... Ich hatte selber schon mal eine Art Wirtschaftssimulation begonnen und gemerkt dass es gar nicht soo leicht ist, die ganzen Dinge miteinander zu verknüpfen.
Auch ich hatte da mit Events gearbeitet und sie für schlecht befunden! :D

Also an sich ist das mit den Events schon klasse, wenn andere Systeme einfach nur drauf hören sollen. Sobald es aber (wie bei dir) hin und her geht, der Sender also auch ein Empfänger sein kann, wird es kompliziert.

Ich denke, dass es nicht so viel Sinn macht alles in klitzekleine Module aufzuspalten, die dann alle miteinander kommunizieren müssen.
Das hier würde ich anders machen:

Zitat
  • Market (read/write), um die aktuellen Preise der Items zu ermitteln und anschließend neue Marktpreise zu berechnen
  • Reputation (read/write), um das Ansehen des jeweiligen Characters herauszubekommen, was dann einfluss auf den Preis hat
  • Inventory (read/write), für menge / verfügbarkeit der Items und änderungen bei erfolgreichem handel

Der Market muss nicht beschrieben werden. Er ermittelt einfach, anhand der Anzahl der verfügbaren Dinge, einen Preis. Dieser Preis ändert sich nicht sofort bei jeder Transaktion, sondern erst nachdem der Besuch im Markt beendet wurde (oder nach einer gewissen Zeit danach). Also erst danach gibt es ein Event, damit der Market neue Preise generieren kann. Klar, wenn irgendwie neue Ware von woanders her rein kommt, kriegt er auch ein Event.

Die Reputation ist eine Eigenschaft des Players, die sich ja beim Handeln normalerweise nicht verändert. Also muss sie bei Handelsbeginn einmalig abgefragt werden und als Berechnungsgrundlage für die Marktpreise einfließen.

Inventory ist natürlich auf beiden Seiten wichtig. Der Mart hat eins und der Player auch. Bei jedem Kauf bzw. Verkauf ändern sich sofort auf beiden Seiten die Werte. Das Inventory des Players informiert also das Inventory des Marktes und umgekehrt.

Nach verlassen des Shops werden die neuen Daten abgelegt und der Market bekommt ein Event, dass er die Preise neu berechnen kann. Jetzt "könnte" auch ein Event dafür sorgen, dass die Reputation sich verändert.

Also:

Market (readOnly) berechnet nur Preise anhand der Verfügbarkeit und der Reputation. Immer wenn sich das Warenlager verändert (oder zyklisch nach gewisser Zeit), entsteht ein Event, welches zur Neuberechnung der Grundpreise führt. Dieser Grundpreis wird über die Reputation des Players verändert. Markt schaut also in sein Lager und begutachtet sich den Player. ;)
Das macht er aber nur, wenn der Markt betreten wird.

Reputation (read/write) wird vom Market ausgelesen und von anderen Dingen beschrieben. Wobei meiner Meinung nach der Handel nicht dazu gehört. Aber selbst wenn, dann erst nachdem der Markt verlassen wurde.

Inventory (read/write) Liest zu Beginn die Daten aus dem Datenmodul aus. Es wird sofort nach jeder Transaktion verändert. Zum Inventory gehört wahrscheinlich auch das Geld. Ist also eine Ware nicht mehr verfügbar oder reicht das Geld für die gewünschte Transaktion nicht mehr aus, kann nicht gehandelt werden. Ob du jetzt auch noch irgendwelche Dialoge mit dem Händler führst, die einen Handel auch unterbinden könnten, weiss ich ja nicht. Ich gehe mal davon aus, dass das mit gescheitertem Hnadel meinst.
Nach verlassen des Marktes werden die neuen Inventory-Daten dem Datenmodul übergeben.


Fazit:
Hier würde jetzt der Market nur aktiv werden, wenn der Player den Shop betritt. Er bekommt ein Event zur Neuberechnung und diese berechneten Werte können dann angezeigt und genutzt werden. Markt gehört dann wohl in den View Layer (auch wenn er rechnet).
Die Reputation wird nur ausgelesen. Könnte aber nach verlassen des Shops ein Event bekommen um sich zu verändern.
Das Inventory füllt sich beim betreten des Shops mit Daten. Jeder Handel, verändert diese Daten. Beim verlassen des Shops, wird das Datenmodul mit den veränderten Daten beschrieben.

Viele Events würde es also nicht geben. Jedenfalls würden sich die Events nicht gegenseitig behindern.
Wie du das jetzt in dein Blockschaltbild einbaust, musst du selber raus finden. :D

Share this post


Link to post
Share on other sites

Hey Malzbie! Erstmal danke für deine (ausführliche) Antwort und deinen input !  :D

Ja das Pub/Sub pattern (Publisher / Subscriber)macht dinge (erstmal) nicht einfacher zahlt sich aber vorallem in größeren Projekten auf jedenfall aus. Das ist aber auch nicht das Problem das läuft :)

Zum Markt:
Da der markt nicht nur vom Spieler besucht werden kann sondern auch von anderen NPCs die den Preis beeinflussen, ändern sich die Preise auch während des Markt besuchs. Außerdem ist es bei WiSims wie z.B. DIe Patrizier / Port Royale üblich das sich auch die Preise am markt ändern während der spieler Kauft z.B. wenn der Spieler 100 einheiten kauft und nach 50 würde ein gewisses Limit überschrtten werden, sodass nicht alle 100 einheiten gleich viel kosten. Aus diesem Grund kauft und verkauft die Logik am markt immer nur 1 Einheit (und das dann z.b. 100 mal) um jedes mal den marktpreis neu zu ermitteln und anzupassen.... Ja ich weis kompliziert aber ich schätze so läuft das auch bei anderen WiSims ¯\_(ツ)_/¯

Reputation:
Die reputation ändert sich auch während der Spieler Handelt nämlich wenn er dem NPC ein schlechtes angebot unterbreitet, das dann abgelehnt wird, und die reputation geht in den keller. Bei guten / erfolgreichen angeboten steigt sie. Du hast recht das die reputation dann am Spieler hängt (oder hängen sollte) aber ich hätte eigentlich auch gerne das NPCs untereinander eine reputation (Ansehen) haben die dann die Preise und ihr handeln entsprechend beeinflussen.

Inventory:
Auch hier schreibe ich während des Handels die änderungen. Andernfalls würde ich probleme bekommen wenn es z.B. nur 100 Wolle am markt gibt und ein anderer NPC / Spieler kauft 50 Wolle Währen der Spieler gerade z.B. 100 wolle kauft möchte.

Ich werde nochmal gründlich über deine Anmerkungen nachdenken aber ich denke in dem von mir visionierten Spiel mit NPCs (Bots) und eventuell multiplayer komme um eine Architektur dieser art nicht herum.

Ich schätze auch eher das meine Views das problem sind das manchmal probleme mit den events bekommen, da sie ab und zu mehr UIs updaten und nicht nur die UI elemente die sie selbst verwalten

 

P.S. Link zum aktuellen Trading Prototypen um selbst mal zu testen und besser einzuschätzen um was es grade geht :)

Viel Spaß
http://polybeast.de/UnityProjects/MVPs/MedievalLife/Trade/index.html

Share this post


Link to post
Share on other sites

Ja, das ist natürlich eine ganz andere Hausnummer!
Jetzt verstehe ich, was du da so machst. Trotzdem ist es nicht realistisch, dass sich der Preis eines Produktes wärend deines Marktbesuchs ändert. Schon gar nicht im Mittelalter! Wir sind ja schließlich nicht ander Börse mit Computerhandel. ;)
Aber selbst wenn sich der Preis ändern sollte, so kann es erst nach einem Handel sein. Also der Preis, den du vor einen Kauf siehst, bleibt solange bestehen, bis du eine gewisse Menge gekauft hast. Nach dem Handel, egal ob erfolgreich oder nicht, könnte er neu berechnet werden.
Genauso darf es nicht sein, dass in dem Markt, wo du gerade bist, ein NPC wärend deines Handels den Preis oder die Verfügbarkeit des Produktes ändern kann. Du bis schließlich an der Reihe und nicht der NPC.

Somit gibt es immer nur Änderungen nach einem Handel. Das betrifft die Reputation, den Preis und die Verfügbarkeit. Dass sich das Inventory des Players zur selben Zeit ändern kann, ist eh klar.
NPC's sollten, meiner Meinung nach, wärend eines Handels in diesem Shop keinen Einfluss haben.

Also:
Sobald du dem Markt besuchst, setzen die NPC's erst einmal aus. Du siehst die Güter und deren Preise. Jetzt kannst du Güter in gewünschter Anzahl in deinen Warenkorb legen und versuchen einen guten Preis auszuhandeln. Egal ob es klappt oder nicht. Nach der Aktion werden die Shopdaten aktualisiert. Das bedeutet, jetzt könnten auch einmal alle NPC einen Handel ausführen. Also alle NPC, die auch am Tresen stehen und gewartet haben, handeln jetzt nacheinander (das alles passiert natürlich in einem Frame). Danach bist du wieder an der Reihe.
Du siehst jetzt dadurch evtl. andere Güter und/oder andere Preise, weil sich das Lager verändert hat. Jetzt könntest du wieder handeln.
Verlässt du den Shop, können die NPC machen was sie wollen.

Es gibt also ein Event vor jedem Handel, welches den Shop aktualisiert indem er seine Datenbanken abfragt und dir die Veränderung anzeigt.
Nach einem Handel gibt es 2 weitere Events. Eines für die Inventorys und eines für die Reputation.

Und so müsste es dann auch für jeden NPC sein. (1) Shop wird aktualisiert, Handel wird getätigt, (2)Inventorys werden verändert und (3)Reputationen werden angepasst.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...

×
×
  • Create New...