The Big Rewrite [The B Files]

21 Mai 2011
Erstellt von xeophin

Das Wichtigste ist gemacht: die Partikel sind nun am richtigen Ort, werden zur richtigen Zeit angezeigt und verhalten sich für jeden Charakter ein bisschen anders. Schliesslich weiss man ja: Partikeleffekte machen 80% des Game-Design-Prozesses aus …

Wenn man den Spass mal beiseite lässt, so kann man zusätzlich bemerken, dass die meisten UI-Elemente inzwischen auch am richtigen Ort sind und das Dialogsystem ebenfalls funktioniert. Wieder.

Moment. Wieso "wieder"?

Weil, was ja irgendwie vorherzusehen war, ich die halbe Prompter-Klasse, die für das Dialogsystem zuständig ist, noch mal neu geschrieben habe. Nicht ganz ohne Grund. Denn ein wichtiger Teil meiner Arbeit diese Woche war, das letzte und endgültige Puzzleteil meines Emotionalen Modelles einzubauen: die Fähigkeit, die Reaktionen eines Spielers zu speichern und später wiederzugeben.

Coping Scheme Record/Replay System

Wie finde ich heraus, wie sich jemand gegenüber anderen verhält? Dies ist die Grundlage dieses Subsystems. Ich habe mich entschieden, zwei Achsen zu verwenden – eine möglicherweise zu vereinfachende Sicht, aber ich denke, dass sich beim Testen schnell herausstellen wird, ob diese beide Angaben genügen.

Die erste Achse ist die Empathie. Ein Agent kann sich eher mit-fühlend oder aber irritiert zeigen (und damit unfähig, die Gefühle des anderen zu verstehen). Die zweite Achse ist der Ton1. Dieser drückt aus, wie aggressiv oder defensiv die Aussage ist. Greift sie jemand anderes an oder ist sie zur Verteidigung da?

Die Aussagen besitzen in den meisten Fällen diese beiden Werte als Meta-Daten. Doch auch die Charaktere sind durch diese Werte beschrieben. Dabei drücken diese die Tendenz aus, dass sie Aussagen in die eine oder andere Richtung machen.

Für die meisten Charaktere sind diese Werte zu Beginn fix vorgegeben. Sobald der Spieler aber als einer dieser Charaktere spielt, beginnen sich diese zu verändern – das Coping Scheme Record System beginnt zu greifen. Je nachdem, welche Aussage die Spielerin oder der Spieler in einem Dialog wählt, gleichen sich seine Werte den Werten der gewählten Aussage an. Die Formel (entwickelt durch Oliver Burkhard und Reto Hobi – Danke an dieser Stelle!) funktioniert dabei so, dass Werte, die dem schon bestehenden Wert ähnlich sind, diesen kaum beeinflussen, aber einen grösseren Einfluss haben, je mehr sie vom schon bestehenden Wert abweichen. Auf dieses Weise sollte sich der Wert nach einiger Zeit dort einpendeln, wo sich der Spieler die meiste Zeit aussagenmässig bewegt.

Wechselt der Spieler den Charakter, kommt nun das Coping Scheme Replay System ins Spiel. Anhand der vorher generierten Werte werden nun im Dialogbaum Aussagen ausgewählt, die ungefähr dem vom Spieler gezeigten Verhalten gleichen sollen. Da die im Charakter gespeicherten Werte aber nur eine Tendenz darstellen sollen, spielen andere Einflüsse eine zusätzliche Rolle.

Im Falle der Empathie wird angenommen, dass die Kontrolle einen grossen Einfluss hat: wer das Gefühl hat, die Situation im Griff zu haben (in Kontrolle zu sein), ist eher bereit, sich auf andere Menschen einzulassen. Wem jedoch droht, die Kontrolle zu entgleiten, wird eher mit Irritation reagieren.

Im Falle des Tonfalls wird dagegen angenommen, dass die Agitation diese beeinflusst. Wer erregt ist, hat eine grössere Wahrscheinlichkeit, andere anzugreifen, als wenn er passiv ist.

Soll aus einer Auswahl von Aussagen mit verschiedenen empathy- und tone-Werten eine gewählt werden, wird deshalb jedes Mal neu ein Wert berechnet, der sich zuerst aus der momentanen Stimmung des Charakters (2 Teile Agitation bzw. Kontrolle und 1 Teil Evaluation) berechnet. Dazu wird der empathy-, bzw. tone-Wert gerechnet, der zusätzlich mit einer Random-Funktion leicht modifiziert wurde. Aus dieser Formel ergibt sich ein Wert zwischen -1 und 1. Dieser wird verwendet, um die konkrete Aussage auszuwählen, wobei jeweils die Aussage genommen wird, die diesem Wert am nächsten ist.

Mit dieser Formel wird sichergestellt, dass die Reaktion der momentanen Stimmung der Figur angemessen ist, trotzdem aber immer in Richtung der empathy- und tone-Werte des Charakters geht.

