mmofacts.com

Möglichkeiten eines C++ backends

gepostet vor 18 Jahre, 4 Monate von law
Hallo,
ich bin grad in der Planungsphase eines BG´s nun möchte ich gern von euch ein paar Infos
Welche Möglichkeiten gibt es ein C++ backend zu realisieren ? Und dann noch die Vor/nachteile der Möglichkeit.
Ich möchte nicht von euch Wissen wie man das programmiert (das kann ich) ich will eher die Techniken kennen lernen.
Mfg law
gepostet vor 18 Jahre, 4 Monate von Kallisti
- Kommunikation mit Frontend ueber Sockets
- Kommunikation mit Frontend ueber Pipes
- Kommunikation mit Frontend nur ueber DB
- Frontend = backend..
Vor und Nachteile kannst du dir selbst ueberlegen. ^^
gepostet vor 18 Jahre, 4 Monate von abuzeus
Wie die Kommunikation aussieht, ist denke ich sekundär. Wichtiger ist - meiner Meinung nach - zu differenzieren, wie das Backend läuft, welche Aufgaben es übernimmt. Ob es nur als Cronjob ab und an angeworfen wird, um Berechnungen schnell und unabhängig vom Frontend zu starten, ob es als Daemon läuft um bestimmte Dinge vorzuhalten (Mails, Eventhandler,...) oder als zusätzliche Kontrollschicht (Caching, Locking von Ressourcen, Filterung, Eingabekontrolle, ...) dazusein, ob es direkt auf Eingaben reagiert, ob also bestimmte Anfragen direkt vom Frontend delegiert werden (schnellere oder sonstwie besser machbare Berechnungen/Daten holen/...) oder ob es, wie schon angeführt das Frontend selbst ist (also eigener Webserver/Server für ein Ajax-Protokoll/XML-Schnittstelle/...). Implementierungsdetails wie Pipe oder Socket sind bei guer Kapselung nicht so ausschlaggebend.
In vielen Fällen ist allein der Nutzen, der durch Trennung verschiedener Bereiche (Ausgabe/Datenberechungen oder Spiel/Ingame Messaging/Kampfberechnungen/...) nicht zu verachten. Dafür lädt man sich die Mühen einer manchmal nicht gerade superkomfortablen Sprache und die Tücken, zwei Systeme zu koordinieren, auf. Bei vernünftiger Planung aber alles halb so wild ;-)
gepostet vor 18 Jahre, 4 Monate von Kallisti
Naja, wenn du ein Backend haben moechtest, sollte imho schon die erste Ueberlegung die sein, ob es direkt mit dem Frontend sprechen kann, oder da die Datenbank zwischenhaengt und in regelmaessigen Abstaenden abgerufen wird... erst dann kannst du ja entscheiden, was genau du im Backend regeln moechtest.
Die Aussage meines Postings war weniger ob Pipe oder Socket, sondern eher direkte Kommunikation oder Zwischenebene...
gepostet vor 18 Jahre, 4 Monate von law
Es wäre in etwa so gedacht
1. Variante
Website -> Backend -> DB <- resourcen cronjob / event handler
2. Variante
Frontend (CGI) -> DB <- resourcen cronjob
(hat zufällig noch jemand einen Link wie man aktivitäten Buffern kann und die dann beim nächsten Tick auszuführen. Sodass es scheint das es live is und man net immer auf tick warten muss)
gepostet vor 18 Jahre, 4 Monate von TheUndeadable
Das sind zwei gültige Varianten.
Ich persönlich würde lieber folgende Architektur nehmen:

| Website | Event Handler |
| Backend |
| Datenbank |
So hast du eine klassische 3 Stufen Architektur und kannst schnell ein Frontent (Website oder Event Handler) austauschen, ein neues hinzufügen oder auch die Datenbank austauschen (bei ordentlicher Kapselung des Datenbankzugriffs).
Das Hauptproblem liegt dann wahrscheinlich in der Kommunikation zwischen Website (PHP) und Backend (C++). Dies kannst du über Sockets, Shared Memory oder Pipes erreichen. Eine scheiß Arbeit.
Oder du nutzt einheitliche Sprachen oder ein Framework, das zu sich kompatibel ist und viele Sprachen unterstützt.
Die einfache Möglichkeit, die ich mal gemacht haben, war folgende:

