capnmidnight / small-town

A Multi-User Domain in Node.JS
7 stars 3 forks source link

Project Direction #83

Open capnmidnight opened 6 years ago

capnmidnight commented 6 years ago

Introduction

This project started out as a basic Multi-User Dungeon written in Racket. I then eventually ported it to Node.JS for... reasons. Over time, I got distracted with other projects, especially VR related ones like Primrose. But ultimately, it's always been at the back of my mind, as I think the format has a lot to still offer us.

I'd like to revive this project, with an open source community behind it. You can reply here with your name, a "Statement of Purpose" for why you want to work on this project (my one concession to keep the complete trolls out), and I will add you as a collaborator. I don't care how much experience you have. I'll give you direct commit access. Ain't nobody got time for gate-keeping over pull requests.

We'll figure out communication arrangements later.

ASIDE: I have no patience for two things: bike-shedding and bad manners. I favor code that works over idealistic code that hasn't been written. "OOP vs FP" or "Vim vs Emacs" are arguments for amateurs. Things like code formatting guidelines make me want to quit programming and join a traveling circus. And people who berate others over these things (or anything else) make me want to burn the entire system down. You will be civil or I will ban you for life. No warnings. And no, no definitions of what "civil" means. It's naturally a malleable concept, as civilization itself is malleable.

What is currently here

The current code base is fairly trivial. It runs a WebSockets server that serves up a basic HTML page that is used as a client to connect to the game. The game runs off of simple text-file formats defining the items and rooms that the user can interact with.

The room definitions are kind of neat, though they are certainly brittle. Ultimately, the representation format of the rooms is an editor issue, not one of storage. I'd normally store such data in an RDBMS, but at the time I wasn't taking this project seriously.

AI bots are a little difficult to define right now. They don't support any sort of branching dialogue. I like the simple format, but again, that's an editor issue.

There's nothing special about the items, except that the recipes come out into a pretty natural format.

A lot of the rest of the code is ad hoc junk. But the general concept of leveraging simple data formats applied in multiple ways to different activities is one that I think will make a small team more productive on a big project.

Where this is going

I'm not married to anything here. The constraint checking for room exits (i.e. locks) and recipes is kind of neat. But there's nothing here that can't be redone, better, from scratch, in a short period of time.

I have a number of ideas in which I'd eventually want to take this project.

Restart in a new programming language

JavaScript is... not my favorite language. I use it a lot, I'm quite good at it, it is our only option for the front-end (I want to continue to maintain an HTML5 front-end, as it will be the most accessible for users). But it requires a lot of extraneous tooling just to work with it in a way that doesn't fall over at the slightest breath.

I like type-safe languages. I'll consider (in no particular order):

Some other language/ecosystem considerations:

Promoting the game to players

A MUD is nothing without users. I'd like to take this seriously as a viable game project and get at least 100 users on a single instance going at a time. I think having a vibrant user base will be necessary to be able to enact some of the experiments I have in mind.

Making the game accessible to modern audiences doesn't necessarily mean making a World of Warcraft clone, however. Games like Dwarf Fortress seem to prove that people are willing to put up with anachronistic representations, if the gameplay is good. I think there's also a good opportunity to expand into the extremely under-served market of blind gamers. We'd have no good excuse for not building accessibility features into the game, since we're starting from scratch.

Experiments

There are a lot of different parts to the game. The command input system, be it a menu or a Natural-Language Processing system. The output representation system, be it a verbatim text description or procedurally generated text. The combat system: hooked into the command system, different forms of combat could be implemented. The economy. Etc.

Some sort of plugin system for different game components could make the project a potential testbed for different MUD, Adventure, and RPG game concepts.

Some experiments I'd like to run:

What you can do

What would you do on this project? I don't know, what can you do? Projects that are meant for user consumption require LOTS of parts, and "well-written, hyper-awesome code" is an extremely small percentage of that. Websites will need to be built. Servers will need to be maintained. Documentation will need to be written. Translations will need to be made. T-shirts will need to be designed (you know, for the yearly convention).

And just because you're a beginner at any of these things doesn't mean your input would not be useful. I'd rather have 10 beginners who push forward every day than 1 expert who sits in his ivory tower and never gets anything actually done.

Conclusion

It's difficult to explain my approach to things. I'm not a heavy planner, or at least, when I attempt to plan things I end up never implementing. But I'm also not really a seat-of-the-pants implementer. I like to know what came before, and I like to sketch rough guidelines. That plan can change quickly if its discovered to be wrong. The most important thing is for the project to be fun and not a burden on the developers. There's no point in losing sleep over this, because it's extremely unlikely to ever make anyone any money.