Natürlich wird auch hier der Test mit Spielerinnen und Spielern zeigen, wie gut dies funktioniert. Balancing ist hier vonnöten – möglicherweise muss man den Einfluss der verschiedenen Faktoren noch besser tarieren, um glaubwürdige Resultate zu erhalten. Zudem hat man glücklicherweise auch die Möglichkeit, dies mit den angebotenen Gesprächsoptionen zu beeinflussen – die natürlich für jeden Charakter individuell sind.

Prompter - Refactored

Die Arbeit mit dem Coping Scheme Record/Replay System ist der eigentliche Grund, weshalb ich den Prompter noch einmal fast zur Hälfte umgeschrieben habe. Um dies zu begründen, muss man aber etwas weiter ausholen.

Als ich mit dem Projekt begonnen habe, bin ich davon ausgegangen, dass ich in einfacher Weise mein schon bestehendes XML-Format für strings nur etwas ausbauen. Tatsächlich war das Format zu Beginn relativ einfach:

<string id="open">
   <text lang="de">Öffnen</text>
   <text lang="en">Open</text>
</string>

Leider blieb es nicht dabei. Ich begann, mehr und mehr Meta-Daten in das Format zu packen - und bin dann schlussendlich so weit gegangen, dass ich schon eine Art Scripting-Sprache daraus gemacht habe:

<string id="f">
        <if property="f1" of="Agent" is="LowerThan" value="1" attributes="memory" />
        <text>Zuviel getrunken gestern?</text>
        <!-- else ... -->
        <go to="h"/>
 
        <topic about="alcohol" enjoyment="-0.3" />
        <emotion tone="-0.5" empathy="-0.5"/>
 
        <option>
            <string id="f1">
                <text>Ich kann mich so schlecht erinnern ... aber ja, kann sein.</text>
                <topic about="alcohol" enjoyment="0.5"/>
            </string>
            <go to="g"/>
        </option>
        <option>
            <string id="f2">
                <text>Das kann nicht sein. Ich trinke doch keinen Alkohol.</text>
                <topic about="alcohol" enjoyment="-0.6"/>
            <emotion tone="-0.4"/>
            </string>
            <go to="g"/>
 
        </option>
    </string>

Es war nicht nur mühsam zum Bearbeiten, es war vor allem auch mühsam, wieder aus dem File herauszulesen. Zudem habe ich mich entschieden, die Struktur möglichst flach zu halten: jede mögliche Aussage des Agenten war auf der obersten Ebene und enthielt die möglichen Antworten des Spielers, von denen aus wieder zu einer dieser Aussagen gesprungen wurde.

Dass ich Probleme hatte, einen sinnvollen Weg zu finden, wie ich aus mehreren möglichen Aussagen eine auszuwählen, bzw. zu bestimmen, dass statt einer Aussage eine andere gezeigt werden soll, zeigt sich auch schon oben. Das <if property="f1" of="Agent" is="LowerThan" value="1" attributes="memory" /> sieht zwar lustig aus, aber war schrecklich zu parsen und noch komplizierter zu schreiben.

Wollte ich nun noch jedes Mal nicht nur eine Aussage haben, sondern aus einer Vielzahl von zwar semantisch gleichbedeutenden, aber emotional unterschiedlichen Aussagen eine auswählen, war das Format endgültig am Ende seiner Möglichkeiten angelangt.

Weshalb ich noch einmal von vorne begonnen habe.

Dieses Mal habe ich mich am XML-Format von FreeMind orientiert, das ich als Dialog-Editor zu verwenden gedenke. FreeMind ist ein Mindmap-Editor und verwendet als Grundeinheit nodes, die in der Folge ineinander verschachtelt sind. Dies hat mir zuerst zwar nicht gefallen, doch nun habe ich es ebenfalls eingeführt. Die Nähe zum FreeMind-Format hat es mir erlaubt, in relativ kurzer Zeit ein XSLT-Script zu schreiben, das mir das FreeMind-Format zu meinem eigenen Format umwandelt – ohne die ganzen Formatierungshinweise, die das FreeMind-Format hat.

Das neue Format sieht nun so aus, dass jede Aussage aus verschiedenen Optionen besteht, mit unterschiedlichen Voraussetzungen und Eigenschaften. Der Prompter ist nun so umgeschrieben, dass er aus diesen Optionen diejenige auswählt, die zum einen am präzisesten ist (d.h. die meisten Voraussetzungen erfüllt), zum anderen den momentanen empathy- und tone-Werten entspricht. Jede dieser Optionen hat dabei wiederum verschiedene Optionen als Antworten, von denen jeweils auch wieder die relevanteste ausgewählt wird.

Dieses Format sieht dann so aus:

