0
\$\begingroup\$

I'm trying to make a Multi User Dungeon (MUD) game, and obviously a pre-requisite to that is a server.

I've seen stuff like this:

          ┌───────────────────────────────────────────────────┐
          │                                                   │
          │Game Logic Implementation                          │
          └────────────▲──────────────────────────┬───────────┘
                       │                          │
                       │              ┌───────────▼───────────┐
                       │              │                       │
Server                 │              │Event Router           │
                       │              │                       │
                       │              └───────────┬───────────┘
                       │                          │
          ┌────────────┴───────────┐  ┌───────────▼───────────┐
          │                        │  │                       │
          │Parser                  │  │Event Translator       │
          │                        │  │                       │
          └────────────▲───────────┘  └───────────┬───────────┘
                       │                          │
───────────────────────┼──────────────────────────┼───────────────────────────
                       │                          │
                       │                          │
Clients                │                          │
          ┌────────────┴────────────┐ ┌───────────▼───────────┐
          │ Client                  │ │Client                 │
          │ Input                   │ │Output                 │
          │                         │ │                       │
          │                         │ │                       │
          └─────────────────────────┘ └───────────────────────┘

(Credit to stack exchange user Phillip on the Gamedev Stack Exchange)

But that's relatively advanced. Is there some way to structure my project more like this?

          ┌───────────────────────────────────────────────────┐
          │                                                   │
          │Game Logic Implementation                          │
Server    └────────────▲──────────────────────────┬───────────┘
          ┌────────────┴──────────────────────────▼───────────┐
          │                                                   │
          │Function                    or Library             │
          │                                                   │
          └────────────▲──────────────────────────┬───────────┘
                       │                          │
───────────────────────┼──────────────────────────┼───────────────────────────
                       │                          │
                       │                          │
Clients                │                          │
          ┌────────────┴──────────────────────────▼───────────┐
          │ Client                     Client                 │
          │ Input                      Output                 │
          │                                                   │
          │                                                   │
          └───────────────────────────────────────────────────┘

To put that more complex stuff under the hood? That way I can focus on developing the game and not setting up a complex server system that basically carries two variables from the client to the server and two variables from the server to the client.

I've tried tutorials, pre-built (public domain) code, and even books but I still can't seem to make it work from scratch.

\$\endgroup\$
6
  • \$\begingroup\$ c++ and server in the search engine of choice is turning up socket examples in 50 lines or less. What do you expect of the server in the future? Usage for your own small personal project? 1k users at the same time? How secure should it be? Where should it run? Does the server has to be c++? \$\endgroup\$
    – Zibelas
    Commented Nov 11, 2022 at 17:43
  • \$\begingroup\$ The server should be C++, and the only security threat I see are macros being used to spam the server or exploits ruining the game balance, both of which are things players can do no matter how secure you are. The best you can do security wise is banning players who send requests too quickly and moderate well. My search engine doesn't seem to have these results. This is a personal project right now for learning purposes. I hope to be able to support up to a couple dozen players at once, but this seems like a problem of bandwidth and game logic, not the programmed architecture. \$\endgroup\$ Commented Nov 11, 2022 at 17:52
  • \$\begingroup\$ I think the thing you are looking for is called a "Game Engine," or maybe more specifically a "MUD Engine." I don't know of any off-hand, but a search on github turns up a few projects, some of which are C++. github.com/topics/mud-engine \$\endgroup\$
    – Tim C
    Commented Nov 11, 2022 at 18:30
  • \$\begingroup\$ I wanted to avoid using a game engine, but I'll look into that. At this point I've spent over a week on the servers alone and I frankly just want to be done with it. \$\endgroup\$ Commented Nov 11, 2022 at 18:31
  • \$\begingroup\$ @HeneryJohnson - Could you elaborate on why you don't want a game engine? I am planning on expanding that comment into a proper answer explaining why I believe that an engine is the right tool for what you're asking, and understanding why your initial objections will help me craft a more useful answer. \$\endgroup\$
    – Tim C
    Commented Nov 11, 2022 at 20:32