| Website | Event-Handler |
| Datenbank |
Die Website war in PHP, der Event-Handler erst in PHP, später in C++. Die Kommunikation zwischen PHP und C++ ging über die Datenbank (Polling). Es gab eine spezielle Tabelle, in der PHP Fragen stellen konnte und das C++ geantwortet hat. Das Polling war auf 1 Sekunde gestellt. Es war insgesamt akzeptabel, wenn auch beschissen. Man könnte auch eine Frage stellen, über eine Systemfunktion ein Event auslösen, das Gegenstück reagiert auf das Event und speichert die Antwort in die Datenbank. Aber ich nutze nie wieder Sprachen, die sich nicht per se verstehen.
Oder am besten gleich per Pipes, Shared Memory oder Sockets (wo wir wieder oben wären).
gepostet vor 18 Jahre, 4 Monate von Kallisti
Ist nur die Frage, ob es sinnvoll ist, Front- und Backend direkt miteinander sprechen zu lassen... hab mir darueber auch den Kopf zerbrochen.
Denke das unterscheided sich auch stark nach Spielkonzept.
Bei mir tut das Backend momentan folgendes:
Jede Minute:
- Geschwader bewegen
- Geschwader die angekommen sind kaempfen lassen
- Fertigstellung von Gebaeuden, Technologien, Einheiten abschliessen und einlagern (also einfach ein select auf die entsprechende Tabelle mit Timestamp Vergleich, wenn fertig, wird es eingelagert)
- Torpedos bewegen
- Torpedos die angekommen sind einschlagen lassen
- Auktionen die angekommen sind einlagern
Alle 15 min:
- Ressourcen verteilen
Alle 6 Stunden:
- Ingame Statistiken ueber die Spieler erstellen
Jede Nacht einmal:
- abgelaufene Kriege berechnen
- Dauerauftraege ueberweisen
- Clankosten berechnen und abziehen
- veraltete Nachrichten loeschen
- veraltete Logs loeschen
- versch. Einstellungen zuruecksetzen
- ein paar Server Statistiken schreiben
Mehr faellt mir grad net auswendig ein..
Im Grunde sind das alles Dinge, die mit ein paar DB queries abgeschlossen sind. Grad so Sachen wie Ressourcenverteilung, alte Nachrichten loeschen usw. sind ja meist nur ein Befehl...
Das einzig wirklich diskutable sind die Einheitenbewegungen und Ticks zur Fertigstellung.
Klar ist es wenig nervig, wenn ein Gebaeude eigentlich fertig waere, aber noch einige Minuten braucht.. so tragisch hingegen auch nicht. Wobei man natuerlich hier auch noch eine redundante Loesung gekoppelt mit dem Frontend eingehen koennte.
Ich weiss nicht, wie es performance maessig aussieht jede Sekunde fuer 10-30 Dinge nen Query an die DB zu senden, um einfach nur abzufragen was wann fertig wird. Man koennte das natuerlich wieder in die Zukunft schauend machen, hat dann aber mit Interaktivitaet zu kaempfen. Was ist wenn der User abbricht? Was wenn andere Einfluesse dazwischenkommen? Macht es also Sinn alle Gebaeude, die in den naechsten z.B. 5 min fertig werden, intern zwischenzuspeichern? Und dann in sekuendlichen Ticks abzuarbeiten. Natuerlich muss man dann u.U. flexibel sein, wenn es um Aenderungen geht...
Die schwierigste Frage sind die Einheiten.
Wir haben eine dynamische Karte, d.h. in einem gewissen Radius sieht jeder User, was sich um ihn herum bewegt (und auch genau in dem Moment an der Stelle ist). Fahrende Geschwader sind auch abfang- und angreifbar durch andere.
Bei den Torpedos, deren Kurs vorher schon klar ist und sich nur durch Kurskorrekturen ihres Ziels aendern wuerde (Neuberechnung), kann man das natuerlich relativ einfach vorausberechnen, auch wenn das Query zur jeweiligen Abfrage ob ein Torpedo sich hochgerechnet in der eigenen Sonarreichweite befaende ein wenig komplizierter wird, dennoch natuerlich nicht so schwer.
Bei den Geschwadern hingegen bin ich mir da noch nicht so sicher... ist schon relativ dynamisch und wenn ich nun in jedem Abfragequery kompliziertere mathematische Formeln (aktuelle Position anhand von Startpunkt, Ziel und Reisezeit errechnen) habe, ist die Frage inwiefern das von der Performance her zu regelmaessigen Updates steht. Tendiere aber dazu auch dies so umzustellen.
Im Grunde muss das Backend dann nicht mehr wirklich viel tun. Alles was in gewissen Intervallen passiert abarbeiten.. vor allem natuerlich kompliziertere Simulationen wie Kaempfe.
Ich denke mittlerweile aber, dass ich das existierende C-Backend durch eines in Perl ersetzen werde. Allein schon fuer den Entwicklungsaufwand, und weil die meiste Arbeit doch noch bei der DB liegt.
Schwanke nur noch zwischen kompletter Java Loesung und PHP+Perl... Was genau waere der Vorteil es in Java zu machen? Front- und Backend koennen applikationsintern kommunizieren... was laesst sich hier optimieren? Man muss eigene Datenstrukturen fuer div. Dinge entwerfen (bsp: Flotten), was viel Arbeit bringt und u.U. dennoch unperformanter ist, als weiterhin ueber die DB zu arbeiten. Es entfaellt zwar die DB Anfrage, dennoch muss man ja auch intern die Datensaetze durchsuchen. Wieso also nicht auch hier die DB verwenden, die genau dafuer da ist.
Nun ist natuerlich die Frage ob man Minuten oder Sekundenticks haben moechte.. auch eine schwere Sache, irgendwo muss ja eine Begrenzung da sein... Unser Backend sleept nach jedem Vorgang fuer eine Sekunde und ueberprueft dann ob eine neue Minute begonnen hat. Ist das der Fall, so legt es los, wenn nicht, sleept es wieder... Man muss ja auch da auf die CPU Belastung achten.
Was bringen mir nun Sekundenticks bzw. wo merkt man es? Bei uns dauert es nach 1-2 Tagen bau u.U. mal 1 min bis etwas fertiggestellt wird... nicht tragisch. Geschwader ticken nur jede Sekunde voran.. nun gut, das koennte man mit geaenderter Positionsabfrage / -berechnung umschiffen.
Ein wirklicher Vorteil sind natuerlich die Ankunftszeiten der Geschwader. Wenn alles in einer Minute passiert, muss man priorisieren. Torpedos zuerst? Angreifer zuerst? normale Bewegungen zuerst? Sind natuerlich auch alles akzeptable Loesungen, nur erreicht man so nicht den 100%igen Realismus. Momentan ordne ich nach Geschwader ID, also mehr oder weniger chronologisch, da unsere Geschwader aber eben sehr dynamisch gesteuert und auch mal mehrere Tage und Wochen unterwegs sein koennen, ist es keine wirkliche Loesung. Hier wuerden mich sekuendliche Ticks schon sehr reizen, aber mit einer ordentlichen Ankunftsberechnung sollte auch das gehen, nur erfolg es eben nicht "wirklich" in dem sekuendlichen Moment... das macht ein wenig Timing kaputt.
Irgendwo ist das aber auch das einzige bei dem es mir wirklich auffaellt. Sollte man nun sekuendlich ankommende Geschwader aus der DB abfragen und abarbeiten? Ist das kein Performance overkill? (naja im Grunde ein Query / Sekunde Mehraufwand). Alle anderen Dinge sind minuetlich ja voellig in Ordnung, nur hier finde ich dass es auffaellt.
Ich sehe momentan also nicht ganz den Vorteil wenn das Backend ueber der Datenbank steht. Die Datenbank ist genau fuer solche Vorgaenge optimiert und fast immer - zumindest bei mir - sind die Backend aktionen lediglich zeitgesteuert und keine direkte Reaktion auf Handlungen im Frontend. Sonst koennte man den Code auch dort platzieren.
Interessieren wuerde mich wie ihr Sekundenticks realisiert habt.
gepostet vor 18 Jahre, 4 Monate von Freshman
Ich habe mir in den letzten 3 Wochen ähnliche Fragen gestellt und
auch mehrere Lösungen Programmiert.
1. Lösung:
Kompletten webeserver aufsetzen
Webserver = Frontend = Backend
Vorteile: Hohe geschwidigkeit
Nachteile: Sehr viel aufwand, weil die Programmierung eines
Webservers viele Risiken mit sich bringt.
2. Lösung:

