Multiplayer Spel och nätverks trafik C#, XNA och Lidgren

Permalänk
Medlem

Multiplayer Spel och nätverks trafik C#, XNA och Lidgren

Jag har sedan en tid tillbaka skrivit lite på ett spel i XNA i syftet att lära mig programmera och har nu kommit en bit, men så bestämde jag mig för att jag vill skriva in multiplayer med, läste på lite om hur UDP och TCP funkar, men insåg att det blir alldelles för mycke för mig att lära för att bara få små funktioner att fungera så tänkte att till just det kan jag använda Lidgren, vilket jag också har fått att fungera nu, till viss del iallafall.
Men sen så dök ju såklart lite problem upp med och det va därför jag tänkte skriva tråden här.
Det första problemet jag stötte på va att Servern och clienten blev lite osynkade, då clienten målar upp allting i 60fps och servern gör alla uträkningar med 30ms mellanrum(testade även 33, 16 och 17).
För att förtydliga då så kör jag En server tråd, även om man bara är en spelare, detta för att förenkla att skriva in för andra clienter med. men när clieten försöker måla i 60fps så blir movement av mobs osv ojämnt/hackigt eftersom att mobsen går inte synkat med clienten, min idée här är iallafall att skriva om ett variabelt timestep för servern så den uppdaterar på 60/per sekund med, sen tänkte jag göra något i stil med att jag skickar position + "påväg till" position till clienten, sen får båda två räkna ut det själva, baserat på tex tid, och försöka göra någon typ av felcheck med för vart moben egentligen är osv.
Men som sagt Hur brukar man göra det här typ? Är jag på rätt väg?

Sen övervägde jag om jag fick ett annat problem med, jag tror jag skickar paket lite för ofta.. just nu skickar jag all info om tex 100 mobs varje uppdatering, vilket då blev en hel del med bara en client (och det skulle ju bli mer om jag ändrade till 60upd/sec), resursövervakaren menar att jag skickade runt 200kb/s, vilket jag tyckte blev lite mycke kanske? så då kom funderingarna på om jag ska lägga in nån typ av "har något ändrats i moben" grej och bara skicka när det blir nån typ av ändring..
Hur mycke data är "okej" att skicka över nätverket?

Andra tips och idéer va gäller lidgren / nätverk uppskattas också.

Permalänk
Medlem
Skrivet av xedoz1:

Jag har sedan en tid tillbaka skrivit lite på ett spel i XNA i syftet att lära mig programmera och har nu kommit en bit, men så bestämde jag mig för att jag vill skriva in multiplayer med, läste på lite om hur UDP och TCP funkar, men insåg att det blir alldelles för mycke för mig att lära för att bara få små funktioner att fungera så tänkte att till just det kan jag använda Lidgren, vilket jag också har fått att fungera nu, till viss del iallafall.
Men sen så dök ju såklart lite problem upp med och det va därför jag tänkte skriva tråden här.
Det första problemet jag stötte på va att Servern och clienten blev lite osynkade, då clienten målar upp allting i 60fps och servern gör alla uträkningar med 30ms mellanrum(testade även 33, 16 och 17).
För att förtydliga då så kör jag En server tråd, även om man bara är en spelare, detta för att förenkla att skriva in för andra clienter med. men när clieten försöker måla i 60fps så blir movement av mobs osv ojämnt/hackigt eftersom att mobsen går inte synkat med clienten, min idée här är iallafall att skriva om ett variabelt timestep för servern så den uppdaterar på 60/per sekund med, sen tänkte jag göra något i stil med att jag skickar position + "påväg till" position till clienten, sen får båda två räkna ut det själva, baserat på tex tid, och försöka göra någon typ av felcheck med för vart moben egentligen är osv.
Men som sagt Hur brukar man göra det här typ? Är jag på rätt väg?

Sen övervägde jag om jag fick ett annat problem med, jag tror jag skickar paket lite för ofta.. just nu skickar jag all info om tex 100 mobs varje uppdatering, vilket då blev en hel del med bara en client (och det skulle ju bli mer om jag ändrade till 60upd/sec), resursövervakaren menar att jag skickade runt 200kb/s, vilket jag tyckte blev lite mycke kanske? så då kom funderingarna på om jag ska lägga in nån typ av "har något ändrats i moben" grej och bara skicka när det blir nån typ av ändring..
Hur mycke data är "okej" att skicka över nätverket?

Andra tips och idéer va gäller lidgren / nätverk uppskattas också.

Här är några bra länkar som går igenom problem och lösningar:
* https://developer.valvesoftware.com/wiki/Source_Multiplayer_N...
* http://gafferongames.com/networking-for-game-programmers/what...

Det tråkiga med multiplayer är att det är ett olösbart problem, det enda man kan göra är att dölja artefakterna. Om du vill ha mjukare rörelser kan du interpolera positionen/orientationen för din mob mellan föregående position och den senaste du fick från servern. Dvs om du vid t0 får position p0 från servern och 30 ms senare vid tid t1 får position p1 och du vill rendera i 60 fps kan du på frame 0 rita position p0, frame 1 medelvärdet av p0 och p1, och på frame 2 använda p1.

