Fizyka nie synchronizuje się poprawnie przez sieć podczas korzystania z Bullet

11

Próbuję wdrożyć system fizyki klient / serwer za pomocą Bullet, ale mam problemy z synchronizacją.

Wdrożyłem niestandardowy stan ruchu, który odczytuje i zapisuje transformację z moich obiektów gry i działa lokalnie, ale wypróbowałem dwa różne podejścia do gier sieciowych:

  1. Dynamiczne obiekty na kliencie, które również znajdują się na serwerze (np. Nie losowe śmieci i inne nieistotne rzeczy) są kinematyczne. Działa to poprawnie, ale obiekty nie poruszają się bardzo płynnie
  2. Obiekty są dynamiczne na obu, ale po każdej wiadomości z serwera, że ​​obiekt został przeniesiony, ustawiam prędkość liniową i kątową na wartości z serwera i wywołuję btRigidBody :: progressToTransform z transformacją na serwerze. Wywołuję także btCollisionObject :: Activate (true); aby wymusić aktualizację obiektu.

Moim zamiarem przy metodzie 2 było w zasadzie wykonanie metody 1, ale przejęcie Bulleta w celu wykonania prognozy biedaka zamiast zrobienia własnej w celu wygładzenia metody 1, ale wydaje się, że to nie działa (z powodów, które nie są w 100% jasne ja nawet przechodząc przez Bullet), a obiekty czasami trafiają w różne miejsca.

Czy zmierzam we właściwym kierunku? Wydaje się, że Bullet ma wbudowany własny kod interpolacji. Czy to może mi pomóc ulepszyć metodę 1? A może mój kod metody 2 nie działa, ponieważ przypadkowo go depczę?

EDYCJA: Innym problemem z metodą 1, którą właśnie zauważyłem, jest to, że odpowiedź na kolizję będzie daleka od kolizji z niezsynchronizowanymi obiektami. Ciała kinetyczne czasami strzelają do nieskończoności, ponieważ nie można ich odrzucić.

Lucas
źródło
Kilka rzeczy, które mogą pomóc ci uzyskać odpowiedź: jakiego języka / silnika używasz? Jaki to rodzaj połączenia? Jak zły jest deficyt synchronizacji w porównaniu z pingowaniem do serwera?
Fibericon,
2
Druga opcja nie działa, ponieważ ustawiasz prędkości na wartościach serwera tylko po kilku ramkach, więc między każdym pakietem jest kilka ramek, w których rzeczy mogą dryfować. Polecam przeczytanie wszystkich postów Gaffera na temat fizyki gry, prawdopodobnie najpierw powinieneś przeczytać „napraw swój timepep”, ale oto ostatni artykuł, który mówi o fizyce w sieci gafferongames.com/game-physics/networked-physics
Roy T.
Używam samodzielnie opracowanego silnika w C ++. Jednak jestem prawie pewien, że deficyt synchronizacji nie jest taki zły, prawdopodobnie 1 ramkę na ping, jeśli musiałbym zgadywać, ale nadal wykonuję głównie testy tylko w sieci LAN. Sprawdzę te artykuły i masz rację, że prędkości są wyłączone. Jednak rzeczy są sposób wyłączone, podobnie jak skrzynia jest po drugiej stronie mapy. Czy nie powinno się jawnie ustawiać transformacji, aby ostatecznie ostatecznie się dostosowało? (nawet jeśli nie jest jeszcze ładna, drży, itp.)
Lucas,
Przeczytałem post Gaffera i był on pouczający, ale wydawało się, że dotyczy głównie ruchu gracza, co już mam. Czytałem i wydaje mi się, że mój kod metody 2 jest praktycznie identyczny z metodą stosowaną w silniku Unreal . Nie zawierają wielu szczegółów, ale zastanawiam się, czy pomysł jest dobry, ale moje użycie Bullet jest po prostu nieprawidłowe.
Lucas,
Interesująca lektura, częściowo związana z Twoim tematem: gamasutra.com/view/feature/3094/… . Chodzi o rts, a nie fizykę, ale dochodzą do punktu, w którym muszą zsynchronizować symulację na serwerze i klientach. Jak to robią? Uruchamiają niezależne symulacje zarówno na kliencie, jak i na serwerze, ale serwer wysyła pakiety, które upewniają się, że symulacja klienta nie różni się i jest poprawiana, jeśli tak się stanie ...
tom van green

Odpowiedzi:

4

Potrzebujesz odpowiedniej prognozy po stronie klienta .

Naprawdę powinieneś przeczytać szczegółowo link Roy T. podany w jego komentarzu . Opisuje, co zrobić z wkładem gracza i fizyką postaci, ale zasada pozostaje taka sama w przypadku „fizyki opartej na serwerze”.

