Multiplayer & Platform behavior - position syncing

Discussion and feedback on Construct 2

Post » Fri Jul 18, 2014 3:52 pm

Hello fellas,

I'm working on a simple multiplayer platformer and having some problems with position syncing on peer side. Don't know what is the best way to implement it:

Host & Peer both have platform behavior = problems with position syncing on a peer side, because multiplayer conflicts with platform behavior ( collision with solids). Apparent position glitches, shaking etc.

Only Host has platform behavior = peer has quite a noticeable lag, almost game breaking.
Last edited by xoros on Fri Jul 18, 2014 9:49 pm, edited 1 time in total.
B
45
S
11
G
4
Posts: 517
Reputation: 7,398

Post » Fri Jul 18, 2014 4:15 pm

Every time i see a post referring this I make the argument that for platform multiplayer games the current method of if interpolation doesn't work very well. What I do is sync instructions instead of objects and get perfect results. Its a bit more complicated but it works. Not realizing what I had developed after researching I found that what im doing is called extrapolation where the client predicts position based on state instead of plotting between two known points.

Here is an example platformer that syncs instructions (function calling) instead of objects. Your welcome to try and adapt it. Just open it in a couple of browsers, click connect then use arrows to move players. You will see the synchronization is near flawless.
multiplayerPlatformFn.capx
You do not have the required permissions to view the files attached to this post.
B
20
S
7
G
1
Posts: 221
Reputation: 2,077

Post » Fri Jul 18, 2014 5:01 pm

@troublesum
Thanks! Just tried your example and it works very smooth with no lags and glitches. Gonna dig into your events to understand how you did it.

Could you roughly describe the main principle behind your implementation?
B
45
S
11
G
4
Posts: 517
Reputation: 7,398

Post » Fri Jul 18, 2014 5:48 pm

@xoros Yeah is more complicated... Ill try my best to describe how it works (as a developer i can write pretty complicated/convoluted code) :)

So to start out what I do is call functions simultaneously on all devices. I sync instructions not objects. Take a look at the Player event "Keyboard LeftArrow" You will notice i call two functions. One of them calls a function "MoveLeft" to move the player on my screen using a simulated action. You will notice the "MoveLeft" function takes a peerid as the parameter. This is so the function will for work any player (as you will see this is the same function each client will call as well using the the peerid they receive).
help1.png

The other function I call "Sync_MoveLeft". This is where the magic happens. "Sync_MoveLeft" packages up the function name "MoveLeft" and a peerid (which is my id since im the one that called it and loads them to a dictionary and then sends the dictionary AsJSON to all peers. Each peer receives the JSON string and loads it back into a dictionary on their end. They read the function name they are supposed to call and the parameters (peerid) they should pass to it and call that same "MoveLeft" function for me on there screen. All clients call the same function. pretty neat...

But I found that the signalling just wasn't quite fast enough and the player would stutter a bit while moving. This where extrapolation comes in. What did was a create method for telling the peers to persist the function call on there end. You will notice in the Sync_MoveLeft function I also package up a persist value of 1. On the peers end they see this persist value and load the dictionary for constant use on their end. So every tick they will now call the move left command with the same peerid even if i don't send another. Poof! the player moves smoothly now.

But now the player will move left to infinity so I need a way to tell it to clear that persisted action. So in the "Sync_MoveLeft" I also package up a persist tag (action tag really) with a key name "move" and the peerid of the player (more than one player could be calling move left at the same time). So what each peer does is when the see a persist value of 1 they check the perstsTag and if a persistTag already exists is clears it. So MoveLeft is persisted until MoveRight is called or stop is called. Bingo.. solid movement and precision control. If i call the same function twice thats not big deal because the persits tag will match and just keep using the same function anyway.

Last just to account account for any potential lag I send a set position command every 30 ticks while I'm moving to ensure player objects don't drift to far out of sync while performing persisted actions.

And that in a nutshell is how it works. Theres a bit more in there but I think if you follow the code along with the comments it should make more sense over time. Its just nice to know that you can achieve smooth movement you just have to do some of the heavy lifting you self and write some extra code.
You do not have the required permissions to view the files attached to this post.
B
20
S
7
G
1
Posts: 221
Reputation: 2,077

Post » Fri Jul 18, 2014 9:30 pm

I think I understand it :) Thanks again, this part is crucial for my project.
B
45
S
11
G
4
Posts: 517
Reputation: 7,398

Post » Thu Feb 05, 2015 10:55 pm

@troublesum
That's amazing!!! I was finally able to get some multiplayer platformer, but I am still having a hard time to understand how these functions works.
How could I synchronize an enemy's sprites movements between host and peers? I've already made Enemy Functions (EnemyMoveLeft, EnemyMoveRight...) and Enemy Synch Functions based on the previous ones, but each peer still see their own enemy unsynchronized.

Thank you very much.
B
5
Posts: 3
Reputation: 331

Post » Mon May 04, 2015 6:21 pm

@troublesum, why all peers have clones? Double spawn.
B
17
S
2
G
2
Posts: 10
Reputation: 1,420

Post » Mon May 04, 2015 6:53 pm

@mdvgames - I don't think i understand your question? Are you having a problem?

The idea is that when a peer successfully connects he calls a function "Spawn_Player" locally on his device and pass it his peer id and start location to create him self on his screen. He then calls a function "sync_SpawnPlayer" that will call that same function all other peers devices with the same information so now his peer object is created on everyone else's screen too. The sync message is really only sent to the host and then the host will broad cast it to the other peers so they call function he wanted with the parameters he passed.
B
20
S
7
G
1
Posts: 221
Reputation: 2,077

Post » Tue May 05, 2015 5:53 am

Message: mdvgames can only post plain text URLS until they have 500 rep. 1 URLS modified. Why?
@troublesum
Sorry for my bad english.
Look at the example and count the number of boxes when we host and peers. Open a few browser windows and check number of boxes. Peers creates more boxes..

http://zalil.su/734020
B
17
S
2
G
2
Posts: 10
Reputation: 1,420

Post » Tue May 05, 2015 7:57 am

ah.. i see what your saying. I haven't looked at this in a while and didn't see that bug. Yah the problem is when the peer asks the host to send him all other peers, the host calls the "spawn_Player" function for everyone and not just the peer that requested it. I forgot about that problem and was why I stopped using this :( .. Trying to coordinate functions to "specific" peers was too complicated in the event sheet so i created a personal plugin that wraps the multiplayer and function plugins together so it does it all for me in a single call. On the example capx however you can just add a check to the "spawn_Player" function that if an object with that peerid already exists to ignore its creation.
B
20
S
7
G
1
Posts: 221
Reputation: 2,077

Next

Return to Construct 2 General

Who is online

Users browsing this forum: No registered users and 14 guests