| Website als CGI |
| Backend |
| Datenbank |
In diesem Fall habe ich ein Programm Programmiert, dass alle wichtigen
Daten vorgehalte hat, damit die Datenbank nicht all zu sehr belastet wird.
Die Datenübertragung habe ich über pipes gemacht.
Ich habe sowohl fontend wie auch Backend als CGI in c++ Programmiert.
Vorteile: Hohe geschwindigkeit, müsste allerdings getestet werden
was passert wenn mehrere gleichzeitig klicken, da es ja auch
Kritische Stellen gibt.
Nachteile:
Stellt also eine sehr hohe Anforderung an den Programmierer und an
das Programmiermodell, habe mich hier einfach mal an das
Observer - Listener Prinzip der Design Patterns gehalten.
Man hat immer 2 Programme die Synchronisiert werden müssen. Das
Einbauen neuer Funktionalitäten würde länger dauern.
3. Lösung

| Frontend (CGI) | Event Handler |
| Datenbank |
Diese Lösung habe ich im Momment im Einsatz.
Das ganze Spiel ist in c++ Programmiert, alle Berechnungen sugenommen
die Ressourcen werden im Spiel gemacht.
Vorteile:
Schnell zu programmieren bei hoher Geschwindigkeit
Nachteile:
Hohe belastung der Datenbank, da viel überwacht wird, da wie
gesagt jede Berechnung im Spiel getätigt wird.
Zur Zeit habe ich diese 3 Wege getestet. Welchen man am Ende Wähl ist
auch ein Stück geschmackssache. Wenn du schnell ans Ziel kommen
willst ist woch die 3. Lösung die schnellste.
Die Eleganteste ist es aber mit Sicherheit nicht.
Am Anspruchsvollsten ist wohl mit Sicherheit die 1. Lösung.
Hier hat man vollen Zugriff auf die Daten. Ob das immer so gut ist
bleibt in den Raum gestellt.
Ich denke am optimalsten ist die 2. Möglichkeit. Nachdem ich einmal
das System aufgebaut hatte, damit die Programme über pipes
miteinander reden ging es recht einfach vorran. Ich habe knapp 2 Abende
gebraucht bis es gut lief mit etwas hilfe von codeproject
Habe es auch einmal mit Sockets Programmiert, diesen Weg dann aber
wieder verworfen, mit gefällt die Technik der pipes besser.
Ich weiß aber nicht wie es aussieht, wenn man das backend
mit php verbinden möchte, denn ich habe das Frontend auf
c++ Programmiert.
gepostet vor 18 Jahre, 4 Monate von mifritscher
Naja, ich habe wohl die einfachst mögliche Variante genommen:

