27 Apr, 2012, Idealiad wrote in the 1st comment:
Votes: 0
This thread is about BAAS, because the more acronyms the better off we all are. Though I have a sinking feeling already about where people will go with the thread title…

Actually I don't know quite what to call it, but here's the basic idea. Say you wanted to create a mud server which was designed to allow the game code to be written in any programming language. The game loop would run something like so:

input –> event(s) produced –> events consumed by subscriber bots –> bots process events –> game state updated

There's a core server (like a SocketMUD), and then bot services connect to it on a normal socket. For example, you might have a combat system bot, a weather bot, an economy bot, and so on. Or you could have just one bot that does it all.

I remember Tyche mentioning a modular/saas mud at one point and that it became somewhat unworkable (my memory might be failing me though). Clearly there are some pitfalls with this idea – latency, memory, and processor constraints are the first ones I think of. Others?
27 Apr, 2012, quixadhal wrote in the 2nd comment:
Votes: 0
Better idea.

Don't cobble up yet another server to try and mitigate mixing languages under a single executable.

Write a custom shell that talks to your game server via a socket, and have players create accounts on your system that get that shell as their login shell. Then they can write their "bots" and run them with whatever tools you provide, and they talk to your server via a standard API, meaning they can't really "cheat" if your server doesn't accept commands that would be considered cheating.

Note that the custom shell is the player's "client", as it will also use the same API to translate the player's typing into commands.
28 Apr, 2012, Idealiad wrote in the 3rd comment:
Votes: 0
Correct me if I'm wrong, but wouldn't that limit me to the UI conventions of a terminal emulator unless I wrote my own emulator (is that the same as writing a shell? I don't think of emulators and shells as the same thing), or used something like Termkit?

The primary goal isn't to let players write bots (of course nothing is stopping them, and they could also use the public API of the core server), but to let the developer write services outside the core game server process.

I was thinking of another major issue the other night – DB access. It seems like the services would be making a lot of repetitive DB calls to the server for every event. I guess the solution to that would be for each service to cache its calls, and the server to notify the services when it needs to update its cache.
28 Apr, 2012, quixadhal wrote in the 4th comment:
Votes: 0
Have you ever logged into a unix shell via telnet/rlogin/ssh?

If you haven't, you should do so and then think about your question. If you have, think about it again. How does a shell limit what you can do?

As you said, a terminal emulator and a shell are not the same thing, and in fact are two quite distinct things that tend to work together. When you log into a unix system, you are using a terminal (emulator) to handle what kind of display you have. The shell you are connecting to (bash/tcsh/etc) is the thing that is accpeting your commands, parsing them, and calling other programs. Shell scripts work just fine without a terminal, although some processes may expect a terminal to function.

Rather than futzing around with writing a server which (as all MUD servers do) tries to mimic the behavior of dozens of unix systems within a single process, my suggestion is to let unix do the work it was designed to do. Let it handle logins, and resource control, and file access. Write a custom shell which talks to your game server and which the unix login system will connect to a terminal, just like ssh or telnetd does now. If you use a standard API to talk to the game server, you can write external scripts or programs that do the same.

You want to take advantage of multitasking. Doing that inside a single process is a pain…. you have to use mutex locks ALL OVER THE PLACE to ensure mulltiple threads aren't trying to read data that's being changed. OTOH, if every player (or agent) is a seperate process that talks to the game via an API, the game server is the one reading/writing the data (as it does now), but some of the computation can occur in the local agent.
29 Apr, 2012, Tyche wrote in the 5th comment:
Votes: 0
Idealiad said:
This thread is about BAAS, because the more acronyms the better off we all are. Though I have a sinking feeling already about where people will go with the thread title…

Dreaming of electric sheep? :-)

Idealiad said:
Actually I don't know quite what to call it, but here's the basic idea. Say you wanted to create a mud server which was designed to allow the game code to be written in any programming language. The game loop would run something like so:

input –> event(s) produced –> events consumed by subscriber bots –> bots process events –> game state updated

There's a core server (like a SocketMUD), and then bot services connect to it on a normal socket. For example, you might have a combat system bot, a weather bot, an economy bot, and so on. Or you could have just one bot that does it all.

I remember Tyche mentioning a modular/saas mud at one point and that it became somewhat unworkable (my memory might be failing me though). Clearly there are some pitfalls with this idea – latency, memory, and processor constraints are the first ones I think of. Others?


Well I've always been obsessed with partitioning muds into subsystems or services. I suppose you could call them bots. I don't think it's all that important whether these services be distributed or not. After all MySQL is really a distributed storage service while SQLite is an in process storage service. You might have reason to care or choose one over the other for performance reasons, but the application interface is pretty much the same. The same is true of plugging applications written in many languages into Web servers. The trick is coming up with a suitable glue; a framework that gives you the ability to plugin modules. Some of the partitioning that's been done in muds is fairly straight-forward, proven and relatively "easy", like a network subsystem or a back-end storage subsystem. Multiple languages using common communication mechanisms have been done like in MUQ, which allows one to write code in special versions of C, Lisp or Forth. Almost all of the programmable servers I've seen, make use of message queues and event queues in that glue. Whether messages are pushed directly into queues in process or sent over a network connection to another process is a matter of choice. CoolMud, for example, does both; messages can be local or to remote servers.

The particular difficulty I think is to successfully partition a game into independent modules. For example, plugging in a GURPS combat module, an Ars Magica magic system, and a home grown movement system. Crazy stuff like that.
29 Apr, 2012, Tricky wrote in the 6th comment:
Votes: 0
Sounds suspiciously like Eggdrop.

(BAAS)
29 Apr, 2012, Idealiad wrote in the 7th comment:
Votes: 0
quixadhal said:
Rather than futzing around with writing a server which (as all MUD servers do) tries to mimic the behavior of dozens of unix systems within a single process, my suggestion is to let unix do the work it was designed to do. Let it handle logins, and resource control, and file access. Write a custom shell which talks to your game server and which the unix login system will connect to a terminal, just like ssh or telnetd does now. If you use a standard API to talk to the game server, you can write external scripts or programs that do the same.

You want to take advantage of multitasking. Doing that inside a single process is a pain…. you have to use mutex locks ALL OVER THE PLACE to ensure mulltiple threads aren't trying to read data that's being changed. OTOH, if every player (or agent) is a seperate process that talks to the game via an API, the game server is the one reading/writing the data (as it does now), but some of the computation can occur in the local agent.


I get the idea of using unix for the core server, but it seems to me that a design like that would be more intimidating to a prospective game maker. Rather than test driving the game on their own server they'd have to use a VM image or maybe a script that automatically deploys to a host like EC2…which could be interesting, food for thought.

As far as multitasking goes, that isn't such a problem, I was planning to use Clojure for the core server.

Quote
Multiple languages using common communication mechanisms have been done like in MUQ, which allows one to write code in special versions of C, Lisp or Forth. Almost all of the programmable servers I've seen, make use of message queues and event queues in that glue. Whether messages are pushed directly into queues in process or sent over a network connection to another process is a matter of choice. CoolMud, for example, does both; messages can be local or to remote servers.


Cool, thanks for the references Tyche.
02 May, 2012, Idealiad wrote in the 8th comment:
Votes: 0
Holy cow, MUQ – it's like a gate into another dimension. :stare:

I've yet to get into CoolMud, but thinking about this today another issue came up – command parsing.

This seems to me like kind of a reverse of the services needing caches of the DB. Given that the command parser and some kind of world model will live in the core server, once a player command is parsed the server needs to know what to dispatch the command to. When a service connects to the server it could register its commands in the server's command cache; if you modify a command set on the running bot it could push the changes to the server's cache.

