Erlang hints for an OO junkie

Chris Pressey cpressey@REDACTED
Wed Aug 11 23:44:13 CEST 2004


On Wed, 11 Aug 2004 09:30:54 +0200
"Johan Warlander" <johan@REDACTED> wrote:

> On Tue, 10 Aug 2004 13:45:30 -0700, Chris Pressey wrote
> > My two cents:
> > 
> > If it's "animate", if it has "dynamic behaviour", if it "moves" -
> > model it as a process.  If it isn't/hasn't/doesn't - model it as a
> > record (or a dictionary.)
> > 
> > So: people, motorcycles, windmills, radios, thunderstorms, etc are
> > processes.  Sandwiches, taverns, tables, mountains, etc are records.
> 
> Okay, here's the catch - it's certainly as you say above, that the
> first set of objects have dynamic behaviour, while the second set
> ordinarily do not.. however, these things are not so static. A dead
> person doesn't move, while an enchanted sandwich might very well fly
> around flapping its lettuce, and for a more down-to-earth example, if
> you leave the sandwich on the table for a week or two it'll definitely
> gain some dynamic behaviour.

Indeed - if things can go from being static to dynamic and back again,
then in the big picture they're dynamic :)

> The thing is that you can seldomly rely on anything at all to be
> non-dynamic in a game. However, one thought I had was if perhaps the
> objects/items as such- even persons and windmills - should be indeed
> records, and the behaviours themselves be the processes, attaching to
> the appropriate record.

This works too.  Each record can have a field for its "animacy", which
might be a process or might be absent.  What this appears to be leading
towards is modelling everything as partly static, partly dynamic.

> For example, a player logging in would cause his in-game body to be
> loaded and instantiated in the game as a record, but his connection to
> the game (that which allows him to issue commands to be parsed and
> executed) would be a process, attached to the body. Similarly, if
> someone casts an enchantment on a sandwich (for whatever devilish
> purposes), that enchantment would be the process, and it would attach
> to the sandwich.
> 
> I don't know if this would solve all of these issues (or indeed any of
> them), but it seems to me like one possible way.

One thing you might want to look at (although you probably already have
considering where you're coming from with this project) is the Inform
language and how it handles "daemons" on objects.  Inform is sorely
limited by the Z-machine; much, much better could be done in Erlang.

> > That said, you could very well model everything as processes, and 
> > have messages propogate from people to rooms back to people, and 
> > such.  This may be a more elegant way to address the problem in some
> > 
> > ways, but in my mind it's not sufficiently more elegant to warrant 
> > doing it.  You can have a *lot* of processes in Erlang, but even so,
> > 
> > the more conservative you are with them, the more efficient the 
> > result.  If you model everything as a process you might be able to 
> > have 50K rooms, 50K items, 50K animals and 50K players; but if you 
> > only model "animate" things as processes you'll be able to have 100K
> > 
> > animals, 100K players, and who knows how many rooms and items :)
> 
> Well, either way would work for me as I'm not aiming to build a
> massively multi-player game; rather, my intended audience if this ever
> turns into a playable game would be somewhere around 40-150 people I
> think.. with the possibility of handing a few hundred, but absolutely
> not numbers in the thousands. The game world as well will probably not
> ever grow too far beyond a few thousand rooms, as I'd rather have 500
> great rooms than 5000 average ones.
> 
> In short, performance -shouldn't- turn out to be the deciding factor..
> I'd be more inclined to value simplicity / beauty of implementation
> (whatever this turns out to mean in Erlang), since those factors tend
> to add a lot to the maintainability of code.

If the implementation limits are no limit to your project, then by all
means, model everything as a process.  If nothing else, this is far more
valuable from the standpoint of how much appreciation of it you can gain
by doing it.  Usually more entertaining, too :)

Going back to the speak/listen example, this changes things just enough
to be interesting enough to mention.  Here's a short brain dump:

When an actor tries to move into a room, a message is sent to the room
telling it that the actor wants to come in.  If the room allows this, it
sends a return message back to the actor telling them they were allowed
in, and both processes update their internal state to reflect the new
position of the actor.

When an actor speaks, a message is sent to the room they are currently
in.  Each room keeps track of all the actors in it, so it relays each of
them the same message.  If the message was "loud", perhaps the room
sends it to all adjacent rooms as well.

Unlike the find_listeners() function of my previous post, this isn't
really a recursive solution, which may have some good ramifications for
performance (a single process isn't blocked doing a traversal; instead,
all the processes involved in the traversal share the load.)

Also, to go back to the subject of OO, it demonstrates a technique
(delegating) that can be thought of the parallel of inheritance in
a purely message-oriented system.  Instead of X IS-A Y, you have
something more like X RELAYS-TO Y.  This is much more flexible, but
since it's correspondingly easier for it to go haywire too, it's likely
that it should be used even more conservatively/wisely than inheritance
should be used in OO systems.

-Chris



More information about the erlang-questions mailing list