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

Multiple channels per delivery type #67

Closed
aienabled opened this issue Jul 21, 2017 · 25 comments
Closed

Multiple channels per delivery type #67

aienabled opened this issue Jul 21, 2017 · 25 comments

Comments

@aienabled
Copy link
Contributor

Hello!
Are there any way of creating more than one sequenced channel?
In Lidgren ( https://github.com/lidgren/lidgren-network-gen3/wiki/Sequence-Channels ) it's possible to have up to 31 sequence channels per any sequenced delivery method.
I looked into the LiteNetLib source and it seems all the channels are created only once in NetPeer constructor.
For me, it makes "sequenced" channel almost useless - I cannot even send health in one channel and ammo in another channel. Only the latest received NetPacket will be used - either ammo or health.

Regards!

@RevenantX
Copy link
Owner

Hi! There is only one channel per message type. I can implement if you really need.
But library have option "MergeEnabled" that will merge packets (health and ammo) together if you send them immediately.
You can send ammo and health together by hands (this is really small overhead. UDP header is 68 bytes).
You can use Unreliable with manual sequence and "channels" :)
I think multiple channels is rarely needed.
But if you have opposite opinion - i will listen)

@aienabled
Copy link
Contributor Author

aienabled commented Jul 21, 2017

I see. Well, it's not a satisfying for my needs.
I mentioned health and ammo as an example. In most games there are much more things which need to be send in sequenced manner but in dedicated sequences. It's simply impossible (or too much extra network traffic) to put all the data into a single packet just because we cannot have dedicated sequences.

In my case, the idea is to have multiple channels per game entity for replication needs. The channels should be dynamically creatable and disposable when not needed anymore.
For example, we need to replicate a few dozens of actors. Each one has its own properties (for example stats - such as health, shield, energy). Every property change needs to be replicated in a dedicated sequenced channel - dedicated per actor. So each actor will have a few dedicated sequenced channels (allocated when needed, disposed when not needed anymore) and network library will ensure that the client has the fresh properties of a every actor and no data is lost in transmission.

Of course, it's possible to write a custom "data" layer over the networking library (as mostly done in AAA games with custom engines). So this "data" layer will send the data in a single unreliable channel and manually do the reliablity and sequencing procedures to ensure all the data is transferred as expected. But it's a lot of work to do and it will have overhead.

Much better to have this functionaly in the network library (as done in Lidgren).
The only problem with Lidgren is that it cannot dynamically allocate/dispose channels and the channels amount is limited to 31 per (sequenced) delivery method. I have hacked all that into my Lidgren fork but don't really like the code and now consider other networking libraries.

@RevenantX
Copy link
Owner

@aienabled do you need multiple channels only with "Sequenced" method?

@aienabled
Copy link
Contributor Author

aienabled commented Jul 21, 2017

@RevenantX, not only, in my game I already use this with any net delivery method which uses sequencing - such as unreliable sequenced, reliable unordered, reliable sequenced, reliable ordered.

@RevenantX
Copy link
Owner

@aienabled in what situation you need multiple channels with "reliable unordered" message type?

@aienabled
Copy link
Contributor Author

aienabled commented Jul 21, 2017

@RevenantX, if player need to receive data as soon as possible and packet order is not important. For example, chat incoming messages. The ordering could be applied later based on the timestamp of the message. But it's important to receive all incoming chat messages.
Though, you're right, it's very rarely used and mostly could be replaced with reliable ordered without much problem to the player.

@aienabled
Copy link
Contributor Author

The thing is, in Lidgren network you could specify sequence channel for any outgoing message. It's not used for the unreliable delivery method, but for any other delivery method, there are 31 channels.

@RevenantX
Copy link
Owner

@aienabled I understand useful scenario of multiple channels with "Sequenced" type and "Reliable Ordered" :) But not with "reliable unordered"

@aienabled
Copy link
Contributor Author

@RevenantX, I think, if you can make it generalized for other delivery methods, it will be no problem to have it for "reliable unordered" also. That's how it done in Lidgren.

@RevenantX
Copy link
Owner

@aienabled I can implement this feature only for "Sequenced" and "Reliable Ordered". Because this feature will add little overhead in packet size, used memory and performance. And maybe this feature will be optional.

@aienabled
Copy link
Contributor Author

aienabled commented Jul 21, 2017

@RevenantX, that's great! Especially if I will be able to dynamically allocate channels and dispose them when they're not needed anymore (i.e. packets are acknowledged and channel is empty/drained). Up to 256 channels per delivery method will be enough for our needs.
Regarding "optional feature" - of course, not everyone need channel numbers (and extra byte per packet to determine channel number) for this. It could be optional with a compile flag or runtime boolean flag, I have nothing against it.

BTW, I missed - are there no unreliable sequenced channels? That's quite useful for me, for example, to send input - I never need to re-send it (no reliability is required as fresh data will be sent soon, it's simply sent with some interval) but it's important to use only latest input. Of course, I could add input Id number to determine if we have newer data, but it's simply better to have such option in network library.

@RevenantX
Copy link
Owner

@aienabled

BTW, I missed - there are no unreliable sequenced channels?

Sequenced - is unreliable sequenced.
There is no "Lidgren" method "reliable sequenced".

@aienabled
Copy link
Contributor Author

aienabled commented Jul 21, 2017

