My team and I are working on an upcoming online fighting game using ENet-CSharp (A C# ENet implementation created by nxrighthere), and we're currently designing the architecture of the server. We would be very glad to hear your suggestions concerning a couple of issues we have been struggling with.

Our current plan is to host a dedicated server for the game, which will handle the logic and game loop of each game instance, and the MonoGame clients will simply deliver the user's commands to the server, and present the updated game state received from it. However, we are not sure how to correctly use ENet with our division of independent game rooms.

Let's say, I have 100 concurrent users connected to the server, and 10 independent game rooms, consisting of 10 players each. At first, we thought that we should have a single ENet Host which will handle all of them, and a single independent ENet thread that will simply receive packets from all ends, alerting the corresponding game room to handle it within its game logic. However, it seems a bit unsafe to have one I/O thread shared by multiple different and parallel instances of the game, so our plan is as such:

  • For each game room (10 players for that matter), a unique ENet Host will be created, and 2 independent threads will run - one for the game loop, and one for the ENet event polling.
  • The ENet thread will call the Service method with a small timeout, expecting to poll one "Receive" event at each iteration, and will queue the commands received from the players.
  • The game loop, at the start of each iteration, will dequeue the commands that have been collected since the last iteration, apply them within the game logic, and so on.

Would you guys say this is a good solution to go by?

A question that rose with that: Correct me if I'm wrong, but as far as I understand, the send rate of the outcoming packets corresponds to the rate of calls to either the "Service" or the "Flush" methods. How can I ensure that at the end of each game loop, the new game state will be broadcasted immediately to the clients? Calling the "Flush" method at the end of each iteration seems logically appropriate, but unsafe at the same time (since it will be called outside the ENet dedicated thread).

Any piece of advice would be more than welcome. Thanks in advance!

  • \$\begingroup\$ It sounds like you have a clear idea of how you want to approach this. It sounds like it's worth a try - want to whip up a test, and post here if it turns out this architecture has a specific observed problem we can help you solve? \$\endgroup\$
    – DMGregory
    Commented Aug 3, 2020 at 22:14
  • \$\begingroup\$ Well sort of yeah, but the question I have specified at the end kinda prevents me from doing so. \$\endgroup\$
    – Ido Sofi
    Commented Aug 4, 2020 at 5:40
  • 2
    \$\begingroup\$ If the question at the end is your blocker, you might not want to relegate it to the end. Edit your question to ask "How to ensure all packets are sent at the end of the server's game loop" in the title, and focus the body of the question on that issue. That's your best bet for drawing in experts who know about this specific aspect. \$\endgroup\$
    – DMGregory
    Commented Aug 4, 2020 at 14:42


You must log in to answer this question.

Browse other questions tagged .