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

Alexander Williams <>
Sat Mar 17 04:18:08 CET 2001

On Fri, Mar 16, 2001 at 01:35:47PM -0600, Chris Pressey wrote:
> I totally agree.  However, I can't think of a way to stop people from
> writing 'bot code like:
>   apply(unix, cmd, ["rm -rf *"]).
> And that would be bad!  I suppose taking out the unix module entirely
> might help... I'm not familiar enough with Erlang to know how many other
> holes are possible, though.

I'm not sure if someone has written the equivalent of Python's
"bastion" or Java's sandbox, essentially a restricted environment in
which only access to listed modules and builtins is allowed.  That's
really what this project would need to allow scripting in Erlang
inside the server.

> I have no idea if my Erlang project will turn out anything like that,
> though.  Currently my temptation is to have a more hierarchical,
> abstract world, mainly because it would simplify it greatly if you could
> just see everything in the current 'room' instead of calculating
> line-of-sight to determine the set of visible objects.

Ie. the "MUD" concept in which the universe is broken into groups of
"cells" or rooms, and all things within a given cell can freely
interact.  Its certainly the simplest means of implimenting a
universe, and the easiest to explain to an outside observer.

> My feelings - though I'm a mnesia newbie - is that one big table (in
> RAM) is going to be the fastest solution - because any partitioning
> would mean more resource-accesses per data-access.  I don't see a lot of
> reason to add filesystem directories to the mix, as mnesia already has
> many of the properties that files have but database fields traditionally
> do not (variable length, complex structures etc.)

The main reason to add a filesystem hierarchy to the system is to make
it easy to modify things from INSIDE the system, on the fly.  Its an
intuitive, understandable thing to say "OK, I need to edit
/server/things/player/commands.erl to add the ability to hug random
people," and then commence said operations, than to say "OK, I need to
grab the "commands" field of the "player" record ... now, where is
that related to everything else?"  Its purely a human-access concern.
One could, theoretically, lay a false filesystem hierarchy over the
mnesia database itself ... but since filesystems already exist, it
seems redundant.  As a pleasant addition, the mnesia database ends up
holding ONLY the persistant data, not the sourcecode.

> That is pretty much the case.  Imagine functions player_loop() and
> npc_loop().  They act very similarly except that player_loop() gets its
> orders from a socket, and npc_loop() calculates its orders using AI. 
> Sure, they could be the same function, since they share some
> functionality, but I think it would be a tad more efficient if they were
> seperate functions (so that NPC's aren't continually checking for their
> non-existant sockets.)

Its all the more efficient to have the Thing/object itself only have a
reference to its "master," which could, in turn, be a Pid of one of
the above.  Thus, you genericise the Thing and allow it to be driven
by either mode, improving your code reusability.

> There are also some 'higher-order sense' that turn out to be useful. 
> For example, being able to see someone else move.  {see_move, Sender,
> NewPosition} or something.

Sure; defining the set of messages your Things can respond to is one
of the basics of game design.  Allowing that kind of extensibility on
a Thing by Thing basis is one of the advantages of being able to drive
a generic core.  :)

> I dunno.  In my scheme, 'live' objects can be suggested to do actions,
> but what they actually do is up to them.  You could suggest to your dog
> that it follow you, and if it is loyal it will obey.  But if it catches
> rabies, it's AI might change and it might not be so complicit!

Not "suggested" as an in-game issue, but controlled by another
process.  Like a Teleport Device can force a move on a Thing, if it
has sufficient priviliges, or, the way an Administrator on a MU* can
@force a Thing to execute actions as if done by the Thing itself.
"Suggesting" is an in-game issue and, as such, is constrined by the AI
of the game.  I'm talking about external forces.

> Well, it seems as if you have two processes here (one for the logic, one
> for the object-state), while I don't see why you need more than one
> process (which can handle both logic and object-state.)

Because logic can change.  The Thing with state persists.  For
example, modelling the Dog that can potentially become RabidDog
becomes easy once you separate logic and state.  As a Dog, it uses a
passive AI instance (PetDog) and its stats are all bound on the
DogThing.  When it goes rabid, Dog is sent a {goRabid} message, it
changes its stats appropriately, and switches its control from PetDog
to RabidDog, wjich then drives its behaviours.  Now, let's say that
the Dog is needed to do some custom things that its best if a person
drives; we reconnect the behaviour Pid from RabidDog to
PlayerConnection where a person is logged in.  Voila, it retains its
rabid stats but takes orders from a person.  When done, swap the
PlayerConnection for RabidDog until RD decides its time is up, then it
says to {returnToNormal} or just tells the Dog to {die}.

Separating state and behaviour lets you do all kinds of fun and
perverse things.  :)

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