godotengine / godotengine/godot

CharacterBody2D position inconsistent across clients depending on collision layer mask

Open
#100,993 0 comments 0 reactions 0 assignees View on GitHub
bug needs testing topic:multiplayer topic:physics
Dominant language
C++
Stars
117k
Forks
26.8k
PR merge metrics
PR metrics pending

Description

### Tested versions


- Reproducible in v4.3.stable.official [77dcf97d8]

### System information

Windows 11 - v4.3.stable.official [77dcf97d8] - Forward+ - NVIDIA GeForce RTX 4070 Laptop GPU

### Issue description

I ran into an interesting bug with the CharacterBody2D physics and Networking. My simple example spawns the "Host" at 500,500 and the "Client" at 0,0. But then the client moves to 500,480 within a few frames.

### Example 1: Players have default collision layers
"Host" window has the "Client" player at 0,0 (as expected) but the "Client" window moves the player from 0,0 to 500,480.

![Image](https://github.com/user-attachments/assets/370b1adb-0fe9-4399-a860-20b590c4073f)

Logged position changes:
```
Changed position (0, 0) (500, 500)
Changed position (0, 0) (0, -17.47415)
Changed position (0, -17.47415) (500, 480.2612)
Changed position (500, 480.2612) (500, 479.9677)
```

### Example 2: Players ignore other players
If the collision layer is changed to "2" (i.e. the players don't collide with each other) then the position of the "Client" is consistent.

![Image](https://github.com/user-attachments/assets/6e8cae82-4e2a-48d1-bdbc-8639be3ea277)

It also is "fixed" by commenting out "move_and_slide();" on line 27 of "player.gd"

Thankfully, for my game I don't want the players to collide, so it it is good enough for me, but I would expect the "Client" player to be at 0,0 without changing the layer since the other player object is nowhere near (500,500).

### Steps to reproduce

1. Get the code from the attached project or clone the commit from my repro https://github.com/RyanRemer/multiplayer_1227/tree/ddef2c3baa4fc9119e5ce523030129106e95e9db
2. Run 2 instances of the game
3. Click "Host" on one and "Join" on the other
4. The "Client" player is at different positions on each window. On the "Host" they are at 0,0 but on the "Client" they are at 500, 479.9677.

Here is the log of any position changes:
```
Changed position (0, 0) (500, 500)
Changed position (0, 0) (0, -17.47415)
Changed position (0, -17.47415) (500, 480.2612)
Changed position (500, 480.2612) (500, 479.9677)
```

To "fix" it, change the Player > Collision > Layer to "2" instead of "1"
https://github.com/RyanRemer/multiplayer_1227/commit/d71a7cd2339b9cf879ca4d768d2a206757f6fda4
Of course, this has the side effect that players don't collide with each other

### Minimal reproduction project (MRP)

https://github.com/RyanRemer/multiplayer_1227/tree/ddef2c3baa4fc9119e5ce523030129106e95e9db

I also removed some other files to try and minimize the project here.
[project.zip](https://github.com/user-attachments/files/18284710/project.zip)

Contributor guide

Open the contributing guide

Research direction

Start with the minimal reproduction project at the linked commit and inspect player.gd, especially move_and_slide() on line 27. Run two instances, compare the host and client position logs with the default collision layers and with layer 2. Done means identifying and correcting the inconsistent CharacterBody2D position without requiring players to stop colliding.

Written by the indexing model from the issue text.

Assessment

Tech stack
godot
Domain
game-dev, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.