Mal wieder KI's

Fragen zum Szenarienbau und Mapdesign

Moderatoren: Henning, Björn_Jernside

Stimmt, Entdecker, den Befehl hab ich übersehen - man lernt doch nie aus...
Allerdings hat das Ganze noch einen anderen Haken, der sich mit ziemlicher Sicherheit nicht beheben lässt. Das Triggersystem erkennt ein KI-Signal ein Mal und diese Erkennung lässt sich nicht mehr aus dem Speicher löschen. Das gleiche Problem also an anderer Stelle!

Du siehst, mein lieber Henning, es ist nicht so einfach...

---

Eine Möglichkeit, die bestimmt hinhaut, aber sehr kompliziert ist, wäre es, eben über Tribute zu laufen. Folgendermaßen:

(defrule
(taunt-detected 1 001)
=>
(tribute-to-player 3 gold 1)
(acknowledge-taunt 1 001)
)

(defrule
(taunt-detected 1 002)
=>
(tribute-to-player 3 wood 1)
(acknowledge-taunt 1 002)
)


Was tut die KI?
Jedes Mal, wenn sie "001" hört, gibt sie Spieler 3 eine Einheit Gold. Jedes Mal, wenn sie "002" hört, gibt sie Spieler 3 eine Einheit Holz.
Spieler 2 besitzt mindestens je eine Einheit Holz und Gold.

Im Editor gibt es dann folgende Schalter:

Schalter 0 - kein Trigger - ein
Bedingung: irgendwas
Effekt: Schalter 1 aktivieren

Schalter 1 - Trigger - aus
Bedingung: Zeitgeber 10
Effekt: Objekt zuweisen (Karren, Einheit)

Schalter 2 - kein Trigger - ein
Bedingung: Eigenschaften ansammeln Spieler 3 1 Gold
Effekt: Objekt anhalten (Karren)
Effekt: Schalter 1 deaktivieren
Effekt: Tribut entrichten Spieler 3 an Spieler 2 1 Gold
Effekt: Schalter 3 aktivieren

Schalter 3 - kein Trigger - aus
Bedingung: Eigenschaften ansammeln Spieler 3 1 Holz
Effekt: Schalter 1 aktivieren
Effekt: Tribut entrichten Spieler 3 an Spieler 2 1 Holz
Effekt: Schalter 2 aktivieren


Vorraussetzungen, dass das hinhaut, sind:
Spieler 3 baut kein Gold und kein Holz ab.
Spieler 2 und Spieler 3 besitzen einen Marktplatz.

---

Zuletzt noch eine Frage:

Muss das Ganze über KI laufen?
Wesentlich einfacher wäre die Variante, dass man zum Stoppen/Bewegen des Karrens z.B. einfach auf den Karren klickt. Das Schema wäre das selbe wie oben, nur eben mit einmal weniger um die Ecke! ;)
Ohne KI ist das ganze doch wesentlich einfacher... Durch das klicken auf den Karren wird der zuweisen Trigger deaktiviert, durch erneutes klicken aktiviert... oder anstatt karren durch ein Gebäude oder so. Zur Sicherheit, dass der Karren dann nicht wegläuft, kann man dann noch einen "leeren" Zuweisen-Trigger machen.

Oder meintest du das schon so, Andi?
Genau das meinte ich mit meiner Schlussbemerkung, ja.

Der "leere Zuweisen-Trigger" oder auch ein getriggertes Anhalten wäre dann natürlich noch ein feines Sahnehäubchen! ;)
@Andi W.: Funktioniert prima! Vielen Dank! :super:
Freut mich! :)

