Crossfire Mailing List Archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: AI scripting language, was Re: CF: More roleplaying



On Wed, Sep 22, 1999 at 09:04:31PM -0700, Mark Wedel wrote:
> David Andrew Michael Noelle wrote:
> > 
> > > Date: Mon, 20 Sep 1999 11:10:08 -0700
> > > From: Ian Main <imain@netidea.com>
> > 
> > > ..  what about embedding a perl interpreter to do AI ?  It's
> > > relatively easy to wrap perl functions around a C API.. you could
> > > just create a fairly simple API for controlling monsters, and then
> > > have ways to trigger the perl functions.  This would allow you to
> > > script monster movements, conversations etc..  you could get some
> > > pretty smart monsters actually :)
> > 
> > I've been thinking about this.  It's an interesting idea, but I don't
> > know that it's practical.  PERL is great for those of us who spend
> > more time reading and writing programming languages than human
> > languages, but the AI scripting for Crossfire should ideally be
> > something more accessable to non-programmers.
> 
>  Ideally yes.  But unless the scripting language is very simple, I think there
> will be some learning curve.
> 
>  I think one thing that needs to be examined is what features are needed in a
> scripting language.  I can take a quick look at perl, and for crossfire, maybe
> it would need about 10% of the functions it has to offer (the regex stuff is
> nice, as is the general control structure, but pretty much all  the standard
> functions should not be used, and even many of the  more simple things (like
> arrays and hashes) have to be carefully done, otherwise you could have a buggy
> perl AI consuming tons of memory as it keeps allocating stuff but doesn't
> deallocate it.

I'm not going to comment on too much of the stuff below because I do not
know the crossfire internals well enough, but I'll share a bit more of my
thoughts on the use of perl..

The callbacks are the way to go.. for instance, I would imagine that
anything anything is said in the room with the npc, a callback could be made
(that would be associated with that npc.. held in its struct or what have
you) so the perl script can parse (probly using regex) the string and figure
out what it wants to do..  Other events might include movement,
dropping/giving, picking things up etc.  

What you can do in perl is define a seperate namespace associated with each
instance of the npc, so you can keep state (if necessary) in whatever
variables you wish and there will be no namespace collisions.  (this is done
using 'package' keyword.. just stick it at the top of the perl code you're
going to eval).  I'm pretty sure I saw a thing to wipe out all memory
associated with a namespace too, so it'll do good garbage collecting for you
and you don't need to worry about memory leaks so much.

The most important part (as usual), is the API you present for the npc's.
You can make it as complex or as simple as you want.. and obviously a well
written API will take you a lot further.

I can give you a hand with this if/when you want to do it.. just let me
know.  Making the gateway between perl and C is really not that difficult
(that's how all many of the perl modules are made, so it's been going on for
a while).

> > A PERL interpreter wrapped around a C API would certainly be more
> > powerful, but might be just a bit on the global thermonuclear overkill
> > side.  If anyone wants to volunteer to do it anyway, be my guest.
> 
>  If we use an outside language, it certainly needs to at least be able to make C
> function calls intro crossfire.  I certainly think it would be a pain for most
> to actually deal with map structures, object stacking, and the like.  So you
> might have some things like:
> 
> watch_map(name, distance): Sets a callback or something so that
> if object with 'name' shows it, it does the right thing.
> take_object, give_object: takes and gives objects.  Some matching is needed. 
> These would deal with the npc's inventory.
> walk: the object moves.
> say: says something (like the current msg)
> listen: listens for some keyword

exactly.

> 
>  And probably some others.  Some things could be very formalized - for example,
> that watch_map function might always call the 'watch_callback' function in the
> ai script, which can then do something else (like turn off the watch, or watch
> for something, or move towards the object to pick it up).
> 
>  With a reasonable set of these primitive functions, I don't think the ai script
> will be all that complicated.  A few state variables could be set for the ai
> processor.
> 
>  Note that in all likelihood, crossfire should know about those state variables,
> so when the map is swapped out to disk, it can save those also.  Otherwise, the
> npc logic code may reset, but the npc itself does not, so it may try to give
> away something it know longer has.
> 
>  Now whether we actually need an outside API program for this, or something
> written internally is something that should be examined.
> 
>  An interesting thought would be npc modules done in C source code.  That then
> of course has access to all the data structure, so could be pretty spectacular,
> but likely should only be used for very special npcs if at all.
> 
> 
> > I think in many cases, the same functions are called for player
> > actions and NPC actions, with some important differences in their
> > object structures.  With the 0.96 object rewrite, those structures are
> > going to change, so some of the functons that are not currently
> > relevant to NPCs may become relevant soon.  ("Soon" being a relative
> > term.)  The next step would be enabling those functions to be called
> > from a script of some sort.  How powerful, accessable, extensible, and
> > concise those scripts are depends on who volunteers to code them and
> > what concensus is reached here.
> 
>  The way I am thinking now is that players will be a subtype of the creature
> subtype (creature being monsters and other killable things).  My thinking is to
> also treat both fairly same at the creature level (strength will determine how
> much a monster can carry, as well as speed adjustments and the like).  This will
> probably have a major balancing effect, which will require a rewrite (that
> monster isn't going to want to pick up everything it can)
> 
>  This at least makes a lot of stuff internally consisent and should reduce the
> code a bit.
> 
> > 
> > Scripting is a critical feature that will strongly influence the rest
> > of the game.  As such, it deserves all the serious discussion and
> > planning we can put into it.  We need a scripting mechanism, but what
> > functionality do we want from it?  What are our priorities here?
> 
>  Some of my thoughts are above.
> 
>  My personal thought is we don't need anything too complex.  I personally would
> rather have a lightweight scripting language so that a lot of the creatures out
> there could use it without it becoming a burden on the game/cpu.
> 
>  But one way to approach this is to ask:  What abilities should npcs be able to
> do that they can't right now.  Some quick thoughts:
> 
>  1) Have at least some memory, so conversation can flow better without having to
> enter the magic keywords it is looking for.  This can be done with just one or
> two state variables.
>  2) Object giving and taking by npcs.  If you are going on some quest, that npc
> should be able to give you something that helps, and at the same time, if you
> have something to give the npc, you should be able to do so.
>  3) Ability to cast spells on demand (after being given something or the correct
> conversation sequence).  So you could pay an npc cleric to cast some spell.
>  4) Directions to use map features (apply below which pulls the lever or the
> like).

