Fun with Erlang (was Re: Stand Alone Erlang for Windows. yet again)

Alexander Williams <>
Fri Mar 16 09:54:31 CET 2001

On Fri, Mar 16, 2001 at 01:16:44AM -0600, Chris Pressey wrote:
> Indeed, I thought about that a bit too.  A mechanism like Perl's
> taint-checking would be nice.  Failing that, probably a little
> object-manipulation language which is compiled into safe Erlang when
> entered.

It seems a bit ... unwieldy ... to plug in a whole separate language
when we already have a perfectly wonderful language (Erlang)
interpreting the core.  I'd probably, given my druthers, throw away
the idea of "representations as objects" for the more-Erlang'y
"representations as processes," since Erlang lets us have extremely
lightweight processes so easily.  More, I suspect, below.  :)

> This started out as an experimental roguelike game in Perl, which

Roguelike.  In Perl.  [instert: making sign of the cross]

> All objects in my game are records in a monolithic mnesia table (which
> is currently ram-and-disc, I will probably change that to ram-only with
> periodic dumps in the future, for speed.)

Yeeow.  That's scary-big, I must say.  (Of course, much of my internal
sense of MU* scale has been shaped by sites like LambdaMOO and
FurryMUCK, both on the edge of outside size.  Once you hit several
hundred to a thousand users on simul a night, even throwing text
around gets messy.)  I probably would have started with the DB itself
being ram-only with dumps ... but that leaves aside the issue of how
objects themselves get stored/updated.  Does one update the mnesia
table itself, or is that merely "current state," and the object
sources are stored in text files in some kind of file hierarchy?  My
gut suggests that such an LP-like scheme might be just what the doctor
ordered, because it makes hot-swapping code easy.

> There is a field 'pid' in the record definition.  Objects with 'agency'
> have a pid associated with them.  Such objects can be NPC's (internal
> bots), in which case the process is responsible for their AI.  Or they
> can be human players or external bots, in which case there's a valid
> value in the 'socket' field too.  So the difference between 'live' and
> 'inert' objects is merely that of an attached process.

Hmmmmmm.  Wouldn't it be easier to have "controlled objects" simply be
associated with a Pid from which they accept messages/method calls,
and its only the nature of the Pid that determines whether its player
or AI-controlled?  A Player Pid would involve a poll for outside input
before it sent messages to the Thing, whereas an AI would be just
sending them based on perceptions (as relayed back by the Thing) and
coded responses.

Exempli gratia (a Thing based on an Erlang Process, because its an
Erlang ML :)):

Thing is considered to be the Pid of the "Thing" process here.

Thing accepts several messages from anyone:

  {see, Sender, Text} -> Something game-environment is seen (usually
room Descriptions and such).
  {hear, Sender, Text} -> Thing hears something.  It might be from
someone speaking in the room or a creaky floor.  Could be anything.
  {smell, Sender, Text} -> I think you get the idea here.

You wouldn't necessarily need to have a message for each sense
(in fact, most MU* systems don't even provide the facility to do so,
Things can only {hear, Sender, Text}).  Pretty much everyone counts on
Sender being useful, for various reasons, so message-sending is
typically only done through protected functions.  Also note that
receiving messages you don't know what to do with should be pretty
much just silently tossed, maybe with a message to a debugging log if
desired.  (It doesn't matter if your Robotic Dog doesn't impliment
{temperatureSense, Sender, Change}, for example.  :))

Likewise, Things can be ordered to do actions (which likely cause
Thing to, in turn, send messages to other Pids in its virtual area,
informing them to remove Thing from the target's content list, etc.).
Command-messages are only accepted from an appropriate Sender (defined
when the Thing is created and probably updatable).  If its not from
Sender, toss it.

Useful command-messages might include:

  {move, Sender, Direction}
  {say, Sender, Text}
  {odour, Sender, Text}
  {reloadCode, Sender}

The last one lets you update the beasty on the fly without requiring
you to do a module:loop call every time through, making it slightly
more efficient and controllable.

A Player's Character, then, would only respond to command-messages
from the Player's ConnectionProcess Pid or a Wizard's privilidged Pid
(and, in turn, would emit status messages to that CP Pid).  A bot, on
the other hand, would have an AI Pid it listened to and emitted to,
but the underlying Thing could be responding to either, invisibly
(and, if desired, switchably).

(Forgive me if this seems scattered, I'm writing this
extemporaneously.  :))

> I'm using a sort of 'object factory' approach where there are no
> classes; instead, 'exemplars' which are copied and tweaked.  Exemplars
> describe distributions for stats (e.g. strength = 3d6) while instances
> have concrete values (e.g. strength = 15.)

Hmmmmm, so you're mimicing a very MUSH/MUX-like system for that.
Though you might want to allow for multiple Exemplars for any given
Instance and arbitrarily deep chains of Exemplars, to allow for more
flexible behaviour.  (Ie. an Exemplar that soley contains the
statistic system and an Exemplar that contains the physical commands
for, say, a certain class of monster, as opposed to another; they
share stats and methods to access stats in common but the Basilisk may
change anything in its LoS to stone while the Cockatrice requires
touching, or something like that.)

I've been reading Theirry's articles as referenced earlier about
implimenting Worldforge in Erlang.  I'll be honest, I dislike the
Worldforge project itself because I think its too ambitious and
unrealistic, but Thierry has broken down the necessary structures
underlying /any/ kind of IP-driven client/server interface very well.
These bits of code could very well form the core of a good MU* server
(and likely give far better performance than we have seen in the past
for MU* servers; soft-realtime is good).

Alexander Williams ()               | In the End,
  "Blue Jester needs food."                             | Oblivion
  "Blue Jester needs fuku-wearing cuties."              | Always                                | Wins

More information about the erlang-questions mailing list