1 Answer 1

5
\$\begingroup\$

That sort of middleware is a Game Engine

From your diagram, it looks like you only want to write game logic and maybe a little bit of presentation/UI, and are looking for a piece of middleware to handle the rest.

The purpose of a game engine is to allow designers to focus on writing the unique game logic of their game, and the engine takes care of the rest. Therefore, the thing that is most likely to solve your problem here is a game engine.

But game engines take control over the program flow away!

Any middleware that solves your problem here will have to take control of the program flow. You will not be able to write a program that starts with int main(void) and which uses networks unless you write your own netcode.

The reason for this is that netcode for a MUD imposes a bunch of requirements on the program's flow, and adhering to those requirements is exactly what makes netcode hard.

Net-code is always multi-threaded

A MUD server needs to be able to receive new log-in requests at any time, and maintain the state of each connection. It also needs to receive input from already connected players, and actively maintain the connections with players who are not currently sending input (to detect when they get disconnected ungracefully).

Every implementation of this that I've seen or worked on has used threads. One thread listens for new connections, each already active connection gets a thread, and the game logic runs on yet another thread.

Net-code is a mess of tricky edge cases, all different

A lot of things can happen when you try to receive data on a socket. Maybe you get the data you expected. Maybe you get data you didn't expect (like a hacker testing your defenses by sending malformed packets). Maybe you don't get data at all because the connection is gone. If you write your own netcode, you have to decide how to handle each of these cases. If you use an engine, you'll have out-of-the-box solutions that just work, based on industry standard practices.

You will probably need to persist character/account data

Your players will probably disconnect and reconnect. Sometimes this will be for network-related reasons, but quite often because humans need to sleep. Handling accounts and authentication yourself will take a lot longer than you think it will.

Are there engines that don't restrict my game logic?

Yes, lots. At a quick search, I found TinyMud-Server which seems pretty close to what you're looking for - but it's a complete program that you add your code to, not just a piece of middleware that you can link with.

If that doesn't meet your needs, there's dozens of other engines out there. A google search for mud server engine c++ will turn up a few hits.

What if I really do want to write my own?

If you're really looking to write your own server, I'd recommend the following:

  • Allocate enough time to learn. Going from "what is a socket?" to "writing a MUD from scratch" will take more than a week, and probably more than a couple months. (It took me two years, but I wrote a couple of other games in between.)
  • Write a TCP echo server. Follow a tutorial for creating a simple one-connection-at-a-time TCP echo server and client. There's lots of such tutorials out there: search for "TCP echo server tutorial C++" to get started.
  • Expand that server to multiple connections. Once you've created a one-connection-at-a-time server, the next step is to handle multiple clients. listen on one thread, receive on one thread per client, and whenever a message comes in, post it to a queue where another thread will see it and send it back to each client.
  • Turn it into a chat server with accounts and sign-in. Add a sign-in process to your initial connection and prepend each message that gets re-sent with the account name.
  • Convert the send thread into your game logic. Once you have the above all finished, it should be straightforward to turn it into a MUD by replacing the main "send message" thread.
\$\endgroup\$
3
  • 1
    \$\begingroup\$ In the section "What if I really do want to write my own?" I would make sure that the client is an actual ssh or telnet client quite early on, as I suppose that's what MUD players typically use. \$\endgroup\$
    – Vaillancourt
    Commented Nov 12, 2022 at 1:30
  • \$\begingroup\$ @Vaillancourt - That might be good enough as a stand-alone answer. I wrote a mud-like game in college, but I wrote it with a custom client that didn't use SSH/Telnet. If you've got knowledge about how to leverage SSH/Telnet for MUDs, I think that would help this asker a lot. \$\endgroup\$
    – Tim C
    Commented Nov 12, 2022 at 21:29
  • \$\begingroup\$ Put more directly: I think that's a good suggestion, but I don't know how to write it because I've never done it. Feel free to edit it in if you do but don't want to write a second answer. \$\endgroup\$
    – Tim C
    Commented Nov 12, 2022 at 21:34

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .