Category Archives: Artificial Intelligence

Custom Action Editing

I’ve got custom action editing working in the zone editor now.  Here’s an example:

Custom action editor screen

To create an action, you select items from the drop down list to build a sentence describing the trigger and the resulting action.

After you have an trigger added, you can add additional actions by selecting the item in the list and clicking “add subaction”.  You can see examples of this in the screenshot.

There are also “find” buttons that help you locate the various items you can use as arguments.  Even though you can just type values into the text boxes, this can be handy when you want to make sure you have the right item or have gotten the spelling right on the spell to cast.

This will be available for mobs and objects in the next release of the zone editor.

Custom Actions: Our Version of Scripting

Some MUDs, including Basternae 2 and those derived from the Envy family tree, support MobProgs.

Some MUDs, inlcluding Basternae 2 and those derived from the Diku/Envy family tree, used custom C code (“spec_fun” code) to add special abilities to mobs and objects.

MobProgs are useful, but they can be a pain to edit because they’re pretty “scripty” and most editors don’t have any data validation.

Special functions require the direct attention of a programmer for things that aren’t necessarily complex enough that they should require code.

What I’ve come up with for Basternae 3 is something I call “Custom Actions”. They can be applied to mobs, objects, races files, and class files. It’s sort of an action template definition that will be easy to edit using the Basternae Editor’s GUI (when I finish it). The general idea is that there are triggers with one or more actions that can be associated with them.

Editing will be done using a sort of “Mad Libs” style interface. You’ll build descriptions of triggers and actions using buttons and drop-downs. For instance:

“When the mobile is attacked”:

“Say” “Tough luck, buddy, I brought my posse with me.”
“Wait” “two seconds”
“Create mob” “8192”
“Create mob” “8193”
“Create mob” “8194”
“Wait” “one second”
“Say” “Now you’re gonna get it!”

“When in combat”:

“Cast spell” “fireball” “4% chance”

“When a player tries to leave the room in direction” “north”:

“Prevent action”
“Say” “You’re not invited to this party.”

“When room contains object” “23” (a corpse):

“Destroy object” “23”
“Echo” “The ravenous bugblatter beast devours another corpse.”
“Wait” “3 seconds”
“Interpret command” “burp”

Here’s a list of the triggers and actions I’ve come up with for the first version:

———-

Each trigger has a percent chance of executing.  Each trigger also has a data field that may or may not be used depending on the type.

Trigger Types

Action: When someone uses the command

Value contains the command name.

Combat: When in combat

Value is not used.

Death: When killled or destroyed

Value is not used.

Engage: When combat is initiated

Value is not used.

Entry: When entering a room

Value is not used.

Exit: When exiting a room

Value is not used.

ObjectInRoom: When room contains the object

Value is the index number of the object to react to.

PlayerEntry: When a player enters the room

Value is not used.

PlayerExit: When a player leaves the room

Value is optional and is the direction to pay attention to.  Blank means watch all directions.

Random: A random chance

Value is not used.

ReceiveItem: When receiving an item

Value is optional and is the index number of the object to react to.

ReceiveMoney: When receiving money

Value is optional and is the minimum amount of money needed.

Speech: When someone says

Value is the word or phrase to react to.

Action Types

Each action has a data field that may or may not be used depending on the type.

Attack: Attack the player who caused the trigger to fire.

Value is not used.

CastSpell: Cast the spell

Value is the name of the spell to cast.

CreateMobile: Creates a mobile

Value is the index number of the mobile to create.

CreateObject: Creates an object

Value is the index number of the object to create.

DestroyObject: Destroys the object

Value is the index number of the object to destroy.  First the room is checked, then the mobile’s inventory.

Delay: Wait for this many seconds

Value is the number of seconds to wait.

Echo: Echo text to the room

Value is the message to be printed to the room.

GiveObject: Give player an object

Value is the object index number to give to the player who caused the trigger to fire.

InterpretCommand: Interpret the command

Value is the command line to be interpreted, i.e. “kick troll” or “jump”.

Move: Move in direction

Value is the direction to move in.

PreventAction: Prevent the action (only works with action and player exit triggers).

Value is not used.

Say: Say something.

Value is the phrase to be said.

Teleport: Teleport to another room

Value is the room index number to teleport to.

TeleportPlayer: Teleport the player who activated the trigger to another room

Value is the room index number to teleport the player to.

TeleportAll: Teleport all players in the room to another room

Value is the room index number to teleport the player to.

UseSkill: Use the skill

Value is the skill specified, i.e. “hide” or “kick”.

ZoneEcho: Echo text to the zone

Value is the text to be shown to everyone in the zone.

Destroy: Destroy self

Value is not used.

———-

One of the good things about the way it’s been coded is that triggers and action types can be added very easily.  The actual in-game implementation of it has yet to be done, but that should be easy enough.

If you think of anything that you could imagine doing in a zone that these commands won’t allow you do do, let me know, either as a comment on this post, or email me if you want to chat in more detail.  My name is xangis and I use Yahoo for my email.

Artificial Intelligence Markup Language (AIML)