I'm not sure to what extent I should protect the user against command namespace collisions between different services (say the user installs GURPS combat and Ars Magica magic, and both have a command called 'fire'). The user could edit either one of the services, or there could be some way to extend commands in the core server itself, but that latter option seems pretty messy. What do people think?
02 May, 2012, Runter wrote in the 9th comment:
Votes: 0
"I'm not sure to what extent I should protect the user against command namespace collisions between different services (say the user installs GURPS combat and Ars Magica magic, and both have a command called 'fire'). The user could edit either one of the services, or there could be some way to extend commands in the core server itself, but that latter option seems pretty messy. What do people think?"

Make the lookup favor the one which registered first, and give it optional syntax like this: "GURPS::fire" or "Ars::fire"

personally, I would suggest making every module, bot, whatever, include some kind of command manifest for the mappings designed to be edited easily when the thing is installed, or later once the conflict is discovered.
02 May, 2012, Idealiad wrote in the 10th comment:
Votes: 0
The issue is, do you edit the mapping in the service, or in the server? Either way, I suppose you could make mappings a user configuration file that persists between service package updates. On top of that, say mud A has package X and Y, and they edit it one way, then mud B has package X and Y and they edit it the opposite way. Biff plays mud A, then goes and plays mud B, and complains about the jerk who invented this dumb command mapping system. ;D

I guess true modularity is something of a fool's errand and not really something I'm shooting for, but I'd like a sane default.
04 May, 2012, quixadhal wrote in the 11th comment:
Votes: 0
If you were using a shell-like system as I described, your PATH would determine which thing wins.
04 May, 2012, Tyche wrote in the 12th comment:
Votes: 0
Idealiad said:
Holy cow, MUQ – it's like a gate into another dimension. :stare:


Admittedly it is a complex example. You can find a much simpler and crude one in TeensyMud. It implements two "languages", TinyMud Boolean expressions and FARTS, using the same interface. But any mud that implements a mud programming language could in theory support multiple languages. LP-MOO is another example, which implements MOO in LPC.

We've got clients now that implement multiple languages like VBscript, Javascript, LUA, Ruby, etc. There's no reason why a mud server ought not support multiple languages. The holy grail of mud servers is going to support Mushcode, MUF, MOO, LPC, DGScripts, and MobProgs. :-)

Idealiad said:
I've yet to get into CoolMud, but thinking about this today another issue came up – command parsing.


I am working on an updated port of CoolMud. It seems the one I did years ago has suffered a little bit rot.

Idealiad said:
I'm not sure to what extent I should protect the user against command namespace collisions between different services (say the user installs GURPS combat and Ars Magica magic, and both have a command called 'fire'). The user could edit either one of the services, or there could be some way to extend commands in the core server itself, but that latter option seems pretty messy. What do people think?


I see command parsing is a separate module. A plugin module might "recommend" commands via a default configuration file. If, for instance, a mud mail plugin conflicts with mud note board plugin, then one would have to configure one or both not to interfere with each other.

Idealiad said:
I guess true modularity is something of a fool's errand and not really something I'm shooting for, but I'd like a sane default.


There are certain aspects of a running game that lend themselves to independent modules or plugins. Things like mud mail, mud boards, account/registration system, player communication, etc. People have created drop-in packages for these types of systems in Mushes and MOOs. Other things are a bit harder because of tighter coupling to other game systems, like weather and movement. Mixing different character creation systems, combat and magic systems would be difficult. I think you'd need some pretty complex translation interfaces,
04 May, 2012, Idealiad wrote in the 13th comment:
Votes: 0
Tyche said:
I see command parsing is a separate module.


I was wondering about this. I can see the appeal of being able to easily swap in a different parser. On the other hand, while it seems likely that someone might want to add their favorite mud bulletin board it seems less likely they would want to try a different parser, so for simplicity's sake I was leaning toward including it in the core.

On the other hand, I can imagine a case where someone may not want to completely replace the parser but just make a small modification, or try a fork of the core parser that has a few add-ons or edits, and in that situation a module would work well.

Quote
If you were using a shell-like system as I described, your PATH would determine which thing wins.