<start>
        <id>ID_1339998793</id>
        <options>
            <option>
                <string id="ID_354832853">
                    <text lang="de">... hey?</text>
                </string>
                <options>
                    <option>
                        <action>quit</action>
                        <empathy>-0.8</empathy>
                        <string id="ID_384006764">
                            <text lang="de">... [weggehen]</text>
                        </string>
                        <options/>
                    </option>
                    <option>
                        <tone>-0.1</tone>
                        <string id="ID_5756210">
                            <text lang="de">Hey! Wohnst du hier?</text>
                        </string>
                        <options>
                            <option>
                                <string id="ID_369089435">
                                    <text lang="de">Ja. Ich bin Luna. Ich wohne im 2. Stock rechts.
                                        Zieht ihr heute ein?</text>
                                </string>
                                <options>
                                    <option>
                                        <tone>-0.5</tone>
                                        <empathy>-0.5</empathy>
                                        <string id="ID_1113899255">
                                            <text lang="de">Das geht dich nichts an.</text>
                                        </string>
<!-- etc. -->

Das Format gibt zwar einen langen Bandwurm an ineinanderverschachtelten Tags, aber da ich das File praktisch gänzlich in FreeMind bearbeiten kann, ist dies nicht sonderlich relevant.

Der Prompter selber gibt dabei von Schritt zu Schritt einfach seine Position im XML-File weiter, und hangelt sich so dem Dialog entlang.

Die Tatsache, dass ich die verschiedenen Aussagen mit einer Priorität versehe, resultiert in einem interessanten Nebeneffekt: ich kann die Antworten, die dem Spieler angezeigt werden, ordnen nach dem wie "passend" sie sind – was wiederum den Effekt hat, dass man sich nicht einfach die Bewegungsabläufe merken kann, um immer wieder die selben Resultate zu erhalten, sondern die Texte effektiv lesen muss, da sie immer wieder an einer anderen Position erscheinen können.

Fazit: es mag vielleicht auf den ersten Blick nicht zu klug gewesen sein, ein ganzes, eigentlich schon funktionierendes System auf den Kopf zu stellen und noch einmal neu zu konzipieren. Tatsächlich ging es aber erstaunlich schnell und hat mir erlaubt, mehr Funktionalität einzubauen. Mal abgesehen davon, dass der Code nun um einiges lesbarer ist und – mit dem Wechsel von XmlNode zu XPathNavigator hoffentlich auch noch etwas performanter.


  1. Möglicherweise ist dieser Ausdruck nicht nicht sehr präzise gewählt. Mir fiel jedoch zu der Zeit kein besserer ein, weshalb er geblieben ist. 

Das Wichtigste ist gemacht: die Partikel sind nun am richtigen Ort, werden zur richtigen Zeit angezeigt und verhalten sich für jeden Charakter ein bisschen anders. Schliesslich weiss man ja: Partikeleffekte machen 80% des Game-Design-Prozesses aus …Wenn man den Spass mal beiseite lässt, so kann man zusätzlich bemerken, dass die meisten UI-Elemente inzwischen auch am richtigen Ort sind und das Dialogsystem ebenfalls funktioniert. Wieder.Moment. Wieso "wieder"?Weil, was ja irgendwie vorherzusehen war, ich die halbe `Prompter`-Klasse, die für das Dialogsystem zuständig ist, noch mal neu geschrieben habe. Nicht ganz ohne Grund. Denn ein wichtiger Teil meiner Arbeit diese Woche war, das letzte und endgültige Puzzleteil meines Emotionalen Modelles einzubauen: die Fähigkeit, die Reaktionen eines Spielers zu speichern und später wiederzugeben.## Coping Scheme Record/Replay SystemWie finde ich heraus, wie sich jemand gegenüber anderen verhält? Dies ist die Grundlage dieses Subsystems. Ich habe mich entschieden, zwei Achsen zu verwenden – eine möglicherweise zu vereinfachende Sicht, aber ich denke, dass sich beim Testen schnell herausstellen wird, ob diese beide Angaben genügen.Die erste Achse ist die *Empathie*. Ein Agent kann sich eher mit-fühlend oder aber irritiert zeigen (und damit unfähig, die Gefühle des anderen zu verstehen). Die zweite Achse ist der *Ton*[^tone]. Dieser drückt aus, wie aggressiv oder defensiv die Aussage ist. Greift sie jemand anderes an oder ist sie zur Verteidigung da?[^tone]: Möglicherweise ist dieser Ausdruck nicht nicht sehr präzise gewählt. Mir fiel jedoch zu der Zeit kein besserer ein, weshalb er geblieben ist.Die Aussagen besitzen in den meisten Fällen diese beiden Werte als Meta-Daten.

Kommentar hinzufügen

Der Inhalt dieses Feldes wird nicht öffentlich zugänglich angezeigt. Wenn Sie ein zulässiges Avatar mit Ihrer E-Mail-Adresse verknüpft haben, wird dieses als Avatar verwendet.
By submitting this form, you accept the Mollom privacy policy.


Navigation



Sprachen


Newsfeeds

Inhalt abgleichen