Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Network] Non player entity snapshot correction #20

Open
yuraj11 opened this issue Jul 22, 2020 · 7 comments
Open

[Network] Non player entity snapshot correction #20

yuraj11 opened this issue Jul 22, 2020 · 7 comments
Labels
enhancement New feature or request

Comments

@yuraj11
Copy link
Contributor

yuraj11 commented Jul 22, 2020

I am working on moveable platform in 2D which has constant velocity and uses StaticBody. The issue is that corrections keep incrementing even though I applied new corrected position. I am running this code on both server and client.

The logic is following:

func _ready() -> void:
 uid = name.hash()
 network.snapshot_data.add_pre_spawned_node(MovingPlatformSnapshot, uid, self)
 # load platform points


func _physics_process(delta: float) -> void:
 ####
 if correction_needed:
  position = correction.position
  next_stop_index = correction.next_stop_index
  ...
  for _i in network.snapshot_data.get_prediction_count(uid, MovingPlatformSnapshot):
   update_platform(delta)
 #### 
update_platform(delta)
network.snapshot_entity(MovingPlatformSnapshot.new(uid, 0).from_node(self))


func update_platform(delta: float) -> void:
    # velocity is constant calculated from next_stop_index which is next point where should platform stop but it is same on server and client
    position += velocity * delta

MovingPlatformSnapshot contains position and next_stop_index

The position in corrected always differ in very similar numbers like 3 pixels difference. Also I have observed same issue with your demo project - glowprojectile.gd it keeps correcting. Maybe there's something missing in the addon like we needed for player entities (correct_in_snapshot) ? I don't even use anything advanced with physics it's just simple position and once it is corrected it should be sync with server.

@Kehom
Copy link
Owner

Kehom commented Jul 22, 2020

The correct_in_snapshot can be used with non player entities and it kind of should be used. The topic Prediction Without Input Data in the tutorial showcases how to re-simulate non player entities.

Now, corrections will occur, specially when dealing with floating point math. It is possible to incorporate an error margin into the comparisons (check topic Floating Point Comparison) which should reduce the number of corrections. Increasing the margin will reduce corrections but may result in slightly offset states. So, if not using the automatic margin calculation, the value must be tweaked.

That said, corrections are not bad if they don't result in visual glitches.

@yuraj11
Copy link
Contributor Author

yuraj11 commented Jul 22, 2020

correct_in_snapshot second parameter is InputData - what it should be in this case?

@Kehom
Copy link
Owner

Kehom commented Jul 22, 2020

Ohh damn. Silly me! I should not write answers when half asleep! I will think about something to allow corrections of non player entities. More specifically, to locate the correct local snapshot. It will probably give an alternative way to perform the same task for entities that use input data.

Are the corrections resulting in visual glitches in your case? If that's the case then I will probably have to move this up in the priority list.

@yuraj11
Copy link
Contributor Author

yuraj11 commented Jul 22, 2020

On the left is client position and on the right is server corrected position:

(-192, 821.666443) (-192, 831.666565)   # start
(-192, 819.999756) (-192, 829.999878)
(-192, 818.333069) (-192, 828.333191)
(-192, 816.666382) (-192, 826.666504)
(-192, 814.999695) (-192, 824.999817)
(-192, 813.333008) (-192, 823.33313)
(-192, 811.666321) (-192, 821.666443)    # <== shifted
(-192, 809.999634) (-192, 819.999756)
(-192, 808.332947) (-192, 818.333069)
(-192, 806.66626) (-192, 816.666382)
(-192, 804.999573) (-192, 814.999695)

as you can see the positions are correct but they are somehow shifted and not in order

@Kehom
Copy link
Owner

Kehom commented Jul 22, 2020

That is normal and the difference will be even bigger when latency increases. That is a byproduct of locally running the simulation. In a way, the client will always be ahead the most recently received data. Think about this. When server dispatches the snapshot data, both server and client continue to simulate the game. Because it takes some time for the data to be delivered, both machines will be "in the future" when compared to that data set.

That is the reason I use input signature to find the local snapshot, rather than the snapshot signature itself.

I'm now considering some options to allow client code to correct local snapshots in a similar way it is done when input data is available. The funny thing, when I implemented the correct_in_snapshot I did indeed think "OK, I already have means to re-simulate non player entities so it should be enough to" but completely forgot that input data is not available to those entities. Ohh well...

@Kehom Kehom added the enhancement New feature or request label Jul 23, 2020
@Kehom Kehom added this to To do in Godot Addon Pack via automation Jul 23, 2020
@yuraj11
Copy link
Contributor Author

yuraj11 commented Jul 23, 2020

I understand that client is ahead of server but still you can stamp what you send to server and then check in history buffer If position send at certain time was valid and If not then do corrections but do not validate actual data only validate history.

@Kehom
Copy link
Owner

Kehom commented Jul 23, 2020

I did think about sending extra information to facilitate things. The thing is, regardless of what data is given, because the client is ahead of the delivered data, there will be local state (a few snapshots) that will be incorrect in case the server disagrees with the client. Correcting a single local snapshot is not enough to prevent visual glitches, that's why I had to provide means to perform this correction for each re-simulated step.

Unfortunately I didn't think though and completely forgot about entities that don't need input data.

Now, just to make things clear, when the correction is requested on the client side, the comparison was done with the snapshot that was in the past, the one that corresponds to the used input, not the most recent local one.

I'm currently evaluating some options that I have to provide the necessary information to perform the local snapshot corrections in a relatively simple way. The simplest way I thought would break compatibility with current code, which I absolutely don't want to do.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
Development

No branches or pull requests

2 participants