Hello. Let me start with a few details about the game I'm developing.
real time Client - Server
Server is the authority
Game is 3D but played on the XZ plane (topdown view).
The client captures a state of the keyboard every frame (input), and every 33 ms sends a collection of those states to the server.
The server receives those inputs and applies them.
So far what I had was this (on the server):
for(std::size_t i = 0; i < _entities.size(); ++i)
{
auto& entity = _entities[i];
auto client = _clients[i];
for(auto& inputState : newInputs[client->id()])
{
// for each input of the client, update its position and looking direction
for(auto& input : inputState.inputs)
{
if (input.movingForward)
{
entity.x += input.dir.x * cfg.playerSpeed() * dt;
entity.y += input.dir.y * cfg.playerSpeed() * dt;
}
entity.dir = input.dir;
}
_lastInputIds[client->id()] = inputState.id;
}
}
As you can see, the client does not have the authority on his position or speed - only his direction.
But now I want to use bullet for physics, because I will need collision detection.
I have changed the above code to:
for(std::size_t i = 0; i < _entities.size(); ++i)
{
auto& entity = _entities[i];
auto client = _clients[i];
auto& inputs = newInputs[client->id()];
if (inputs.empty())
entity.rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f));
for(auto& inputState : newInputs[client->id()])
{
for(auto& input : inputState.inputs)
{
if (input.movingForward)
{
auto velX = input.dir.x * cfg.playerSpeed();
auto velZ = input.dir.y * cfg.playerSpeed();
entity.rigidBody->setLinearVelocity(btVector3(velX, 0.0f, velZ));
}
else
entity.rigidBody->setLinearVelocity(btVector3(0.0f, 0.0f, 0.0f));
entity.dir = input.dir;
}
_lastInputIds[client->id()] = inputState.id;
}
}
...
_world->stepSimulation(dt); // this is the bullet world
Now I set the linear velocity of the entity's rigid body and after a while I call _world->stepSimulation. But this is not good because the client sends multiple inputs packed together. By doing this I am ignoring all of this inputs except the last one..!
If I try to update the world inside the loop, I will be updating physics for all other rigid bodies in the world, which I do not want.
What I want is to somehow update the same rigid body multiple times but not update any other rigid bodies. Is this the way it is normally done? Does anyone know a way to do this in bullet?
Thanks a lot.
Edit: I can, of course, move the bodies manually using btRigidBody::translate. But is this a good solution?