Frontend stündlicher cron-job
Objekt-Dateien (von Frontend oder cron eingebunden)
Datenbank
alles mit php
Vielleicht nicht das ausgetüftelste, es tut aber seinen Zweck und man hat keine Duplication von Code :-)
für schnellere Spiele ersetze ich den cron-job durch einen dauernd laufenden EH, der schaut ob was zu tun ist, sich dann 10 Sekunden oder bis zum nächsten Auftrag schlagen legt, den Auftrag erledigt, und sich wieder schlafen legt. Dadurch dass der EH dauernd läuft fällt das Interpretieren nicht ins Gewicht, dass muss nur 1x beim Starten gemacht werden...
gepostet vor 18 Jahre, 4 Monate von kudi
Hm
Also in meinen Konzept ist es vorgesehen, dass ich alles mit PHP mache wenn es anfällt.
BSP: Spieler logt ein oder klickt auf eine neue Seite --> neue Rohstoffe werden berechnet.
gepostet vor 18 Jahre, 4 Monate von Freshman
und was machst du, wenn ich Rohstoffe von einem Plündere,
der lange nicht da ist?
Bekommt man dann nichts, weil er nicht da war?
Des weiteren könnte das ziemlich Aufwänig werden, da du viel zu viele
Interaktionen mit der Datenbank bekommen wirst.
Dann stellt sich noch die Frage wie kompliziert deine Ressourcen
berechnet werden. Bei einer Einfachen Funktion ist das ja noch kein
Problem, wenn du sowas simples wie Ress = (Level * Level + 1) / 2 * Faktor
machst.
Wenn du aber vielleich nen log oder ähnlich komplexe Funktionen
reinbringst um einen schönen kurveneffet zu bekommen, dann könnte
dein System sehr Rechenlastig werden.
Ein Backend für die Berechnungen in einer dafür gemacht Sprache ist
schon wichtig.
gepostet vor 18 Jahre, 4 Monate von zufall_
rohstoffberechnung ist noch das einfachste. ich speichere die minutenproduktion in der selben tabelle wie die rohstoffe. ein minütlicher cronjob der "spalteA = spalteA + spalteB" ausführt ist auch bei 100000 zeilen kaum zu bemerken. man muss nur dafür sorgen, das bei minenausbau, energieknappheit oder ähnlichem die minutenproduktion angepasst wird. ich habe das ganze noch nicht als "stored procedure" getestet aber das bietet sich bei dem system auch an.
gepostet vor 18 Jahre, 4 Monate von Drezil
www.galaxy-news.de/mypage/5618_drezil/blog/144_quot_ressourcen_sind_doch_einfach_quot.html
mehr brauch ich zu ress glaub ich nicht sagen..
ich habe vorerst alles in php.. aber ich pllane mein bachend als c++-deamon, der im hintergrund die db aktuell hält.. (selbstredend ne transaktionssichere db)
kommunizert wird mit dem frontend dann nur noch über die db. per cron kann ich dann schauen, ob der deamon noch läuft.. oder ich schmeisse ihn per php (mit irgendnem befehl ging das doch..) nur dann an, wenn ich ihn brauche.

Auf diese Diskussion antworten