# Selbst-handelnde Objekte im Client-Server Betrieb



## tincup (8. Feb 2010)

Hi Leute.

Mache gerade ein paar Überlegungen zu einem Echtzeit Online-Spiel. Völlig unabhängig vom Typ des Spiels habe ich folgende Frage:

Angenommen serverseitig ist für jedes agierende Objekt im Spiel (Gegner, NPCs etc.) auch ein Java-Objekt erzeugt, welches entsprechend in der Spielwelt "handeln" kann. Wie implementiert man bei so etwas am besten das Timing dieser Objekte, d.h. dass immer wieder alle Objekte auch Code ausführen dürfen?

Für jedes Objekt einen eigenen Thread erstellen geht offensichtlich nicht, denn je nach Spiel kann es da ja um 1000e-10000e gehen. Eine Alternative wären eine Schleife, die in einem fixen Zeitinterval (z.B. 1 oder 2 Sekunden) eine Update-Funktion für jedes Objekt aufruft. Damit wäre die Engine aber irgendwie recht starr, jedes Objekt kann nur einmal pro Sekunde reagieren.

Hat jemand irgendwelche Ideen dazu?


----------



## dayaftereh (8. Feb 2010)

Ich würde mal sagen! du hast die Objekte in eine Liste oder Map? Die würde ich in einem Bestimmten Zeit Intervall durchlaufen, um Kollision oder sonstige sachen zu prüfen und daruf zu reagieren!


----------



## SlaterB (8. Feb 2010)

wie sowas in echt funktioniert interessiert mich auch eher als dass ich es schon wüßte,
aber deine 1-2 sec sind ja übertrieben pessimistisch auf modernen CPUs, ist ja nicht so als wenn jeder davon 1000 Schachzüge in die Zukunft berechnen muss,
da würde ich erstmal von Film-Echtzeit ausgehen: jeder kommt 30x pro Sekunde dran!, zumindest für einige Grundfunktionen, Test auf neues Objekt in 'Sensorreichweite' usw.,

dann gegebenenfalls kurz etwas mehr zu tun, einen Plan für die nächsten Sekunden aufstellen und wiederum die nächsten zig Durchläufe nur beibehalten bis ein externes Ereignis wie ein Treffer eintritt,
in dem Fall dann sofort reagieren, da muss nicht 1-2 sec gewartet werden

in einem Spiel sind doch aber auch nur normalerweise wenige hundert komplexe Akteure gleichzeitig aktiv oder? 
wenn für Unmengen an menschlichen Clients jeweils separate Spiele laufen (höchstens 10 zusammen mit 100 NPCs)
dann müssen derartige 'Instanzen' doch nicht alles auf dem gleichen Computer, gar im gleichen Programm ablaufen?
WoW hat sicher paar mehr PCs rumstehen..


----------



## tincup (8. Feb 2010)

Hmm ja du hast vielleicht recht, man kann wahrscheinlich wesentlich schneller updaten. Damit wäre es dann nicht mehr so starr. Für größere Angelegenheiten müsste man dann über verschiedene CPU Kerne (per Threads) oder eben Rechner (wahrscheinlich sehr schwierig) ausweichen.

Für kontinuierliche Abläufe (z.B. Bewegung) muss man dann wahrscheinlich über die vergangene Zeit und die Geschwindigkeit des Objektes schrittweise bewegen. 

Aber ihr seht es auch so, dass es nur diese beiden Möglichkeiten gibt (1. selbst laufen als eigene Thread oder 2. regelmäßig aufgerufen werden), oder?


----------



## tincup (8. Feb 2010)

Nachtrag:
Die Idee mit der Trennung der Zeitskalen ist auch nicht schlecht. Sehr schnelles Abarbeiten von stumpfen abhandeln (z.B. Bewegung) und selteneres Updaten, wenn es um Taktik und Planung geht.


----------



## andre111 (8. Feb 2010)

In "Killer Game Programming in Java" ist in Kapitel 2 ziemlich genau erklärt, wie sowas funktioniert:
Kapitel 2


----------



## Noctarius (8. Feb 2010)

Ich würde einen ExecutorService nutzen und dort Events für die einzelnen Objekte registrieren. So hast du einen Threadpool und bist unabhängig von der Zeit.

Den Utils-Timer würde ich für solche Sachen nicht mehr benutzen. Schon gar nicht serverseitig.


----------



## tincup (8. Feb 2010)

Danke für die Tips und Links!

An eine Message-Queue hatte ich auch schon gedacht. Werde das alles mal durchgehen.

Welcher Timer ist geeigneter?


----------



## Gast2 (8. Feb 2010)

```
public interface Denkleistung
{
    void think();
    void hit(GameEvent ge);
}

// ...

Collection<Denkleistung> gameobjects;
```

und die Liste immer fleißig durchrattern und bei jedem Object thnik() aufrufen ... das macht dann das was es soll und bei Objekten die ein Event erhalten (z.B. Treffer) rufst Du einfach hit() auf ... und übergibst da dann das entsprechende GameEvent



> Welcher Timer ist geeigneter?


ein Thread und immer alles durchrassel ... die Zeit nehmen um abzusätzen wie weit sich die Objekte beim letzten think() bewegt haben


----------



## tincup (8. Feb 2010)

@Mogel:

OK, ja das würde meinem "update" Schema von oben entsprechen.
Klingt sinnvoll.


----------

