Vom Piraten beschimpft (Tag zwei meines RPGMaker Experiments)
Jetzt wird es Zeit für ein erstes echtes Experiment. Ich bitte ChatGPT um ein Plugin mit diesen Kommandos:
-
SetNPCDescription: ein Kommando, mit dem man in einem Event beschreiben kann, was der jeweilige NPC ist, wie er heißt, was seine Ziele sind, was sein Character ist. Wichtig, damit das LLM ihn mit Leben füllen kann und er sich plausibel verhält.
-
DecideAndAct: ruft das LLM auf. Ich verwende "Mistral Large", was zwar nicht auf dem Level der amerikanischen Top-Modelle performt, aber schnell ist, ein guter Kompromiss zwischen Performance und Antwortzeit.
Diesmal verhaut sich ChatGPT ein wenig - nach ein wenig Herumprobieren (wie kriege ich in einem RPGMaker Spiel einen Debugger? Kann die LLM bitte was in die Konsole loggen?) findet die AI heraus, dass die Antwort von Mistral ein wenig anders ist als erwartet. Danach funktioniert's - ich habe parallel zum Spieler agierende NPCs, die sich bewegen, reden und Gegenstände, die sie haben, dem Spieler geben können.
Dann beginnt das große Testen. Das große, trickreiche Testen.
Als Test habe ich ein erstes richtiges RPGMaker-Ereignis geschrieben: der NPC Rudolf ist ein böser Pirat. Ich habe noch keine Ahnung, wie der Spieler mit einem LLM NPC interagieren soll. Drum hat Rudolf den Plan, sich dem Spieler zu nähern und ihn, sobald er direkt bei ihm steht, auf Piratenart zu beschimpfen.

Das Problem der Koordinaten
Das Koordinatensystem von RPGMaker ist wie ein Bildschirm, dh wächst nach unten. Das war den LLMs erstaunlich mühselig beizubringen. Dauernd wollte sich der Pirat, der oben rechts von mir stand, mir nähern, indem er sich nach oben bewegte, bis er am Bildschirmrand ankam.
Drei Promptverbesserungen. Keine Lösung. Schließlich ChatGPT gebeten, einen Prompt zu schreiben. Heraus kam dieser Molloch:
COORDINATE SYSTEM AND MOVEMENT POLICY (STRICT):
- Origin is top-left. x increases to the right. y increases downward.
- Let dx = player.x - npc.x; dy = player.y - npc.y.
- Choose axis that most reduces distance: if |dy| >= |dx| choose vertical, else horizontal.
- Direction: - If vertical: direction = \"down\" if dy > 0 else \"up\".
- If horizontal: direction = \"right\" if dx > 0 else \"left\".
- Hard constraint: After applying the move, Manhattan distance must strictly decrease.
- Never pick \"down\" when dy < 0. Never pick \"up\" when dy > 0.
- Never pick \"right\" when dx < 0. Never pick \"left\" when dx > 0.
- If the chosen axis would not reduce distance, pick the other axis if it reduces distance; otherwise return a \"wait\" action (ms=800).
- Do not reason with compass directions; follow the numeric rule exactly.
Das funktioniert für meinen Piraten, aber ich vermute, es ist zu stark auf "nähere dich dem Spieler" zugeschnitten. Nun ja, für's Erste reicht es. Der finstre Pirat läuft auf mich zu.
Fast.
Das Problem der Parallelität im RPGMaker
Tatsächlich läuft er jetzt auf mich zu und vorbei, und umkreist mich.
Es hat einige Zeit gedauert, bis ich verstanden habe, was hier los ist. Ich lasse das LLM-Ereignis im Modus "Parallel" laufen. Ich hatte vermutet, in diesem Modus läuft ein Ereignis nebenläufig, und wenn es fertig ist, wird ein neues erzeugt. Tatsächlich werden aber jedes feste Zeitintervall solche Ereignisse erzeugt. Folgendes ist passiert dann z.B.
1. Ereignis wird erzeugt, merkt, ich bin diagonal rechts unter ihm.
2. Ereignis denkt (dh. Das Ereignis hat dem LLM die Situation übermittelt und wartet auf Antwort)
3. Zweites Ereignis wird erzeugt, merkt, ich bin diagonal rechts unter ihm.
4. Ereignis 2 denkt
5. Ereignis 1 ist fertig, erkennt "ich will zunächst nach oben gehen, um neben dem Spieler zu stehen"
6. Ereignis 1 geht nach oben.
7. Ereignis 2 ist fertig, erkennt "ich will zunächst nach oben gehen, um neben dem Spieler zu stehen"
8. Ereignis 2 geht nach oben.
9. Ereignis wird erzeugt, merkt, ich bin diagonal rechts über ihm.
Viele der NPC-Ereignisse basieren also auf einer veralteten Situation und führen zu falschen Entscheidungen.
ChatGPT hat mir dann ein Lock-Verhalten eingebaut, das parallele Ausführung verhindert. Alternativ könnte man ausprobieren, ob "Autostart" und eine kompliziertere Ereignislogik im RPGMaker besser wäre.
Danach läuft's super. Der Pirat geht schnurstracks auf mich zu und überschüttet mich mit piratigem Geschimpfe. Juhu.