One of the things I plan to have the MUD engine support is AIML. That’s an XML-based file format that defines conversational data for a “chatterbot”. I’m sure most everyone has heard of the Eliza, Julia, or A.L.I.C.E chat bots.

The idea is that you can create personalities that respond to certain phrases, much like quest messages do/did in previous versions of Basternae, but you can take it even further by having compound triggers, matches, variables, and responses to previous inputs.

There’s really no limit to how simple or complex you can make your ‘bot’, from responding to only a single phrase to an encylopedia of knowledge that might almost pass the Turing test.

Here’s a bit of info about the format:
Overview from Dr. Wallace, creator of AIML

And, of course, here’s the obligatory Wikipedia link:
AIML on Wikipedia

One tool I’ve found that I like so far is the GaitoBot AIML Editor, which you can get here:
GaitoBot AIML Editor Homepage

If you know any German, the bot on the Gaito site is kind of fun to banter with. I know just enough to make it think I’m an idiot. 😛

If you want to start building your own bot personalities — grumpy Trolls, arrogant Elves, Dwarves too busy working to deal with your nonsense, or schizophrenic tinker gnomes — then feel to grab the GaitoBot app and start building personalities. The intent is to be able to load AIML files directly into the MUD and associate them with one or more mobs.

All I’ve done so far is generate some C# classes from the AIML schema, but that went smoothly enough. I’m not sure yet whether I’m going to build my own bot engine or use an existing open source one.

What MUDs Have The Best AI?

Most MUDs have mobiles of very limited intelligence that stand around waiting to be killed and often don’t even bother to remember that you attacked them ten seconds ago.  Some games have more intelligent creatures that actively try to defend themselves and take down the enemy by the most effective means (always fireballing trolls, dispelling undead opponents, etc.)  What MUDs have you played with more advanced/detailed mob AI?  What was it like?

Sure, there are the obvious ones from the Basternae ancestry, but I’m looking for the ‘best of breed’ so I have a standard to measure against.

Integrating Python?

One of the things I’ve been worrying over is how to write a new scripting and artificial intelligence engine that integrates all the buttery goodness and capabilities of MobProgs and the homebrew probability-based AI system I wrote for Basternae II along with the only-used-once movement scripts I put together. They were all pretty powerful, but the bad things are/were:

1. Too many pieces of code to maintain.
2. Required a programmer’s full attention — far too complex for a zone writer or newbie-level web scripter to use.
3. Always required a recompile if changes were made.
4. Always required a reboot to load new changes. This made it un-tweakable. Want a mob to cast fireball half as often? Change it and reboot the MUD.
5. Extremely zone-dependent. If we unload the plane of fire, we still have all of the plane of fire scripts active, including hard-coded mob names and numbers.

It definitely shouldn’t require a restart of the game just to make a troll kick someone in the head more often. This naturally leads me to Python and/or IronPython, since it’s my current obsession. I have some reading to do, but don’t be surprised if I come up with a scripting engine of pure awesomeness.

A Whole New Spell And Skill Engine

Well, maybe not a *whole* engine quite yet, but certainly two thirds of one.

I’ve generated about 500 little XML files to hold all of the skill and spell data for dynamic runtime loading.  It’s all pretty neat — skills and spells can be tweaked by hand without having to compile any code (though the MUD requires a reboot) and they’re loaded at runtime, stored in a Dictionary type, and accessed based on their names.

There isn’t a single hard-coded spell or skill value in the engine.  Hardcoded values were something that always bothered me.

Another thing I did in this process is embed “logical preference” data in the skill and spell files so that the AI engine can be improved while at the same time removing the need for thousands of lines of “spaghetti code” like in Basternae 2.  You see, each spell and skill check in B2 was hardcoded in a specific order and with a specific percentage chance.  Adding a skill or rearranging mob AI meant editing these in more than one place.

Instead (when the AI code is done), we’ll be able to set a few flags on each spell or skill and it will handle it automatically (unless a specific mob has a personality override file).

Oversimplified example:

Fireball.xml:  Type = offensive, Preference = 65, Likelihood = 40
LightningBolt.xml:  Type = offensive, Preference = 50, Likelihood = 50

This means, essentially, that a mob would have a 40% chance of casting fireball during combat, and if that didn’t go off, it would have a 50% chance of casting lightning bolt.  Changing the way the mob performs in combat is just a simple number tweak.

I have some pretty huge plans for mob AI, but this new spell/skill system goes a long way toward making those plans easy to implement.

I also have yet to embed all necessary custom code in the spell/skill files, but one thing that’ll be done is that most information needed to trigger a spell will be embedded in the file.  Instead of manually writing a dozen lines of the same code for each spell to validate the target, check saving throws, set damage type and amount, send messages, and deliver the affect(s), most spells will use one general-purpose function that checks the spell types and flags and executes the spell’s action.

This means that most standard spells that are just damage or single-affect, like “soulshield” or “fireball” won’t have any embedded code at all.  Instead, only super-involved custom spells like the enchantment spell “earthen smith” will have their own embedded instructions.

Well, that was long-winded.  It had to be — I’ve done a lot and I’m pretty proud of what I’ve accomplished with this.