Ich nehme an, du hast die KI-Variante gewählt?
Ja, die mit den Tributen. Trotzdem ist da noch ein kleiner Haken. Der Spieler gibt jetzt also "001" bzw. "002" ein. Das entspricht als Taunt "Ja" und "Nein". Das nervt natürlich tierisch und passt ja gar nicht zum Spiel. Ich wollte das dann umändern und habe als Zahlen dann völlig beliebig die "111" und die "112" gewählt. Jetzt geht es nicht mehr ... ? :( Und ich musste wieder auf 001 und 002 umsteigen ... Warum ist das so?
Hast du immer beide Zahlen umgetauscht? Also nach "taunt-detected" und nach "acknowledge-taunt"?
Gute Frage! Das könnte der Haken an der Sache sein!
Nachdem mein letztgenanntes Problem hervorragend mit eurer Unterstützung gelöst wurde, kann ich Euch ja mal ein neues auftischen. Folgende KI meinerseits ist gegeben:

(defrule
(true)
=>
(set-strategic-number sn-maximum-food-drop-distance 0)
(set-strategic-number sn-maximum-wood-drop-distance 0)
(set-strategic-number sn-maximum-gold-drop-distance 0)
(set-strategic-number sn-maximum-stone-drop-distance 0)
(set-strategic-number sn-maximum-hunt-drop-distance 0)
(set-strategic-number sn-food-gatherer-percentage 0)
(set-strategic-number sn-gold-gatherer-percentage 0)
(set-strategic-number sn-minimum-civilian-explorers 0)
(set-strategic-number sn-wood-gatherer-percentage 0)
(set-strategic-number sn-cap-civilian-explorers 0)
(set-strategic-number sn-percent-civilian-explorers 0)
(disable-self)
)

(defrule
(true)
=>
(set-strategic-number sn-percent-enemy-sighted-response 100)
(set-strategic-number sn-hits-before-alliance-change 25)
(set-difficulty-parameter ability-to-maintain-distance 100)
(set-difficulty-parameter ability-to-dodge-missiles 100)
(set-strategic-number sn-number-explore-groups 0)
(set-strategic-number sn-percent-attack-soldiers 0)
(set-strategic-number sn-task-ungrouped-soldiers 0)
(set-strategic-number sn-number-attack-groups 0)
(set-strategic-number sn-enemy-sighted-response-distance 10)
(set-strategic-number sn-total-number-explorers 0)
(set-strategic-number sn-relic-return-distance 0)
(disable-self)
)

; ============== MILITÄREINHEITEN ERSCHAFFEN


;Milizsoldat
(defrule
(unit-type-count-total militiaman-line < 9)
(can-train militiaman-line)
=>
(train militiaman-line)
(chat-local-to-self "Infanterist")
)

;Langbogenschütze
(defrule
(unit-type-count my-unique-unit < 8)
(can-train my-unique-unit)
=>
(train my-unique-unit)
(chat-local-to-self "Langbogen")
)

;Plänkler
(defrule
(unit-type-count-total skirmisher-line < 9)
(can-train skirmisher-line)
=>
(train skirmisher-line)
(chat-local-to-self "Plänkler")
)

;Ritter
(defrule
(unit-type-count-total knight-line < 7)
(can-train knight-line)
=>
(train knight-line)
(chat-local-to-self "Ritter")
)

;Mange
(defrule
(unit-type-count-total mangonel-line < 3)
(can-train mangonel-line)
=>
(train mangonel-line)
(chat-local-to-self "Mange")
)

;Speerkämpfer
(defrule
(unit-type-count-total spearman-line < 4)
(can-train spearman-line)
=>
(train spearman-line)
(chat-local-to-self "Speerkämpfer")
)

---> Im Prinzip eine Freeze-KI, die Einheiten ausbildet.
Diese KI soll jedoch nun alle 7 Minuten angreifen, sobald Spieler 1 zu dieser KI feindlich steht.
Nun die Frage:
Wie müssen die AI-Befehle dafür aussehen? Kann mir jemand die Komplettlösung dafür hier einmal in korrekter Form auflisten?
Ich wäre sehr dankbar!
Oha, dagegen is ja mein Problem ein Kinderspiel :)
Deswegen werd ich mich mal vordrängeln ;)


Folgendes Problem:

(defrule ;erkunden
(true)
=>
(sn-cap-civilian-explorers 2)
(sn-total-number-explorers 3)
)

Jez bring des (verdammte) Programm nen ERR2005er Fehler in der Zeile mit dem sn-cap-civ..

Was verdammt noch mal is da falsch dran???
Zunächst mal Mordreds Problem, das ist wirklich einfach:

Du hast ganz einfach keine Aktion definiert!
Richtig wäre:

(defrule ;erkunden
(true)
=>
(set-strategic-number sn-cap-civilian-explorers 2)
(set-strategic-number sn-total-number-explorers 3)
)

Der Parameter allein hilft nichts - du musst dem PC schon sagen, was er damit tun soll!

---

Zu Hennings Problem:

Ich muss gestehen, das übersteigt etwas meine KI-Kenntnisse. Aber selbst mit besseren KI-Kenntnis ist das vermutlich ein nicht triviales Problem.

