Construct-bugs icon indicating copy to clipboard operation
Construct-bugs copied to clipboard

[Multiplayer] Jump issue for peer with local input prediction

Open Chadori opened this issue 2 years ago • 10 comments

Problem description

[Multiplayer] Jump issue for peer with local input prediction.

I was observing feasibility of using the Multiplayer plugin again ever since the new updates, it's the closest thing we have to a smooth sync, until I've came across this bug again. I think this is the last issue we have with the multiplayer plugin, I really hope this finally gets fixed.

If fixing this is not a priority, please at least allow us to disable local input prediction to one axis, in this case the y-axis, since it will at least remedy the issue and make multiplayer platformer somewhat feasible. Thank you.

Attach a .c3p

B̶u̶g̶ ̶r̶e̶p̶o̶r̶t̶ ̶-̶ ̶M̶u̶l̶t̶i̶p̶l̶a̶y̶e̶r̶ ̶p̶l̶a̶t̶f̶o̶r̶m̶e̶r̶.̶z̶i̶p̶

Bug report - Multiplayer platformer.zip) - (Edited) Fixed collision points and origin of player object, just in case it disturbs testers.

Workaround

For those who need a workaround for this issue, here's a smooth solution:

Steps to reproduce

  1. Open two (2) previews, the project will automatically assign the host and peer.
  2. Try jumping from the peer's application.

Observed result

  • The peer fails to jump properly.

Expected result

  • For the client-side prediction to work with jumps.

Additional resources

  • https://www.construct.net/en/forum/construct-2/bugs-21/multiplayer-platformer-jump-113533

Chadori avatar Aug 16 '23 18:08 Chadori

Multiplayer bugs generally prove exceptionally difficult to deal with. I'm not sure we'll be able to make progress on this any time soon.

AshleyScirra avatar Aug 17 '23 10:08 AshleyScirra

Yeah, it's nearly a decade of a bug report way back from Construct 2, I'm probably expecting too much. Although, I understand, you're a small team afterall. I'll probably just have to use Unity with smooth sync for this, or Godot, since they both have multiplayer support, thanks anyway.

For other's sake though, I'll leave this open.

Chadori avatar Aug 17 '23 10:08 Chadori

For those who need a workaround for this issue, here's a smooth solution:

The concept is simple; basically, the goal is to avoid the y-axis server reconciliation (position correction) received from the host and only handle client-side prediction for the user-player peer from a peer-client perspective. However, since the Sync object action only has 4 options and none of those allow us to sync only one axis, which I also requested previously, we will have to do this indirectly instead.

image

We will need to avoid syncing our actual player with a placeholder, not to be confused with the player placeholder for the platform behavior, but a placeholder for the multiplayer entity. This placeholder must also have the same behaviors as your player placeholder, in this case the platform behavior.

image

I'll call this multiplayer entity placeholder "Mask", and it will be invisible throughout the game. The behavior and goals of the multiplayer entity placeholder will be the following:

  • Host

    • Receive input from the peer.
    • Instantly set the x-axis and y-axis of the player placeholder to the multiplayer placeholder since the host state is the authoritative state.
  • Peer

    • Receive input from the host.
    • Receive server-authoritative game state.
    • [Important] For the non-local (non-user) players, instantly set the x-axis and y-axis to their multiplayer placeholders since the game state received from the host will not be conflicted.
    • For the user player (local user), instantly set the x-axis of the player placeholder to the multiplayer placeholder. Although, DO NOT set the y-axis of the player placeholder to the multiplayer placeholder, instead allow the client-side prediction (platform behavior of the multiplayer placeholder) to simulate the y-axis movement.
  • Limitations: Since this is only a workaround, there are limitations.

    • There is a small chance that a jump can get misplaced; you must check the difference between the y-axis of the multiplayer placeholder and the y-axis of the player placeholder to see if it needs teleporting. Since this rarely happens, there's no need to interpolate; rather, just instantly set the position, although that's up to you.

    The platform behavior should now sync smoothly with the multiplayer plugin, until the multiplayer plugin is officially fixed.

Chadori avatar Aug 17 '23 16:08 Chadori

[Warning] The sample projects have simulated latency!

Chadori avatar Aug 17 '23 16:08 Chadori

suggestion: image change the data dropdown to checkboxes like the add child action: x y angle

F3der1co avatar Aug 19 '23 14:08 F3der1co

Hi @AshleyScirra, maybe we can avoid the difficult sync algorithm rewrite, at least for now, if we are allowed to disable the y-axis server reconciliation by adding flexibility in the object sync options? This includes the suggestion above, which resembles the hierarchy options.

It's the most pragmatic approach and the quickest solution. And after having tested the workaround for a while now, the sync does feel smooth, even with simulated latency. The only caveat is the very rare chance the y-axis can stray off, but that can still happen even with a decent sync algorithm.

Chadori avatar Aug 19 '23 14:08 Chadori

Hi @AshleyScirra, please at least allow us to turn off the y-axis reconciliation with the Sync object action. It really messes up the jumps. I've fixed that by making a multiplayer placeholder instance, but it messes up position correction with Sine behaviors or anything actually, by making the platform instance jump erratically.

I don't know why you think this issue is so difficult. The workaround is simply a fix by commenting this out: image

And to fix the plugin, just add options wherein it only each of the following options:

  • ro.AddValue(INTERP_LINEAR, precision, "x");
  • ro.AddValue(INTERP_LINEAR, precision, "y");

