Open Veritius opened 1 year ago
Looking at the bevy adapter is made a bit more difficult by this as well, the example helps but doc comments would be tremendously useful.
Naia looks great, and I'm excited to get it working in my project. However, I'm finding it to be quite difficult to adopt Naia due to the lack of documentation. Even simple user-facing things have no explanation. For example:
pub struct ReliableSettings {
pub rtt_resend_factor: f32,
}
What does this actually do? I can guess that it's somehow related to round-trip-times and resend cadence, but what is the factor multiplied against? Why is the default 1.5
, and how do I know if I need to change it?
// ChannelMode
pub enum ChannelMode {
UnorderedUnreliable,
SequencedUnreliable,
UnorderedReliable(ReliableSettings),
SequencedReliable(ReliableSettings),
OrderedReliable(ReliableSettings),
TickBuffered(TickBufferSettings),
}
Ordered
vs Unordered
seems straight forward enough, but what's the difference between Ordered
and Sequenced
? What is TickedBuffered
and why would I want to use it? Why can it only be sent client->server?
Etc. Etc. Just little one line explanations would be a huge improvement here. Yes, we can see some of these things being used in the demos, but that doesn't shed any light on "why". If you want to build something different than the demo, your only option is to read and understand the naia source directly, which is more difficult because of the lack of "what are we doing and why?" comments.
Thanks for writing naia! A little help wrapping my head around its usage would be most welcome though :)
Hey there @dubrowgn , thanks for checking naia
out. I totally agree that this is a major sore spot with the library right now. Unfortunately I'm currently not able to be a very active maintainer for the next while, so there is unlikely to be very much commenting added to the codebase in the near future. That said, I suggest asking any questions in the Discord, there seem to be a number of members that are actively using naia
in their personal projects and they may be able to help you out. In my opinion, naia
is currently not a very easy library to jump into for these reasons. Thank you for understanding.
You may find this online guide written by @snen helpful: https://blog.snen.dev/building-with-bevy/03-integrating-online-networking
As far as the questions you listed:
ReliableChannels resend messages at an interval until they receive a receipt of delivery. That interval is equal to (rtt_resend_factor
* currently_measured_round_trip_time). The sender will not be able to receive a receipt of delivery any sooner than round_trip_time
, so a factor of 1.5
is used as a default. However you may want to wait longer / shorter amount of time than that for various reasons?
Sequenced
terminology is lifted from Laminar https://timonpost.github.io/laminar/reliability/reliability.html
TickBuffered
channels implements the per-tick command buffering as explained in Overwatch netcode explanation https://youtu.be/zrIY0eIyqmI?feature=shared&t=1343 . You'll see after understanding that approach why it only makes sense that the messages be sent from Client->Server: The Client ticks "ahead in the future" of the Server and adjusts it's clock such that the Server should always have a buffer of Command frames to read from for each player on each and every tick. Commands which the Client hasn't received a receipt of delivery for are pro-actively sent every single Tick until receiving that receipt or it is measured that the Tick has passed on the Server.
Anyway, hope all goes well with your project!
@connorcarpenter, that's great! I have actually seen that video before (it's filled with loads of great stuff), I just didn't realize that's what TickBuffered
was implementing. I opened https://github.com/naia-lib/naia/pull/191 to just add these descriptions to the code for future naia consumers (e.g. me :).
This has already been very helpful because I had previously assumed TickBuffered
was probably what I wanted since the demo used it. However, it's not the right choice for my use case (deterministic lockstep). Obvious in retrospect, but there it is.
This isn't exactly useful.