Entwickler-Ecke
Internet / Netzwerk - Was brauch ich für ein Lan Game
Kaspall - Di 03.05.11 22:06
Titel: Was brauch ich für ein Lan Game
Tag leute, also folgendes: Ich habe mir die letzten paar Wochen/Monate damit vertrieben einen kleinen ego-shooter mit Delphi und OpenGL zu basteln, und wie der Titel schon sagt will ich das ganze auch multiplayer-fähig machen. Ein einfaches LAN-Spiel (also kein internet-kram) würde mir schon reichen.
Ich hab mch mal schlau gemacht auf google aber so richtig die Antwort auf meine Frage bekomm ich da nicht.
Ich hab dann mal ein chat-programm mit nem Tutorial gebaut (mit WinSocketServer/Client) und versucht auf demselben Weg wie das chat-Progamm Nachrichten verschickt, auch Koordinaten vom Spiel mühsam in einen string zu packen und das dann auf den anderen Rechner zu senden, vom programm empfangen, zerlegen udn auslesen zu lassen.
Naja, nette Theorie, hm?, HA-HA-HA.
Da funktioniert genau gar nix. Ich lass die Daten 60-mal pro Sekunde raus-senden aber der Serversocket auf dem anderen Computer nimmt nix oder vielleicht mal alle 10 Sekunden was an, warscheinlich weil das Programm mit der ständigen Renderei der Spielszene beschäftigt ist. Seufz. Ich bräuchte da mal Einsteiger-Hilfe in die Netzwerkwelt mit meinem Delphi2010.
Ich hab noch nen Tipp namens INDY!! bekommen, gesucht und gefunden in meiner VLC, aber da sind ja so krankhaft viele Komponenten, und alle können weiß der Teufel alles.
Da verlier ich den Überblick, oder besser gesagt, ich hab hier keinen^^
Ich weiß nicht mit welchem protokoll ich sowas realisieren soll, was ich quasi benötige ist etwas das es mehreren Rechnern ermöglicht sich gegenseitig in Echtzeit mit Daten übers LAN zu bombadieren und auch alles schlucken und auswerten was die anderen ihnen so zuwerfen, das ganze sollte auch noch halbwegs flüssige Ergebnisse liefern.
Und: Kann ich da, wie ich bisher mitbekommen habe NUR strings übergeben oder auch direkt Zahlen, das würds mir schon mal erleichtern^^
*verneig*, Kaspall
Narses - Di 03.05.11 23:42
Moin!
Kaspall hat folgendes geschrieben : |
| Ein einfaches LAN-Spiel (also kein internet-kram) würde mir schon reichen. |
Vorab: da besteht kaum ein Unterschied, wenn es im LAN läuft, dann wird es meistens auch im Internet funktionieren. ;) (OK, gibt da bei UDP-Broadcasts idR Probleme)
Kaspall hat folgendes geschrieben : |
| Ich hab mch mal schlau gemacht auf google aber so richtig die Antwort auf meine Frage bekomm ich da nicht. |
Um es kurz und schmerzlos zu machen: es gibt dafür auch keine Patentlösung. :nixweiss:
Kaspall hat folgendes geschrieben : |
| Ich lass die Daten 60-mal pro Sekunde raus-senden aber der Serversocket auf dem anderen Computer nimmt nix oder vielleicht mal alle 10 Sekunden was an, warscheinlich weil das Programm mit der ständigen Renderei der Spielszene beschäftigt ist. |
Wenn du alles im Hauptthread der Anwendung machst, kannst du das sowieso vergessen, du brauchst auf jeden Fall mehrere Threads. :idea:
Kaspall hat folgendes geschrieben : |
| Ich hab noch nen Tipp namens INDY!! bekommen, |
Das sind "lediglich" WSA-Wrapper-Komponenten, die auch einige Standard-Protokolle abdecken. Aber das bringt dich bei deinem konkreten Problem auch nicht weiter, weil die Auswahl des Wrappers kaum Einfluss auf die grundlegenden Probleme bei diesem Konzept hat. Die Indy-Lib wird immer gerne als Schlagwort verwendet, aber als Allheilmittel wirkt das auch nicht (und ohne Nebenwirkungen sind die Kompos schon mal lange nicht).
Kaspall hat folgendes geschrieben : |
| Ich bräuchte da mal Einsteiger-Hilfe in die Netzwerkwelt mit meinem Delphi2010. |
Kaspall hat folgendes geschrieben : |
| was ich quasi benötige ist etwas das es mehreren Rechnern ermöglicht sich gegenseitig in Echtzeit mit Daten übers LAN zu bombadieren und auch alles schlucken und auswerten was die anderen ihnen so zuwerfen, das ganze sollte auch noch halbwegs flüssige Ergebnisse liefern. |
Mal so als Ansatz:
- Du brauchst für den Game-Server einen eigenen Thread, damit die Spiel-Logik nicht von der GUI beeinträchtigt werden kann.
- Wie gerade angedeutet muss die Aufbereitung der Ansicht auch in einem eigenen Thread stecken, damit das nix anderes blockiert.
- Du solltest mit timebased-movement arbeiten: also aus dem Timecode des Spiels muss die Position der einzelnen Objekte berechnet werden.
- TCP-Verbindungen werden vom OS leicht verzögert, um den Overhead bei der Paketbildung zu reduzieren. Also entweder auf UDP ausweichen (Unicasts gehen auch im Internet, lediglich UDP-Broadcasts werden normalerweise von den Providern gefiltert) oder per Socket-Option den Nagle-Algorithm abschalten.
- Du musst deine Spiel-Logik so designen, dass keine oder möglichst wenige Handshakes notwendig sind. Das kann dann zwar manchmal zu komischen "Teleporter-artigen" Effekten kommen, aber so gibt´s keine Hänger. Beispiel: Zwei Spieler bewegen sich und schießen aufeinander. Für den Schuss ist es eigentlich nur wichtig, wann dieser ausgelöst wurde, den "Rest" kann dann jeder Client für sich aufbereiten und in die GUI bringen. Ob getroffen wurde, sollte dann allerdings wieder der Server vorgeben, damit es nicht zu Inkonsistenze kommt. Vorteil: das ganze fühlt sich viel "flüssiger" an, weil so die Projektilposition nicht synchronisiert werden muss. Generell: der Server sollte nur mit "Eckdaten" arbeiten und diese bei den Clients synchron halten, das Inbetweening sollten die Clients für sich ausfüllen. Weil: es kommt nicht darauf an, dass die Bildausgabe des Spiels bei zwei nebeneinander aufgestellten Monitoren exakt synchron ist, normalerweise sieht jeder Spieler ja nur sein eigenes Bild und hat keinen Vergleich. Es kommt also nur darauf an, dass die Aktionen und Resultate folgerichtig sind. ;)
- Es bringt in der Regel nix, stumpf 60 mal pro Sekunde die Position eines Objektes zu senden, damit erzeugst du nur Netzlast. Übertrage absolute Positionen, aber nur dann, wenn sich das Objekt bewegt hat.
Das mal so als grobe Orientierung. Es ist leider eben gar nicht mal so einfach, "ein einfaches LAN-Spiel" sauber zu implementieren... :?
Kaspall hat folgendes geschrieben : |
| Und: Kann ich da, wie ich bisher mitbekommen habe NUR strings übergeben oder auch direkt Zahlen |
Selbstverständlich kannst du auch binäre Daten übertragen, das müssen nicht zwangsweise Strings sein. Allerdings ist das nochmal leicht schwerer handzuhaben, weil sich mit Strings besser "hantieren" lässt. ;)
cu
Narses
Kaspall - Mi 04.05.11 10:29
Danke mal für die mächtige Antwort, ich muss mir da quasi selbst was überlegen was:
A: das Netzwerk nicht überlastet mit zu vielen Anfragen und,
B: Muss ja nicht 100% synchron sein, HEHE
Also wenn ich beispielsweise alle clients die Position an den server senden lasse, server verarbeitet, rechnet die Szene ob jemand wen erschossen hat oder so ect. und schickt dann die aktuellen Positionen an die Spieler wieder raus, wobei sich bei denen nur die Positionen der anderen Spieler update damit man selber "ruckelFrei" rumrennt^^
Nja, ich glaub da heißt es probieren, probieren, probieren^^
ALF - Mi 04.05.11 16:10
Kaspall hat folgendes geschrieben : |
| Also wenn ich beispielsweise alle clients die Position an den server senden lasse, server verarbeitet, rechnet die Szene ob jemand wen erschossen hat oder so ect. |
nicht ganz.
Es passiert alles auf den Clienten! Der Server selbst gibt nur die 'Koordinaten oder das was passiert ist' als Info an die anderen Clienten weiter und der Client setzt es dann um.
Wenn Du(client) also ein Schuss ausführst, Procedure PlaySound(schuss.wav), dan hörst Du den weil die Wav dafür auf deinen Rechner ist!
An den Server gibst Du(client) die Info SendtoServer('Schuss'). Der Server gibt nun die Infos an die anderen Clienten SentToClients(schuss) und die anderen Clienten führt diesen Info bei sich aus, PlaySound(schuss.wav). Den die selbe Wave befindet sich auch bei allen Clienten.
Kongret, (reiner server)der Server muss also keine grapfischen oder audio sachen ausführen. Berechnen muss er auch nix. Nur die Daten verschicken!
Anders ist es wenn ein Spieler den Server macht und gleichzeitig auch Client ist.
Hier sollte man evtl ne extra exe machen die dann als Server fungiert und im Hintergrund läuft!
Beides in eine Exe zu integrieren geht auch, ist aber manchmal sehr hinderlich!
Gruss Alf
Mr_Emre_D - Mi 04.05.11 18:58
Aus der Sicherheitsperspektive ist das totaler Müll.
Rechnungen sollten nur beim Server laufen, sonst nichts und nirgends!
Der Server nimmt relative Daten an, prüft sie auf Integrität, führt, falls notwendig, intern Berechnungen durch um für weitere Integritätsüberprüfungen vorbereitet zu sein, und "reicht" die Daten weiter.
Alle Berechnungen, die clientseitig ablaufen, sind nicht vertrauenswürdig.
Ich kann mich leicht durchs Code stöbern und die Berechnung manipulieren.
Ich werde dir jetzt eine universelle Methode/Protokoll beschreiben, für die du nur zwei Klassen benötigst und sogut wie überall einsetzen kannst.
1. DatenpaketKlasse
2. PufferKlasse
1. Die Datenpaket-Klasse besteht aus zwei Elementen:
- Größe
- Daten
In ihr befindt sich ein Paket, das später in die Warteschlange der PufferKlasse aufgenommen wird (Queue).
2. Eine PufferKlasse, die Daten queuet (in eine Schlange aufnimmt).
Zur Funktionalität:
Zu jeder Server- und Clientsocket Komponente definierst du dir zwei Pufferklasseninstanzen.
Pseudocode
Quelltext
1: 2: 3: 4:
| TMySocket = class(<SocketTyp>) private SendBuffer, ReceiveBuffer: TPufferKlasse; end; |
Wichtig ist, dass du nun jedesmal, wenn du etwas Seitens Client oder Server schicken willst, dieses nicht direkt tust, sondern in deine Pufferklasse (SendBuffer) pufferst.
Optimalerweise werden dann in einem Thread die Puffer abgearbeitet. Genau dasselbe sollte auch mit dem Empfangen geschehen. Datenpakete, die ankommen, werden sofort an die Warteschlange drangehängt (ReceiveBuffer; gepuffert).
Jetzt kommt der Knackpunkt bei dem ganzen: Merken, wann ein Datenpaket angekommen ist.
Du liest vom Datenpaket erst einmal die Größe aus dem Datenstrom aus.
Ist die Gesamtgröße der Warteschlange > Größe + Größe der Größe im Datenstrom, dann ist dieses Paket vollständig angekommen und darf nun von der Schlange entfernt werden.
Narses - Mi 04.05.11 20:59
Moin!
Mr_Emre_D hat folgendes geschrieben : |
| Aus der Sicherheitsperspektive ist das totaler Müll. |
Aha, du fängst beim Häuser bauen also auch immer direkt im 3. Stock an, ja? :zwinker:
Mr_Emre_D hat folgendes geschrieben : |
Rechnungen sollten nur beim Server laufen, sonst nichts und nirgends!
Der Server nimmt relative Daten an, prüft sie auf Integrität, führt, falls notwendig, intern Berechnungen durch um für weitere Integritätsüberprüfungen vorbereitet zu sein, und "reicht" die Daten weiter.
Alle Berechnungen, die clientseitig ablaufen, sind nicht vertrauenswürdig. |
Ja, das ist alles sicher schön und gut, aber wenn du die Basics nicht drauf hast, dann werden die komplexen Sicherheitsüberlegungen das Ganze bestimmt einfacher machen... :lol:
Mr_Emre_D hat folgendes geschrieben : |
| Ich werde dir jetzt eine universelle Methode/Protokoll beschreiben, für die du nur zwei Klassen benötigst und sogut wie überall einsetzen kannst. |
Hast du schön und richtig beschrieben, bringen aber für die Probleme, die der Threadersteller hat, leider keine Besseung. :nixweiss: Die stecken nämlich in der Spielelogik/-technik, und nicht in der Transportschicht. :idea:
cu
Narses
ALF - Mi 04.05.11 21:34
Mr_Emre_D hat folgendes geschrieben : |
Aus der Sicherheitsperspektive ist das totaler Müll.
Rechnungen sollten nur beim Server laufen, sonst nichts und nirgends!. |
Welche Rechnungen? Die xy Coordinaten der Spieler ob er den Gegenspieler sieht oder was für rechnungen meinst Du .
In einem LanGame muss generell der Client alles ausführen! Der Server stellt nur sicher das die Infos (Pakete)an die jeweiligen Clienten gesendet werden. Es interesiert dem Server nicht, wie weit ein Spieler vom andern entfernt ist oder ob er sich gerade Duckt hinter einen Baum versteckt oder ob er Tot ist. Das einzigste was der Server noch übernehmen kann ist die Statistik. Klar da muss er natürlich Rechnen wenn er die Ergebnisse für alle liefern soll.
Primitiv ausgedrückt; dem Server ist es egal was da für Daten hin und her gehen.
Nur die Clienten selber wissen damit was anzufangen!
Weiss also auch nicht was Du sagen wolltest mit Deinem Thread. :gruebel:
Alles andere hat
Narses ja schon gesagt
Gruss Alf
Mr_Emre_D - Mi 04.05.11 22:05
Narses
Diese Analogie ist nicht unbedingt angebracht. Wenn man sicher programmiert, dann von grundauf!
Exzerpt, Threadstarter
| Zitat: |
"(...)Ich hab dann mal ein chat-programm mit nem Tutorial gebaut (mit WinSocketServer/Client) und versucht auf demselben Weg wie das chat-Progamm Nachrichten verschickt, auch Koordinaten vom Spiel mühsam in einen string zu packen und das dann auf den anderen Rechner zu senden, vom programm empfangen, zerlegen udn auslesen zu lassen.
Naja, nette Theorie, hm?, HA-HA-HA.
Da funktioniert genau gar nix"
|
So wie es aussieht, werden Daten nicht richtig übermittelt. Das Problem liegt also bei der Übermittlung von Daten!
Alf
Genau das meinte ich ist Quatsch.
Sagen wir mal, meine absoluten Koordinaten sind bei einem 2D Spiel x: 0 ^ y: 0 und ich kann mich nur schrittweise in eine Richtung bewegen.
Was ist nun, wenn ich rein theoretisch das Spiel hacke und anstatt schrittweise, über das ganze Feld springe - bzw. teleportiere?
Wenn die Berechnungen beim Clienten (Spieler) laufen, dann ist soetwas sehr einfach realisierbar! Und das sollte man imho meiden!
Nichts für ungut!
ALF - Mi 04.05.11 22:26
Mr_Emre_D hat folgendes geschrieben : |
Alf
Genau das meinte ich ist Quatsch.
Sagen wir mal, meine absoluten Koordinaten sind bei einem 2D Spiel x: 0 ^ y: 0 und ich kann mich nur schrittweise in eine Richtung bewegen.
Was ist nun, wenn ich rein theoretisch das Spiel hacke und anstatt schrittweise, über das ganze Feld springe - bzw. teleportiere?
Wenn die Berechnungen beim Clienten (Spieler) laufen, dann ist soetwas sehr einfach realisierbar! Und das sollte man imho meiden!
|
Wovon reden wir?
Das wird bestimmt kein Spiel ala COD4, Crysys, ET, WOW und wie sie alle heissen.
Natürlich kann man nun die Engine mit einfliesen lassen, geb ich Dir ja recht.
Ich glaube aber das dies den Rahmen den der TH vor hat sprengen würde.
Also beschrengt man sich auf das Notwendigste. Da hat er schon genug zu tun :mrgreen:
Gruss ALf
Mr_Emre_D - Mi 04.05.11 22:56
-.-'
Ich weiß zwar, dass der Threadstarter noch ein Neuling ist oder zumindest in dieser Hinsicht, aber trotzdem finde ich diese Einstellung nicht ok. Wenn er etwas lernt, dann auch richtig. (bezieht sich jetzt auf ALF)
Übrigens, es ist gar nicht so schwer, die Berechnung auf dem Server durchzuführen. Da muss er es nur dementsprechend ausprogrammieren. Mehr nicht. Keine extra Hürden!
ALF - Do 05.05.11 00:10
Mr_Emre_D hat folgendes geschrieben : |
| ..aber trotzdem finde ich diese Einstellung nicht ok. Wenn er etwas lernt, dann auch richtig. (bezieht sich jetzt auf ALF) |
Das hat mit lernen weniger zu tun als mit Zeit. Da er dies allein macht und noch in diesem Leben Spielen will mit seinen Freunden :wink:
Mr_Emre_D hat folgendes geschrieben : |
| Übrigens, es ist gar nicht so schwer, die Berechnung auf dem Server durchzuführen. Da muss er es nur dementsprechend ausprogrammieren. Mehr nicht. Keine extra Hürden! |
Wenn das so einfach ist, frage ich mich, warum grosse Hersteller allein für die Netzwerkengine
mehr als 1Jahr brauchen incl tests und dann trotzdem noch xPatches rausbringen. Dort arbeitet eine grosses Team genannt Profis. Gut, der vergleich hingt :wink: ändert aber nix am Prinzip.
Wenn er die Engine als Server deklariert ok. Nur dan ist er alt und grau wenn er damit fertig ist! Ei die weil dies was anderes ist, als wenn er nur ein Server schreibt zum Connecten, und der den TRransport verwaltet.
Darauf würde ich mich als
einzelner gar nicht einlassen. Hier würde ich das echt so umsetzten, der Client macht ALLES und der Server dient nur als Schnittstelle.
So hat er wenigstens noch Zeit, irgendwann mit seinen Freunden sein Spiel zu spielen.
Und wenn er dies fertig hat, hat er schon überdurchnittlich viel gelernt.
Wenn ich mich recht entsinne gabs da sogar Spiele,
langlang ist her, die nach diesem Prinzip arbeiteten.
Egal, entscheiden muss er selber, dies können wir ihm nicht abnehmen :mrgreen:
Gruss Alf
Mr_Emre_D - Do 05.05.11 01:03
So leid mir das auch tut - das ist schwachsinnig.
Ob er es beim Server implementiert oder beim Clienten, ändert nichts daran, dass er es SO ODER SO implementieren muss. Und vom Schwierigkeitsgrad her IST ES NICHT ANDERS. ES IST DASSELBE.
Aber ich habe keine Nerven mehr dazu...
ALF - Do 05.05.11 02:32
Ok noch mal kurz dazu:
Ich gehe davon aus das der TH ein Egoshooter hat mit KI.
Wenn er schon ein Spiel hat mit KI, so hat er schon sämtlich Informationen. Ob getroffen wurde, wie schwer er verletzt ist, ob jemand Tot ist ob ich ihn sehe oder er nur mich usw..
Anstatt der KI nimmt er nun den den anderen Rechner wo ein Mensch dransitzt und brauch nur die Daten des anderen Rechners dafür einsetzten.(ist schon schwer genug)
Will er jedoch nen richtigen Gamserver machen(so wie Du es vorschlägst) der
alles verwaltet, so muss er das Spiel FAST noch einmal schreiben nonvcl, weil er keine graphic/sound dafür benötigt, quasi aus der Vogelperspektive(Cheatsprüfung mit eingeschlossen), incl aller Maps die der Server verwaltet oder auch levels. Hinzukommt noch wann das Spiel startet ob die Clienten bereit sind usw ob sie auch alle die gleich Map haben,.. mehr will ich gar nicht sagen.
Der Server währe sozusagen der Schiedsrichter der alle Daten prüft, vergleicht ob sie Regelkonform sind und dann erst die Daten genemigt und weiter leitet.
Wie
Narses es schon in seinem Thread ausführte.
| Zitat: |
| Für den Schuss ist es eigentlich nur wichtig, wann dieser ausgelöst wurde, den "Rest" kann dann jeder Client für sich aufbereiten und in die GUI bringen. Ob getroffen wurde, sollte dann allerdings wieder der Server vorgeben,.... |
Und so geht es noch mit vielen anderen Dingen weiter. Dies währe sozusagen das Rechnen mit allen Clienten.
Natürlich ist dies das Ideale, stelle ich nicht in Abrede.
Aber
allein Programmieren, vom Testen ganz zu schweigen. Dies hat nichts mit Lernen oder wollen zu tun, sondern mit Zeit.
Da lobe ich mir meine Variante, irgend ein Spieler macht den Server sucht die Map/Level aus und ladet die anderen ein.
Könnt mich nun schlagen, steinigen
Aber ein richtigen GamesServer(Engine) selber zu schreiben ist zu Zeitintensiv!
Gruss ALf
Kaspall - Fr 06.05.11 20:51
Meine Güte, Leuteeeee. Nicht streiten^^
Also folgendes: Mein Egoshooter aht noch keine KI, das is ein reines Deathmatch-Spiel.
Ich hab die letzten Tage rumprobiert mit den TCP-Sockets die bei Delphi standardmäßig dabesind, also nix mit Indy.
Ich habs so gelöst: Der Server schickt immer die Positionen aller Spieler an alle Cleints, diese verarbeiten die Infos, bis auf ihre eigene Position, die wissen sie ja selber besser^^
Mit dazu schickt der Server die aktuelle Satistik an Lebenspunkte, kills und deaths der einzelnen Clients, also alles auf einmal. Die clients verarbeiten das für sich, wenn ein client sieht er hat einen death bekommen "stirbt" er quasi.
Sobald die clients fertig sind mit rechnen schicken sie ihre infos wieder an den server. Der Server "sammelt" die Daten aller clients und wartet maximal 1/5 Sekunde auf die Daten(geht meist vieel schneller), sobald alles da ist verarbeitet er und das Spiel beginnt von Neuem.
IM lokalen Netzwerk funktioniert das superflüssig, übers internet mit z.B Hamachi gehts eigentlich auch ganz annehmbar.
Hier ist ein Video von meinem Entwicklungsstand von vor 2 Tagen (nur eine Testszene im zu zeige das es klappt):
http://vimeo.com/23274089
Natürlich sieht das bis heute schon besser aus, in 2 Tagen rumprobieren und entwickeln geht schon einiges weiter.
Wer will kann gerne dann mal beta-mitspielen^^
ALF - Sa 07.05.11 10:50
Respekt :zustimm:
Als Betatester gern 8)
Gruss Alf
trm - Sa 07.05.11 11:20
Ich auch :)
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2026 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!