In experimenting with building standalone dedicated server executables I came across a problem replicating vehicle movement (with my project). I suspected this was due to the nature of my project so I created a vehicle template project and built a standalone dedicated server in an attempt to isolate the issue. The same problem occurs: you cannot move your vehicle. It moves a little bit (due to client-side prediction, I suspect) but is then snapped back to its original location.
I’ve been digging through engine code to see if I can understand where this location correction would occur but I haven’t figured it out yet. It’s also entirely possible that I’m building my dedicated server executable incorrectly, since everything works just fine in PIE mode with a dedicated server. However, I did test my process with the third person character template and movement on a dedicated server works correctly. It is for this reason that I started digging into the WheeledVehicleMovementComponent, but I can’t tell where there would be a difference between the PIE dedicated server and the standalone; both report their NetMode as NM_DedicatedServer .
Run the game binary (eg, [Game].exe) and connect to the server (open 127.0.0.1:7777) (I also tried connecting to the local network IP but the movement issues persist)
Once connected, the vehicle should stutter and you shouldn’t be able to move forward
After some more experimentation, I think this issue might be related to the wheels and not client-side prediction/rewind and replay. It seems like the wheels can’t make up their mind. I’m going to try to identify what could be different about a standalone dedicated server versus the PIE dedicated server when it comes to determining the wheel position. I estimate this will take me 1-5 years to figure out.
I placed a cube in the scene with simulated physics. In the editor, running 2 clients on a dedicated server, the cube falls to the floor. In the standalone server, the cube doesn’t fall. So I think perhaps something is up with simulated physics on the standalone dedicated server. This would also explain why my projectiles work (they’re translating) and my vehicles don’t.
I’m going to try to find out why physics simulations aren’t running on the standalone server.
Engine deveveloper rcl recommended that I verify that the server isn’t expecting a local controller, as this wouldn’t be available to a standalone dedicated server. To check this in a simple setting, I created a C++ VehicleTemplate project and surrounded any calls to
GetController()
with
if (Role < ROLE_Authority)
{
...
}
and logged everything. It doesn’t appear that the server is trying to access any controllers; with or without this Role check, movement is impossible and physics simulations do not run.
Thanks to a tip from user HateDread I was able to fix this!
The SkeletalMeshComponent.bEnablePhysicsOnDedicatedServer property was preventing physics simulations from running in a standalone dedicated server environment (where the IsRunningDedicatedServer() check returns true).
The solution was to set Mesh->bEnablePhysicsOnDedicatedServer = true. This property is currently not exposed to Blueprints, so Blueprint vehicles will need to subclass a C++ vehicle superclass with this line in the constructor.
I created a pull request (https://github.com/EpicGames/UnrealEngine/pull/454) to expose this property to Blueprints so content-only multiplayer vehicle games can run on a standalone dedicated server without having to subclass a C++ vehicle class.
I probably never would have figured this out if HateDread didn’t mention it in IRC.
There is a nasty pitfall related to SkeletalMeshComponent::bEnablePhysicsOnDedicatedServer. Just in case that also someone else has stumbled on it and is reading this: enabling physics for the skeleton using the editor checkbox and then setting bEnablePhysicsOnDedicatedServer=true in code will lead to erratic behavior. You must call SetSimulatePhysics(true) after setting bEnablePhysicsOnDedicatedServer=true, even if you have the Simulate Physics box checked in the editor!