Skillsystem

  • Hallo zusammen und ein frohes neues Jahr!


    Ich möchte gerne ein Skillsystem in mein Projekt einbauen, soweit habe ich das auch getan in dem ich sozusagen "Skills" mit einem Drag&Drop in Skillslots einfügen kann usw.

    Das funktioniert auch super, aufgebaut ist das ganze über ein Structure System.


    Nun bin ich leider an einem Punkt angekommen wo ich Denkfehler habe/bekomme.


    Hierzu ein Beispiel:


    SpielerLebenspunkteMax: 1000 (basis)


    1.

    Skillname: "Mehr Leben"

    Effekt: + 100 max Lebenspunkte


    2.

    Name: "Lebenskraft"

    Effekt: + 10% max Lebenspunkte


    3.

    Name: "Kriegstreiberei"

    Effekt: +30% Schaden und -20% max Lebenspunkte.



    Das sind 3 Beispiele, um euch besser zu erklären was ich mit Logik Fehler meine.

    Wo und wie genau ich diese Abfragen einfügen soll im MyCharacter ist mir aktuell auch noch etwas unklar, es geht mehr darum zu verhindern sich selber ein Bein zu stellen über das man stolpert, etwa wenn man die Übersicht verliert wo etwas ist.



    Max Leben Spieler ist 1000.

    Füge ich nun Skill, 1, 2, 3 ein ergibt sich folgendes:


    1000 + [1.] 100 = 1100 Lebenspunkte

    1100 + [2.] 10% = 1210 Lebenspunkte

    1210 - [3.] 10% = 1089 Lebenspunkte


    Soweit so gut, leider ist hier schon der erste Fehler zu sehen, da ich alles einfach zusammenrechne und nacheinander aufbaue.



    Würde ich also das ganze rückführen wollen, ergibt sich dieses Problem:

    1089 + [3.] 10% = 1197,9 Lebenspunkte

    1197-9 - [10%] = 1078,11 Lebenspunkte

    1078,11 - [1.] 100 = 978,11 Lebenspunkte


    Das Problem ist ja ganz klar zu sehen das es so nicht funktioniert...



    Wie mache ich das nun richtig?

    SpielerLebenspunkteMax: 1000 als Hauptvariable

    Dazu eine Separate Variable für feste Werte und eine weitere für Prozente?

    z.B.

    Skill 1 + 2 + 3


    Hauptvariable: 1000 Max leben

    +

    Ganzzahlvariable: 0 + 100 Leben

    +

    Prozentzahlvariable: 0% +10% - 10% = 0 %

    = 1100 Lebenspunkte.


    Also für jeden Skill eine zusätzliche externe Variable erstellen und diese dann immer in eine Berechnungsformel einbauen?



    Neben diesen ganzen Zahlen kommen natürlich noch besondere Fähigkeiten hinzu.

    Nachtsicht, Verwandlungsformen usw. also nicht nummerische Skill-Veränderungen.



    Bei meiner Frage geht es mehr darum wie ich das ganze sinnvoll und möglichst einfach einfügen kann, ohne das ich umständlich für alles separat verändern muss (umständlich betrachtet).


    Freue mich auf Antworten von euch!

    • Offizieller Beitrag

    Ja wie Tomarr schon sagte im Prinzip alles in Dezimalzahlen umrechnen. Damit lässt es sich doch sowieso viel Besser rechnen.


    Bei Zeiten ist das auch besser statt in 60min rechnest du in 1,00. Eine dreivirtelstunde ist dann 0,75 oder 10 min sind 0,10.


    Bedenke wenn du in % rechnest, kann es unter umständen zu Rundungsfehlern kommen. Wodurch wenn die Formel nicht sauber ist du niemals mehr 100% haben kannst oder du auf einmal mehr als 100% hast. Deswegen machen saubere Nachkommastellen absolut Sinn.


    Überleg dir eine Formel mit der du die Basis Werte errechnest.

  • Ja wie Tomarr schon sagte im Prinzip alles in Dezimalzahlen umrechnen

    Deine Erklärung ist nicht ganz zu 100 % richtig.


    Wenn du mit Plus und Mius bei Prozent rechnest, kommt es nie hin.


    Nehmen wir die 1000. 10 % von 1000 sind halt 100. Also ergibt 1000 + 10 % = 1100.


    Jetzt gibt es zwei Möglichkeiten. Entweder, wenn du die 10 % wieder abziehen möchtest, dann kannst du auch den Basiswert nehmen, sprich 1000 - 10 %, das ergibt dann halt wieder 100. also musst du dann kommst du wieder bei 1100 auf die 1000.


    Im Kaufmännischen, sprich mit Mehrwertsteuer usw. wäre das aber recht kompliziert. Deswegen nimmst du den Wert deiner Wahre, 19 % Mehrwertsteuer, sprich 1000 × 1,19 = 1190. Wenn du die Mehrwertsteuer nun vom Endpreis wieder rausrechnen willst, teilst du halt die 1190 durch die 1,19. So hast du immer einen sauberen Wert und musst dir nicht immer den Grundwert zwischen merken.


    Alternativ dazu kannst, bzw. musst, du halt die Prozentrechnung immer mit dem Grundwert machen, wenn dieser sich nicht verändern kann. Also immer angewandt auf die 1000.


    Oben scheint es mir so gewesen zu sein, dass erst 1000 + 10 % gerechnet wurde, also 1000 + 100, ergibt 1100. Danach wurde versucht, 1100 - 10 % zu rechnen. Das geht natürlich nicht, denn 10 % von 1100 sind halt 110 und ergibt am Ende 990.

  • Es gibt ja verschiedene Möglichkeiten wie du vorgehen kannst.


    Wenn du einen Basiswert hast, der sich auch ändern kann, dann kannst du die Prozentwerte eben halt wie von mir oben beschrieben berechnen. Wobei nach dem Komma eben halt der Prozentwert steht. Du musst, halt dann nur immer dafür Sorgen, dass der Basiswert immer aktuell gehalten wird, auch im Ergebnis. Wenn der Bonus dann verloren geht, aus welchen Gründen auch immer, Rüstung kaputt, Waffe verloren oder so, dann kommst du von dort aus immer zum aktuellen Basiswert zurück.


    Wenn dein Basiswert nicht flexibel ist, würde ich gar nicht über Prozente gehen, wozu auch? Gib deinen Rüstungen, Waffen oder was auch immer, einfach feste Werte, die hinzuaddiert, bzw. bei Verlust subtrahiert, werden und gut ist. Damit hast du dann am wenigsten Probleme überhaupt. Weil, wenn ich das oben richtig gelesen habe, gehst du eh immer vom Basiswert für die Boni aus. Also zum Beispiel Basiswert 1000, Rüstung 10 %, neuer Wert 1100. Noch ein Amulett dazu, neuer Wert 1100 + 20 % oder so, passiert ja nicht. Du gehst ja immer vom Basiswert aus.


    Deswegen, wenn der Basiswert sich ändern kann, zum Beispiel durch Training, also sich permanent ändern kann, dann Methode 1. Bleibt der Basiswert das gesamte Spiel über konstant, dann den Gegenständen einfach Werte vergeben und gut ist.

  • Hallo


    Du kannst dazu das Gameplay Ability System nutzen. Hier die offiziellen Doks.

    Ein Attribut besteht aus zwei Werten - einem BaseValue und einem CurrentValue. Der BaseValue ist der permanente Wert des Attributs, während der CurrentValue der BaseValue plus temporäre Änderungen durch Skills.


    Der CurrentValue ist also der Basis Wert + Skill, wenn ein Skill hinzukommt oder entfällt wird das dann entsprechend neu berechnet, inkl. Buffs und Debuffs etc. Der Basis Wert bleibt aber gleich.


    Gruss

  • Danke an euch allen, dass sind wichtige Infos!


    Ich frage eben nach weil da so viele Dinge bei mir zusammen kommen.


    Basis Lebenspunkte: 1000

    Attribut Ausdauer, gibt Bonus auf HP.

    Waffen + Rüstungen Boni oder Mali.

    Flüche, Boni oder Mali.

    Talente, Boni oder Mali.

    Krankheiten, Boni oder Mali.

    Feinde, immer Mali.


    usw.


    Das sind eben viele Faktoren und bei meiner alten Berechnung mit einem Wert ergibt das immer Fehler.

    Alles nur über Prozente zu machen ist auch nicht gut, weil es zu einfach und unspektakulär ist.

    Abgesehen davon sind feste Werte (z.B. +100 Lebenspunkte) für weitere prozentuale Bonis viel attraktiver.



    Wie verpacke ich diese ganze Berechnungen?

    Über ein Makro oder lieber ein Component?

  • Spontan würde ich das Ganze in eine Funktion schreiben, die diese Berechnungen anstellt.


    Also rein planmäßig werde ich auch an diesem Punkt landen, nur momentan bin ich dabei Shader/Materialien zu erstellen, und das seit einem halben Jahr. Wird also noch dauern bis ich an dem Punkt bin. Aber in meiner Planungskladde habe ich den Punkt erst einmal als Funktion geplant.


    Als Makro eigentlich weniger, denn die Berechnung brauchst du ja nur an wenigen Punkten in deinem Programm. Entweder jedes Mal, wenn du etwas angreifst, wo dann berechnet wird, wie viel Angriff und TP usw. du inkl. Boni hast.


    Und einmal, wenn du abwehrst, wie viel Def, HP inkl. Boni du hast.


    Also zwei Funktionen durch die du das Ganze laufen lässt, je nach Situation, Angriff oder Abwehr. Spontan, je nachdem was du vorhast, sollte das reichen.


    Aber wegen der Übersicht auf jeden Fall in eine Funktion packen. Die Möglichkeit für Übersicht zu sorgen wird oft viel zu sehr (*räusper* auch von mir) vernachlässigt.

  • Tomarr


    Ich weiss nicht ob eine Function zu unflexibel wäre.

    Das Problem sehe oder hatte ich bei meinen Schusswaffen + Fahrzeugschusswaffen. Da diese getrennte Systeme verwenden aber Waffentechnisch gleich sind, habe ich das über ein Component geregelt, wodurch beide auf das gleiche Grundsystem zugreifen können.


    Sozusagen 2 Basis Funktionen + Munition System aus dem beide Systeme ihre Informationen beziehen.


    Vorher hatte ich das auch als einfache Function gehabt und das ganze geht nur bis zu einem gewissen Grad gut. Wenn es umfangreicher wird, kann schnell die Übersicht verloren gehen.


    Das mit Schaden, Leben und Schutz sind nur die Anfangstalente.

    Es kommen noch weit mehr spezial Talente usw.


    Darum habe ich nachgefragt, weil je mehr andere Systeme man einbaut, um so mehr Dinge muss man beachten ohne das man selber stolpert. Neben dem ganzen Quest System, dafür Talente machen die auf die Quests Auswirkungen haben und das auch bei Spielern die andere Quests haben, obwohl man die gleiche Quest auch ohne Quest erledigen kann.

  • Das ganze System beruht ja eigentlich nur auf zusammenaddieren oder multiplizieren mehrerer Boni. Sprich, du schmeißt alles in die Funktionen, was dir Boni für Angriff, und in eine andere Funktion, was dir Verteidigungsboni gibt. Also ein Array für Angriffsboni, ein Array für Verteidigungsboni, irgendetwas in der Richtung vielleicht.


    Ich weiß ja letztendlich nicht, was alles in deinem Spiel vorkommt und was du bisher umgesetzt hast und wie oder so. Deswegen kann ich dir natürlich nur erstmal sagen wie ich es geplant habe.


    Wenn ich in meinem Spiel so weit bin, kann es natürlich sein, dass ich da auch noch andere Lösungen in Erwägung ziehe, aber erst einmal erscheint mir das die einfachste Lösung zu sein.

  • Das ganze System beruht ja eigentlich nur auf zusammenaddieren oder multiplizieren mehrerer Boni. Sprich, du schmeißt alles in die Funktionen, was dir Boni für Angriff, und in eine andere Funktion, was dir Verteidigungsboni gibt. Also ein Array für Angriffsboni, ein Array für Verteidigungsboni, irgendetwas in der Richtung vielleicht.


    Ich weiß ja letztendlich nicht, was alles in deinem Spiel vorkommt und was du bisher umgesetzt hast und wie oder so. Deswegen kann ich dir natürlich nur erstmal sagen wie ich es geplant habe.


    Wenn ich in meinem Spiel so weit bin, kann es natürlich sein, dass ich da auch noch andere Lösungen in Erwägung ziehe, aber erst einmal erscheint mir das die einfachste Lösung zu sein.

    Genau so geht es mir ja auch, vermutlich geht es allen so hier.

    Der Anfang ist echt am schwersten, wenn es dann mal läuft um so besser.


    Bin mir da auch noch unsicher bezüglich Function oder Component, obwohl beides recht ähnlich ist.

    Der Vorteil am Component ist das es extern abläuft, andererseits mit einer Function hat man gleich alles da, schwierige Entscheidung.


    Was ist mit den anderen hier, wie haben die ihr Skill/Talent System gemacht?

  • Was ist mit den anderen hier, wie haben die ihr Skill/Talent System gemacht?

    Ich habs im letzten Spiel ganz einfach gehalten...
    Alle ausgerüsteten Items wurden in nem "Equipped-Array" abgelegt und immer wenn was neues dazu kam, wurde alles nochmal neu per Loop zusammen gerechnet ^^


    Hätte ich auch bei nem Skill-System so gemacht, ein Loop dauert ja keine Ewigkeit und ist performanter als man denken würde, außerdem wird es ja nur berechnet wenn man was anlegt und nicht ständig, während man nichts tut.

  • Wie gesagt, letztendlich kommt es auf die Komplexität deines Bonisystems an.


    Die Art wie es Butterfly gelöst hat, ist natürlich die einfachste überhaupt. Da hast du dann immer einen endwert, den kannst du dann direkt benutzen. Ich schätze mal, dass er da eine kleine Funktion gebastelt hat, oder auch direkt im Hauptblueprint, wo dann dieser Wert errechnet wird.


    Ich selber bin ja immer ein Freund davon auch kleinere Dinge dieser Art in eine Funktion zu packen, weil wenn man etwas ändern möchte, so im Nachhinein, das ist etwas übersichtlicher. Allgemein versuche ich inzwischen auch etwas "Modularer" zu programmieren.


    Denn, wenn dein Bonisystem vielleicht auch später, etwas komplexer werden soll, zum Beispiel wie bei einem RPG, wo ja Anahnd dr Boni dann Wahrscheinlichkeiten ausgewürfelt werden, dann wird es schnell mal etwas komplexer.


    Ich selber habe es bei mir, wie gesagt, wie folgt geplant. Eine Funktion, der übergibt man das Array, mit dem, was der Charakter gerade anhat, sprich Rüstung, Waffen, Schild oder was auch immer. Ich bin mir noch unsicher, ob ich die Skillboni dann noch in einer Extrafunktion berechnen lasse, aber ich denke ja, bei beiden werden die relevanten Boni dann per Array übergeben und in der Funktion dann halt entsprechend zugeordnet und entsprechend ausgewürfelt auf Erfolg oder Misserfolg.


    Wie dann die Boni verwendet werden, da kann ich dir Raten kauf dir ein Grundregelwerk von einem Pen and Paper Rollenspiel, sehr gut eignet sich da AD&D oder auch Pathfinder oder das schwarze Auge oder so. Da sind die Regeln natürlich sehr gut für den Spieleführer erklärt und viele Rollenspiele benutzen auch diese Regeln, ich glaube am häufigsten ist AD&D, aber das Regelwerk ist schwierig zu bekommen. Aber die Anderen gehen halt auch.


    Und wenn du so ein Regelwerk verstanden hast, dann fällt es dir auch relativ leicht es in der Programmierung umzusetzen. Ich selber benutze zum Beispiel Pathfinder, weil das habe ich bereits. Zwar bin ich mir auch noch nicht ganz sicher, wie genau ich es umsetzen werde, aber so weit bin ich ja auch noch lange nicht. Ich muss erstmal den Rest in den Griff bekommen, bevor ich da jetzt an ein Kampfsystem oder ähnliches zu denken wage.


    Leider versuche ich das Ganze auch schon ein wenig auf UE5 umzusetzen, wenn auch etwas locker, weil ist ja erst EA, deswegen noch nicht ganz produktiv, aber das ist in meinem Fall nicht ganz so schlimm. Schlimm ist nur, ich habe Visual Studio 2022 installiert und mit der UE5 funktioniert das nun bedauerlicherweise noch nicht zusammen, zumindest nicht ohne irgendwelche Tricks, die es wohl gibt, auf die ich aber keine Lust habe. Und einen ziemlichen Teil würde ich dann auch in C++ umsetzen wollen. Wenn das funktionieren würde, dann würde ich gerne versuchen, mit dir zusammen etwas Brauchbares zu erarbeiten, vielleicht auch zusammen hier im Forum, sodass jeder seinen Senf dazugeben kann. Vielleicht kommt dann ja etwas gutes, universell einsetzbares und brauchbares dabei heraus. Wir haben hier ja einige fähige Figuren im Forum.

  • Ich schätze mal, dass er da eine kleine Funktion gebastelt hat, oder auch direkt im Hauptblueprint, wo dann dieser Wert errechnet wird.

    Ja ^^
    Hier eine der ersten Functions überhaupt...

    Oben werden alle Stats zusammengezählt und in nem Array gespeichert.
    Unten in der Function (Function in Function) wird nur noch alles in einer von mir vorgegebenen Reihenfolge angeordnet, braucht wohl kein Screenshot ^^



    Danach wurden wieder alle Stats (in ner weiteren Function) ausgelesen, die im Character selbst ne Funktion hatten:

    Wollte das Ganze irgendwann auch mal automatisieren, hab ich aber nie, wie mir grad auffällt, hehe


    Ich selber bin ja immer ein Freund davon auch kleinere Dinge dieser Art in eine Funktion zu packen, weil wenn man etwas ändern möchte, so im Nachhinein, das ist etwas übersichtlicher.

    Ja, auf jeden Fall sollte man Funktionen verwenden ^^

    Als ich Mitte 2018 mit meinem ersten Projekt angefangen hatte, hab ich alles ins Event-Graph rein gepackt, hier mal ein kleiner Ausschnitt:

    Vieles davon würd ich inzwischen nicht mehr so machen, wobei das so schon übersichtlicher ist, als was ich sonst schon so sah...

    Im neuen Projekt hab ich auch Actor-Components verwendet, was es auch einfacher macht, wenn man so schon viele Funktionen hat.

  • Das sind gute Infos!

    Ich beabsichtige auch dieses Talentsystem für Waffen/Rüstungen zu nehmen, ebenso auch bei den Monstern.

    Nur das mit dem korrekten zusammenrechnen kriege ich noch nicht so ganz hin.

    Dafür funktioniert das optische Einfügen in die Slots perfekt ^^


    Habe das bisher so gemacht.

    2 Arrays, eines als "Angewendet" und das andere als "Verfügbar", nur die im angewendet werden zusammen gezählt, alles andere bleibt zur verfügung.


    Wobei ich mich jetzt frage wie man einen Bool wert addieren kann, klingt komisch aber siehe hier:


    Ich möchte eine Fähigkeit/Talente einbauen die eine Nachtsicht erlaubt.

    Z.B. Fähigkeitname: "Katzenauge"

    Erlaubt es dir in der Nacht zu sehen.


    Andererseits möchte ich auch Fähigkeiten/Talente einbauen die das ganze wieder negieren.

    Z.B. Fähigkeitname: "7. Sinn"

    Du siehst nun Umrisse anderer Lebewesen, dafür kannst du nicht im dunkeln sehen.


    Sozusagen Talente die sich auch gegenseitig aufheben können, am einfachsten wäre ein Bool, aber da gibt es ja nur JA und NEIN.

    Wie rechnet man solche Spezialsachen zusammen?

    Integer wäre auch nichts, da ich alle Fähigkeiten/Talente zusammen rechne.

    Hätte ich also 3 Talente die jeweils +1 Nachtsicht geben und 2 Talente die -1 Nachtsicht geben, würde trotzdem eines über bleiben.


    Wäre nicht mal so doof wie es klingt aber irgendwie auch komisch.

  • Sozusagen Talente die sich auch gegenseitig aufheben können, am einfachsten wäre ein Bool, aber da gibt es ja nur JA und NEIN.

    Wie rechnet man solche Spezialsachen zusammen?

    Mit AND & OR ?
    AND, wenn JA & JA dann = True
    OR, wenn eines von beiden JA dann True.

    Beispiel: es wird abgefragt ob "Nachtsicht" AND "7. Sinn" wenn TRUE dann wird es negiert bzw. dein gewünschter Effekt.

    Also bei boolesche Variablen wüsste ich halt nur dass du "Und", "Oder", "Nicht" -Abfragen machen kannst.

  • Sozusagen Talente die sich auch gegenseitig aufheben können, am einfachsten wäre ein Bool, aber da gibt es ja nur JA und NEIN.

    Wie rechnet man solche Spezialsachen zusammen?

    Integer wäre auch nichts, da ich alle Fähigkeiten/Talente zusammen rechne.

    Hätte ich also 3 Talente die jeweils +1 Nachtsicht geben und 2 Talente die -1 Nachtsicht geben, würde trotzdem eines über bleiben.

    Ich glaube, du gehst das zu kompliziert an. Warum sollte sich jemand das Talent Nachtsicht erarbeiten und dann zwei Talente, die dagegen arbeiten? Im Zweifelsfall musst du eigentlich wirklich nur die Summen der Talente erfassen, und wenn Nachtsicht halt positiv ist, dann hat er Nachtsicht, ist es Null oder negativ, dann halt nicht.


    Wenn ein Talent übrig bleiben muss, also Nachtsicht +1, ein Talent Nachtsicht -1, dann kann er halt beides nicht. Wenn du jetzt Nachtsicht +1 hast und zwei Talente -1, dann bleibt ja automatisch 1 Talentpunkt übrig, der gegen die Nachtsicht arbeitet.


    Ein wenig blöd wird es nur, wenn du zwei unterschiedliche Talente hast, die gegen die Nachtsicht arbeiten, also Nachtsicht +1, 7. Sinn +1, nicht geblendet werden +1. Die beiden letzten Talente arbeiten gegen die Nachtsicht. Dann musst du halt priorisieren welches von beiden übrig bleibt. Und das macht es etwas schwierig. Der eine Spieler findet vielleicht das eine Talent, welches dann noch funktioniert doof, der andere findet das andere doof.


    Was ich dir vielleicht vorschlagen würde ist, dass solche Talente vom Spieler aktiv zeitlich begrenzt ausgelöst werden können. RPGs leben ja von einem gewissen Training und der entsprechenden Wahrscheinlichkeit ob ein Versuch klappt oder nicht. Ich würde da eher in diese Richtung gehen. Nicht, dass der Spieler irgendwie stundenlang spielt, um gewisse Talente zu bekommen und das nächste Talent macht es dann zunichte oder ein Artefakt macht da stundenlanges Training kaputt oder so.

  • muss da Tomarr schon zustimmen.
    Man weiß aber auch nicht genau was du da ja vor hast. Vielleicht ergibt es auch alles Sinn was du da planst und es ist was richtig innovatives. :D

    Aber ich frage mich auch, ist es nicht vielleicht designtechnisch sinnvoller solche Talente von einander Abzuzweigen? Also man muss sich im Talentbaum eins von beiden entscheiden. Wenn du eins wählst wird das andere geblockt. Also möchte der Spieler eher Nachtsicht oder Umrisse von Lebewesen sehen. Letzteres dann wahrscheinlich auch durch Wände? Oder im dunkeln auch nützlich um diese schneller zu entdecken.
    Beide Talente haben also Vorteile. Also warum nicht entscheiden lassen?

    PS. Beim Entscheiden der beiden Talentbeispiele macht es sogar Sinn, da beide was mit der Sicht zu tun haben und diese halt verbessern.

  • Gab von Epic mal das berüchtigte "Gameplay Ability System". Das wurde aber irgendwann sehr komplex und wurde von Epic zwar nicht fallengelassen - aber Epic hat irgendwann durch die Komplexizität des Systems die Lust verloren auf Dokumentation und Beispiele. Das ganze wurde aber von Dritten fortgesetzt - es gibt also eine schier unendlich komplexe Doku und Example Project. Für SIngle Player isses eigentlich schon fast "overkill", aber für ein sehr komplexes MMORPG evtl. interessant...


    https://github.com/tranek/GASDocumentation