mmofacts.com

Server = Pflicht?

gepostet vor 19 Jahre, 2 Monate von Balduran
Hallöchen

Bis vor paar Monaten hatte mein Game ca. 120 aktive Gamer...
Ich habe jede Minute per Remote-Cronjob von Cronjob.de mein Berechnungsskript aufgerufen.... das Game hatte inzwischen 4000 städte pro Minute zu berechnen.... Nach ein paar Tagen brauchte der Skript mehr als eine Minute zum berechnen aller sachen das heißt das bereits ein neuer skript gestartet wurde obwohl der erste nochnicht fertig war O_o
Nach 1 wocher wurde mir die domain gesperrt weil ich übermäßig viel DB-Traffic Produziert hatte... (Berechnungsskript hat über 70.000 Abfragen/Querys pro Aufruf getätigt)

Najo nun sind einige Spieler geflüchtet(Game hat auch nichmal en Kampfsys)
Nurnoch stolze 15 aktive Gamer :-(
Trotzdem selbes Problem.. 4k zu berechnende Städte... hab den Script nu auf schwachstellen überarbeitet nun braucht er anfangs 14 sekunden-... steigt aber inzwischen durch mehr Städte auf 19 sekunden...
ich lasse ihn nurnoch alle 20 Minuten aufrufen, bevor meine HP wieder gesperrt wird


Nun frag ich mich wie ich das problem lösen soll.....
Eigenen Server wo ich datenbank so sehr stressen kann wie ich will? oder kann man irgendwie anders alles schneller und effektiver berechnen lassen?
Ich mein ich kann mein Game ja nichmehr als Echtzeit Spiel anpreisen weils ja mit 20 minuten ticks läuft


falls ihr ne Lösung für mein Problem habt, dann helft mir
gepostet vor 19 Jahre, 2 Monate von Riston
du könntest zu Beispie mit einem VServer angangen. Ist halt net so stabil wie ein "echter" server, man kann aber alles installieren
gepostet vor 19 Jahre, 2 Monate von Balduran
und inwiefern bringt mich der server weiter? also was kann ich tun für eine bessere berechnung ?
gepostet vor 19 Jahre, 2 Monate von Qmaster
Ich glaube dasss du noch keinen eigenen Server benötigst. Zumindest nicht bei der Anzahl der Spieler. Wenn du aber ca. 20 Euro im Monat übrig hast, könntest du dir einen kleinen Root-Server mieten.

Dein Problem ist dass du zu bestimmten Zeiten sehr viel Serverlast verursachst, und genau dass sehen Webspaceanbieter nicht gern und versuchen dann solche Kunden loszuwerden. Du darfst eben andere Kunden des Betreibers nicht behindern.

Mein Vorschlag wäre, alle Aktionen nicht auf Tickbasis zu berechnen sondern in Echtzeit. Dass heisst alles geschieht genau dann wenn es geschehen sollte und nicht alle 20 min. Somit wird die Last auf die gesamte Zeitspanne verteilt .

Eine andere Möglichkeit wäre, die zu berechnende Datenmenge zeitlich zu verteilen. Anstatt alle 20 min alles zu berechnen, könnte man z.B. nach 5 Minuten die Rohstoffe zuweisen, nach 6 Min. alle Gebäude bauen, nach 7 Min. alle Kämpfe berechnen. Das wäre zwar immernoch Tickbasiert aber auf die Zeit verteilt in kleinen Berechnungsschritten die nur wenige Sekunden dauern würden. Ich denke dass dieser Ansatz auch leichter zu realisieren wäre, als der erste.
gepostet vor 19 Jahre, 2 Monate von woodworker
ich finde das problem liegt in der berechung jeder minute.

stell dir mal die frage ist das wirklich so ok?
ist das wirklich gutt durchdacht?
evtl grössere tickzeiten.
evtl echtzeit.
gepostet vor 19 Jahre, 2 Monate von Balduran
wie soll ich denn ne echtzeit hinkriegen ?
mir fällt nix andres ein als cronjobs :-(


ich hatte ne zeitlang das bei jedem seitenaufruf alles berechnet wird... ging auch alles gut... war aber zu anfang des spiels nur mit der zeit dauerte des immer länger...
gepostet vor 19 Jahre, 2 Monate von TheUndeadable
Ein ganz primitive Lösung:
Jeder Webseitenaufruf überprüft, ob es irgendwelche Jobs gibt, die noch zu erledigen sind. Allerdings musst du dann garantieren, dass nicht 2 Skripte gleichzeitig eine Aktion bearbeiten.
gepostet vor 19 Jahre, 2 Monate von Balduran
najo aber was soll ichen nu machen um echtzeit herzustellen?

ohne server werd ich nit die möglichkeit haben en programm nebenebi laufen zu lassen was alles berechnet



aber ma anders gesehen:
is echtzeit ein muss?
gepostet vor 19 Jahre, 2 Monate von Fornax
Ich hab bei mienen Gebäuden eine art echtzeit. beim bauen eines gebäudes wird der time() wert + dauer in Sekunden in der datenbank gespeichert. jedesmal, wenn die seite gebaeude.php oder nachrichten.php aufgerufen wird, guckt er, ob ein gebäude fertig ist
if($datenbank_zeit >= time()){bauen()}




ich hatte erst ein script, das in die db schrieb, wann die letzt berechnung war. dann hat er die dauer seit dem berechnet und dementsprechend die rohstoffe verteilt. Jetzt habe ich mit aber vorgenommen, ein C-Script zu schreiben.
gepostet vor 19 Jahre, 2 Monate von The_Alien
Echtzeit ist kein muß. Ist zwar etwas schwieriger zu programieren aber es verteilt die lasten besser. Und es müßen nicht inaktive berechnet werden da nur sachen berechnet werden die "neu" sind.

Wozu ein zusätzliches tool?
Zb habe ich eine routine die alle anstehenden transfers erledigt die offen sind - und das wird bei jedem seitenaufruf ausgeführt. Hört sich nach viel last an aber die aufträge müßen und werden so oder so irgendwann verarbeitet und so kommen sie an wann sie sollen und nicht "gesammelte" Werke von zig Minuten was die last dann richtig hoch treibt.

Wenn du wirklich auf Ticks setzen willst würde ich den Abstand erhöhen da ja auch aktionsmöglichkeiten zwischen den Ticks möglich sein sollten. Und dann evtl wirklich die aufteilen.
Zudem solltest du mal daten "Filter" und nur das bearbeiten was nötig ist.
Heißt nur zb dort resourcen berechnen wo auch die neuen Res benötigt werden (Bei aktiven). Denn wenn mal die Inaktiven wegfallen verurschen sie ja auch keine Last mehr.
gepostet vor 19 Jahre, 2 Monate von Balduran
sorry aber ich verstehs mit der echtzeit immernochnit so ganz :-(
ich mein vielleicht liegts daran das ich zu unerfahren bin oder halt einfach andre systeme gewohnt bin und mich da nicht reindenken kann :roll:

ich will echtzeit in meinem game und wenn ihr meint das des mit meiner spieleranzahl (also 15 -100) möglich ist dann bitte ich euch mir irgendwie en tutorial zu geben oder mir des zu erklären weil ich nicht weiss wie ich sons machen soll ausser mit diesen dummen cronjobs :-(
gepostet vor 19 Jahre, 2 Monate von The_Alien
Nun ich habe das zb so:

Eine Tabelle in der alle Flüge stehen inkl. der Zeit des starts, der ankunft und wann sie zurück sein sollen.
Bei jedem klick auf die übersicht eines Users überprüft ein script ob einies dieser schiffe angekommen oder zurückgekommen ist und wenn ja so wird es bearbeitet.Dann einfach mit der aktuellen Zeit im query abfragen.

Entsteht dadurch (zb angriff) ein Kampfbericht so wird erst dann dort die neue Resourcenmenge berechnet da in dem Planet die letzten Res und die letzte zeit vermerkt sind. Gleiches mit Gebäudebau forschung usw.

Wenn also ein User inaktiv ist so wird er bzw seine Planeten erst neu berechnet wenn sie angeflogen werden.

Meine testrunde läuft auf einer 1&1 Hompage und verträgt ohne Probleme 150 aktive user und das komplette Forum.
gepostet vor 19 Jahre, 2 Monate von RedMax
Auf diese Art habe ich auch zuerst programmiert, allerdings hatte ich da schon einen leistungsstarken Server. Das ging bis ~1500 Spieler ganz gut, ab dann schluckt das zu viel unnötige Prozessorzeit (jedesmal checken, ob was passiert ist). Ich habe dann das ganze Zeug einfach in einen Hintergrundthread gepackt und keine Performaceprobleme mehr.
gepostet vor 19 Jahre, 2 Monate von Rob-oter
Ich habe das bei mir so gelöst:

Die Ressourcen werden bei jedem Klick neu berechnet. Aber die neue Ressourcenanzahl wird nicht in die DB geschrieben, sondern nur angezeigt.

Nur alle 30 Sekunden werden die Ressourcen neu Berechnet und in die DB eingetragen.

Das System ist so ausgelegt, das aber nie Ressis verloren gehen!

Alle paar Sekunden wird auch gecheckt, ob ein Gebäude/Forschung fertig ist.
Dadurch kann ich die Querys relativ gering halten.
Wobei ich dazusagen muss, das dieses System nicht im Einsatz ist, da noch niemand spielt ^^

So, hier noch ein extrem günstiger vServer-Hoster: www.nodeeps.de
Ich selbst war dort schon Kunde, habe aber wieder gekündigt, da mir die Wartung eins Servers zu Zeitaufwändig ist. Schau dich da mal im Forum um, dann kannst du dir ein Bild vom Hoster machen!
gepostet vor 19 Jahre, 2 Monate von Balduran
Original von The_Alien

Wenn also ein User inaktiv ist so wird er bzw seine Planeten erst neu berechnet wenn sie angeflogen werden.




So wie ich des jetz verstanden habe wird nur das berechnet womit man interagiert.. also wenn ich mich einlogge wird alles berechnet was auf meinen planeten/städten stattfindet oder hat wenn ich angreife oder spioniere wird des ziel auch aktualisiert

also alles womit man interagiert


nur ne frage: wird nur der selektierte planet berechnet oder alle von einem ??
gepostet vor 19 Jahre, 2 Monate von Sogil
Hast du dir schon überlegt, den Tick nicht mehr in einem Skript zu berechnen, sondern in einem kleinen C++ Programm das vom Cronjob aufgerufen wird?

Aber auch bei den Datenbankabrufen müsste es noch erheblich optimierungsmöglchkeiten geben. 70.000 Queries pro Aufruf ist etwas arg viel...
gepostet vor 19 Jahre, 2 Monate von Sarge
also vom 1min Tick-alles berechnen solltest du aufjedenfall weg.. egal wie groß dein server dimensioniert ist, den hast du bald sinnlos vollgestopft.

Nehmen wir die Ressourcen: Interresiert irgendjemanden das 140 von 150 nicht eingeloggte user gerade x gold dazu bekommen haben? Nein das wird erst interresant wenn eine Aktion auf dem Account verursacht wird. Sei es dass der entsprechende User sich einloggt, ein Raubüberfall auf den User veranstaltet wurde oder seine Mine aufgestockt wird. Dadurch vermittelt man den User eine Art "Echtzeitberechnung".

Irgendwie scheint mir das ganze auf das alte Problem wie zähle ich die Summe von 1 bis 1000 ? solange i <= 1000 s+=i++ oder s=1000*1001/2

Bei 70k queries/aufruf =min bei gerademal 150 user wird da wahrscheinlich kein c programm mehr helfen. ich mein 70k/60 = 1,xk/sec bei 150 usern...
gepostet vor 19 Jahre, 2 Monate von Kallisti
Also wir haben Minutenticks und die Ressourcenverteilung ALLER user geht in einem einzigen query...

Ich finde es hingegen weit sinnvoller, weil sich die Last verteilt und nicht zu peakzeiten enorm hoch wird.

Vor allem Dinge wie die Berechnung von Kaempfen... wenn du das nicht automatisch geschehen laesst, musst du es 1. an zig stellen beruecksichtigen, was eigentlich immer Probleme mit sich bringt und 2. geschehen dann die meisten Dinge auf einmal wenn die meisten Leute online sind.

Ebenso die "Ueberfaelle" - Es werden in einem query alle endenden Missionen (auch Transporte, Ueberfuehrungen etc.) ausgelesen und dann der Reihe nach abgearbeitet.
gepostet vor 19 Jahre, 2 Monate von Blabbo
Ich glaube du solltest einfach mal überlegen, ob dein Spiel unbedingt 4k Städte braucht, die JEDE MINUTE neu berechnet werden müssen.

Ich weiss ja nicht, was da so fett passiert in deinen Städten, aber
1. würde das doch bestimmt auch alle 10 Minuten reichen und
2. sind 4k einfach so brutal zuviel, wer braucht denn die bitteschön?

Vielleicht einfach mal ein bisschen tiefer stapeln?
gepostet vor 19 Jahre, 2 Monate von Balduran
naja die ersten städte waren relativ schnell besetzt.. und das game hat ja kein kampfsys und da kam es ziehmlich schnell das ein paar user 1000+ städte geholt haben um auffer highscore ganz oben zu sein


mit den querys isses ja zurzeit auf 30k runtergegangen ;-)
gepostet vor 19 Jahre, 2 Monate von None
30k ?
Rufst du alle Werte einzeln ab?
 

for($x=0;$x
$var=mysql_query("SELECT * FROM `users` WHERE `id`='$x'");
$user=mysql_fetch_assoc($var);
// CODE ZUM AKTIONEN ÜBERPRÜFEN
}

Wenn du das so löst, solltest du versuchen gleich alle Werte abzurufen:
 

$var=mysql_query("SELECT * FROM `users`");
while($user=mysql_fetch_assoc($var)){
// CODE ZUM AKTIONEN ÜBERPRÜFEN
}


Wenn du 1000 User hättest würdest du beim ersten Codebeispiel 1000 Queries haben und beim zweiten nur 1!
gepostet vor 19 Jahre, 2 Monate von The_Alien
Ich denke mal die Masse kommt durchs updaten - denn man muß ja jede stadt einzeln updaten.

Aber (wenn noch nicht genutzt) evtl mal auch wegen JOINs nachschauen - dadurch habe ich 80% der querys eingespart - ist zwar von den querys aufwendiger aber erspart der Datenbank ne masse arbeit.

Aber man kann halt nichts genaues sagen sondern nur allgemeine tipps geben da man nicht weiß wie es programiert ist.

Und sowas funktioniert auch - man muß nicht erst auslesen und dann woanders eintragen:

UPDATE ship_build,planets SET ship_build.userid=planets.userid WHERE planets.gal=ship_build.gal AND planets.sys=ship_build.sys AND planets.plan=ship_build.plan
gepostet vor 19 Jahre, 2 Monate von BLUESCREEN
@Balduran:

Ich würde sagen größere BGs sollten schon einen eigenen Server haben, aber bei deiner Spielerzahl kann man noch ohne auskommen.

Vor allem gilt: Bloß keinen VServer bzw. Root-Server mieten, wenn du nicht genügend qualifiziert bist, den abzusichern und von der Software her auf dem neuesten Stand zu halten. Dein Server ist sonst nur ein Sicherheitsrisiko für das du verantwortlich bist!

Zu deiner Berechnung:

Da dieses Berechnungsscript bestimmt nicht nur eine Aktion wie z.B. die Rohstoffproduktion berechnet, sondern mehrere Dinge (z.B. Rohstoffe, Kämpfe, Bewegung von irgendwas usw.) mach am besten erstmal folgendes:
Erweiter das Programm insofern, dass es für jeden dieser Bereiche die ausgeführten Queries mitzählt und am Ende eine Übersichtsliste in irgendeine Datei oder so schreibt.
Dadurch kannst du schonmal die Schwachstellen finden.
Du könntest die Auflistung auch hier posten - es sind schließlich genug Entwickler hier, die mglw. schon auf den ersten Blick beurteilen können, wo du Queries einsparen kannst.
gepostet vor 19 Jahre, 2 Monate von Kallisti
Ein Beispiel, wie du zB mit einem Tick ressourcen verteilen kannst:

sprintf(temp, "UPDATE user SET metall=LEAST(MID(gebaeude,19,2)*4000,MID(gebaeude,21,2)*%i+metall), sauerstoff=LEAST(MID(gebaeude,19,2)*4000,MID(gebaeude,23,2)*%i+sauerstoff), rohoel=LEAST(MID(gebaeude,19,2)*4000,MID(gebaeude,25,2)*%i+rohoel), silizium=LEAST(MID(gebaeude,19,2)*4000,MID(gebaeude,27,2)*%i+silizium), element122=LEAST(MID(gebaeude,19,2)*4000,element122), credits=LEAST(MID(gebaeude,19,2)*4000,credits+%li)", get_long_from_options("metall_pro_level"), get_long_from_options("sauerstoff_pro_level"), get_long_from_options("rohoel_pro_level"), get_long_from_options("silizium_pro_level"), get_long_from_options("add_credits"));


Dabei sind alle Gebaeudestufen in einer Zeichenkette in derselben Tabelle (010101 waeren zB drei gebaeude auf Stufe 1).

Die Options am Ende liessen sich auch noch direkt mit der "einstellungen" Tabelle verknuepfen...

Ansonsten poste eben genauere Infos zu dem was bei dir wie passiert...
gepostet vor 19 Jahre, 2 Monate von docjay
also die idee find ich auch ganz gut einfach Ticks einzuführen...
Wie wärs zum beispiel, wenn du alle 5 Minuten einen Tick machst (oder alle 10) damit sparst du enorm Traffic...
Das ist dann zwar nicht mehr ganz Echtzeit, aber immernoch ein schnelles Spiel...

Mit PHP kenn ich mich leider nicht so aus, dazu kann ich dir keine hilfen geben.
gepostet vor 19 Jahre, 2 Monate von Balduran

Ich hab ma eben den script als txt datei hochgeladen dann könnt ihr euch den ja ma anschauen

...

danke für alle tipps

gepostet vor 19 Jahre, 2 Monate von schokofreak
Original von Kallisti

sprintf(temp, "UPDATE user SET metall=LEAST(MID(gebaeude,19,2)*4000,MID(gebaeude,21,2)*%i+metall), sauerstoff=LEAST(MID(gebaeude,19,2)*4000,MID(gebaeude,23,2)*%i+sauerstoff), rohoel=LEAST(MID(gebaeude,19,2)*4000,MID(gebaeude,25,2)*%i+rohoel), silizium=LEAST(MID(gebaeude,19,2)*4000,MID(gebaeude,27,2)*%i+silizium), element122=LEAST(MID(gebaeude,19,2)*4000,element122), credits=LEAST(MID(gebaeude,19,2)*4000,credits+%li)", get_long_from_options("metall_pro_level"), get_long_from_options("sauerstoff_pro_level"), get_long_from_options("rohoel_pro_level"), get_long_from_options("silizium_pro_level"), get_long_from_options("add_credits"));


Bitte überleg dir mal was da passiert, wenn temp nicht genügend gross ist.
-> Absturz der Software oder sogar Ausführung fremden Codes.
Lustisch...

Auf diese Diskussion antworten