johnnybubonic commented 6 years ago

hey (this is the guy that runs the @SysAdm_Podcast twitter; chain of proof: https://twitter.com/SysAdm_Podcast profile => https://twitter.com/brentsaner => https://keybase.io/squarer00t, GH is proofed there as well as personal twitter).

just wanted to check in and let you know my GH handle. like i said on twitter, i know more of the operations end, so while i won't be much help with the code i can help with input for what i'd like to see if i was running it on a server, but i won't be able to contribute much other than some python helpers.

to add to the list you have, it'd be helpful if there was an API to query current playerbase/individual players, game state, and other meta information. i presume this would be exposed via the proposed WebSocket interface?

if you go with C#, i'd be sure to make either Mono or the Linux port of .NET part of your testbed, considering that's likely where this would be running. I can imagine addressing the large playerbase problem by developing a leafed/tree node model for servers, and one could accommodate growth by just spinning another server into the peer network. (most likely via AWS/EC2, as much as i loathe to admit it, hence my conjecture that it's likely it'd be running on a Linux environment).

text-to-speech is (mostly) a solved problem, thankfully; espeak would, i think, be a good candidate. you can see (admittedly a dated) discussion of using it in a C# project here: https://sourceforge.net/p/espeak/discussion/538922/thread/3c639ae6/ However, I'd suggest instead simply exposing a text stream via a pipe or the like; many users who use assistive technologies like TTS already have their machine set up with a native TTS engine and, depending on the OS of the client machine, can easily be hooked into i'd presume.

hope this helps.

capnmidnight commented 6 years ago

Yeah, cross-platform build is something that is pretty important to me, as I do use a lot of different computers, even if Windows is my primary system. Now is a good time to put the work into getting a good system in place. I hate how almost all of Google's projects involve incredibly convoluted dev environment and build setups. I think it's almost intentional, to keep people from casually using their code.

On the text-to-speech issue, yes, there are lots of systems available. I'm primarily thinking of the need to design with text-to-speech in mind. I suspect your typical adventure game room descriptions will be a tad verbose and eventually get annoying in a TTS environment.

Network setup is definitely my weakest area in projects like this. So a huge area of help that you might be able to fill is designing the server and network setup and guiding the development setup to make deployment easy and fast.

I definitely want to support multiple types of clients. I've found it to be a good means of pushing projects towards good designs when they are forced to support both GUI and text UIs.

johnnybubonic commented 6 years ago

ugh, tell me about it. what happened to just writing good code that was so clean it compiled in all of clang/LLVM, mingw, and gcc without a hitch? ah, the good ol' days.

but back to TTS, yes! i hadn't thought about that. perhaps a way of filtering the stream would be good. options like "never speak the room description", "only speak the room description on first entry", etc.

a quick overall for the network would be you have one (or more, i guess) controller server(s) ("master") for a "network". each network would be, in the concept of MUDs, a universe. masters would encompass entirely different games (kind of like how there are different IRC networks).

on connecting to a master, a player would be prompted for a "realm" to start in (or their state could be cached for X days, where they would connect to the realm they were in last, etc.).

you'd then have a server for each "realm" of that network; this would serve as control for players, controlling which server to balance them to depending on which "region" they'd be "traveling" to.

for example, say i am playing game Foo (network/universe "Foo"). I have not connected before, so i am prompted for a realm (this could even be automatically determined via class-, faction-, or race-specific, etc. as many MMORPGs do). i choose the lush green forest land (realm/"continent") of "Bar" (or i choose to be an Elf Rogue, and as such i am placed to the native realm for Elves, the forest realm "Bar"). i travel through the starting area, region (city, village, etc.) "Alpha", through "Beta", etc. eventually reaching "Zeta". i now am at the edge of realm "Bar", at the seaport of "Zeta" (on "Bar"'s coast). i decide to take a ship to travel to the next "continent" (realm), "Baz".

under the hood, "Bar" tells my client "you should now disconnect from me and connect to "Baz", in region "Alpha." to the user, this could be displayed as anything from a "Loading..." or "Traveling..." text to some (pre-fetched) graphical loading screen for GUI clients, etc. meanwhile, back in the underlying tech, my client has connected to realm "Baz", and i am now in region "Alpha". etc.

that's probably how i'd handle the scaling. care would need to be taken to appropriately manage resources depending on how crowded a given realm may be at any time, but this being a MUD and the servers wouldn't need to render any actual graphics or the like, just processing player actions (via a messaging queue or something), this shouldn't be as big a deal as it sounds.

this model affords certain benefits.

capnmidnight commented 6 years ago

Yeah, that makes sense. I'm only familiar with telnet and SSH as a user, can they redirect the user to an entirely new connection? Or would the Controller Server have to act as a load balancer? Or if not, there could be special SSH servers that are such a load balancer just to accommodate stateless clients.

There are some MUD clients that were able to automatically make sense of many of the existing games. Mudlet is one example, where it could do basic scripting of commands and also generate maps of the land. I think I used zMUD back in the day. Maintaining compatibility with these clients would be pretty cool. I don't think they were expecting any specific API, just that a lot of the MUDs were all implemented in the same MUD code bases like DikuMUD. It'd be interesting to try to scavenge some of that old code (I believe all of the popular MUD systems are now long out of active development) and see if there are any lessons to learn from them. A bit of software archaeology, if you will.

johnnybubonic commented 6 years ago

"can [telnet, SSH] redirect the user to an entirely new connection?"

nope; a redirection like that would have to either be actually multiplexed (they ssh to serverA, serverA decides to tunnel/forward to socket on serverB1 or serverB2, etc).

a "true" redirection would be handled by the client and server. server would tell the client "hey, disconnect from me and connect to IP 1.2.3.4 on port 123".

"Or would the Controller Server have to act as a load balancer?"

it could! that'd be like the first example (serverA => serverB1/2). but the problem there is that while you have a persistent connection to serverB1/2, it's maintained through serverA via a tunnel the entire time. this can cause socket exhaustion and/or throughput issues on serverA eventually. (it's unlikely- we're talking maxing out the interface throughput, usually > 1GBps, and 50-ish-some-thousand simultaneous connections - but it also creates a single point of failure that's an easy DDoS target.)

"Or if not, there could be special SSH servers that are such a load balancer just to accommodate stateless clients."

perhaps, but that'd be something you'd be patching or writing yourself. SSH relies heavily on things like hostkeys to make sure you're actually connecting to the right box and not being MitM'd, which is essentially exactly what we'd be doing (but beneficently, and by design) here.

i think i remember zMUD! reversing those sort of interfaces/protocols should be fairly easy; i'd imagine they're just plaintext over a TCP socket with parsing done on the server end (and various display/rendering parsing being done on the client-side for things like bold text, etc.). though it could be ANSI. if you can find me a daemon and some clients, i can grab some pcaps and try to figure it out from there.

capnmidnight commented 6 years ago

(updated the main post in this thread to provide context to anyone linking in directly to it)

capnmidnight commented 6 years ago

Let's keep this thread high-level/intro stuff/onboarding folks. Let's discuss technical design details in wiki pages. Just write down whatever you want. Riff as fast as possible.

cotterpinx commented 6 years ago

Hi! I'm Lisa. This sounds like fun, I'd love to join. I'm only enh with JS, know more C#, but spend most of my time learning Drupal at the moment. So not sure what all I'd get into but sign me up, plz. Spent a few years using MOOs as part of my projects in grad school so I have a soft spot for them.

capnmidnight commented 6 years ago

Welcome Lisa!

TrevorFSmith commented 6 years ago

Howdy, I'm Trevor. I was a VargonMUD user for a few years starting in the late 90s, and I miss the ambient chitchat and coding of that place. I'm using Rust for a work project and wonder if it might be interesting to use the new Rust-to-WebAssembly toolchain to write code that runs on both the server and in the browser. I also just stumbled onto react-blessed, which is an ncurses lib for terminal apps in Node.js.

capnmidnight commented 6 years ago

Hi @TrevorFSmith. Sorry for the delay in replying. Often, if I don't remember to reply to a message right away, it gets lost forever.

So many things make me want to do Rust these days. I just started on The Rust Book. Some of the things remind me of modern C++, some Scheme. One of the things that attracts me to it for this project is the fact that multiplayer games are inherently difficult to secure.

And I'm definitely interested in the Rust-to-WASM stuff that is going on. JavaScript is one of the languages I know best, and as the saying goes, familiarity breeds contempt. That's not entirely true, I've definitely mellowed out in my old age and no longer believe in complaining about the warts of various programming languages. But the last few years of working on Primrose have taught me a thing or two about JavaScript project management, and having WASM as an escape hatch is very appealing.