Из моего опыта, полная репликация состояния физики двигателя трудно и не нужно.
Для многопользовательских игр в режиме реального времени вы обычно запускаете локальную физическую симуляцию и вносите в нее исправления, если состояние (позиции, вращения, скорости) слишком сильно отличаются от состояния сервера. Unreal Engine использует этот подход, читайте дальше: https://docs.unrealengine.com/udk/Three/NetworkingOverview.html#Physics
Игры, которым требуется только исходное состояние физической сцены для выполнения анимации (например, пошаговые игры), также не нуждаются в полном физическом состоянии. Физические двигатели: deterministic, если вы используете их детерминированным способом. Для того, чтобы вновь играть по физике анимацию так же, как на двух клиентов, имейте в виду:
- Сброс (повторно создать)
b2World
перед началом моделирования, чтобы избавиться от любого внутреннего состояния в b2World
.
- Настройте свой физический мир, создавать органы на их исходных позициях и т.д.
- шага моделирование вперед, используя один и тот же фиксированные временный шаг на все клиент (не использовать рендеринг кадра времени дельты, потому что это не то же самое на всех клиентах!).
- Если вам нужно взаимодействовать с телами во время моделирования (например, применить силу), то важно сделать это на с таким же номером шага.
В качестве примера, следующая функция будет возвращать тот же результат каждый раз, когда на всех клиентов, если все они получают тот же InitialPhysicsState
:
float deterministicFunction(InitialPhysicsState state){
b2World* world = createWorld(state);
b2Body* body = world->GetBodyList();
for(int i=0; i<100; i++){
if(i==50){
body->ApplyForce(b2Vec2(10.0f, 2.0f));
}
world->Step(0.01f, 8, 3);
}
return body->GetPosition().y;
}
Спасибо за ответ. Уже сделал это с движком p2.js. – ElSajko