-
Notifications
You must be signed in to change notification settings - Fork 32
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
Support custom ticks from FixedUpdate games #68
Conversation
Some time ago I used Bevy's tick, but since I wanted to open door for rollback implementation for other people, I switched to |
Hmm, yes... At the moment my resource containing the fixed timestep tick is accessed in at least 50% of my game systems. The If I made the ServerPlugin able to configure where the If i did that, NetworkTick would be incremented once per non-rollback tick of my fixed timestep, because the server would call diffs_sending_system once per fixed timestep too. I could then sync my existing tick resource to the value of NetworkTick at the start of fixed timestep on the server, instead of just incrementing it myself. Rollback should work fine, because that would wind back my tick resource, and simulate forward to the original value without calling into replicon at all. Meanwhile the client doesn't care about any of this, the tick it sees passed in to the deserialize fns would be the right thing. I think that could work 👍 This would allow me to get rid of ServerPlugin being abstract over UserTick, which is ugly. If there was an identical setting on both the server and client plugins like I'll implement this and report back. |
@RJ If I understand correctly, you don't want to run sending system inside fixed timestep. Ideally you want to run it once inside
Will this work for you?
Yep, this is why I suggesting this :) And also because I introduced |
Allows for more flexible fixedtimestep integration, with manual incrementing of the network tick.
Ok, ready for review - all working in my game, and i've added tests for the new features. Thanks 👍 |
Already done in projectharmonia#69.
No longer necessary, looks like a leftover from the previous approach.
- Replace `Option` with default `despawn_recursive` and remove custom despawn test since now it's not a special case. - Allow to initialize it inside `ReplicationRules` instead of setting it as part of plugin (I found it a bit confusing).
Since we have only one such function.
I would prefer `replicate_with` to have all parameters.
I think that this should be a part of third-party crate that implements it. Using custom functions will just work, I don't see much value in testing them.
I also removed public access from the tick value. You still can get its value or create a new one. Similar to how it's done for Bevy's `Tick`.
Co-authored-by: UkoeHB <[email protected]>
DRAFT - I got my game mostly behaving well (except predicted spawns) using bevy_replicon with these changes.
I will write some tests if you would like to merge this, or something similar. I'm fairly sure this is a generally useful and necessary feature for games which used fixed timestep.
UserTick support
The ticks replicon uses for tracking are (rightfully) world level ticks from pre/post/update. But fixed timestep games (such as simulations with rollback) need their own tick that increments with no gaps in it, because every tick represents a simulation step.
I made ServerPlugin (and the
ReplicationPlugins
group) generic overUserTick
- a user provided bevy resource which derefs to au32
. This is for the tick from the FixedUpdate step, in games that use FixedUpdate (like for simulations with rollback networking).Now every time replication data is assembled for sending, bevy_replicon will read the
Res<SimulationTick>
resource, deref it to au32
, and include it in the replication data.This value is made available as the
user_tick: Option<u32>
parameter in the following places:This means a custom deserializer can use the user_tick to apply component updates in the past, to a specific frame.
here's my game client's deserializer for bevy_xpbd's Rotation component, which uses
bevy_timewarp
to apply the update to a prior frame (thus triggering rollback):These changes unfortunately mean initialization of
ServerPlugin
andReplicationPlugins
is uglier, because you have to specify UserTick, even if you don't need it. I provided a NoUserTick as a dummy value when you don't need the feature. Most of the diff is updating existing tests and docs to change how plugins are initialized 😬 Perhaps there's a better way to do this?The UserTick is an
Option<u32>
which i'm encoding into the replication buffer after the existingcurrent_tick
. This will cost 1 bit when not in use. Seemed a worthwhile tradeoff vs. extra code complexity, but open to suggestions!Configurable despawning function
I added a configurable despawn function to
ReplicationRules
, in case you want clients to do something different than justdespawn_recursive
when the server despawns something. The default behaviour is unchanged here.In the case of rollback, I need to be able to insert a
Despawn
component instead of immediately despawning, so rollback systems can do stuff.Configurable remove component function
In addition to
replicate_with
there is now areplicate_and_remove_with
which allows providing a custom function to remove components from entities. The default behaviour is unchanged here.