It's not about which module wins; you want the player-entered 'fire' command for module X to work and module Y to work, so you need to rename one of them somewhere.
05 May, 2012, Tyche wrote in the 14th comment:
Votes: 0
Idealiad said:
I was wondering about this. I can see the appeal of being able to easily swap in a different parser. On the other hand, while it seems likely that someone might want to add their favorite mud bulletin board it seems less likely they would want to try a different parser, so for simplicity's sake I was leaning toward including it in the core.

On the other hand, I can imagine a case where someone may not want to completely replace the parser but just make a small modification, or try a fork of the core parser that has a few add-ons or edits, and in that situation a module would work well.

There's always been a long standing argument over centralized versus decentralized parsers. MOO and COOL implement objects that have verbs (commands). Objects in the current "environment" are searched for verbs. However, there is a .parse() function called on players by the driver. Commands are passed to that function first, so commands can be overridden centrally. I believe it's similar for LPMuds, some mudlibs implement centralized command parsing, some decentralized, and some mixed.

Methinks mixed is probably a good way to go. That way if you implement subsystems that have their own commands that interfere with each other, you can define central commands that map to the ones defined on the subsystem objects.
07 May, 2012, Idealiad wrote in the 15th comment:
Votes: 0
I'm wondering if anyone has experience with RPC protocols and what they would recommend. It seems like using some implementation of JSON RPC would be a simple way for services to use the API of the core server, but searching around hasn't yet revealed any opinions about it either way.
10 May, 2012, Idealiad wrote in the 16th comment:
Votes: 0
Well I've learned more about serialization options since the other day.

Reading an old post by Tyche here leads to the question, even if you have a message format (BSON, MessagePack, JSON, etc.), are there existing protocols I could take advantage of? For example, what's the 'Telnet' of JSON? Would that be JSON RPC (or MessagePack RPC, etc.). Is it simply HTTP and so on? Are there common game messaging protocols out there?
10 May, 2012, Tyche wrote in the 17th comment:
Votes: 0
RPC can and is done using TCP, UDP, HTTP, IPC, RDP and probably other protocols. The marshalling of data can done using many different formats, XML, JSON, BSON, YAML, ad inifinitum.
It's the combination of internet protocol, data format, and other negotiation/interface glue that defines a particular RPC protocol.
There are dozens of them like CORBA, Java RMI, XHTTP, Ruby dRb.
Which one you use might be heavily influenced by what language you plan on using.
Also some RPC protocols implement a blocking or wait for response mechanism, some implement a non-blocking event type mechanism, some both.
There are also other pieces that might be included in an RPC protocol like service discovery, ring servers, security/policy servers.
11 May, 2012, Idealiad wrote in the 18th comment:
Votes: 0
One issue is whether to sign onto a particular RPC framework or stick with messaging, whether JSON, BSON or whatever. It seems reasonable to support several formats (as the goal is to support services in whatever language, why lock into one format) but I'm not sure how reasonable it is to support several RPC frameworks.

Also given the basic design,



I wonder if the message flow is too complicated. For example,

Player command –>
net proxy –>
core server command parser –>
net proxy –>
service (probably at least one more request/response back to server for data) –>
net proxy –>
core server –>
net proxy –>
player(s)

On the other hand I feel like routing everything through the proxy is better than wiring the services directly to the server.
12 May, 2012, Idealiad wrote in the 19th comment:
Votes: 0
Extending that diagram,



The message flow would look something like,

Player command for intermud chat –>
net proxy –>
core command parser –>
intermud service –>
net proxy(s) –>
(then tracing the flow at one mud)
core (logs it) –>
net proxy –>
player(s)

What I don't know if I like here is that services like intermud chat need server and client code, to handle connecting to "their mud's" net proxy as well handle other muds' net proxies connecting to them. I wonder if it would be better to just wire the net proxies together, which could then make use of other muds' services like,

Player command for intermud chat –>
net proxy –>
core parser –>
intermud chat service –>
net proxy –>
its own core server and other net proxies listening for this event –>
(tracing at another net proxy)
core server logging it –>
net proxy –>
player(s)
0.0/19