If you cannot fix stuffs like these for us, please at least allow the community to edit the runtime again. The features in Construct 2 days were more superior than today, because of the community.

Chadori avatar Sep 14 '23 04:09 Chadori

For the next beta I've added an option for Multiplayer's 'Sync object' to have individual checkboxes for X, Y and angle, so you can choose to sync just the X axis for example. However it doesn't look to me like it helps much: firstly the peer input prediction still doesn't work very well, probably because the problem is related to input prediction, not the fact it's syncing the Y axis. Secondly, naturally the peer only sees the host move horizontally, as it's not sending any Y position data. Thirdly the peer sees objects created in the wrong place as it doesn't have a Y co-ordinate so doesn't know where to vertically place a newly created object (so it defaults to a Y of -1000), although I guess it's easy to set the starting position for the peer.

I think the real problem is with input prediction. I would guess both input prediction and the Platform behavior are attempting to make contradictory changes to the object, e.g. sometimes input prediction might try to push the object in to the floor, but the Platform behavior doesn't allow that so will push it out again, but perhaps not quite in the same place, due to the fact it doesn't expect to be pushed in to a solid. The ideal solution would be for input prediction to use specially designed algorithms adapted to the Platform behavior. This might involve things like looking ahead to see if input prediction causes it to land on the floor. At this time I don't know what those algorithms would involve, so it would probably take some research and development time to experiment with and figure out the best approaches and any necessary customisations. However the Platform behavior is extremely complicated, and the Multiplayer feature is extremely complicated and compounded by problems like the fact it's tough to even attach a debugger to a multiplayer game. Perhaps it will turn out there are some simple rules that help it work well, but I don't know how it will go, and it could take a long time to get there - so I think the "difficult" tag here is well deserved.

I'd suggest exploring a workaround along these lines:

  • Sync both X and Y, but turn off input prediction. Then you have a precise movement, but on a delay.
  • On the peer, make that synced object invisible, and create a non-synced object with the Platform movement as the visible object on top of the synced object.
  • Now when the peer plays the game, the visible Platform object responds immediately, and the invisible object follows on a delay.
  • Now the task is to apply correction to the visible Platform object so it doesn't go too far off where the synced object is. Keep a history of the visible object's positions, and use that to find where it was in the past according to the network latency. Then the offset from there to the synced object should be approximately how far off the visible Platform object is in its current position. Then the challenge is to find a way to slowly (and hopefully not too noticeably) adjust the visible Platform object to correct the offset. This is difficult, especially under poor network conditions.

That essentially is what input prediction does, but the logic is in your event sheet, so you can tweak it to adjust it to the needs of a platform game. (Or if you're happy with coding, write this logic in JavaScript.) For example you might want to handle correction differently depending on if the player is on the floor, by a wall, jumping or falling. To be honest I'd be interested to know any algorithms you come up with that handle this well, as I don't know what the best approach would be, and it could take a long time to find out (and as ever we are extremely busy).

I'll leave this issue open as I think it's worth trying to find a way to get input prediction to do something a bit more reasonable with the Platform behavior, but I'm sure there will be all sorts of further cases that would need additional handling - people like to customise the Platform movement with things like wall jump, wall climbing/sliding, ladders, dashes, etc. which all potentially affects how input prediction is handled. And given this involves getting two extremely complicated features to co-operate better, it is likely to be very difficult and take a long time, so I'm afraid I can't promise when we'll be able to make progress on this.

Multiplayer is hard, and platform engines are hard - I suspect this would be very tough no matter the engine used. The custom input prediction approach allows you to try to find a way to solve the problem yourself though, and you can do that with the existing Platform behavior features. Perhaps a behavior that can track the history of object movements would help with this as it would make the historical tracking part easier, and it could be used as a "follow" behavior too. Things like that which solve bits of the problem and make custom solutions easier are probably the best direction for the time being, as I'm not sure how feasible a general-purpose input prediction algorithm for arbitrarily customized platform movements is. It may ultimately turn out that such a thing is not really possible, and so it has to be customized per-game, in which case better customization options is indeed the best solution.

AshleyScirra avatar Oct 12 '23 16:10 AshleyScirra

I was wondering if there was any progress made on solving this issue?

SPECT0R1A avatar May 16 '24 20:05 SPECT0R1A

I was wondering if there was any progress made on solving this issue?

I'm afraid no. The Construct Team has more important things to do like breaking plugins, unsupporting features and tormenting plugin developers for no reason.

  • https://www.construct.net/en/forum/construct-3/plugin-sdk-10/addon-sdk-v2-182122
  • https://www.construct.net/en/comments/67450

Chadori avatar May 17 '24 13:05 Chadori

In the next release there are two additional options for controlling how input prediction works:

  • Avoid solids: this stops input prediction moving the object in to a solid. If it would have moved the object in to a solid, it instead leaves the object in the same position.
  • Platform mode: when enabled for an object using the Platform behavior, this stops input prediction on the Y axis while the Platform movement is on the floor. It will resume input prediction on the Y axis whenever the object is in mid-air.

These settings are fairly simple but if both are enabled it seems to do a much better job of input prediction with the Platform behavior.

If it doesn't do enough, I'm afraid as per my previous comment, I don't know what else ought to be done about it. Further improvements would need research to identify a better algorithm for handling this type of movement, and that should be filed as a feature request describing the algorithm to use.

AshleyScirra avatar May 29 '24 15:05 AshleyScirra