StellarConflict-Tagebuch, Seite zwei.
Autor: Tjabo Kloppenburg (tk@taponet.de)
Datum: 3.März 2002
 

Liebe Gemeinde... :-)

Der Name
First of all: Der Name des Spiels ist ein Arbeitstitel. Damit das Programm später auch international Anklang findet, brauchen wir dann auf jeden Fall noch einen internationalen (=englischen) Namen.
Vielleicht  etwas aus (Stellar Command, Stellar Alliance, Stellar Strategy o.ä.). Da müsste man mal Herrn Gurgel befragen, welcher dieser wirklich phantasievollen Namen noch frei ist.

Kopfzerbrechen / Hostorder
Was mir momentan am meisten Kopfzerbrechen bereitet ist die "Hostorder", wobei ich mich auch von http://www.xs4all.nl/donovan/help/hostorder.htm nicht ganz unbeeinflusst sehe... Donovan beschreibt dort die Hostorder von VGAPlanets 4.

Ich hatte ja schon Überlegungen angestellt, dass ein Schiff, das Cargo beamt und gleichzeitig angegriffen wird, Probleme beim Beamen bekommen müsste. Nur weiß der Spieler in dem Moment, wo er seinen Zug macht, ja nicht, dass das Schiff  angegriffen wird. Der Spieler beamt also Cargo und Geld auf einen Planeten, befiehlt dort den Bau von Minen und Fabriken, eine Starbase bekommt den Auftrag, Torpedorohre und Antriebe zu erstellen, und vielleicht werden die sogar schon auf ein anderes Schiff übertragen. Soll das alles jetzt automatisch serverseitig deaktiviert werden, weil das erste Schiff wegen des Angriffs die Sachen nicht runterbeamen kann oder die Hälfte verloren geht? Das könnte reichlich kompliziert werden...
Aber es klingt plausibel, oder?

Jetzt muss ich mir also ein schlaues Konzept einfallen lassen, wie ich den Kram unter einen Hut bringe. Mein Unterbewusstsein schleuste gerade das Wort "tree" in meine Gedankengänge:
Man müsste auf der Clientseite kleine Abhängigkeitsbäume erstellen. Sagen wir, Node_1 ist das Übertragen von Erzen und Geld auf einen Planeten mit Starbase. Node_2, abhängig davon, wäre a) das Bauen von 40 Minen (unter Verbrauch von Erzen und Geld), sowie b) ein Auftrag an die Starbase, Torpedowerfer zu produzieren. Der Zweig b) würde dann noch eine Erweiterung erfahren: Installiere die Rohre auf Schiff 432.

Das PROBLEM dass ich dabei sehe ist, dass die Programmierung eines Clients dadurch erheblich verkompliziert werden würde: Es würde dort nicht mehr ausreichen, auf dem Planeten und den Schiffen "flach" mitzuzählen, wieviel Geld und Erz gerade dort ist, man müsste den Baum verwalten.

Oder aber: man rekonstruiert den Baum serverseitig anhand der Reihenfolge der mit dem Turnfile "eintrudelnden" Kommandos, wobei man ja eh bei jedem Kommando prüft, ob die Voraussetzungen (Ressourcen) erfüllt sind. Das Scheitern eines Kommandos muss dann dem Client im Gamefile mitgeteilt werden.

Beispiel:
TRANSFER_MONEY_SHIP_TO_PLANET 1(shipID) 12(planetID) 1200(Tacken)
TRANSFER_CARGO_SHIP_TO_PLANET 1(shipID) 12(planetID) 14(CargoTypeID) 400(einheiten)
BUILD_PLANETARY_OREMINES 12(planetID) 1(OreMineType) 40(count)
BUILD_STARBASY_WEAPONS 4(starbaseID) 6(WeaponType) 4(count)
INSTALL_WEAPONS_BASE_TO_SHIP 4(starbaseID) 432(shipID)

sowie beim feindlichen Schiff:
SHIP_MEDIUM_ATTACK_SHIP 4(eigeneSchiffsID des Feindes)