Note that it's easy to get a list of things in perl and play with it.. eg:

@inventory = get_inventory ("some_payer");

foreach $inv (@inventory) {
  print "I have a $inv\n";
}

where of course, get_inventory () would be calling a C function that pushes
all the items onto the perl return stack..

given a whole pile of them.. you might end up with AI that looks something
like:

# sub call perl function 'talked' whenever someone 'says' something
connect_talk_event ('talked');

sub talked
{
  my ($sentence) = @_;
  
  if ($sentence =~ /hello/) {
     message ("Hello there good sir");
  }
}

# call 'gave_me' when someone gives you something
connect_give_event ('gave_me');

sub gave_me
{
  my ($item) = @_;
  
  if ($item eq "A big pile of turds") {
     message "You bloody twit!";
     move_to (20,23);
  }
}

and so on..  it would probly be a bit more difficult once you get into
looking at the map and objects around you etc.

>  Thats a short list which would make NPC's in places like the tavern much more
> interesting.  Other more interesting features would be more sophisticated
> movement for NPC's (but that could get complicated in a hurry)
> 
>  That said, some logic for the more monster NPC's:
> 
>  1) Only cast spells that are useful.
>  2) Only pick up stuff that is useful.
>  3) Ability to use a more varied list of items (drink that potion of healing or
> whatever).
>  4) Better tactics (although, in many cases, they are not terrible right now -
> creatures like orcs know enough to shoot arrows from a distance and only close
> when they run out).  Since the player is sort of designed to win, logic for
> running away probably doesn't make a lot of sense (where is the monster going to
> go).
>
>  I seperate the monster and npc (friendly) logic since the interactions between
> the two tend to be fairly different.  Also, the monster logic is more likely
> should be hard coded like it is now (pick up, cast, etc).  The big problem is
> that some areas just need to be updated, like the spell casting logic.

Interesting.. it would certainly be an interesting exercise to try just
attaching a chunk of perl code to the struct of each monster for AI :)  You
could even have it attempt different strategies at random.. I like hack and
slash, but I think it'd be cooler if the monsters were smarter.

Ian

"Simplicity is achieved by the elimination of special cases, such as the
discrimination between devices and files."

   - Brian Kernighan and John Mashey.
-
[you can put yourself on the announcement list only or unsubscribe altogether
by sending an email stating your wishes to crossfire-request@ifi.uio.no]