För att minska mängden data du skickar kan du:
* Bara skicka det som ändrats (det som du föreslog).
* Packa datan tightare, tex istället för att skicka 32 bitar per komponent för en position kan du istället skicka skillnaden mot förra.
* Bara skicka data som du vet att klienten behöver (tex i ett MMO behöver du inte skicka all data för NPC:er som är för långt bort för att ritas på klienten).
* Skicka data olika ofta beroende på avstånd från spelaren. Om en mob är långt bort kommer du inte märka interpolations-glitcharna som kan uppstå om du skulle skicka data 15ggr/sekund.

Permalänk
Medlem

Jag har inte läst den här, men den verkar bra:
http://www.gabrielgambetta.com/fast_paced_multiplayer.html

Permalänk
Medlem

Ja, de spel som jag har gjort som går via server så har jag gjort så att servern beräknar positionsdata med ett visst mellanrum (tiden beror på antal spelare och vad det är för spel, osv, men säg 30 ms) och klienterna grundar sedan ett "antagande" vart objektet kommer att vara under tiden som den inte får ny positionsdata från servern, dock under säg max 90 ms (tre uppdateringar från servern, 90/3 = 30). Efter att tiden har gått ut utan att klienten har fått ny data så blir det connetion timeout.
Antagandet beror på vart objektet befann sig senast, och vilka egenskaper det hade, såsom fart, riktning och dylikt.

Vad jag har förstått så är det på liknande sätt man gör i de flesta spel, och det har fungerat bra för mig iallafall. Har dock max hanterat 40 klienter (det var kopplat via virtuella maskiner till servern, där varje klient hade en random generator som gjorde så att objektet flyttade på sig olika) och det fungerade "bra", med tanke på att det var mitt första spel med flera spelare än 4.

Visa signatur

That which does not kill me makes me stronger. That which does kill me I'll deal with when I respawn.

Permalänk
Medlem

Detta får någon rätta mig på, men skriver det iallafall!
Timing är väl det svåraste, samt att räkna ut hur mycket data du verkligen behöver skicka och hur ofta.

Säg att du står på punkt A.
Flyttar dig mot punkt B., Du har en hastighet (varierande?) så du kan beräkna hur lång tid det ska ta från punkt A till B, är det kortare än en sekund? Och kommer det ha någon betydelse för gameplay:et? Har det mindre eller ingen betydelse så kan du skicka datan till klienterna att objektet kommer befinna sig mot punkt B och kommer inte att sluta röra sig förrens destination B är uppnådd. Har det större betydelse, hitta ett jämnt och bra intervall att kolla mot klienten om objektet har ändrat sin input / destination / hastighet, är detta fallet, så bör data skickas, annars kan du passa detta interval att skicka datan.

Det finns mycket som spelar in när det gäller att skicka data och ofta, så bäst är att tänka till vad du behöver skicka och hur ofta, etc

Exempel av Minimal data:
Ett rum sprängs, en sylvass nål åker genom rummet, det enda du behöver skicka är riktning, utgångshastighet / tryck, ska den rotera? Du väljer att den inte ska ha någon kollision, då är bästa valet att bara skicka denna data 1 gång till alla klienter, så får dom göra jobbet med att räkna ut vad som ska hända. Ingen data krävs för att uppdatera alla klienter med nuvarande position av nålen. (Om man nu vill att nålen ska bete sig som i detta exempel)

Exempel av Mer data:
Ett rum sprängs och en järnlåda slungas iväg i en hastighet, riktning etc, massa saker kommer att spela roll, rörliga objekts kollision (spelare, kulor, omgivning?) Här kan det vara bättre att skicka data mer frekvent för att få alla objekt synkade med kollision, hastigheter etc.

//AJL

Visa signatur

C#/MonoGame Fanatiker.
Pixel Artist & Game Developer

Permalänk
Medlem

Sist jag utvecklade nätverk var i ett spel likt Quake.
Det jag gjorde var att försöka lägga så mycket som möjligt på server sidan.
Använd nån form utav "eventhandler" när nånting sker och lägg i nån buffer.
Med hjälp av ping storlek på data kan du beräkna ett "rimligt" intervall när du skickar.
Interpolering likt det dom gör i half-life 1.

Det som är bra med att lägga så mycket du kan på serversidan gör att du även kan hantera fusk och dylikt på ett mer "korrekt" sätt.
Detta var dock i C/C++, men själva logiken och tänket ska ju fungera oavsett språk.

Visa signatur

Corsair 16GB (4x4096MB) CL9 1600Mhz | Asus P8Z77-V PRO |
Samsung SSD Basic 830-Series 256GB | Intel Core i7 3770K 3,5Ghz |
Asus Xonar Essence STX | Noctua NH-U9B SE2 | Antec Performance One P280 | Corsair HX 850W 80+ Gold Modulär | MSI GTX 770