How should I architect my (mostly) text-based game server? How should I architect my (mostly) text-based game server? ruby ruby

How should I architect my (mostly) text-based game server?


Although you probably don't like to hear it I would still recommend to start investigating HTTP servers first. Although programming for them seemed boring, synchronous, and non-persistent to you, that's only because the creators of the servers did their job to hide the gory details from you so tremendously well - if you think about it, a web server is so not synchronous (it's not that millions of people have to wait for reading this post until you are done... concurrency :) ... and because these beasts do their job so well (yeah, I know we yell at them a lot, but at the end of the day most HTTP servers are outstanding pieces of software) this is the definite starting point to look into if you want to learn about efficient multi-threading. Operating systems and implementations of programming languages or games are another good source, but maybe a bit further away from what you intend to achieve.

If you really intend to get your fingers dirty I would suggest to orient yourself at something like WEBrick first - it ships with Ruby and is entirely implemented in Ruby, so you will learn all about Ruby threading concepts there. But be warned, you'll never get close to the performance of a Rack solution that sits on top of a web server that's implemented in C such as thin.

So if you really want to be serious, you would have to roll your own server implementation in C(++) and probably make it support Rack, if you intend to support HTTP. Quite a task I would say, especially if you want your end result to be competitive. C code can be blazingly fast, but it's all to easy to be blazingly slow as well, it lies in the nature of low-level stuff. And we haven't discussed memory management and security yet. But if it's really your desire, go for it, but I would first dig into well-known server implementations to get inspiration. See how they work with threads (pooling) and how they implement 'sessions' (you wanted persistence). All the things you desire can be done with HTTP, even better when used with a clever REST interface, existing applications that support all the features you mentioned are living proof for that. So going in that direction would be not entirely wrong.

If you still want to invent your own proprietary protocol, base it on TCP/IP as the lowest acceptable common denominator. Going beyond that would end up in a project that your grand-children would probably still be coding on. That's really as low as I would dare to go when it comes to network programming.

Whether you are using it as a library or not, look into EventMachine and its conceptual model. Overlooking event-driven ('non-blocking') IO in your journey would be negligent in the context of learning about/reinventing the right wheels. An appetizer for event-driven programming explaining the benefits of node.js as a web server.

Based on your requirements: asynchronous communication, multiple "subscribers" reacting to "events" that are centrally published; well that really sounds like a good candidate for an event-driven/message-based architecture.


Some books that may be helpful on your journey (Linux/C only, but the concepts are universal):

(Those were the classics)

  • The Linux programming interface - if you just intend to buy one book, let it be this one, I'm not entirely through yet but it is truly amazing and covers all the topics you need to know about for your adventure

Projects you may want to check out:


I'd recommend reading a bit about unicorn web-server design. That should give you some insight into thread vs. process discussion.

http://unicorn.bogomips.org/DESIGN.html

http://tomayko.com/writings/unicorn-is-unix


I don't know much about Ruby - sorry - but I think the architecture needs to be driven by your requirements (motherhood, apple pie...I know).

If you're building something that needs to scale to large numbers of users, your architecture needs to reflect that - and you end up making all sorts of decisions you don't necessarily need to make if you're operating at more modest scale.

Response time also plays a big part - I don't think that is such a big deal with MUD style games, but for web servers or FPS games, it's a huge issue.

Having said that - the only systems similar to what you describe that I know in any detail use an event driven programming model - clients trigger events, the system updates its internal state, and notifies affected clients. The "internal state" is actually stored in a separate application, again communicating using sockets - this allows the app to be scaled by adding more servers to handle client interaction. Not sure you need that level of complexity.

Threading is indeed a real issue, and it creates hard-to-test code, so whilst dash-tom-bang's answer is indeed a little off topic, testability is a significant concern.