0
\$\begingroup\$

I am running a simple box2d simulation on nodejs server.(planck.js) 2 bodies are connected to each other with distance joint and one is orbiting around another.

I also have a java libgdx client with box2d.

There are box2d world and bodies created both on client and server but for now i am not steping client side world because i am not sure how to sync client world and server world.What is happening right now is server is running the simulation,sending position data to client and client sets the position without ticking box2d world(which i know is wrong,i should run simulation at both sides and sync somehow because of latency)

I tried to fix timesteps of client and server but i am not sure whether i did it correct or not ?

This is code from server side:

     var lastUpdate = 0
    var accumulator = 0
var TIMESTEP = 1/60


        function startSimulation(){
            lastUpdate = Date.now();
                setInterval(tick,1000/60);
                setInterval(sendMovingData,40)

        }
        function tick(){

            var now = Date.now();
            var dt = now - lastUpdate;
            lastUpdate = now;

            gameLoop(dt);
            }


        function gameLoop(dt){
            var frameTime = Math.min(dt, 0.25)
                        accumulator += frameTime

                        while (accumulator>= TIMESTEP) {

                            world.step(TIMESTEP, 6, 2);
                            accumulator -= TIMESTEP;
                            setConstantVelocity()// applys forces on movingBody



                        }



        }
        function sendMovingData(){
        //sends position data to client
        }

If i use this code and just set position on client obviously result is pretty bad: (client is just seting positions world is not ticking) please checkout this video

https://streamable.com/v8r6h

If i run the simulation just on client locally without server this is how it looks: https://streamable.com/8r63k

Client side:

fun render() {
                var frameTime = Math.min(Gdx.graphics.deltaTime, 0.25f)
                accumulator += frameTime

                while (accumulator>= TIMESTEP) {


                        world.step(TIMESTEP, 6, 2);// comment this if you recieve data from server


                    accumulator -= TIMESTEP;
                   setConstantVelocity() // comment this if you recieve data from server





                }

I also tried to run simulation on both sides and implement something similar to client side prediction.Check this code and result please. Server:

var lastUpdate = 0
        var accumulator = 0
    var TIMESTEP = 1/60


            function startSimulation(){
                lastUpdate = Date.now();
                    setInterval(tick,1000/60);

            }
            function tick(){

                var now = Date.now();
                var dt = now - lastUpdate;
                lastUpdate = now;

                gameLoop(dt);
                }


            function gameLoop(dt){
                var frameTime = Math.min(dt, 0.25)
                            accumulator += frameTime

                            while (accumulator>= TIMESTEP) {

                                   world.step(TIMESTEP, 6, 2);
                    accumulator -= TIMESTEP;
                    setConstantVelocity()
                    tickNumber++
                    sendMovingData()


                            }



            }
            function sendMovingData(){
            //sends position data and tick number to client
            }

Now client side is a little bit more different:

     fun render() {
                    var frameTime = Math.min(Gdx.graphics.deltaTime, 0.25f)
                    accumulator += frameTime

                    while (accumulator>= TIMESTEP) {


                                world.step(TIMESTEP, 6, 2);

                                setConstantVelocity()
                                tickNumber++



                        accumulator -= TIMESTEP;


                    }
    }



       fun setConstantVelocity(){
        //apply forces to movingBody
           var data:JSONObject = JSONObject()
                data.put("x",movingBody.position.x)
                data.put("y",movingBody.position.y)
                data.put("tickNumber",tickNumber)
                pendingInputs.add(data) // there is an arraylist for saving client moves.

        }

fun recieveIncomingData(){ // called when server data arrives
var serverTickNumber = data.get("tickNumber").toString().toInt()

        var newPositionVector = Vector2(data.get("x").toString().toFloat(),data.get("y").toString().toFloat())
        movingBody.setTransform(newPositionVector,0f)

       var j = 0
        while (j < pendingInputs.size)
        {
            var clientMove = pendingInputs.get(j)
            if (clientMove.get("tickNumber").toString().toInt() <= serverTickNumber) // recvd from server
            {
                pendingInputs.removeAt(j)
            }
            else
            {
                var clientMoveVector:Vector2 = Vector2(clientMove.get("x").toString().toFloat(),clientMove.get("y").toString().toFloat())
                movingBody.setTransform(clientMoveVector,0f)

                j++;
            }
        }



}

This is the result of running both on client and server: https://streamable.com/vwxxb

So i read a ton about this on internet tried some interpolation stuff and client side prediction but couldnt make it work.I guess i need some code example.By the way i am not sending any input from client to server right now.

Is this correct implementation of fixed time step ? I feel like server side simulation is running faster(?)

How do i run simulation on both sides and have a smooth movement of circle while keeping server authoritative? (i guess this is releated to client side prediction but i am kinda confused and looking for examples )

edit: i converted my code to whenever client applies force on body it sends an input with sequence number, then server applies input on body and returns positions of body to client with same sequence number , than client side prediction happens.still performs bad tomorrow i will add code

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.