🔨 Splitting out networking workload
zach2good opened this issue · comments
I affirm:
- I understand that if I do not agree to the following points by completing the checkboxes my issue will be ignored.
- I have read and understood the Contributing Guide and the Code of Conduct.
- I have searched existing issues to see if the issue has already been opened, and I have checked the commit log to see if the issue has been resolved since my server was last updated.
Describe the feature
(I was going to include my plans for "zone executors" in here, but that just muddies the water, so that'll come after this)
Currently, the way we flip-flop between:
- (tick) Networking operations
- Reactions to incoming packets
- (tock) For each zone on process
- For each entity in zone
- Tick()
- Some other bits and bobs
- For each entity in zone
As you can see, this is painfully sequential, and it means that we leaving a lot of processing time on the table for ticking zones.
What I propose is the following:
- (main thread) Networking operations
- Receive incoming packets, validate them, determine which zone they're intended for, add to the queue for that zone
- (other thread) For each zone assigned to the process
- For each entity in zone
- If there are incoming packets, action them
- Tick()
- For each entity in zone
I'm still pondering what ramifications this will have if each (player) entity has a queue of incoming packets to be actioned, or whether or not it should be zone-based. The architecture won't change hugely between the two, so I could go with zone-based first and then see whats happening after.
I don't know if it would be better to do this work before, after, or alongside another bit of work I have planned:
restructuring our packet definitions to be:
src/
packets/
c2s_0x01a_player_action.h/.cpp
s2c_0x00d_char_update.h/.cpp
I don't know if I should have c2s
and s2c
subfolders, and drop that from the names, or keep both, or neither.
Each c2s
packet is going to need to be replaced with a class that forces the implementation of:
virtual bool validate() = 0;
While we could have this for outgoing packets too, there isn't really any need, since we're in control.
This all essentially means that (once the work is complete), packet_system.cpp
will be nothing more than the table at the end. The packet_size
lookup will be rolled into validate()
, etc.