(Wenn man die Aktions-Bezeichner als ID im Turnfile unterbringen würde, dann könnte man die Turnfiles wesentlich schlechter debuggen.)

Und da haben wir eine neues Problem:

Wenn die Schiffe eine clientrelative Nummerierung haben, wie bilde ich dann das Kommando für den Angriff auf ein anderes Schiff (im Unwissen über die Nummerierung des Gegners)?

Sage ich "Greife das Schiff auf Position x/y an!", dann gibts Probleme mit mehreren Schiffen auf der gleichen Position. Ich könnte ggf. sagen: "Greife mit meinem Schiff 3 das Schiff Feds.BlackEagle an."
Dann muss sichergestellt sein, dass niemals zwei Schiffe einer Rasse gleiche Namen tragen (womit ein (unwichtiges?) taktisches Element verloren ginge). Auch muss dann der Name des Schiffes außen auf den Rumpf gepinselt sein, damit der Gegner sagen kann, welches meiner Schiffe er angreifen will.

Prinzipiell könnte man jedem Schiff im Universum serverseitig eine Zufalls-ID verpassen, aber ich denke es ist spieltechnisch schöner, wenn man ein gegnerisches Schiff "BlackEagle" verfolgt und niedermacht, als ein Schiff "4age$TGws6sd".... ;-)

Fazit mit anderen Worten: Wenn man gegnerische Schiffe sieht, so sieht man deren Namen (der ja nichts über die Anzahl der Schiffe des Gegners verrät, im Gegensatz zur spieler-relativen ID).
Der Angriff erfolgt über die Angabe des Namens des feindlichen Schiffes in der Notation: "Rasse.SchiffsName".
Nachteil: Die Doppelbenamung von eigenen Schiffen zwecks Verwirrung des Gegners fällt flach. Das ist durchaus schade. Auch kann es dann eventl. zu Encoding-Hickups kommen (Text mit Sonderzeichen im Turnfile).
 

Der Knackpunkt ist jetzt: Schiff 1 wird unerwartet von einem getarnten feindlichen Schiff angegriffen.

Was nun?
Zum einen ist es sicherlich sinnvoll, dass ein Spieler für jedes Schiff das Verhalten im Angriffsfall zum Einen global, aber auch einzeln für jedes Schiff festlegt. Zum Beispiel mit der Order

SET_ATTACK_REACTION_FOR_ALL_SHIPS 8(idOfReaction, here: fight back with all weapons)
SET_ATTACK_REACTION_FOR_SHIP 1(shipID) 4(xfer all cargo to planet, fight back)
 

Anmerkung zur Verwendung der IDs
Die Verwendung von IDs hat den gewaltigen Vorteil, dass man auf der Serverseite kaum Einschränkungen hat, was das Erweitern der Funktionalitäten hat. Am Anfang teilt der Server dem Client (zB im Worldfile) mit, welche Reaktionen auf Angriff es gibt -- mit IDs und Text. Beim Client kann dann ganz einfach eine Klappliste in einem Eigenschafts-Dialog erstellt werden, wobei sich der Clientprogrammierer überhaupt nicht um die Pflege der IDs kümmern muss.

Beim Hostrun würde das so aussehen:
Gehe alle Schiffe durch:
Nehme Schiff 1.
Ermittle Situation von Schiff 1.
If (Situation == angegriffen):
   sammeln und später verarbeiten
elseif (Situation == normal):
...

Schiffe, die sich in einem Angriffszustand befinden, werden in einem späteren Abschnitt gesondert bearbeitet. Das erfolgt dann in Abhängigkeit von den Attack-Reaction-Orders. Usw.

Auf der nächsten Seite versuche ich mal zu sammeln, was der Host alles machen muss, und in welcher Reihenfolge.
Danach werde ich dann Spielsituationen wie die eben sammeln, und dann schauen, wie ich die Hostorder modellireren muss, damit in allen Situationen ein sinnvoller Hostrun funktioniert.