Es gibt Möglichkeiten, Angriffe hintereinander zu schalten. Als Beispiel sei hier Emperors "Weg des Kriegers" angeführt - da kannst du ein solches Konstrukt in der AI nachlesen.

Einfacher, aber nicht ganz so elegant ist es aber vermutlich, einen zusätzlichen "Kampf-Spieler" einzuführen, zu dem bei Beginn des Angriffs alle Kämpfer wechseln. Diesem bräuchtest du dann nur eine recht aggressive KI zuweisen. So würde ich es wahrscheinlich machen... :rolleyes:

Wie gesagt, ein Kochrezept kann ich dir aber leider nicht geben...ich werde das Handbuch studieren, aber vielleicht kann inzwischen wer anderes weiterhelfen! ;)
Ach du Schande..
So einfach.. :rolleyes:

Ich hab aber dazu aber nichts in diesem Scripting-Handbuch gefunden.. :KopfgegenWand:
... aber vielleicht kann inzwischen wer anderes weiterhelfen! ;)
Where is Günter when I need him the most?
Also gut...ich denke, ich habe eine Konstruktion gefunden, die deinen Ansprüchen fürs erste genügen dürfte:

(defrule ;bei Feindlichkeit beginnt der Kampf
(players-stance 1 enemy)
=>
(set-stance 1 enemy)
(set-goal 1 0)
(disable-self)
)

(defrule ;erster Angriff
(goal 1 0)
=>
(set-goal 1 1)
(enable-timer 1 150)
(set-strategic-number sn-percent-enemy-sighted-response 60)
(set-strategic-number sn-enemy-sighted-response-distance 40)
(set-strategic-number sn-group-form-distance 50)
(set-strategic-number sn-maximum-attack-group-size 30)
(set-strategic-number sn-minimum-attack-group-size 10)
(set-strategic-number sn-number-attack-groups 3)
(set-strategic-number sn-attack-group-size-randomness 0)
(disable-self)
)

(defrule ;Stillstand
(goal 1 1)
(timer-triggered 1)
=>
(set-goal 1 2)
(disable-timer 1)
(enable-timer 2 150)
(set-strategic-number sn-maximum-attack-group-size 0)
(set-strategic-number sn-minimum-attack-group-size 0)
(set-strategic-number sn-number-attack-groups 0)
)

(defrule ;sonstige Angriffe
(goal 1 2)
(timer-triggered 2)
=>
(set-goal 1 1)
(disable-timer 2)
(enable-timer 1 150)
(set-strategic-number sn-percent-enemy-sighted-response 60)
(set-strategic-number sn-enemy-sighted-response-distance 40)
(set-strategic-number sn-group-form-distance 50)
(set-strategic-number sn-maximum-attack-group-size 20)
(set-strategic-number sn-minimum-attack-group-size 10)
(set-strategic-number sn-number-attack-groups 3)
(set-strategic-number sn-attack-group-size-randomness 0)
)

---

Anmerkungen:

Die KI macht Folgendes:
Nachdem die Diplomatie auf "feindlich" gestellt wurde, wird der PC ebenfalls zum Feind. Er beginnt seinen ersten Angriff sofort, legt nach einer gewissen Zeit eine Pause ein und greift dann wieder an. So geht das dann immer weiter.

Zu beachten:
Die Zahlen, die verwendet werden, musst du für deine Map individuell wählen:

enable-timer 1 ==> die Zeit, die zwischen Ruhe und Angriff verstreicht
enable-timer 2 ==> die Zeit, die zwischen Angriff und Ruhe verstreicht
sn-percent-enemy-sighted-response ==> wieviele Soldaten sollen bei sichtbarem Gegner als Verteidigung geschickt werden (in %)
sn-enemy-sighted-response-distance ==> wie weit darf der Gegner entfernt sein, damit sich die Verteidigung darum kümmert
sn-group-form-distance ==> wie weit dürfen Soldaten auseinander stehen, um Gruppen zu bilden
sn-maximum-attack-group-size ==> wie groß sollen die Angriffstrupps max. sein
sn-minimum-attack-group-size ==> wie groß sollen die Angriffstrupps min. sein
sn-number-attack-groups ==> wie viele Angriffstrupps sollen höchstens gemeinsam agieren

(Die Strategischen Nummern sind in beiden Bedingungen gleich zu wählen!)

Um all diese Zahlen richtig auszubalancieren, musst du wohl oder übel so viel wie möglich testen. Anhaltspunkte sind: Größe der Karte, Größe des Gegners, Größe des PCs, Entfernung des Gegners, ...

