DEVELOPERS
JOSE RAULY
AI Programmer
Before RAS I took a Software Engineering degree, with the Graphics specialty, the first one in Spain (Deusto University) and the second one in London (Middlesex University). While in University I did some database programming (boring as hell, btw). Then I moved back to England (to Etchinghill Studios), to work developing stuff for the Internet, first a 3d chat program, and later the seed of an online RPG, still in the works there. While in England I discovered RAS because of their web page, and I got in touch with them immediately. Here, at RAS, I have worked for 2 and a half years on Blade, doing the AI with Bob Yves, the animation system with Angel Cuñado and game programming in general.
There are three programs running in this picture. Visual C is used for coding. The file AI.cpp is the main gate of C to the Python interface. It toggles the main events of the AI, so the given character will have to decide how to respond to that event. The file A_star.cpp is the high level file for the path finding code. It exports a structure of sectors (which build the maps in Blade) in order to find the optimum path. SourceSafe is a tool used for centralizing the code, scripts and data files (sounds, animations, etc) The directory selected is the "Enemies" one, where the different attributes, animations and combos of the races are stored. Still, that's not all the info for the NPC, as some of the high level ones are stored straight in python. Also, you can see the performance in the Task Manager to be careful with the memory usage (not so relevant for the AI, but VERY relevant as the project is reaching completion).
The AI isn't updating all the times; only for the paths that are already set up, and not even all the times the either. Only every time gap (bigger or smaller, depending on the relevance of the possible event toggled), the checks (and the toggling of the event) are performed. So, we have the same results and we save quite some CPU time.
The AI in Blade consist of:
Reactive AI
Our high level AI is event-driven. That means that it updates itself only when
some events are toggled (when an NPC sees the enemy, like the typical example).
In that way, we have generic functions like "SeeMyEnemy", which makes
the NPC to respond in a natural ways. Of course, it can be customized for
different races and different particulars. The typical reactions are seeing
and/or hearing something, receiving damage and/or killing the current enemy (it
doesn't have to be the player all the times), watching another character
performing an alert animation, loss of sight of the current enemy, entering a
non allowed area or a not-to-stay-for-long area (they stay there only for a few
seconds) and entering short/long range combat. They investigate sounds, and, in
general, they react to their environment. They will protect certain areas,
patrol and calling for help. Others will come (or modify slightly their
behavior at least) if their hierarchy of actions tell them to do so.
Path
finding
A solid path finder was the first task in the AI that was done in Blade . It is
also one of the most complex ones. There are two different subsystems. First,
Pre-calculating the potentially most interesting path with the lowest CPU use
possible. Second, execute it; dodging objects is necessary, breaking some
others, climbing, etc, and recalculating (previous point), with a different set
of priorities, the path if found a major problem. So the idea is to have a nice
look pathfinder with the minimal CPU use. Normally, for the path finding code
you need some kind of checkpoints (I couldn't find a better name, although it's
not the best). A given path consists of a set of consecutive checkpoints. So,
in the world we have LOTS of those checkpoints, linked in a web style. So, it's
like having a huge data structure of lots of those nodes. In some games as I've
heard - like Half Life, I think - those check points are given by the level
editors with editing tools. As we use a portals/sectors engine, we though that
it was more flexible just using those sectors and the portals that interconnect
them to represent that data. So, to find a path we perform a simple A star
search with those nodes (a typical algorithm for path finding). The same
algorithms are used for all NPCs, but with taking into account many variables.
For example, if an orc can climb to very high places to chase you, they will
only if they are allowed to. Otherwise they will mark that as impossible and
try another set of sector like the best path.
We have tried to
minimize the problems with path finding in tight spots and/or crowded rooms and
hopefully there will not appear those kinds of bugs. Still, there are points in
the code in which you have to assume something, not just to make it simpler,
but also to make it fast enough. But there are always tricks to use...:-)
If light and darkness will affect AI reactions and pathfinding is something
that is still under consideration. The main problems is that we want the player
to enable or disable shadows, but a change in the graphical setting must under
no circumstances lead into a change in gameplay. If the "toggle
shadows" options stay, this could lead into that part of the AI not usable.
Other goals like collecting items like food and getting more experience points
were rejected, apart from being too CPU intensive, because the difficulty in
balancing the gameplay. Although it sounds quite good to have enemies like
that, it is not-so-brilliant to have dozens of enemies with an unexpected
behavior, because the gameplay will suffer, and games are about gameplay after
all. It isn't an excuse. Those behaviors were studied a lot before being
rejected.
Combat
The NPCs choose the next attack (or row of attacks, or combos) based on its
life, the enemies, and the environment (to name just a few, because there are
many). Special moves (magic attacks, invisibility and others that should be
kept secret) are included here. If the enemies are intelligent enough, they use
grouping techniques. They will coordinate in combat. One of them will be the
leader and the others will protect him. In the combat, the attack set can vary
a lot from one race to another, and the probability to perform them can change
during the combat. The difference is even more relevant when using magic
attacks, etc. Sometimes they can set up ambushes and more elaborated ones. If
they chase you, they will climb anywhere (if allowed) , break objects to get
close to you, and attack in very sophisticated ways. They will not use straight
lines or stupid behaviors (unless it is supposed to be stupid).
Scripts
This is used for some very specific behaviors (like an enemy that flees to
alert others), which happens only in a given sector of a map. First, the high
level AI is done mainly in script (using python), making constant reference to
low level instructions. In that way, CPU intense functions (like checking the
collision of an attack against the world) that are in C (faster than python). Therefore,
the scripts do not have to deal with the format of the animation's data and
other "unnecessary" stuff. Still, most of the times and with some
lack of precision, the scripted AI is referent to situations like showing a NPC
appearing trough a door, show another NPC attacking him and in the case where
you try to help him, but you are too far away so before you get there he dies
and the other one runs away. This KIND of script (mostly linear, with almost no
interaction even as it looks like that) is used in Blade just when needed, only
for story-telling purposes (either an emotional response of the player or a
progress in the plot of the game). The use of the standard AI libraries of a
more scripted thing depends on the needs on each case. Mixed solutions happen
quite often as well. .
I worked mainly in the first two parts (reaction and pathfinding) and some other stuff, based on the path finding like patrolling, arches and etc. I also did some of the game programming, and I have been working lately on the animation system, and the combat system (animation and combos wise) too. The sensation of having something (or, more likely), someone "alive" in your computer is a pretty nice feeling. Apart from the graphics field, I think it's one of the most interesting areas in computing. The most frustrating part of programming AI is being limited to a small percent of the CPU time and as it is the AI for the game it is a bit ironic, but you are limited because the gameplay must be fun. I mean, you can always improve the use of the A-star algorithm (the standard for path finding algorithms) in your game, but you cannot try too radical and innovative things without risking the game design.