mmofacts.com

Echtzeit, aber wie?

gepostet vor 17 Jahre, 11 Monate von jonasq
Da per Forensuche nichts Themendeckendes gefunden wurde, mal hier die Frage.
Ein Spiel in Echtzeit soll es werden (konzeptionelle Phase) und ich bin am überlegen, wie ich da die Echtzeit im Hintergrund behandeln/berechnen will ...
Könnt ihr mir da Denkanstöße geben, wie das realisiert wird/werden kann?
einen erfolgreichen Tag noch
/jonasq
gepostet vor 17 Jahre, 11 Monate von Flint
Ich nehme an du verstehst unter Echtzeit das entreffen eines Ereignisses (Event) zu einem vorher bestimmten Zeitpunkt, Beispiel Spieler baut Gebäude das 2 Stunden später fertiggestellt wird oder Einheit bewegt sich von A nach B und kommt in B um xx:yy an.
Eine möglichkeit sowas zu Lösen ist ein Daemon, also ein ständig laufender Prozess, der eine zeitlich sortierte Warteschlange (Queue) überwacht und die eintreten Event abarbeitet. So eine Queue könnte z.B. eine MySql Tabelle sein.
Wenn der Spieler so ein Ereignis anstößt wird in der DB eingetragen wann was beendet ist. Der Daemon sucht regelmäßig in der DB nach Ereignissen die zeitlich an der Reihe sind und arbeitet diese ab, anschließend entfernt er den Eintrag aus der Queue.
Vorraussetzung für diese Lösungsmöglichkeit ist ein Server auf dem du die Rechte hast eigene Prozesse zu starten.
gepostet vor 17 Jahre, 11 Monate von None
Oder du machst es so, das bei jeden Seitenaufruf (z.B. in einer common.php) die Queue abgearbeitet wird. Bei mindestens eine Spieler durchgehen online (bezogen auf mehrere Spieler, welche in unterschiedlichen Zeitspannen online sind.) wird diese Queue nicht zu lang werden. Falls mal wirklich kein Spieler online sein sollte, würde ich zu Sicherheit noch einen stündlichen CronJob einrichten, welche auch die z.B. die common.php aufruft.
gepostet vor 17 Jahre, 11 Monate von Murmeltier
Moin,
ein Spieler klickt zB auf bauen.
Dadurch wird die Zeit, wann das Gebäude (ein Bsp.) fertig ist in die Datenbank eingetragen.
Wenn der Spieler nun erneut diese Seite aufruft, wird geschaut, ob ein Ereignis eingetragen ist, und wenn ja, ob es schon fertig ist, oder wie lange dies noch ist.
End Zeit - Aktuelle Zeit = Restzeit
gepostet vor 17 Jahre, 11 Monate von None
Und was ist wenn sich ein Spieler ein oder zwei Tage nicht einloggt? Dann wird es erst beim Login fertiggestellt. Man sollte Ereignisse durch alle Spieler abarbeiten lassen können. Am besten wenn bei jeden Seitenaufruf eine Datei (z.B. common.php) aufgerufen wird. Dann kommt es schon der Echtzeit näher. Oder so wie es mein voriger Vorgänger schon sagte. Durche einen Daemon bzw. Prozess.
gepostet vor 17 Jahre, 11 Monate von Fornax
Wenn man aber für 1000 bei jeden Aufruf der Gebäudeseite prüft, ob ein Gebäude der 1000 Benutzer fertig ist, ist das für den Benutzer mit der Ladezeit auch nicht grad schön. Daemon, Cronjob, etc. sind wohl die besten Mittel
gepostet vor 17 Jahre, 11 Monate von MagicForrest
Ich denke es würde reichen wenn man nur für den User prüft, bzw falls ein anderer Spieler mit diesem interagiert (zb bei Spionage oder angriff/etc.).
Das würde Ressourcen sparen, und wäre sogar mehr Echtzeit als ein Cronjob, und um einiges schneller als eine common.php, bei zu vielen Usern auch wieder "mehr Echtzeit".
gepostet vor 17 Jahre, 11 Monate von Blabbo
stimmt.
welche Daten für welche User aktualisiert werden müssen,
hängt halt von Spielprinzip ab.
Da muss man schon selber ein bisschen das Hirn einschalten.
Bei JEDEM Seitenaufruf ALLES aktualisieren dürfte ein krasser PerformanceKiller sein, wenn mehr als 5 Leutchen mitspielen
gepostet vor 17 Jahre, 11 Monate von jonasq
Also wohl Damen bzw Cronjob.
Kann da jemand die Vorteile/Nachteile beider Strategien beschreiben, und, was ich damit machen kann, und was nicht mehr? Wo hört der eien auf, und setzt der andere vllt an?
Ist ein Daemon auf eine höhere Programmiersprache angewissen( C, C++, java usw...)? Oder kann man derartiges gar in php realiseren (für ein webprojekt ja recht vorteilhaft...
Einem Verweis auf entsprechende HowTos wäre ich nicht abgeneigt, falls sich wer berufen fühlt
Vielen Dank
/jonasq
gepostet vor 17 Jahre, 11 Monate von Itchy
Natürlich kannst Du auch einen daemon in PHP schreiben, Du kannst den auch in Shellskript schreiben, wenn Du möchtest
Ein sehr einfacher daemon in PHP könnte wie folge aussehen:

while( true ) {
while( stuff_to_do() ) {
do_stuff();
}
sleep( 1 );
}
?>
Der würde also sekündlich checken, ob es was zu tun gibt, das gegebenfalls ausführen und danach für eine Sekunde hinlegen um danach wieder von vorne anzufangen.
Natürlich ist das kein "richtiger" Daemon und wirklich Echtzeit ist das auch nicht, sondern quasi nur sekündliche Ticks, aber die Idee sollte klar werden und kann beliebig verfeinert werden
gepostet vor 17 Jahre, 11 Monate von None
Was bedeuted diese Zeile?
#!/usr/bin/php -q

gepostet vor 17 Jahre, 11 Monate von Toby
Sagt der Shell, welchen Interpreter sie verwenden soll.
Dadurch kann man das Script direkt aufrufen, ohne das man vorher noch irgendwie php aufrufen muss.
gepostet vor 17 Jahre, 11 Monate von Itchy
Ich geh natürlich davon aus, daß so ein Daemon auf einer Shell läuft - den wird ja wohl niemand über einen Browser starten, oder? Außerdem läuft das Skript auch auf eine Standardkonfig sicher länger als 30 Sekunden - die max_execution_time gilt nur für reine Rechenzeit. Ein Skript
while( true )

sleep( 1 );
Läuft den ganzen Tag - natürlich würde es irgendwann beendet werden, aber nicht nach 30 Sekunden Und dies auch nur im Browser - ruft man ein Skript über "php skript.php" auf, läuft das Ding bis zum Sanktnimmerleinstag - im Kommandozeilenmodus ist max_execution_time nämlich außer Kraft gesetzt, außer man setzt es explizit.
gepostet vor 17 Jahre, 11 Monate von Toby
Also bei mir findet sich unter /etc/php5/cli eine php.ini und die sollte doch bei auf der Shell ausgeführen Scripten gelten, oder?
Allerdings war auf meinem SuSE-System die entsprechende Config tatsächlich auskommentiert. Aber auf meinem Debian-System nicht, daher gehe ich schon davon aus, das das gilt?!
Und wir wollen ja gerade, das unser Script was rechnet.
gepostet vor 17 Jahre, 11 Monate von gorgo
interpolation
Echtzeit heisst nicht das man jeden zeitpunkt berrechnet sondern nur das der spieler zu jedem zeitpunkt ein aktuelles (zu diesem zeitpunkt gehörendes) Ergebniss geliefert bekommt.
gepostet vor 17 Jahre, 11 Monate von Murmeltier
Original von DieZone
Und was ist wenn sich ein Spieler ein oder zwei Tage nicht einloggt? Dann wird es erst beim Login fertiggestellt. Man sollte Ereignisse durch alle Spieler abarbeiten lassen können. Am besten wenn bei jeden Seitenaufruf eine Datei (z.B. common.php) aufgerufen wird. Dann kommt es schon der Echtzeit näher. Oder so wie es mein voriger Vorgänger schon sagte. Durche einen Daemon bzw. Prozess.

Stimmt, das habe ich nicht bedacht...naja, aber fast hätte es geklappt
gepostet vor 17 Jahre, 11 Monate von Blabbo
Für die Eigenschaften, die eh nur für den Spieler relevant sind, ist es egal, ob er sich nun eine Stunde, einen Tag oder eine Woche nicht einloggt.
Wird ja dann alles nachberechnet, wenn er wieder da ist.
gepostet vor 17 Jahre, 11 Monate von Itchy
Original von gorgo
interpolation
Echtzeit heisst nicht das man jeden zeitpunkt berrechnet sondern nur das der spieler zu jedem zeitpunkt ein aktuelles (zu diesem zeitpunkt gehörendes) Ergebniss geliefert bekommt.

Komische Definition von Echtzeit und absolut nicht passend für jedes Game. Für Popelgames à la ich starte den Bau um 17:00 Uhr und um 21:00 Uhr ist meine Goldmine fertig, reicht es natürlich aus, wenn nur zur Endzeit was gemacht wird und zwar das Ereignis "Neue Goldmine bereit".
Anders sieht es bei Bewegungen aus: möchte man, daß z.B. während einer Bewegung Ereignisse eintreten können, dann muß man zu jedem Zeitpunkt wissen, wo sich die Objekte gerade befinden. Vor allem dann, wenn sich die Bewegungsvektoren der Objekte während der Bewegung auch noch ändern können.
Aber sagen wirs mal so: für die meisten Browsergames ist das wohl weniger interessant, da die nach dem obigen Schema funktionieren, sprich: Bauauftrag -> Fertig und dazwischen ist rein gar nichts.
gepostet vor 17 Jahre, 11 Monate von Blabbo
Original von Itchy
Anders sieht es bei Bewegungen aus: möchte man, daß z.B. während einer Bewegung Ereignisse eintreten können, dann muß man zu jedem Zeitpunkt wissen, wo sich die Objekte gerade befinden. Vor allem dann, wenn sich die Bewegungsvektoren der Objekte während der Bewegung auch noch ändern können.

hehe, wer kann sich darunter jetzt was vorstellen?
Aber so wie ich das verstanden habe,
wäre auch das im Nachhinein berechenbar,
ausser diese EReignisse hängen auch von den Aktionen anderer Spieler ab.
gepostet vor 17 Jahre, 11 Monate von Itchy
Gah, natürlich setze ich voraus, daß die Objekte global sichtbar sind und nicht nur für einen Spieler wichtig sind. Wenn dem so ist, kann man sich den ganzen Firefanz sparen.
Ich rede von Sachen wie direkte Steuerung von Raumschiffen, also nicht, fliege von A nach B und in der Zwischenzeit befindet sich das Raumschiff in einem nicht näher definierten Nimbus und wird quasi für diese Zeit "aus dem Spiel genommen" sondern fliege von A und B und wenn ich zwischenzeitlich Lust habe, so kann die Scanner vom Schiff auf andere, in der Nähe befindliche Schiffe scannen und ggf. einen Abfangkurs setzen.
Klar, theoretisch würde es reichen, immer nur den Bewegungsvektor und die Zeit dazu abzuspeichern und nur bei jeder Änderung des Vektors die Position zunächst auszurechnen. Nur würde das bedeuten, daß bei o.g. Scannvorgang erstmals aus allen Vektoren aller Objekte deren Position errechnet werden muß. Da würde ich doch eher zu der Lösung tendieren, die Positionen mit einer Auflösung von 10 Sekunden aktuell irgendwo abzuspeichern, damit man sich die Rechnerei beim erwähnten Scannen spart.
gepostet vor 17 Jahre, 11 Monate von Blabbo
Stimmt, in dem Fall ist die beschriebene Methode nicht mehr sinnvoll.
Da müssen eben Cronjobs her.
Die meisten BG´s verfügen aber leider nicht über solch einen schönen Autopiloten, deswegen reicht oft die "ich berechne nur wenn der Spieler aktiv ist"-Methode.
Aber wie gesagt, es hängt eben vom Spielrpinzip an.
Möglich ist auch eine Mischlösung.
gepostet vor 17 Jahre, 11 Monate von Wulf
Ich hatte in den letzten 10 Minuten einen Beitrag geschrieben (viel laenger und detailierter als dieser hier) der dann beim Abschicken von einer Fehlermeldung des Forums gekillt wurde. Ich hatte den Text nicht kopiert und weg ist er...

Naja, hier nochmal in Kuerze:
Bei Spacetale verwende ich eine Mischung aus 'fauler' Aktualisierung (Alle Raumschiffe im aktuellen Sonnensystem werden nur bei Abruf ihrer Daten aktualisiert) und einer Aktualisierung per Thread.
Alle sich bewegenden Raumschiffe werden von diesem Aktualisierungsthread alle x Zeiteinheiten aktualisiert. Dadurch verhindere ich, dass ein Raumschiff aus einem System wo keine Spieler online sind (==> keinerlei 'faule' Aktualisierung in diesem System) mit einem Hyperraumsprung in das aktuelle System springt und dabei nicht gesehen wird.
So ist es hoechstens um x Zeiteinheiten zu spaet in dem aktuellen System aufgetaucht.
gepostet vor 17 Jahre, 11 Monate von Blabbo
Original von Wulf
Ich hatte in den letzten 10 Minuten einen Beitrag geschrieben (viel laenger und detailierter als dieser hier) der dann beim Abschicken von einer Fehlermeldung des Forums gekillt wurde. Ich hatte den Text nicht kopiert und weg ist er...


Da bist du nicht der erste:
Sie haben keine Berechtigung, diese Seite ...
gepostet vor 17 Jahre, 11 Monate von Drezil
Ist mir grad auch passiert .. also alles nochmal in kurz:
ich kann gorgo nur voll und ganz zustimmen .. seine definition passt - finde ich - wie die faust aufs auge ..
Wieso denken alle bei echtzeit, dass in jeder (Milli-)Sekunde in der Datenbank die aktuellen daten stehen müssen?
Es reicht vollkommen, wenn zu dem zeitpunkt des aufrufes alle sfür den aufruf relevaten daten da sind und alle aktuell sind.
Ich mache dasbei mir ständig (2D-Universum, Scanner/Sensoren, Flottenabfangen im Flug, Kursänderungen jederzeit, Routen/Patroulliesystem, ...)
Und das alles ohne cronjobs und "nur" über verktoren Live/Vorrausberechnung.
Die Datenbank weiss beim anlegen des Kurses schon, was wann passieren könnte (Kampf, wenn feindliche Flotten sich treffen, stationiereung von truppen um weltall, nächste Kursänderung der flotte, stop und automatische abbau von asteroiden, ...) und prüft dann zu dem zeitpunkt nochmal. Also in der DB steht quasi schon die zukunft - der spieler kann sie nur nicht abfragen .. ^^
gepostet vor 17 Jahre, 11 Monate von Itchy
Das ist alles mögliche, nur eben keine "Echtzeit" - was wohl daran liegt, daß in Deinem Spiel keine Echtzeit benötigt wird. (Mal davon abgesehen, daß der Begriff Echtzeit in der Informatik eine ganz andere Bedeutung hat, dabei gehts eher um Hardware und dazugehörige Echtzeitbetriebssysteme).
Will man tatsächliche "Echtzeit" haben, so kommt man nicht drumrum in bestimmten Abständen den Datenbestand upzudaten. Ich will nochmals auf mein Beispiel "Scanner" zurückkommen.
Du steuerst Dein Raumschiff und wirfst den Scanner an, der Dir alle Objekte im Umkreis von einem LJ anzeigt. So, wie bitte bestimmst Du, welche Objekte das sind, wenn Du keine aktuellen Positionsdaten hast? In diesem Falle bleibt wirklich nur, über die Vektoren sämtlicher Objekte deren aktuelle Position auszurechnen und dann zu überprüfen, ob sich die Objekte in Reichweite befinden. Klar, möglich ist das, kann aber bei entsprechend vielen Objekten schon mal eine Sekunde Rechenzeit in Anspruch nehmen, wenn nun 10 Spieler gleichzeitig auf die Idee kommen, die Scanner anzuwerfen, hat man ein Problem.
Würde man allerdings alle 30 Sekunden die Positionen ausrechnen und wegspeichern, würden die große Rechenzeit eben nur alle diese 30 Sekunden anfallen, ansonsten kann man bequem auf diese Daten zurückgreifen, die eben maximal 30 Sekunden "veraltet" sind - aber das läßt sich verschmerzen, so wie es Wulf aufgezeigt hat.
gepostet vor 17 Jahre, 11 Monate von Mudder
Naja Drezil.. da weiss die Datenbank wann wo gekämpft wird, aber das die neue Mine bei Fertigstellung auch arbeiten soll, dass weiss sie nicht
Ne aber ich würde auch eine Mischung verwenden. Wobei ich den Aktionen verschiedene Prioritäten gebe. Eine Truppenbewegung ist wichtiger als die Ressourcenberechnung und wird entsprechend aktueller berechnet.
Sprich eine Truppenbewegung wird alle 30 Sekunden aktuallisiert, während die Ressourcen nur alle 5 Minuten berechnet werden. Solch eine automatische Berechnung für "Schläfer" zusammen mit einer Live-Berechnung bei Useraktion und man hat eine recht stabile Echtzeitdarstellung.. welche man mit etwas Story auch gut darstellen kann.
Wobei man auch einfach sagen muss, dass die Berechnungen auf jedes Spiel angepasst sein müssen. Ein BG mit 10000 Spielern kann zu Stosszeiten kaum eine Live-Berechnung vornehmen, sondern hier müssen die Ticks schon etwas eingeschränkt werden.
gepostet vor 17 Jahre, 11 Monate von Flint
Es ist sicher richtig das "Interpolation"/"Usernahe aktualisierung" für die meisten Spiele auch funktioniert aber je nach Art des Spiels ist imho der Aufwand es zu realisiern größer als eine "Zeitnahe quasie Echtzeit" Lösung.
Zumindest sehe ich keinen Grund nicht auf die Zeitnahe Userunabhängige Lösung zu setzen, außer man hat nicht die Möglichkeit Cronjobs/Daemons auszuführen. Wenn das der Grund für eine andere Lösung ist ist es eh nur ein Workarround um diese Beschränkung zu umgehen und damit 2te Wahl ^^
Ich sehe keinerlei Nachteile einer Daemon Lösung gegenüber einer "Interpolations" Lösung, daher ist für mich die Daemon Lösung die erste Wahl.
PS: Ich mache vor jedem Abschicken ctrl-a ctrl-c sonst würd ich hier schon lange nix mehr schreiben ^^
gepostet vor 17 Jahre, 11 Monate von gorgo
Klar, theoretisch würde es reichen, immer nur den Bewegungsvektor und die Zeit dazu abzuspeichern und nur bei jeder Änderung des Vektors die Position zunächst auszurechnen. Nur würde das bedeuten, daß bei o.g. Scannvorgang erstmals aus allen Vektoren aller Objekte deren Position errechnet werden muß. Da würde ich doch eher zu der Lösung tendieren, die Positionen mit einer Auflösung von 10 Sekunden aktuell irgendwo abzuspeichern, damit man sich die Rechnerei beim erwähnten Scannen spart.

Es geht um ECHTZEIT und keine 10 Sekunden Ticks. Das was du da machst ist KEINE Echtzeit und scheinbar benötigts du auch speziell keine wirkliche echtzeit und somit auch keine interplation.
Wenn man aber leiber alles totreden will solls mir egal sein. Jeder der sich wirklich mit Echtzeitprogrammierung befassen will, sollte nicht der illusion erliegen das Echtzeit gleich die ständige Neuberrechnung von Daten bedeuted. Denn genau dann muss man sich schon aus technischen aspekten auf zeitintervalle festlegen. Je komplexer die berrechnungen um so größer die nötigen zeitintervalle. und ich red nicht von browsergames sondern von echten Maschinencode. Ich würd gern mal einen von itchy programmierten Flugsimulator sehen der auf interpolation der Daten verzichtet.
jeder (spiele)Netcode den ich kenne verwendet interpolation um die postionen der spieler vorrauszusehen weil Daten eben nicht immer zuverlässig ankommen. Das auch Spiele wie DAoC interpolieren sieht man gut bei massenschlachten und wenn es mal lagt.
Aber wie gesagt ..war nur ein Hinweis..ihr könnt euch auch Echtzeit als 10
sekundentakt definieren, dann passt das auch wieder
gepostet vor 17 Jahre, 11 Monate von Flint
Gorgo wir reden hier über Browsergames!
Was ich unter "Echtzeit" in diesem Zusammenhang verstehe habe ich am Anfang explizit hingeschrieben.
Wenn du aber über was ganz anderes reden willst ist das gut und schön nur schreibs dabei
gepostet vor 17 Jahre, 11 Monate von gorgo
ich red aucd über browsergames
und Echtzeit in browsergames ...
edit: ich hab immer die angewohnheit den leuten meist ins Profil zu schauen und mir auch ihre Arbeit anzusehen. mach mal bei mir denn weist das ich hier nicht nur teoretisiere
gepostet vor 17 Jahre, 11 Monate von Flint
Naja ich halte Vergleiche mit MMORPGS ala DAOC und Flugsimulatoren mit Browsergames für wenig relevant, auch wenn sie für deine Argumentation natürlich nützlich sind.
Woraus entsteht die Notwendigkeit der von dier beschriebenen Interpolation bei DAOC? Ganz einfach um die latenz zwischen Client und Server zu verschleiern und die Interpolation findet auf dem Client und nicht auf dem Server statt. Sieht man immer schön wen mann einen Disconnect/Lag hat und der Char noch in die alte Richtung weiterläuft. Ist zumindest bei WoW so, DAoC hab ich schon ewig nicht gespielt.
Ich kann keine für Browserspiele relevante Argumentation erkennen außer das der Begriff Echtzeit nicht ganz passend ist. Vorallem wenn man anfängt den Begriff Echtzeit aus der Spielewelt mit dem Begriff Echtzeitprogrammierung aus der Informatik zu vermischen.
gepostet vor 17 Jahre, 11 Monate von Sarge
Also ich sehe es wie Gorgo.
Interpolation ist ein legitimes Mittel das man einsetzen sollte, wenn man solche Späße wie Itchy beschrieben hat ermöglichen will.
Der unterschied ob man nun ein Eventsystem vom User direkt berechnen lässt immer wenn er die Information abruft oder von einem Dämonen ganze Zeit über berechnet ist prinzipiell ja kaum ein unterschied. Du verschiebst nur die Last ein wenig, wenn der dämon arbeitet verteilt er es imho schöner über die Zeit aber du kannst einzelne Peaks haben die anders nicht aufgetreten wären... berechnet der user es hat er immer ein kleinen peak da er es zuerst berechnen muss bevor die seite da ist. Da finde ich persönlich die Dämon lösung schöner, aber es kommt ab einer gewissen Userzahl eh zu kaum ein unterschied mehr da immer jemand online sein wird.
Allerdings erlaubt dir imho weder der Dämon noch die vom Userberechnete reine Event-Lösung solche späße wie Itchy es vorhat. Da sind updates imho nötig. Aber ich würde dies nicht an einer Zeit festmachen wie er - alle 30sec werden die Flotten aktualisiert. So hast du einen sehr bösen Peak und dieser wird dir imho Schwierigkeiten ab einer gewissen Größe bereiten. Warum du auf Interpolation der verbleibende Zeit (also die Zeit die seit der letzten 30sec marke vergangen ist und in dieser Zeit hätte sich dein Schiff ja auch bewegt - vllt macht das genau den unterschied aus ob ein Scanner ihn erwischt oder nicht) verzichtest ist reine Faulheit dann und ein Verlust von Genauigkeit. Kann man aber machen.
Rein theoretisch würde es auch ganz ohne diese Updates gehen und man könnte den ganzen Weg interpolieren, aber da würde die Anzahl der zu berechnenden Objekte wirklich viel zu sehr steigen.
Ich würde ein solches Update wie gesagt aber nicht an der Zeit festmachen sondern nun ,nehmen wir der einfachheit halber dieses Beispiel der Schiffe und einer 2 dimensionalen karte, ein logische Unterteilung der Karte nocheinmal unternehmen und ein größeres Raster über diese legen. Nun setzt du ein Event zu dem interpolierten Zeitpunkt wann dieses Schiff die nächste Rasterlinie überschreitet, wenn dieses erreicht wird wird das Schiff dem neuen Raster zugeteilt.
Bei einer Aktion nun wie dem Scannen so musst du nur alle Objekte interpolieren die in den betroffenen Raster ( bei geeigneter Rasterwahl und Scannerreichweite gerade einmal max 4 Raster) vorhanden sind. Somit hast du eine genaue Berechnung der Positionen ohne diese 30sekunden Peaks indem _alle_ berechnet werden müssen. So werden diese Updates schön verteilt über die Zeit gemacht da jedes Schiff ja zu einem anderen Zeitpunkt eine Rastergrenze überschreitet.
Zwei kleine Ausflüge:
Ein client-mmorpg arbeitet wie gorgo gesagt hat auch mit Interpolation/"predictions", da man dort vorallem auch mit dem Fall umgehen muss das Nachrichten verloren gehen und somit nicht garantiert werden kann das innerhalb 100-200ms die neue Position des Gegners da ist da sonst ein merkliches ge"beame" stattfinden würde. So manch einer updated die Position im client dann nichteinmal auf die tatsächliche Position die er erhalten hat, sondern versucht dann zwischen Interpolation und tatsächliche ein schönen weichen übergang zu berechnen und du siehst tatsächlich eigtl meiste Zeit garnicht die "wirklichkeit".
Sehr schön sieht man es wie gorgo schon gesehen hat in DAoC wenn ein Spieler ein disconnect hat das er immer weiter seinen letzten Bewegungsvektor weiterläuft, oder bei WoW merkt man oft wie leute zu ihrer tatsächlichen Position zurück"gebeamt" werden. Bei Guildwars ist mir aufgefallen das die Feindbewegungen allesamt schön flüssig gemacht wurden, man sich selbst dafür des öfters mal ein stück "teleportiert" wenn der Server schon meint das du schon n ganzes Stück weiter bist am Gegner dran als dir es dein Client dargestellt hat weil die Interpolation gemeint hatte du würdest mit einem Gegnerischen Spieler kollidieren und dich nicht durchgelassen hat.
Ein kleinen Abstecher nur am Rande in die Welt der Informatik: Dort ist vereinfacht "Echtzeit" so definiert, das du garantieren kannst das Aktion xyz innerhalb von t z.b. Millisekunden o.ä. ausgeführt werden kann zu jedem Zeitpunkt/Zustand in dem sich dein System eben befindet. Dann unterscheidet man meist noch harte Echtzeit indem diese Forderung uneingeschränkt gelten muss. ( z.b. die Entscheidung ob der Airbag in deinem Auto ausgelöst werden soll oder nicht muss immer innerhalb soundsoviel ns getroffen werden ) oder weiche Echtzeit indem vereinzelte Zeitüberschreitungen erlaubt sind aber in irgendeiner form bestraft werden. Z.b. ein mediaplayer.
gepostet vor 17 Jahre, 11 Monate von Wulf
@Sarge und gorgo
Koennt ihr mal "Interpolation" genauer definieren?
gepostet vor 17 Jahre, 11 Monate von Sarge
Naja ganz simpel z.b.:
Du hast startpunkt(x,y) S, bewegungsvektor (x,y) v und startzeit - aktuelle zeit-> vergangene Zeit t.
also aktueller Punkt deines schiffes P = S + v*t
D.h. du musst nicht andauernd die position neu berechnen sondern kannst zujedem beliebigen Zeitpunkt einfach direkt den jetzigen punkt berechnen. auch wenn er in der datenbank immer noch an deinem Startpunkt ist und erst wenn entsprechendes Event eintrifft zu deinem Endpunkt verschoben wird.
Das ganze kann natürlich beliebig komplex gestaltet werden, d.h. du könntest eine einem Schiff 20 wegpunkte geben , daraus die funktion berechnen und dann abhängig von zeit und geschwindigkeit des schiffes die aktuelle position auf dieser kurve berechnen.
gepostet vor 17 Jahre, 11 Monate von Wulf
Original von Sarge
also aktueller Punkt deines schiffes P = S + v*t
D.h. du musst nicht andauernd die position neu berechnen sondern kannst zujedem beliebigen Zeitpunkt einfach direkt den jetzigen punkt berechnen. auch wenn er in der datenbank immer noch an deinem Startpunkt ist und erst wenn entsprechendes Event eintrifft zu deinem Endpunkt verschoben wird.

Mmmhhh das sieht fuer mich nach der ganz normalen Positionsberechnung aus.
Ich sehe auch den Zusammenhang mit einer Datenbank nicht so richtig.
Bei Spacetale laufen alle Berechnungen immer nur im Speicher ab und werden nur zu Backup-Zwecken in die DB geschrieben.
Die Position wird serverseitig bei jedem Aufruf der getPosition() Methode neu berechnet (aehnlich der obigen Formel) und erst dann zurueckgegeben.
Dem Browser wird die aktuelle Position und Geschwindigkeit geschickt, der sie dann solange per P = S + v*t selbststaendig neu berechnet, bis ihm der Server ein Aenderungsevent geschickt hat.
Dann bekommt der Brower die neuen Daten (Position, Geschwindigkeit) - Genau da passiert dann Euer in den vorherigen Posts beschriebenes "beamen" wenn Server und Client unterschiedliche Positionen berechnet hatten und der Client sich wieder an den Serverstatus anpasst.
Nur zum besseren Verstaendnis:
Interpoliere ich dabei?
Wenn ja, serverseiteig oder clientseitig?
gepostet vor 17 Jahre, 11 Monate von Drezil
Original von Itchy
So, wie bitte bestimmst Du, welche Objekte das sind, wenn Du keine aktuellen Positionsdaten hast? In diesem Falle bleibt wirklich nur, über die Vektoren sämtlicher Objekte deren aktuelle Position auszurechnen und dann zu überprüfen, ob sich die Objekte in Reichweite befinden. Klar, möglich ist das, kann aber bei entsprechend vielen Objekten schon mal eine Sekunde Rechenzeit in Anspruch nehmen, wenn nun 10 Spieler gleichzeitig auf die Idee kommen, die Scanner anzuwerfen, hat man ein Problem.

Ich habe weit mehr als 2000 Planeten + 250 Userflotten + 1000 sonstige Obejekte..
Dann habe ich noch (nicht opimiert) x Scanner die auf verschiedenen Positionen mit verschiedenen Radien aktiv sind.
Meine Datenbank berehnet den genzen krams in nen paar ms... für mehrere 100 getroffene Objekte in einem der Radien ..
visualisiertes Beispiel: yzgyr.is-a-geek.com/mu/polmap/pol-karte060324.htm
Jeder Spieler in der Allianz [GA] sah da jeden Punkt, der sich in irgendeinem dieser Kreise befindet. Das ganze Bild ist die Galaxie mit o.g. > 3000 Objekten..
Als Server hab ich nen alten PII mit 700(?)MHz und selbst zu spitzenzeiten habe ich keine Probleme mit lahmenden Seiten (es lahmt eher daran, dass es nen Homeserver hinter ner 768er-ADSL-Leitung ist..)
Ich hab mal grad ne aktuelle gemacht ..
yzgyr.is-a-geek.com/mu/polmap/pol-karte060705.htm
Hie ist es nach Krasser .. Zu BAOD gehört nicht nur im inneren einge große Kreise, sondern auch die ganzen mittelgroßen Kreise aussen ..
Das Ganze Läuft auch noch Flüssug .. ich mach mal grad nen Screen, was alles berechnet wird ..
So (ca. 20 min später...)
Screen 1, Screen 2, Screen 3, Screen 4 (Bitte Screen 3 ansehen um die Farbgebung zu verstehen)
Ich denke man sieht nun, wie viele objekte de facto wirklich abgefragt werden.
Prinzipiell sagen, dass so etwas zu aufwendig ist ist immer schlecht.
Original von Mudder Naja Drezil.. da weiss die Datenbank wann wo gekämpft wird, aber das die neue Mine bei Fertigstellung auch arbeiten soll, dass weiss sie nicht

Dazu habe ich mich an anderer Stelle bereits geäussert..
Desweiteren habe ich ein Problem theoretischer Natur bzgl. der Datenbank
Die Daten werden auf die Festplatte geballert. Die Festplatte ist immer "lahm". Von parallelem schreiben/lesen mal ganz abgesehen. Wenn ich nun alle 10 sec (oder eben jede minute) 2000 Planeten + 100 Flotte (die fliegen) + ? die änderungen da draufballer.. Wird die nciht etwas ausgelastet? Muss die nächste abfrage nicht warten, bis die Daten komplett geschrieben sind? Wie schaut das aus, wenn man das durch Transaktionen noch verkompliziert? Ich frage lieber 2x öfter ab, als dass ich 1x unnötig schreibe ..
EDIT:

Bei Spacetale laufen alle Berechnungen immer nur im Speicher ab und werden nur zu Backup-Zwecken in die DB geschrieben.
Wäre eine praktikable Lösung dazu .. Muss man nur vorsichtig sein, dass die Daten nicht inkonsistent werden, wenn jemand mal die Sicherung im Rechenzentrum rausdreht und vergessen hat die USV's anzuschalten .. ^^
gepostet vor 17 Jahre, 11 Monate von Sarge
Wenn du die zugehörige funktion - hier im zweidimensionalen Fall den flug vektor - aus Start und Endpunkt berechnest würdest du ganz streng genommmen mathematisch gesehen Interpolieren.
Deine verwendete Art ist genau das was ich meinte, ob das nun im objekt gespeichert wird oder in der Datenbank ist ja erst einmal egal.
Das ist trivial solange das Objekt nur dargestellt wird bzw mit sich selbst agiert (richtungsänderung).
Aber wenn du nun zusätzlich zu deinem einem Objekt ein zweites hast, das mit allen Objekten in seiner Reichweite interagieren will ( wie itchy es beschrieben hat der scanner), wie realisierst du das dann?
Itchy speichert deswegen alle 30 Sekunden die positionsberechnung für alle Objekte und prüft auf diesen "veralteten" Daten. Unschön, ungenau und unperformant meiner Meinung nach.
Deswegen mein Vorschlag über ein Raster diese Objekte nur zu bestimmten Zeitpunkten zu updaten/"beamen" (rastergrenze) und dann dafür in kauf nehmen bei einer Interaktion eine etwas erhöhte berechnung wer in der reichtweite ist.
Alle Objekte der ganzen Karte zu berechnen ob sie in reichweite sind kann nicht der goldene Weg sein, wenn man das ganze in einer gewissen größe/spielerzahl haben will.
Clientinterpolation hat nun ersteinmal nichts damit zu tuen.
Dort hast du dann z.b. eine Anzahl von punkten aus der Vergangenheit und vllt eins zwei aus der Zukunft (man setzt die clientzeit etwas hinter die Serverzeit) und berechnet daraus per interpolation eine konkrete funktion um ein schönen bewegungsablauf zu bekommen (da dort das beamen wirklich sichtbar und unschön wäre ).
Bis jetzt ist das zumindest keine relevanz in BG's zumindest nicht das ich eins kenne bei dem schnell&flüssige Bewegungen nötig sind.
gepostet vor 17 Jahre, 11 Monate von Drezil
Original von Sarge
Aber wenn du nun zusätzlich zu deinem einem Objekt ein zweites hast, das mit allen Objekten in seiner Reichweite interagieren will ( wie itchy es beschrieben hat der scanner), wie realisierst du das dann?

Was meinst du mit interagieren? abfangen? Handeln? Blockieren?
automatisch oder per user-befehl?
abfangen per userbefehl geht bei mir auch jederzeit .. ist nur 1 sql-abfrage (zwar lang und ekelhaft - aber nur 1!) ..
hmm... clientinterpolation .. das bringt mich auf ne idee ...
kann man auch Ajax-daten streamen?
Man könnte ja einen Kampf auch "darstellen", wie er gerade läuft ..
mit ner ganzen menge java-funktionen im browser .. das ganze soll dan wirken wie nen video.. geht das? Kann ich dann per ajax Daten nachsenden, wer z.B. auf wen mit was feuert? Wieviel Bandbreite bracuht das? Belastet das den server sehr? ...?
gepostet vor 17 Jahre, 11 Monate von Sarge
@Drezil das war noch an Wulf geschrieben nicht dich
btw die anzahl der querys ist kein messwert den man nehmen sollte mit einer kannst auch die gesamte leistung des servers ziehen
@Clientinterpolation das musst du wohl testen ob es aktzeptabel möglich ist, wollte ich schon vor langen einmal aber nie zeit dafür gehabt.
gepostet vor 17 Jahre, 11 Monate von Drezil
Hab schon bemerkt, dass das nciht an mich war ^^
Ich finde die Anzahl der querys ist ein bedingter messwert.. Jedes abstzen der query "dauert", bis das ergebnis vorliegt ..
Bei mir heisst 1 query: 1 optimierte query, die unter normalen umständen < 0.1 sec braucht..
Leider habe ich auch keine zeit irgendwie etwas zum thema clientinterpolation zu testen ..
Aber vllt. schreibt hier wer nen Framework dafür ..
gepostet vor 17 Jahre, 11 Monate von Itchy
EDIT: ich nehme alles zurück, ich hab da MySQL echt unterschätzt und werde in Zukunft die Sachen selber testen, bevor ich hier Sachen rumposaune.
Eine Query:
SELECT id, (x+(dx*2000-start)) AS c_x, (y+(dy*2000-start)) AS c_y
FROM `test` WHERE
sqrt(((x+(dx*2000-start))-20000)*((x+(dx*2000-start))-20000)+((y+(dy*2000-start))-50000)*((y+(dy*2000-start))-50000))<10000
Dauert bei 20000 Objekten auf meinem Gurkenserver (1GHz) gerade mal 0.0049s. Bin echt beeindruckt von der Performance.
Damit kann man wirklich die Positionen bei Bedarf berechnen und nicht in irgendwelchen großen Intervallen.
gepostet vor 17 Jahre, 11 Monate von Sarge
niemand vergleicht hier BG's mit client-spielen und will jetzt in der diskussion eine clientseitige interpolation vornehmen... so zumindest mein empfinden. Es geht nun einzig alleine um die Serverseite und warum ich dort getrost auf ein 30sek tick verzichten kann um "echtzeit" hinzukriegen oder eben auch nicht.
Arbeitet man mit rein statischen Objekten d.h. ein solche Scanner ist immer am gleichen ort nachdem er erbaut wurde könnte man auf das ganze gedöns auch komplett verzichten und ausschließlich auf das gute alte EventSystem zurückgreifen. Also wenn flotte startet berechnet man entlang des Weges wann Flotte A in Scannerbereich B eintritt und setzt entweder da ein Event bei dem es dann dahin ge"beamt" wird oder man vermerkt es/regestriert sich im Scanner je nach aufbau und muss dann garnie die Position des Schiffes updaten bis es seine Richtung ändert entweder dadurch das es ankommt oder dadurch das es vom Spieler eine Richtungsänderung bekommt.
Allerdings bekommt man damit nun wieder das problem das das aufstellen/erweitern der scan radien (bzw das berechnen der schnitte) eine nicht unerhebliche berechnung benötigen da man an sich jedes flugobjekt ja nun wieder neu berechnen müsste wann es in der neuen Scanner-Reichweite ankommt. Für ein großes Spiel auch nicht das wahre. Hier könnte wieder ein Raster helfen die menge der Kandidaten gering(er) zu halten
// Ok ich bin zugegebenermasen auch überrascht das mysql so fix ist. Allerdings ab einer gewissen größe sagen wir mal durchschnittlich 20k Spieler/server wenn man nun bedenkt damit scanner sinn machen müssen auch fluglänge selbst schon länger sein .... dann sagen wir einmal ein Spieler hat durchschnittlich ~10 flottilien unterwegs dann sind das schon keine 20k objekte mehr sondern 200k objekte...
Auch wenn mysql verdammt schnell ist zugegebener maßen (wäre interessant zu wissen ob sie wirklich die berechnung für jeden datensatz machen oder irgendein trick anwenden auf den ich nicht komme) find ich es suboptimal das es dafür alle objekte anfassen muss(meiner meinung zumindest) und diese lösung sollte relativ schlecht nach oben skalieren.
Man könnte ja einmal ein paar tests machen 10k, 100k, 1Million etc objekte die dauer
gepostet vor 17 Jahre, 11 Monate von Sarge
Ok, das ganze hat mich nun doch nichtmehr so recht loslassen wollen und ich habe folgendes Test-Script für mich/euch geschrieben...
Es fügt in eine table (zu meinen testzwecken war es (id,x,dx,y,dy,start_zeit alles int, id unique+auto_increment) beliebig viele zufalls Werte ("Flotten") ein und fragt zufällige KreisRadien um Zufallspunkte (die "Scanner") nach Objekten ab.
Code sollte selbsterklärend sein und angehängt.
Auf einem recht schwachbrüstigen Server auf dem einiges noch läuft waren die Werte für 10k
Avg was: 0.01686 , 100k 0.17562 , 1000k Avg was: 1.6390 sekunden.
Ich halten also fest, es wächst proportional zu der Eingabegröße. Skaliert also nur bedingt gut, bzw eher schlecht. Ist aber in den unteren Bereichen von selbst sehr flott unterwegs.
Wer also seine Objektzahlen klein halten kann, kann auf weitere spirenzchen verzichten.
Will man einfach "mehr", so würde ich ein Raster wie erwähnt drüberlegen und es so wählen das die Anzahl der Objekte in nem noch schön schnellen bereich sind ohne das die dafür notwendigen updates (für jedes objekt und passierte grenze eines) nicht zu groß wird.
gepostet vor 17 Jahre, 11 Monate von Drezil
Rastern schön und gut (ich mache einfach einen kasten um alle objekte und schmeiss das mit ins where ->
SELECT id, t.x+(t.dx*(now-start)) AS c_x, t.y+(t.dy*(now-start)) AS c_y
FROM `test` t join test tt WHERE
sqrt(pow((t.x+(t.dx*(now-start)))-(tt.x+(tt.dx*(now-start))),2)+ pow((t.y+(t.dy*(now-start)))-(tt.y+(tt.dy*(now-start))),2))<10000 && (tt.x+(tt.dx*(now-start))) < randRechts && (tt.x+(tt.dx*(now-start))) > randLinks && tt.y+(tt.dy*(now-start)) < randUnten && tt.y+(tt.dy*(now-start)) > randOben
ist nen bissl fixer bei einzelnen kleinen radien, weil die ergebnismenge auf die dann noch die wurzelberechnung losgelassen wird nur die restmenge ist, die den einzelnen rahmen-abfragen durch die lappen geht ..
(ich weiss nciht, ob die einelnen where-dinger nun passend angeordnet sind .. da kommt es auf die reihenfolge an ... achja.. die query oben ist pseudo-code .. den rand kann man z.b. als quadrat um den kreisradius sehen .. und now bzw. start müsste man ersezten durch passende sachen (unix_timestamp() oder so.. ggf normieren auf dir vektorangaben. macht man es sonst mit unix_timdestamp() dann bewegt sich die flotte jede sec um den vektor))
klappt aber nicht bei:
yzgyr.is-a-geek.com/mu/polmap/pol-karte060705.htm (die orangen dinger ganz aussen vergrößern die "äußere Box" so, dass sie kaum noch was filtert ..)
Solche sachen will ich spieltechnisch vermeiden.. man soll nicht mehr omnipresent sein können, da dies auch dem politischen geschehen nicht entgegenkommt (wer mein blog liest, weiss, dass ich eine "Blockbildung" will)
gepostet vor 17 Jahre, 11 Monate von jonasq
Hui, die Performance von mysql überrascht mich immer wieder....
Da ist doch einiges mehr möglich, als ich für möglich gehalten hätte.
Ich danke erstmal für eure Ausführungen, kann mir allerdings nochmal jemand genauer auf den Unterschied zwischen Daemon (wie oben beschrieben) und einem cronjob eingehen? Das ist irgendwie nicht so ganz ersichtlich.
Derzeit tendiere ich zu ner Abwandlugn der sleep/wait Methode, wobei ich die noch zeitlich testen müßte... man hat ja sonst nix zu tun *g*
/jonasq
gepostet vor 17 Jahre, 11 Monate von Itchy
Daemon = ein Programm, welches die ganze Zeit geladen (im Speicher) ist und Aufträge über Pipes, MessageQueues, Dateien, Sockets o.ä. erhält und abarbeitet
Cron = ein Daemon, der die Aufträge in den crontab files abarbeitet
Wenn man einen eigenen Daemon benutzt so hat das den Vorteil, daß eben nur ein Prozess dafür aktiv sein kann (man kann natürlich auch Kindsprozesse erzeugen, aber das liegt in Deiner Hand). Würde man z.B. einen Prozess mit dem Cron sekündlich starten, so wäre es möglich, daß Prozess von 16:00:00 Uhr noch rödelt und schon Prozess von 16:00:01 Uhr startet, was u.U. gefährlich sein kann, da man dann wieder mit irgendwelchen Sperrmechanismen (Filelocks, Semaphoren...) arbeiten müßte, damit sich die Prozesse nicht gegenseitig stören.
gepostet vor 17 Jahre, 11 Monate von jonasq
Ahja, prima.
Gut, eh ich anfange binäre Semaphoren, Locks usw einzubauen *g*
/jonasq

Auf diese Diskussion antworten