Außerdem ist zu beachten, dass diese KI eine passable Kampfroutine, jedoch keine Verteidigungsroutine hat - ich weiß nicht, inwiefern das in deiner Map relevant ist. Wenn ja, solltest du in den Angriffsbedingungen wenigstens noch die Zusatzbedingung "(not (town-under-attack))" hinzufügen, da Angriffe ansonsten die Verteidigung stören könnten!


Ich hoffe, das war aufschlussreich! ;)
Merci! :super: :eek:
Ich weiß, ich halte den Laden hier aktuell ein bisschen sehr auf Trab, aber ich hab da noch ein Problem. Ich hoffe ich fang nicht an zu nerven. Es ist mir fast schon peinlich, diese Frage zu stellen, aber ich kriege die verdammten Dorfis nicht zum Stehen!

Was muss ich in den Script eingeben, damit die Dorfis nicht jagen gehen und nicht fischen?

Ich kriegs einfach nicht gebacken! Sie sollen doch nur ihre Felder bestellen ... :tieftraurig:
Du hast fragen.. Ich will, daß die Nahrung sammeln, egal wie, aber meine Dorfis holzen immer nur Holz ab..
Der letzte Test sah so aus: Gegner: Ritterzeit; AI: Dunkle Zeit..
Wie schaff ich des??
Und noch ne Frage: Was muß ich machen, daß der Späher nich nur so geistesabwesend danebensteht, sondern das Land erkundet??

Es is zum verzweifeln..
Das ist auch einigermaßen schwierig. Unter Umständen hilft dir der Befehl:

(defrule
(true)
=>
(set-strategic-numer sn-food-dropsite-distance 3)

Sie Zahl sagt der KI, wie weit weg eine Nahrungsquelle von der Mühle/dem Dorfzentrum maximal sein darf, um benutzt zu werden. Sind also in deiner Map die Felder in der Nähe der Mühle/des Dorfzentrums, andere Nahrungsquellen aber weiter entfernt, kannst du die Zahl so wählen, dass es hinhaut.

Ansonsten ev. über Schalter zuweisen... :rolleyes:


EDIT:
*****

Fragen über Fragen...so schnell kann man ja gar nicht schreiben. Also, lieber Mordred:

Die Dorfis kannst du mit diesen Befehlen zu ihren Tätigkeiten bringen:

(defrule
(true)
=>
(set-strategic-number sn-food-gatherer-percentage 25)
(set-strategic-number sn-stone-gatherer-percentage 25)
(set-strategic-number sn-gold-gatherer-percentage 25)
(set-strategic-number sn-wood-gatherer-percentage 25)

Durch ändern der Zahlen erhältst du andere Prozentsätze.

Für das Erkunden durch Soldaten gibt es folgende SNs:

(defrule
(true)
=>
(set-strategic-number sn-number-explore-groups 1)
(set-strategic-number sn-maximum-explore-group-size 5)
(set-strategic-number sn-minimum-explore-group-size 1)

Je nach Zahlen mehr/weniger und größere/kleinere Erkundungstrupps.

Und zum Voranschreiten:

(defrule
(can-afford-research feudal-age)
(was auch immer)
=>
(research feudal-age)

Mit der Bedingung, die du willst und natürlich auch mit den anderen Zeitaltern (castle-age, imperial-age)! ;)
Ich versuche mich momentan an einer AI, die so handelt, wie ich es tun würde. Aber bei

Code: Alles auswählen

(set-strategic-number sn-food-gatherer-percentage 25)
kann ich ja nich bestimmen, ob die Felder, Beeren, Schaafe, Rehe, Fische, etc. als Nahrungsquelle nutzen..

Meine Strategie:
Ich will, daß zuerst Nahrung gesammelt wird (die fangen ja gleich mit Holz an..), dann einen neuen Dorfi erschaffen, Haus bauen, weitere Dorfis zum Nahrungsammeln, 2-4 zum Holz hacken.. mehr Häuser, Hafen, Fischerboote, Kaserne, Dorfis zum Goldabbau, Feudalzeit..
..
..
..
@Andi: Gute Idee! Das heißt ich lösche einfach Küstenfische und Rehe in der Nähe der DZs und der Mühlen. In die KI füge ich den von dir genannten Befehl ein und die Dorfis kümmern sich dann hoffentlich um die Felder. Mal sehen, ob das klappt! :D