I'm currently working on a computer role-playing game1 that will be
programmed in Visual Basic. Here's an overview of what I've come up
with so far on the AI.
Since this was
my first foray in AI the first thing I did was buy and read the book
"Paradigms of Artificial Intelligence Programming: Case Studies
in Common Lisp".2 This introduced me to different types of AI
and gave me a general idea of the topic. After reading the book I
had to decide what level of AI should be put in the game. Should I
go for a very complex AI or use tricks to give the illusion of thinking?
The complex AI would take too much effort for a single programmer
and would not necessarily mean better gameplay. And the simple AI
would mean making a game similar to all the others. And I had to take
into account that I never plan anything on paper before programming.
So my solution was to make a flexible AI that would be complex enough
to allow modifications in the game without having to make too many
code modifications and easy enough so that it would be controllable
to assure an interesting game.
Now that the level
of complexity of the AI was decided I had to start desiging it. The
first thing I did was to separate each element that would constitute
the parts of the AI:
The environment:
This is what makes the world. The locations and the objects. In classic
game programming the objects are usually defined in the program as
variables and have a certain number of parameters. For example:
Weapon(x).Type
= "Sword"
Weapon(x).Value = 100
Weapon(x).Damage = 0
etc...
But this way of
defining the objects would require code modification if I wanted to
add an attribute. And the AI would have to be modified to take into
account the new attribute. So I decided that all the objects would
be defined "externally". Objects have certain characteristics
and some of them can be modified. For example, a ball (object) is
red (color attribute) and can be thrown (action) and if so it's location
(attribute) will change. With these elements I can start the game
editor. I made an "attribute editor", an "object editor"
and an "action editor".
The attribute editor allows the creation of attributes like "open/closed
state" for a door, a box or any object that can be opened or
closed. This attribute can have the value "open" or "closed".
A "damage" attribute could have a value between 0 and 100
reflecting the amount of damage an object would have. This allows
the AI to be able to check for an object's attribute and possibly
try to modify it. For example a character could "see" that
that door is closed and if there was a reason for it he could try
to open it.
Now that attributes
are created I need a way to allow their modifications by the player
or a character. This is what the "action editor" is used
for. An action consists of a few key elements. First we need to make
sure that an action is only available when certain conditions are
true. For example, an "open" action should not be available
on a door which state is "open". The "required attributes"
is there for that purpose. This section contains all the attributes
that are checked to make the action available. So in the "open"
action the "open/closed state" attribute is checked for
the "closed" value. When all the required attributes passed
the test we can now go in the "verify attribute" section.
This is where attributes are checked and if they are not the desired
value the player is notified of it. For example if a door's "locked
state" attribute is "locked" the game can tell the
player "this door is locked, unlock it first.". And lastly,
there's the "attribute modification" section. In the door
example this section would contain the "open/closed state"
attribute modification to the value "open".
The object editor
allows to give different objects different attributes and possible
actions. For example, after creating a new "door" object
we can assign it an "open/closed state" attribute to know
if the door is open or closed. Then we can assign it a "locked"
attribute with "true" of "false" as possible values
to know if the door is locked. Then we can create "open"
and "close" actions and assign it to the door. Once the
door object is finished we could create a "key" object and
give it "lock" and "unlock" actions that would
modify the "locked" attribute. Finally, this is where it
becomes interesting, how would the AI work with that information.
The AI now has
enough information to be able to do basic thinking. It can work with
the created objects without writing specific code for each different
object. Here's an example of how this works.
Continuing with
the door example, a character could "see" that the door's
"open/closed state" atribute is "closed". If for
whatever reason that character would "want" that attribute
to be "open" it would "think" the following way.
First it would check which actions modify the "open/closed state"
of an object. It would find that the "open" action does
just that. Now that he would know what action to perform he would
check what are the required attributes for the action. The "open"
action requires the "open/closed state" of the object to
be "closed" wich is true. Next he would check for the attributes
verifications. Here the door's locked atribute must be "false"
wich could be "true" for the sake of a good example. Now
that he "knows" that he needs the modification of the door's
"locked" attribute he would start again the thinking process
where he would find that the "unlock" action can do that.
After performing the "unlock" action on the door he could
now perform the "open" action and finally get the door open.
How about that? We now have an AI that can interact with a modifiable
world.
This is where
I am now. The next steps will probably be in these areas:
The characters
need to have a knowledge base of their own to prevent them from "knowing
it all". For example, in the verifications section of a key's
unlock action could be the "unique id" attribute. This attribute
would make sure that the key unlocks only the right door (key.uniqueID=door.uniqueID).
But the character must not know wich door has the correct id. So there
needs to be a kind of "filter" that would hide the doors
and keys ids until the right key and door combination would be found.
The characters
need to have motivations or goals. They can interact with the world
but now they need a reason to do so. This could be achieved by attributes
requirements. For example, the "hungry" attribute of a character
should always be below 90% (goal: character.hungry < 90) to make
sure that he sometimes eats. This attribute would rise as time goes
by and the action of eating would result in the attribute lowering.
Hierarchies, family
trees and relationships between characters needs to be adressed. This
will allow the characters to interact with each other based on who
they like, how high they rank and their family ties.
The hardest part
will probably be the conversations. It will have to allow the flexibility
of a text parser without having the player to enter text. I am still
thinking about this part and I think that it will be achievable.
That's it. Hope
that you enjoyed my little text.
Compiled
from different essays at Generation5 website-Benoît
Prézeau