Nie jest to łatwe do zaimplementowania, ale w kilku słowach, w przypadku obiektów gry, które muszą być zsynchronizowane:

  • Uruchom fizykę na serwerze i kliencie;
  • Serwer regularnie wysyła aktualizacje;
  • Klient stale i płynnie dostosowuje swój świat fizyki do wartości serwera.

Więc tak, podążasz we właściwym kierunku swoją metodą 2. Jednak po prostu nadpisanie wartości nie wystarczy, dostaniesz skoki na kliencie, to, co musisz zrobić, to płynnie i stale interpolować do wartości serwera.

Jeśli chodzi o rzeczywisty błąd, nie znam Bulleta, ale prawdopodobnie brakuje niektórych wartości, np. Ustawiłeś prędkości liniowe i kątowe, ale czy ustawiłeś przyspieszenia?

Laurent Couvidou
źródło
Dzięki! To sprawia, że ​​czuję się lepiej, że jestem na dobrej drodze. Omówię teraz mój kod grzebieniem z drobnymi zębami. Być może jakieś powiadomienie się nie uruchamia lub, jak mówisz, brakuje mi wartości, ponieważ metoda 2 powinna (gwałtownie) działać.
Lucas,
3

To, co robię osobiście, to ten, kto hostuje grę, tworzy świat fizyki i synchronizuje obiekty z klientami. Nawet jeśli jest to schemat sieci p2p, nadal opieram silnik fizyki na jednym z klientów odtwarzacza.

Inna fizyka, której używam, a która to czysta słodycze, nawet nie wymaga synchronizacji.

W prototypie, który wykonałem jakiś czas temu, zwanym „boilerzerker”, prowadziłem fizykę na hoście, a efekty cząsteczkowe (również przy użyciu fizyki) nie były synchronizowane w sieci, ale były niezależne dla każdego klienta, ponieważ były słodyczami.

tsturzl
źródło
Dzięki, tak, to jeden ze sposobów, aby się tym zająć. Jednak nie powoduje to miłej reakcji klienta na kolizję na rzeczy, które robi klient, a także cukierki oka nie zawsze będą poprawnie oddziaływać, ponieważ nie mogą odepchnąć rzeczy serwera (przynajmniej w tym czasie). Wydaje mi się, że to musi być możliwe, ponieważ silniki takie jak Unreal i Source wydają się to robić.
Lucas,
Eye Candy nie musi być synchronizowany, można go obliczyć dla każdego klienta. odpowiedź na klienta jest obliczana na serwerze, współrzędne dla klienta są właśnie obliczane i wysyłane z powrotem, nie wysyłasz oddzwonienia do klienta mówiącego, że koliduje, co prawdopodobnie wyglądałoby okropnie.
tsturzl
2

Niemożliwe jest wdrożenie synchronicznych sieciowych światów fizyki. Mała różnica w kroku N Oczywiście znacznie większa różnica w kroku N + 1 Nie można przyłożyć sił ani impulsów, aby zachować synchronizację i wyglądać realistycznie.

Rozwiązania:-

  1. Możesz rozważyć zsynchronizowanie tylko kilku obiektów, takich jak postacie lub samochody wyścigowe, szczególnie jeśli są one kinematyczne. Ale większość świata nie byłaby zsynchronizowana, żeby wyglądać realistycznie.

  2. Możesz mieć jeden świat fizyki na serwerze i przekazywać pozycje i prędkości obiektów klientom.

Max
źródło
Możesz spróbować zagrać w grę sieciową z fizyką, aby zobaczyć, że światy nie są zsynchronizowane. np. Need For Speed ​​World jest darmowy i zawiera gry wieloosobowe oraz podstawową fizykę. (skrzynie na drodze i przedmioty do zniszczenia)
Max
Nie jestem pewien, czy dokładnie za tobą podążam. Jestem pewien, że jest to możliwe, ponieważ wiele gier pozwala graczom na rzucanie skrzynkami (na przykład). Wygląda na to, że twoja opcja 2 jest podobna do mojej opcji 2, ale nie mogę zmusić Bulleta do czystego przyciągania obiektów do pozycji serwerów. Może to mój główny problem?
Lucas,
1
Nie. Zwykle jest to złudzenie synchroniczne. Jeśli porównasz ekrany, zobaczysz, że kiedy odbijesz się w polach, pola lecą w różnych kierunkach. lub pudełka wcale nie są fizyką (tylko edytowane animacje). Liczba pól jest różna. Kiedy mówię animacja, mam na myśli, że za ruchami nie ma animacji fizycznej. Nie stosują różnych sztuczek, dzięki czemu obraz wygląda nieco zsynchronizowany, ale nie są to synchroniczne światy fizyki. Powinieneś spojrzeć i porównać, jak poruszają się w różnych grach.
Max