With
all the flexibility we have created, and the open-ended nature
of the system, which runs finite code but is driven by infinite
varieties of personality parameters passed to it, have we created
a debugging nightmare? The answer is, of course, "yes!",
but we didn't want to make a simple, linear and predictable AI,
which would have been easy to debug. What we do have the framework
for is a complex, colorful, sometimes unpredictable, but plausible
AI which can operate a great variety of characteristic agents.
There are two classes of bugs which we are most likely to come
across related to this system. The first is "that character
shouldn't be able to do that" type bugs. Examples would be
characters walking through locked doors, waving their axe at you
from 200 meters away and doing you damage--and other things which
fly in the face of the way your game world is meant to work. The
best way to avoid these bugs is to separate out the code modules
which decide what the character wants to do, and the code which
actually makes these actions happen in the game world. This second
code module can then be the enforcer of the game rules, so that
even if the character wants to walk through the locked door, it
won't be allowed to (of course, it is better if the character
realizes that the door is locked and stops bashing its head against
it).
The
second, and probably more tricky, certainly more nebulous, type
of bugs will be those of the "why did that character do that?"
kind (for example, "why does that character keep trying to
use its crossbow even though it has run out of bolts?").
These bugs are likely to be trickier to fix because they are dependant
on both the code which selects different behaviors, and the personality
parameters being passed in. They are likely to be more nebulous,
because sometimes you may be unsure if what you are seeing is
a bug or not. What the character is doing may be what the designer
wanted, even though it looks dumb to you. On the plus side, bugs
of this sort are often not spotted by the lay observer, so that
what to you is an annoying bug, to the average player can appear
to be a sophisticated emotional response of the agent who is so
scared by the violence of the battle that they keep trying to
fire their crossbow a couple of times before they realize all
the ammo is gone (believe me, I've seen it).
The
best way to attack the second kind of bugs is probably by having
a debug-logging system. The AI system in Worms 3D logs
all its evaluations of the various plans it is considering, and
why they were scored up or down. It logs what decisions it came
up with, and what actions were carried out as a result of those
decisions. The system has various "verbosity" levels,
so that it is able to create these logs in a release build given
to QA, with minimal speed impact, but can be run in verbose mode
when debugging in greater depth, to give full details of everything
it did. A logging system for a game with many agents active at
the same time may want to have a separate log file for each agent,
or it may be more useful to keep them together and provide a custom
"reader" program which is able to filter the log by
agent. Once you have a good logging system, you will be able to
dissect the behavior of your characters at leisure, and, if your
testers can be persuaded to add the AI logs to any bug report
related to the AI, you'll have evidence and additional information
for each bug they find.
Extensions
The
beauty of the system that has been described is that it is very
flexible and easily extended. One area that I have not discussed
so far is that of multi-agent behavior, i.e., squad behavior,
inter-agent communication, and so-on. The system most naturally
lends itself to an "artificial life" (emergent/bottom-up)
approach, which could easily be achieved by adding decision parameters
which took account of other nearby agents (e.g., a "ring
alarm bell" behavior could be scored down if another nearby
agent was already running a "ring alarm bell" behavior).
An alternative approach to squad behavior would be to have a nominated
leader amongst a group of agents (which might, or might not, be
a different type of character), who could have a "pass command"
behavior (with appropriate grunts and gesticulations if so desired).
Conclusion
By
designing your AI system to be driven by personality parameters
provided in data files for each kind of agent, you can make possible
a much greater quantity, variety, (and probably quality) of AI
characters than would be possible by hard coding them in by hand.
With thought, it is possible to provide great flexibility and
extensibility to the data files, so that whole character types
can be added without programmer intervention.
By
including parameters which drive the choices between behaviors
for the characters and the details of their behaviors, the same
AI system can run a huge variety of genuinely varied and distinguishable
agents, which not only look different, but have different personalities
and abilities.
For
Further Information