@RevenantX, wow, that's frustrating. I just checked my code for ReliableSequenced usage and found that I'm using it already in 21 places and where it's important to reduce traffic (by sequencing), but have reliablity. It's most popular network delivery method for me. For example, character stats (health/energy/etc), crafting progress, weapon firing mode. It's all important to have, reliably, latest value, but with reduced traffic (by sequencing - not re-sending late data). Should I create another issue here for this feature?

@RevenantX
Copy link
Owner

RevenantX commented Jul 21, 2017

Should I create another issue here for this feature?

If you need this feature - sure. :)

@miketheprogrammer
Copy link

@aienabled @RevenantX : Bump, but let me add some clarity. @aienabled , you should really rethink the reliability of messages. Amazon lumberyard would tell you that health, energy, etcetera are all eventually consistent, and that a reliable message should only be pumped, after those values have stopped updating for some grace period.

@RevenantX . This feature is essential to any game trying to implement fine grained Interest Based replication, with dedicated channels so that reliable channels can have their own buffers, this prevents all your events from locking up, instead of just the channel that is being abused currently.

I see no reason why channels should be implemented for unreliable messaging except for uniformity. The user of the library can implement it themselves at the application level, however alot can be said for uniformity of implementation.

I give my +1 for this feature, and will gladly donate to see it implemented. Thankfully it is one of those things that is not necessary for a project on day 1 but can be added when it is complete.

@RevenantX
Copy link
Owner

@miketheprogrammer i will add multichannel mode after i complete ReliableSequenced packet type)

@rikimaru0345
Copy link

So far I have worked around this by simply opening multiple connections to the server.

Are there any arguments against this except for a tiny bit more memory consumption?

@aienabled
Copy link
Contributor Author

aienabled commented Dec 4, 2018

I see there is still no multichannel support, though a lot of great improvements are done and I'm really impressed with all these changes and overall project activity.

I wish to try LiteNetLib with my MMO project I talked about before (game page, now available as a free open alpha and getting very positive reviews; currently using Lidgren.Network) but multiple channels support is one of the requirements. It's possible but not reasonable to implement on the application level (by using unreliable channel and manually sending and processing ACKs) - I believe it will be beneficial to have this feature for everyone, implemented and perfected in the network library itself.

Ability to transfer certain packets as sequenced (with or without reliability) is very useful. But the usefulness of the sequenced channel is very limited if there is only a single channel of this kind for the whole game connection - it could be beneficial for a certain kind of session-based games like a FPS shooter where a basic set of data is replicated every other frame and client should receive only the latest version of this data (but in that case it's actually could be easily implemented on an application level just by checking the relative sequence number of the packet). For any large project (like an MMO game I'm building) multiple channels support is a real necessity and implementing this in a proper way (performance-wise) is a serious challenge.

Also, I would prefer to contribute in an open-source project to make this feature useful and optimized for everyone than to implement it on an application level specifically for my game engine.

Regards!

@RevenantX
Copy link
Owner

@aienabled i am working on this feature. Just want to make it with maximum usability, so it takes some time)

@TimonPost
Copy link

TimonPost commented Dec 17, 2018

I am researching this topic also and was curious if this library had this functionality and saw this. I originally saw this idea in Raknet. RakNet is a C++ lib like this one. They call it ordering streams. You could use this as a reference: http://www.raknet.net/raknet/manual/sendingpackets.html

Just a summary of what they are:

What?

You can think of ordering streams as something to separate the ordering of packets that have totally no relations to one and another.
A game-developer might want to send some data ordered; some data unordered while other data needs to be send sequenced etc.
This idea from RakNet who already has implemented this functionality (check out ordering streams for more info)

How?

To make this more clear let's imagine the following scenario's:

  1. Let's say the player firing packets had to be ordered relative to player movement packets because you wouldn't want the shot to originate from the wrong position.
  2. You want to chat messages to be ordered.

Player movement and chat messages are totally not related to one and another.
You don't want the movement packets to be disturbed if a chat message is dropped.
It would be nice if we can order player movement, chat messages separated from each other.

This is exactly where ordering streams are for.
The user can, for example, say: "Let me put all chat messages on ordering stream 1 and all player and bullet movement packets on ordering stream 2".
Since once a bullet is shot

This way you can have different types of packets ordered separately from each other.

@rikimaru0345
Copy link

@RevenantX
I assume this will be implemented (correct me if I'm wrong) and I have a question.

How will the implementation look like roughly?
Will we be able to set what channels there are and what their transport settings are?

Like before/while constructing the NetManager maybe we could do something like:

AddChannel(id: 1, deliveryMethod: DeliveryMethod.ReliableOrdered, debugChannelName: "abc");

and LiteNetLib would just ensure that the channel IDs start at 1, there are no IDs skipped, no IDs are assigned twice... and of course some upper limit (32 channels at most I thought was mentioned at some point?)

@RevenantX
Copy link
Owner

@rikimaru0345

I assume this will be implemented (correct me if I'm wrong) and I have a question.

Yes. There is work in progress.
Right now there is some things that i don't solved, so i cannot say anything this)

@Krakean
Copy link

Krakean commented Feb 19, 2019

@RevenantX any progress on this ticket?

@RevenantX
Copy link
Owner

RevenantX commented Feb 23, 2019

@Krakean @aienabled you can test bleeding edge here: https://github.com/RevenantX/LiteNetLib/tree/channels

@RevenantX
Copy link
Owner

8d7336e integrated to master

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants