Brainiac Behavior Engine User's Guide
About Brainiac Behavior Engine
*Contact Info
*License
*High Concept of Brainiac Behavior Engine
*Getting Started: Basics Of The Brainiac Behavior Engine
*Basic Entities
*Core And ItemScores Structures
*Brainiac Conventions
*Linking Brainiac Behavior Engine To Your Application
*Requirements
*Using Brainiac BE
*Visual C++ Notes
*Getting Started With The Brainiac Data Manager
*1. The Basics
*2. Setting A New Database
*3. Building Behavior Patterns
*Behavior Pattern 1: Killing in the Name Of...
*Behavior Pattern 2: Robbery
*Behavior Pattern 3: Conspiracy
*Brainiac Native Verbal Interaction
*Programmer's Reference
*Goal And Criteria
*Action
*Strategy
*Agent
*EventsRegistry
*PersonalLog
*Non-Member Functions
*About Brainiac Behavior Engine
Brainiac Behavior Engine (or Brainiac BE) is a highly customizable state-of-the-art AI engine; it is primarily designed for creating computer strategy / adventure / role-playing games (CRPGs) that feature lifelike behavior on the part of computer-controlled characters. Brainiac BE is virtually weightless so far as maintenance is concerned, can be tweaked in every possible direction, and is more advanced than any functionality that could be created from scripts. The list below mentions only a few of the Brainiac capabilities:
Brainiac BE uses a simple and effective object oriented model to simulate character decision-making processes at a high level.
Copyright © 1999 Twilight Minds
Send your comments, requests and proposals to:
Email:
bbe_support@twilightminds.com
bbe@twilightminds.com
Twilight Minds homepage:
http://www.twilightminds.com
TWILIGHT MINDS BRAINIAC BEHAVIOR ENGINE (BBE) PUBLIC LICENSE
Version 1.0
PREAMBLE
Please read this license carefully before using the Twilight Minds'
Brainiac Behavior Engine (BBE). By downloading and using
BBE, you are agreeing to be bound by the terms of this license.
If you do not or cannot agree to the terms of this License, do not
download or use BBE.
This license is intended to make the BBE source code available to
everyone who wants the opportunity to use it or contribute to this
Twilight Minds project. Note that BBE is a commercial product.
It is not in the public domain, nor is it "freeware" or "shareware".
By making the source code available, the Twilight Minds Design
Group is not giving it away nor abandoning any right of ownership.
By using BBE you agree to be bound by the spirit and the terms of
this license.
This license permits you to use BBE to create and sell products.
You may also redistribute BBE. You may also make modifications
to the BBE source code and distribute them too.
If you modify the BBE source, excerpt any portion of it, or if
you use a modified version of the engine source, you must make your
source code available for others to use under the same terms that
we have granted you. This guarantees that modifications to BBE will
be available to everyone and the best modifications can become part
of any official Twilight Minds release. Your source code must be
released concurrent with releasing any executable built with BBE.
If you do not wish to make your source code available you must
obtain a separate license from the Twilight Minds Design Group.
If you use any original unmodified Twilight Minds-built BBE binaries
there is no requirement for you to make your source code available.
You must display the original unmodified Twilight Minds animated logo
as the first logo on startup of your product, demo or application.
You must also prominently display the Twilight Minds logo on any
marketing materials, advertising or packaging of your product.
These terms are good for the community because they make source code
available to everyone and encourage the sharing of improvements. They
are good for Twilight Minds because some companies will opt to not
share their source and will prefer to pay to license the engine instead.
These kinds of licenses will help to fund future Twilight Minds
development and subsidize the free licenses that many people will enjoy.
1. DEFINITIONS
1.1. ``Contributor'' means each entity that creates or contributes to
the creation of Modifications.
1.2. ``Contributor Version'' means the combination of the Original
Code, prior Modifications used by a Contributor, and the
Modifications made by that particular Contributor.
1.3. ``Covered Code'' means the Original Code or Modifications or
the combination of the Original Code and Modifications, in each case
including portions thereof, and any Source Code which duplicates,
enhances, modifies or replaces functionality of the Covered Code as
defined in Exhibit B.
1.4. ``Electronic Distribution Mechanism'' means a mechanism
generally accepted in the software development community for the
electronic transfer of data.
1.5. ``Twilight Minds'' means Twilight Minds Design Group, a
partnership.
1.6. ``Executable'' means Covered Code in any form other than
Source Code.
1.7. ``Larger Work'' means a work which combines Covered Code
or portions thereof with code not governed by the terms of this
License.
1.8. ``License'' means this document.
1.9. ``Modifications'' means any addition to or deletion from the
substance or structure of either the Original Code or any previous
Modifications. When Covered Code is released as a series of files, a
Modification is:
A. Any addition to or deletion from the contents of a file
containing Original Code or previous Modifications.
B. Any new file that contains any part of the Original Code
or previous Modifications.
1.10. ``Original Code'' means Source Code of computer software
code which is described in the Source Code notice required by
Exhibit A as Original Code, and which, at the time of its release
under this License is not already Covered Code governed by this
License.
1.11. ``Source Code'' means the preferred form of the Covered Code
for making modifications to it, including all modules it contains, plus
any associated interface definition files, scripts used to control
compilation and installation of an Executable, or a list of source code
differential comparisons against either the Original Code or another
well known, available Covered Code of the Contributor's choice. The
Source Code can be in a compressed or archival form, provided the
appropriate decompression or de-archiving software is widely
available for no charge.
1.12. ``You'' means an individual or a entity exercising rights
under, and complying with all of the terms of, this License or a future
version of this License issued under Section 7.1. For legal entities,
``You'' includes any entity which controls, is controlled by, or is
under common control with You. For purposes of this definition,
``control'' means (a) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (b) ownership of fifty percent (50%) or more of the
outstanding shares or beneficial ownership of such entity.
2. SOURCE CODE LICENSE
2.1. The Twilight Minds Grant.
Twilight Minds hereby grants You a world-wide, fully paid, royalty-free,
non-exclusive license, subject to third party intellectual property claims:
(a) to use, reproduce, modify, display, perform, sublicense and
distribute the Original Code (or portions thereof) with or without
Modifications, or as part of a Larger Work; and
(b) under patents now or hereafter owned or controlled by
Twilight Minds, to make, have made, use and sell (``Utilize'') the
Original Code (or portions thereof), but solely to the extent that
any such patent is reasonably necessary to enable You to Utilize
the Original Code (or portions thereof) and not to any greater
extent that may be necessary to Utilize further Modifications or
combinations.
2.2. Contributor Grant.
Each Contributor hereby grants You a world-wide, fully paid,
royalty-free, non-exclusive license, subject to third party intellectual
property claims:
(a) to use, reproduce, modify, display, perform, sublicense and
distribute the Modifications created by such Contributor (or
portions thereof) either on an unmodified basis, with other
Modifications, as Covered Code or as part of a Larger Work; and
(b) under patents now or hereafter owned or controlled by
Contributor, to Utilize the Contributor Version (or portions
thereof), but solely to the extent that any such patent is
reasonably necessary to enable You to Utilize the Contributor
Version (or portions thereof), and not to any greater extent that
may be necessary to Utilize further Modifications or
combinations.
2.3. Your Grant.
You hereby grant to Twilight Minds a world-wide, fully paid,
royalty-free, non-exclusive license, subject to third party intellectual
property claims:
(a) to use, reproduce, modify, display, perform, sublicense and
distribute the Modifications created by You (or portions thereof)
either on an unmodified basis, with other Modifications, as
Covered Code or as part of a Larger Work; and
(b) under patents now or hereafter owned or controlled by You,
to Utilize the Modifications (or portions thereof), but solely to
the extent that any such patent is reasonably necessary to enable
Twilight Minds to Utilize the Modifications (or portions thereof), and not
to any greater extent that may be necessary to Utilize further
Modifications or combinations.
3. DISTRIBUTION OBLIGATIONS
3.1. Application of License to You.
The Modifications which You create or to which You contribute are
governed by the terms of this License, including without limitation
Section 2.2. The Source Code version of Covered Code may be
distributed only under the terms of this License or a future version of
this License released under Section 7.1, and You must include a copy
of this License with every copy of the Source Code You distribute.
You may not offer or impose any terms on any Source Code version
that alters or restricts the applicable version of this License or the
recipients' rights hereunder. However, You may include an additional
document offering the additional rights described in Section 3.6.
3.2. Application of License to Twilight Minds.
(a) Other Products.
Twilight Minds may include Covered Code in products other than
BBE without such additional products becoming subject to
the terms of this License, and may license such additional
products on different terms from those contained in this License.
(b) Other Licenses.
Twilight Minds may license the Source Code including Modifications
incorporated therein, without such additional products becoming
subject to the terms of this License, and may license such
additional products on different terms from those contained in
this License.
(c) Other Releases.
Twilight Minds may create new releases of BBE without such
releases becoming subject to the terms of this License.
3.3. Availability of Source Code.
Any Modification which You create or to which You contribute must
be made available in Source Code form under the terms of this
License either on the same media as an Executable version or via an
accepted Electronic Distribution Mechanism to anyone to whom you
made an Executable version available; and if made available via
Electronic Distribution Mechanism, must remain available for at least
twelve (12) months after the date it initially became available, or at
least six (6) months after a subsequent version of that particular
Modification has been made available to such recipients. You are
responsible for ensuring that the Source Code version remains
available even if the Electronic Distribution Mechanism is maintained
by a third party. Furthermore, the Source Code to the Modifications
You create or contribute must be delivered in fully compilable form
using commonly available tools. If the tools used to compile the
Source Code are not commonly available You must also include the
tools, in Source Code and Executable forms, as part of the
Modifications.
3.4. Description of Modifications.
You must cause all Covered Code to which you contribute to contain
a file documenting the changes You made to create that Covered
Code and the date of any change. You must include a prominent
statement that the Modification is derived, directly or indirectly, from
Original Code provided by Twilight Minds in (a) the Source Code, and
(b) in any notice in an Executable version or related documentation in
which You describe the origin or ownership of the Covered Code.
3.5. Intellectual Property Matters
(a) Third Party Claims.
If You have knowledge that a party claims an intellectual
property right in particular functionality or code (or its utilization
under this License), you must include a text file with the source
code distribution titled ``LEGAL'' which describes the claim and
the party making the claim in sufficient detail that a recipient will
know whom to contact. If you obtain such knowledge after You
make Your Modification available as described in Section 3.3,
You shall promptly modify the LEGAL file in all copies You
make available thereafter and shall take other steps (such as
notifying appropriate mailing lists or newsgroups) reasonably
calculated to inform those who received the Covered Code that
new knowledge has been obtained.
(b) Contributor APIs.
If Your Modification is an application programming interface
and You own or control patents which are reasonably necessary
to implement that API, you must also include this information in
the LEGAL file.
3.6. Required Notices.
You must duplicate the notice in Exhibit A in each file of the Source
Code, and this License in any documentation for the Source Code,
where You describe recipients' rights relating to Covered Code. If
You created one or more Modification(s), You may add your name as
a Contributor to the notice described in Exhibit A. If it is not
possible to put such notice in a particular Source Code file due to its
structure, then you must include such notice in a location (such as a
relevant directory file) where a user would be likely to look for such a
notice. You may choose to offer, and to charge a fee for, warranty,
support, indemnity or liability obligations to one or more recipients
of Covered Code. However, You may do so only on Your own
behalf, and not on behalf of Twilight Minds or any Contributor. You must
make it absolutely clear that any such warranty, support, indemnity or
liability obligation is offered by You alone, and You hereby agree to
indemnify Twilight Minds and every Contributor for any liability incurred
by Twilight Minds or such Contributor as a result of warranty, support,
indemnity or liability terms You offer.
3.7. Distribof Executable Versions.
You may distribute Covered Code in Executable form only if the
requirements of Section 3.1-3.6 have been met for that Covered
Code, and if You include a notice stating that the Source Code
version of the Covered Code is available under the terms of this
License, including a description of how and where You have fulfilled
the obligations of Section 3.3. The notice must be conspicuously
included in any notice in an Executable version, related
documentation or collateral in which You describe recipients' rights
relating to the Covered Code. You may distribute the Executable
version of Covered Code under a license of Your choice, which may
contain terms different from this License, provided that You are in
compliance with the terms of this License and that the license for the
Executable version does not attempt to limit or alter the recipient's
rights in the Source Code version from the rights set forth in this
License. If You distribute the Executable version under a different
license You must make it absolutely clear that any terms which differ
from this License are offered by You alone, not by Twilight Minds or any
Contributor. You hereby agree to indemnify Twilight Minds and every
Contributor for any liability incurred by Twilight Minds or such
Contributor as a result of any such terms You offer.
3.8. Larger Works.
You may create a Larger Work by combining Covered Code with
other code not governed by the terms of this License and distribute
the Larger Work as a single product. In such a case, You must make
sure the requirements of this License are fulfilled for the Covered
Code.
4. RESTRICTIONS
4.1. You agree to:
(a) display the original, unmodified Twilight Minds animated logo
as the first logo on startup of your product, demo or application;
(b) prominently display the Twilight Minds logo on any marketing
materials, advertising or packaging of your product, demo or
application;
(c) distribute the Covered Code to third parties who agree to be
bound by these terms and conditions;
(d) make reasonable efforts to discontinue distribution of the Covered
Code upon Twilight Minds' release of an update, upgrade or new version of
the Covered Code and to make reasonable efforts to distribute such
updates, upgrades or new versions to your customers who have
received the Covered Code herein;
(e) be solely responsible for any update or support obligation or other
liability which may arise from your distribution of the Covered Code.
4.2. You may not:
(a) remove, alter, obscure, or modify in any way the appearance or
operation of the Twilight Minds logo;
(b) copy the Covered Code, in whole or in part, except as provided in
this License;
(c) make any statement that your product is "certified," or that its
performance is guaranteed, by Twilight Minds.
5. INABILITY TO COMPLY DUE TO STATUTE OR
REGULATION
If it is impossible for You to comply with any of the terms of this
License with respect to some or all of the Covered Code due to
statute or regulation then You must: (a) comply with the terms of this
License to the maximum extent possible; and (b) describe the
limitations and the code they affect. Such description must be
included in the LEGAL file described in Section 3.5 and must be
included with all distributions of the Source Code. Except to the
extent prohibited by statute or regulation, such description must be
sufficiently detailed for a recipient of ordinary skill to be able to
understand it.
6. APPLICATION OF THIS LICENSE
This License applies to code to which Twilight Minds has attached the
notice in Exhibit A, and to related Covered Code.
7. VERSIONS OF THE LICENSE
7.1. New Versions.
Twilight Minds may publish revised and/or new versions of the License
from time to time. Each version will be given a distinguishing version
number.
7.2. Effect of New Versions.
Once Covered Code has been published under a particular version of
the License, You may always continue to use it under the terms of
that version. You may also choose to use such Covered Code under
the terms of any subsequent version of the License published by
Twilight Minds. No one other than Twilight Minds has the right to modify
the terms applicable to Covered Code created under this License.
8. DISCLAIMER OF WARRANTY
COVERED CODE IS PROVIDED UNDER THIS LICENSE ON
AN ``AS IS'' BASIS, WITHOUT WARRANTY OF ANY KIND,
EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT
LIMITATION, WARRANTIES THAT THE COVERED CODE IS
FREE OF DEFECTS, MERCHANTABLE, FIT FOR A
PARTICULAR PURPOSE OR NON-INFRINGING. THE ENTIRE
RISK AS TO THE QUALITY AND PERFORMANCE OF THE
COVERED CODE IS WITH YOU. SHOULD ANY COVERED
CODE PROVE DEFECTIVE IN ANY RESPECT, YOU (NOT
TWILIGHT MINDS OR ANY OTHER CONTRIBUTOR) ASSUME THE
COST OF ANY NECESSARY SERVICING, REPAIR OR
CORRECTION. THIS DISCLAIMER OF WARRANTY
CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO
USE OF ANY COVERED CODE IS AUTHORIZED HEREUNDER
EXCEPT UNDER THIS DISCLAIMER.
9. TERMINATION
This License and the rights granted hereunder will terminate
automatically if You fail to comply with terms herein and fail to cure
such breach within 30 days of becoming aware of the breach. All
sublicenses to the Covered Code which are properly granted shall
survive any termination of this License. Provisions which, by their
nature, must remain in effect beyond the termination of this License
shall survive.
10. LIMITATION OF LIABILITY
UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL
THEORY, WHETHER TORT (INCLUDING NEGLIGENCE),
CONTRACT, OR OTHERWISE, SHALL TWILIGHT MINDS, ANY
OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED
CODE, OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE
LIABLE TO YOU OR ANY OTHER PERSON FOR ANY
INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES OF ANY CHARACTER INCLUDING, WITHOUT
LIMITATION, DAMAGES FOR LOSS OF GOODWILL, WORK
STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR
ANY AND ALL OTHER COMMERCIAL DAMAGES OR
LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS
LIMITATION OF LIABILITY SHALL NOT APPLY TO
LIABILITY FOR DEATH OR PERSONAL INJURY RESULTING
FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT
APPLICABLE LAW PROHIBITS SUCH LIMITATION. SOME
JURISDICTIONS DO NOT ALLOW THE EXCLUSION OR
LIMITATION OF INCIDENTAL OR CONSEQUENTIAL
DAMAGES, SO THAT EXCLUSION AND LIMITATION MAY
NOT APPLY TO YOU.
INDEMNIFICATION: YOU SHALL INDEMNIFY, HOLD
HARMLESS, AND DEFEND TWILIGHT MINDS AND ITS
SUPPLIERS FROM AND AGAINST ANY CLAIMS OR LAWSUITS,
INCLUDING ATTORNEY'S FEES, THAT ARISE OR RESULT
FROM YOUR USE OR DISTRIBUTION OF ANY PRODUCT
INCORPORATING THE COVERED CODE IN WHOLE OR IN
PART.
11. U.S. GOVERNMENT END USERS
The Covered Code is a ``commercial item,'' as that term is defined in
48 C.F.R. 2.101 (Oct. 1995), consisting of ``commercial computer
software'' and ``commercial computer software documentation,'' as
such terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with
48 C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4
(June 1995), all U.S. Government End Users acquire Covered Code
with only those rights set forth herein.
12. MISCELLANEOUS
This License represents the complete agreement concerning subject
matter hereof. If any provision of this License is held to be
unenforceable, such provision shall be reformed only to the extent
necessary to make it enforceable. This License is governed by the
laws of the State of Texas and the United States, including patent and
copyright laws. Any claim arising out of this License will be brought
in Harris County, Texas.
The application of the United Nations Convention on Contracts for
the International Sale of Goods is expressly excluded. Any law or
regulation which provides that the language of a contract shall be
construed against the drafter shall not apply to this License.
13. RESPONSIBILITY FOR CLAIMS
Except in cases where another Contributor has failed to comply with
Section 3.5, You are responsible for damages arising, directly or
indirectly, out of Your utilization of rights under this License, based
on the number of copies of Covered Code you made available, the
revenues you received from utilizing such rights, and other re
factors. You agree to work with affected parties to distribute
responsibility on an equitable basis.
EXHIBIT A.
``The contents of this file are subject to the Twilight Minds Brainiac
Behavior Engine (BBE) Public License Version 1.0 (the
"License"); you may not use this file except
in compliance with the License. You may obtain a copy of the
License at http://www.twilightminds.com/tmBBElicense.txt.
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or
implied. See the License for the specific language governing rights
and limitations under the License.
The Original Code is BBE, released November 29, 1999.
Copyright (C) 1999 Twilight Minds Design Group All Rights
Reserved.
Contributor(s): ______________________________________.''
EXHIBIT B.
Functionality of the Covered Code includes:
(a) Handling AI-specific processes;
(b) Storing, loading and managing the binary data;
High Concept of Brainiac Behavior Engine
The three basic conceptual units of behavior used in Brainiac BE are Goals, Actions and Strategies. As in real life, characters set Goals and then search for suitable Strategies to obtain these Goals.
A Strategy consists of one or more Actions; if a character evaluates the Actions making up a Strategy to have a reasonably chance of success (and to be morally acceptable), the Strategy will be adopted and the Actions scheduled. For example, every character might want to acquire a given expensive item. Some characters might be able to purchase the item, while others might be able to steal the item. Most characters will not find a suitable and morally acceptable Strategy and will put the whole issue to one side. (At least, this is the way it should be to prevent unwanted hyperactivity on the part of your characters. The level of activity is -- of course -- configurable through your own settings).
Characters will attempt Actions on every "environment change" (that is, when a character leaves, disappears, changes state, arrives or appears). In the debugger, Actions are executed continuously because there are no other tasks.
Every Action and Strategy includes an Objective. The Objective is a character targeted by this particular Action. A Strategy Objective is not necessarily the Objective of every Action that is a part of that Strategy (you can look at the examples, such as conspiracy or assassination, using the Brainiac BE Data Manager).
A Criteria Id must be specified in order to choose an Objective. A Criteria is set of limits defining, as you might expect, criteria for the potential Objective. Technically, Criteria records are stored in a Goal file, as both use the same format and are conceptually close. Flags and limitations also exist in connection with Actions, such as conditional loops in case of failure and referenced Objectives.
An important point to take note of is the difference between Goals and Strategies. A Goal is a morally independent state that a character might want to achieve. For example, neither stealing nor buying an item is a Goal. Both are Strategies for acquiring this item. To determine the real Goal, consider an alternate Strategy that leads to the same end state.
Getting Started: Basics Of The Brainiac Behavior Engine
The figure below shows the hierarchy of the basic Brainiac entities. The Agent entity contains a Strategy entity, which consists of several Actions. Strategy has a Goal. All the entities use Core structure, which contains the most important attributes of the Agent.
The Brainiac concept is simple and intuitive; you should soon get the hang of it. All processes start with a motivation, which is defined by a Goal structure. Once an Agent has decided that it wants to pursue a Goal, the process of selecting a Strategy begins. The Strategy that is adopted will be the one that best fits the Agent's profile and that appears the easiest to accomplish. The Agent then schedules Actions within the Strategy for execution. Goals, Strategies and Actions are defined in the Brainiac Data Manager during the design process.
The cornerstone structure in Brainiac is called Core. It contains the most elementary and univeral Agent features. Core is recognized and used by all Brainaic classes and most non-member functions.
Core And ItemScores Structures
The Core structure contains basic and universal Agent attributes. A similar structure exists for inventory items and is called ItemScores. The ItemScores structure contains a subset of the Attributes included in Core; these being Meanness, Foreignness, Wealth, Beauty and Personality. In addition, a current Owner ID is specified.
typedef struct _Core {
AlignmentType alType;
percentage Wickedness;
percentage Anarchy;
percentage InitialAttitude;
percentage AttitudeChangeUnit;
percentage SuddenChange;
percentage LieProbability;
//Impression values - [1] means "true social"; [0] -
// "seemed social"
percentage Meanness[2], Wealth[2], Beauty;
percentage Foreignness;
percentage Intelligence[2], Courage;
short UserDefined[3];
ID attId;
Attitude *attPersonal; //tree of personal attitudes
_Core *LastAccessedBy;
unsigned char CurrentEnvironment;
ID LastTargettedInAction, LastCommittedAction;
BOOL Dead;
} Core;
typedef struct {
ID ItemID;
ID Owner;
percentage Wickedness;
percentage Anarchy;
percentage Meanness, Foreignness, Wealth, Beauty, Personality;
percentage Influence;
//0 to 100 - percentage of influence on the
//overall Impression
BOOL CanBeDivided;
unsigned short UserDefined[3];
} ItemScores;
The agent stats used in Core / ItemScores structures are:
Other attributes are:
Linking Brainiac Behavior Engine To Your Application
Windows '95 or better
Any Win32-supporting C++ IDE or compiler
You will have to complete a number of tasks in order to make use of Brainiac in conjunction with your application:
1) Link BBE.LIB to your project. Include the BRAINIAC.H header file in the module that will make use of Brainiac functions.
2) When generating your characters or other computer-controlled entities, ensure that an Agent object is defined for each one.
3) You must call the InitActionLib() non-member function when loading your application and the FreeLibLists() non-member function when exiting it.
4) Optionally (but it is recommended), you may prepare functions that assemble an array of pointers to all Agent objects, and an array of arrays containing pointers to their inventory items.
5) When a character or entity enters or departs the currently considered game location (an "environment change") you must call the Agent::Scan() function for every Agent present at that game location.
6) You must call the Agent::ExecuteNextAction() method when you want a character or entity to act. The best timing is probably for Agents to actat each environment change. In that case, agents who failed in an action won't attempt to needlessly execute the action again (possibly leading the abandonment of their strategy).
To work with Brainiac BE in a Visual C++ IDE, you will have to perform the following tasks:
1) In Tools/Options/Directories, add the BRAINIAC.H header file to the "Library files" directory list.
2) Add Visual C++ BBE.LIB to your project. This can be done in Project/Settings/Link.
Getting Started With The Brainiac Data Manager
Brainiac characters operate using three tools: Goals, Actions and Strategies. A Goal defines a desired end result, such as winning a game or getting rich. A Strategy is made up of a chain of possible Actions that can be undertaken in order to attain a Goal. In the case of getting rich, a Strategy could be made up of Actions revolving around theft, trading, playing the stock market, or any one of a hundred other tactics.
If character A meets with character B and B satisfies all of the criteria contained in one of A's Goal records, then A will attempt to pick a Strategy which:
a) Serves to accomplish this Goal, and
b) Suits character A's temperament and that A believes is possible to accomplish
If character A finds such a Strategy, it will be scheduled for execution. The execution of Actions within a Strategy may branch and loop, but individual Actions are generally fairly straightforward.
To start a new database, delete all of the files in the Brainiac directory using the ".db" extension. (Note that the default database is also stored in Default.zip. Keeping backup files often saves later grief.) Only one database can be used by the Database Manager at one time, but the files for other databases can of course be stored elsewhere.
Let's build a few behavior patterns, advancing from simple events to more complex examples. We'll start with everyone's favorite, the Lethal Attack.
Behavior Pattern 1: Killing in the Name Of...
1.1 The Goal
The first step is in building a behavior pattern is always to analyze the desired sequence of events in order to determine the Goal. In this case, it couldn't be more straightforward: you would like one character to attempt to kill another character. Obviously, the Goal of the attacking character should be to kill the Objective character (remember that the Objective character is the target of an Action or a Strategy). Now you can load the Brainiac Data Manager and take the following steps:
1) Open the Database menu and select Goals... to view the Goals Table.
2) Click on the Insert button.
If you deleted all files with ".db" extensions, there will be no Goals in the Goal table. After clicking "Insert," you should now be looking at the Goal/Criterion update window.
3) Enter a description of the Goal in the "Description" field. For this Goal, we could use "killing out of enmity."
Now why would a character want to kill someone else? There are always plenty of reasons available, more is the pity, but we shall choose the most obvious: personal hatred. "Personal hatred" translates to Brainiacese as "the evaluator's attitude to the target ranges from -100 to -75." (These limits are not strict, however. Attitudes range from -100 to 100 -- the higher the better. You can play with your own settings and give your characters choleric or phlegmatic temperaments).
4) Select the Attitude Limits tab.
Do you see the number "129" everywhere? It means that a given slot is unused.
5) Now enter the following values on the "Evaluator's To Target" attitude line: Low = -100, High = -75.
A green check should appear, meaning that the Attitude slot is now being used. Press Enter to save changes, or click the OK button. What...it wouldn't close! Apparently, we forgot something. This would be the Importance field in the General tab, which is selected now. Importance comes into play when a character has to choose between two different Goals, one of which has already triggered a Strategy. Importance can take any value from one to ten, where ten is most important.
6) Enter "9" in the Importance field.
7) Click the OK button to save the Goal.
The Goal will now appear in the Goals Table. You can further edit the Goal by double-clicking on its line in the Goal Table, or by clicking the "Change" button.
1.2 The Strategy
Now that we have set up our Goal, we must create an accompanying Strategy. Note that a Strategy is really just a set of Actions and a few accompanying attributes.
1) Open the Database menu and select Strategies... to open the Strategies table.
2) Click on the Insert button.
You should now be looking at a window entitled "Update the StrategFile." Let's first identify this strategy:
3) Enter "lethal attack" (as suitable description as any) in the Name field.
4) Enter "tutorial: lethal attack" in the Description field.
The next step is to link our new Strategy to a Goal. You can either type the Goal numeric ID into the Goal field yourself or select a Goal from the Goals table:
5) Place the cursor in the Goal field and press F2 key or right click the mouse.
You should now see the same Goals table as before, but with the useful addition of the Select button. (Note that in this mode you can still branch off to add, edit or delete Goals). To link the Strategy to our Goal, do the following:
6) Highlight the "killing out of enmity" Goal (by clicking on it, or using the arrow keys) and press Select.
The Goals Table will vanish, and you should see that the Goal field in the Strategies window now contains the correct Goal ID and name.
1.3 The Actions
Now that our Strategy has a Goal, it's time to place Actions. As it happens, this Strategy only has the one Action: a straightforward attack. Let's add it this:
7) Click on the Append button.
(Notice that it's "Append," and not "Insert." New Actions will always be appended to the end of this list). You should now be looking at a window labeled "Browse the Actions File"). As before, we can add, change or delete entries in any such table in this lookup mode as well as in the regular mode.
8) Click on the Insert Button.
The Insert button is used to add a new Action record to the Actions file, and will pop up the "Update the Actions File" window.
9) Type "attack" in the Name field of the Update window.
10) Switch the Action Type to Vital using the radio button.
Setting an Action as "Vital" will turn on all the checking routines which deal with "matters of life and death." Next, we should set the other aspects of the new Action. Minimum Intelligence is first: this is the Intelligence level that a character must possess in order to initiate this Action.
11) Set Minimum Intelligence to 1; it doesn't require much in the way of brainpower to hit someone.
Let's look at Attitude Change next. The Objective character's attitude towards the character who initiated this Action will change by this amount after the Action was accomplished. Here we must give a value which will switch the kindest man on earth into a hostile state of mind; -90 is more than enough.
12) Set Attitude Change to -90.
Required Courage is -- not surprisingly -- the Courage required to initiate this Action when the initiating character and the Objective character are about even in their overall combat abilities. On the scale from 1 to 10 we should give it about an 8.
13) Set Courage to 8.
The value entered for Difficulty is used to evaluate the overall Strategy Difficulty parameter. This value prioritizes the selection of Strategies, the assumption being that characters will try easier methods (lower Difficulty numbers) first. Violence is -- hopefully -- one of the last resorts, so we shall assign Difficulty a value 30 (on a scale 1 to 100).
14) Set Difficulty to 30.
Wickedness and Anarchy are measures of the evil and chaos, respectively, inherent to this Action if the Objective character is a totally neutral towards the initiating character. On a scale of 1 to 100, this Action should rate around 75 for Wickedness and 50 for Anarchy.
15) Enter 75 in the Wickedness field.
16) Enter 50 in the Anarchy field.
The "Attitude From" and "To" fields restrict this Action to a certain emotional state, where the initiating character's Attitude towards the Objective character is within the specified range. On the assumption that most people will not attempt to kill their friends, we shall set this range from -100 to 10 (out of a total range of -100 to 100, where -100 is absolute hatred).
17) Enter -100 in the "Attitude From" field and -10 in the "To" field.
That would be that! We've finished defining the Action, but before going on we should explain the two function-related fields. These are for programmers who wish to code their own Actions. The "Function Module ID" field should contain the ID number of the run-time module (a DLL or EXE) that holds the function used to handle this Action. (The ID is given in the run-time modules table.) The "Function Label" field should contain the export pattern (typically contained in a .DEF file) of the function.
18) Hit the Enter key or click the OK button to save your changes.
You should now be back to the Actions table, in the lookup mode. We now need to select this Action for our Strategy.
19) Click on the Select button.
The Action will now be added to the list in the "Update The Strategies File" window.
18) Hit the Enter key or click the OK button to save this Strategy.
Congratulations! You have just created your first simple Brainiac behavior pattern.
2.1 The Goal
Robbery is more sophisticated behavior pattern than the crude attack of the previous example. We should analyze it first: it would seem fairly obvious that the Goal of a robbery is usually to acquire an item (often money).
Item acquisition is a special case among Goals in Brainiac, as it has a variable Importance. When the Attributes of a potential Objective character are evaluated to see if a Goal should be triggered, that character's inventory is checked for items that -- in the opinion of the initiating character -- are valuable (not only in financial aspect). If the item acquisition Goal matches, then the Importance attribute is assigned based on the value of the items held by the Objective character.
The item acquisition Goal record should not hold any criteria. On the other hand, it must include a condition which is always false, such as 10 < Courage < 1, used in the demonstration database). All this serves to prevent the accidental triggering of Strategies while an inventory is checked. It is natural to ask, why do we need this record at all? The answer is simple: Strategies use the Goal as a primary key in the database. To distinguish Strategies that aim to acquire an item, such Strategies must be linked to the item acquisition Goal.
Do not forget that if you are going to prepare a new database from scratch, you must redirect the item acquisition Goal ID to point to your record. This is done by calling the SetGoalItemAcquisitionID() function. By default, the inventory scanning loop synchronizes to Goal record 1.
2.2 The Strategy
We'll use a simple and fairly crude plan. The initiating character (robber) will first attempt to intimidate the Objective character (victim); the robber will demand the item and threaten to attack the victim if the demand is not met. The Strategy will end successfully if the threat succeeds. If the threat fails to intimidate the victim, the robber will attack. After the victim is dead, the robber will acquire the item. Note that this plan contains a simple branching statement revolving around the success or failure of the threat.
1) Call up the Strategies table, click on the Insert button.
We are now back to the "Update the Strategies File" window. Hopefully this is all looking more familiar by now. Next, you can breeze through setting up the Strategy:
2) Type "robbery" in the name field and "tutorial: robbery" in the description field.
3) Set the Goal ID field to "item acquisition" by right-clicking on the field and selecting from the Goals Table.
2.3 The Actions
It is now time to define the Actions that make up the robbery Strategy. You should still be looking at the "Update the Strategies File" window:
1) Click the Append button to call up the Actions table.
2) Click the Insert button to create a new Action.
Our first task here is to define the threat portion of the Strategy.
3) Enter "threat" in the Action name field.
4) Set the Action Type to "Verbal."
You will also need to set the following values: Minimum Intelligence = 8, Attitude Change = -8, Required Courage = 7, Difficulty = 3, Wickedness = 10, Anarchy = 0 and Attitude from -100 to 40. Remember that these values apply only to this Action -- not to the Strategy as a whole.Robbery is fairly antisocial, but threatening someone is not as undesirable an act in and of itself.
5) Click the OK button or press the Enter key to save the changes to the Action
6) Press the Select button to add the newly created "threat" Action to the Strategy list.
Verbal Actions (Actions involving speech) are typically associated with Content Actions. When making a Verbal Action -- a deal proposal, request or threat -- Content Actions are proposed within the context of the Verbal Action. The Brainiac convention is to firstly describe the initiating character's verbally proposed Action ("me"), then the Objective characters proposed response ("you"). In our current Strategy, the verbal action on the part of the robber is -- more or less -- "give me that item or I will attack you!" The robber (initiating Character) is proposing both an attack and that the victim (Objective character) hand over the item. By the Brainiac rules, therefore, we must first add "attack" and secondly add "give item" as Content Actions.
7) Make sure that the "threat" Action is highlighted.
8) Click on the enabled "Append This Verbal Action Content" checkbox.
This important checkbox is at the bottom of the window; it is enabled only if the last Verbal Action is highlighted in the Action list. (As "threat" is the only Action present, the checkbox should be enabled).
9) Click on the Append button to bring up the Actions window.
10) Highlight the "attack" action and click on the Select button.
This will take you back to the Strategy window. You should see "attack" added to the list as 1A, and the Action name is bound by quotes. This is a visual reminder to show that this is a Content Action. We should now define the "give item" Action.
11) Return to the Actions screen as before -- making sure that "threat" is highlighted and the checkbox on.
12) Click on Insert to add a new Action.
Fill out our new Action as follows: type "give item" in the name field, switch the Action type to Mechanic, set Minimum Intelligence = 1, Required Courage = 1 and Difficulty = 1. For all intents and purposes, these 1's mean a practical absence of requirements for this Action. The other fields are left at their default values.
13) Press the Enter key or click the OK button to save this Action.
14) Click on the Select button in the Actions window to add this Action to your Strategy.
This should be appended in the same way as "attack," but as Action 1B. Now that we have added the two allowed Content Actions to the "threat" Verbal Action, the "Append This Verbal Action Content" checkbox will be unchecked and disabled. Recall that the Strategy must end if the threat succeeds.
15) Highlight the "threat" action.
16) Click on the "Target And Conditional Branch..." button.
This will pop up a window that contains a fair amount of frightening stuff. For the moment, however, our interest is in the checkbox at the bottom -- "End Strategy If This Action Succeeded".
17) Check the "End Strategy If This Action Succeeded" checkbox.
18) Click on the OK button.
This will set up the necessary condition that will end the Strategy on the success of the "threat" Action. Now we can add the last parts of this Strategy.
19) Use the Append button and the Actions window to add the "attack" action to the list.
20) Click on the Append button again.
The last step in this Strategy is to take the item. We will therefore need to create a "take item" Action.
21) Click on the Insert button to create a new Action.
Fill in the Action fields as follows: type "take item" in the name field, switch the action type to Mechanic and enter the same values as you did for the "give item" Action. (These were Minimum Intelligence = 1, Required Courage = 1 and Difficulty = 1).
22) Press the Enter key or click on the OK button to save your changes.
23) Click the Select button to add this final Action to the list.
Phew! Looks like we're done here. You should save the Strategy:
24) Hit the Enter key or click on the OK button to save this Strategy.
Notice that in setting up the robbery Strategy you have at least touched upon the creation of Verbal Actions, Content Actions and a simple branching of Actions within Strategies.
Behavior Pattern 3: Conspiracy
3.1 The Goal
A conspiracy scenario, like the first sample behavior pattern, revolves around an initiating character who wants to kill the Objective character. In this case, however, the initiating character is unable to successfully accomplish an attack alone. The initiating character will then find a potential assassin, telling the potential assassin that the Objective character attacked someone that the potential assassin likes. The initiating character will then ask the potential assassin to attack the Objective character.
The Strategy and Actions in this example will be a little more complex that in the previous examples; you'll learn to assign immediate and reference criteria, and how to use advanced branching. By way of contrast, the Goal is easy. This Strategy is (yet another) one of the ways to dispose of someone, so the Goal is "killing out of enmity." Conveniently, we have already defined this Goal in the first example.
3.2 The Strategy
We shall quickly set up the parameters of the Strategy:
1) Call up the Strategies table.
2) Click on the Insert button to create a new Strategy.
3) Right-click on the Goal ID field and select "killing out of enmity" from the Goals Table.
4) Type "conspiracy" in the name field and "tutorial: conspiracy" in the brief description field.
3.3 The Actions
We are now ready to start on the Actions that make up this Strategy.
1) Click on the Append button.
2) Click the Insert button in Actions File window.
You should now be looking at the "Update the Actions File" window. We are going to define the "statement" Verbal Action:
3) Enter "statement" in the name field.
4) Switch the action type to Verbal.
"Statement" is a neutral Action that requires at least a little native intelligence to carry out. We shall set the following values: Minimal Intelligence = 6, Difficulty = 3, Required Courage = 3 and Attitude from -65 to 100 (this last because it is a little hard to make a statement while apoplectic with anger).
5) Hit the Enter key or click on the OK button to save the changes.
6) Click the Select button to add this Action to your Strategy.
Now we must define the Content Actions for the "statement" content.
7) Highlight the "statement" Action in the list.
8) Check the "Append This Verbal Action Content" checkbox.
9) Click the Append button.
We need to choose a Content Action. The statement we are going to define here will run along the lines of "this person attacked that person!"
10) Select the "attack" action to add it to the list as 1A.
11) Now click on the Append button again.
12) Click on the Dummy button to add a "dummy" action to the list as 1B.
Here, the first Content Action associated with the "statement" Action is all that is needed to describe the statement made by an initiating character. Statements support only one Action per statement. There can be no default initiating character in the statement; "dummy" Actions are used to point to the initiating character. So far we have been doing just fine with the default targets, but in this case some changes must be made to the targets of the statement Action and its Content Actions.
The statement, the first Action in this Strategy, is made to a potential assassin and not to the Strategy Objective character (the victim). We need to translate this targeting of a specific Action within the Strategy into Brainiacese:
13) Highlight the "statement" Action.
14) Click on the "Target And Conditional Branch..." button.
You should now be looking at the Target Assignment window. What is needed here is an "immediate" target criteria; that is, a target character who will be selected immediately before this Action executes. In order to make this work, we will first need to declare that we are using an immediate target. Secondly, we must define the criteria by which such an immediate target will be selected.
15)Make sure the "Immediate Target Criteria..." checkbox is selected.
16) Right click in the criteria field to bring up the Criteria Table.
We don't need to use an inventory-related criteria here:
17) Make sure the Common radio button is selected.
18) Click on the Insert button to add a new criteria record.
What to choose in the Goal/Criteria Update window? It would be logical to select a potential assassin capable of killing the intended victim.
19) Enter "potential assassin" in the Description field.
20) Switch "Criteria Limiting Values and Action Flag's Type" to "Relative to strategy objective."
21) Go to the Target Criterion Limits tab.
22) Assign limits of 1 to 100 to Meanness (Combat Ability).
23) Click on the Enter button to save the newly created criteria record.
Note that by changing the "Criteria Limiting Values..." selected radio button like this, we are comparing the abilities of the potential assassin and the victim (who is the Strategy Objective character).
24) Highlight the new criteria in the Criteria Table.
25) Click on the Select button to assign this criteria to the Action that you're currently editing.
Having assigned the immediate target criteria for the potential assassin, we are now done with the Target Assignment window.
26) Click on the OK button or press the Enter key to return to the Strategy window.
We are not done with the statement Action yet; we must still edit the target of the "attack" Content Action. The statement Action in its entirety runs something along the lines of "hey! Mr. Potential Assassin! Mr. Victim attacked Mr. Friend Of Potential Assassin!" We have already dealt with the "hey! Mr. Potential Assassin!" part by setting the immediate target criteria for the statement action. Now we must sort out the targets involved in the second part. In Brainiacese, the second part of the statement (the "attack" Content Action) can be read as "the Strategy Objective character attacked a friend of the Action 1 Objective character!"
27) Highlight the "attack" Content Action.
28) Click on the "Target And Conditional Branch..." button again.
29) Make sure "Immediate Target Criteria..." is selected in the Target Assignment window.
30) Right click in the "Immediate Target Criteria..." entry field to bring up the Criteria Table.
31) Click on the Insert button to create a new Criteria record.
In this new criteria we will be defining the sort of character that will be a "friend of the Action 1 Objective character."
32) Enter "Friend of Act 1 Obj" in the Description field.
33) Go to the Attitude Limits tab.
34) Enter "1" in the Referenced Action field.
We would like the potential assassin's attitude should be friendly or better; enter 75 and 100 in the "Ref. Action Objective's To Target" from and to fields respectively.
35) Hit the Enter key or click on the OK button to save the changes.
36) Highlight the new criteria record in the Criteria Table.
37) Click on the Select button to assign the criteria to the Action being edited.
38) Select the "Not In Strategy" radio button in the Target Assignment window.
39) Press the Enter key or click on the OK button to save your changes.
We are now done with the "attack" Content Action. What about the "dummy" Content Action that is used to hold the character who initiated the reported Action? The initiating character is the Strategy objective character by default; which is to say the victim. In this case, we don't need to change the default setting.
Onwards! We have completed the first part of this Strategy, but there is more to come. The second part is a request made to the potential assassin to attack the victim.
40) Click on the Append button in the "Update the Strategies File" window.
41) Click on the Insert button in the "Browse the Actions File" to create a new Action.
42) Enter "request" in the name field, and switch the Action Type to "Verbal."
We shall set the following values for a request Verbal Action: Minimum Intelligence = 5, Difficulty = 3, Required Courage = 3 and an Attitude range of -30 to 100.
43) Press the Enter key or click on the OK button to save the new Action.
44) Make sure that the request Action is highlighted.
45) Click on the Select button to add the "request" Action to the list.
You can now add the Content Actions to the request Verbal Action. In this case, the first and second content Actions will be the same as those contained by the statement Verbal Action; "attack" and "dummy" Actions respectively. Don't forget to check the "Append This Verbal Action Content" checkbox before adding the Content Actions to the request Action. Once this is done, we must ensure that these new Actions have the correct targets.
46) Highlight the "request" Action and click the "Target And Conditional Branch..." button.
The request has to be made to the same character as the statement Verbal Action was; in Brainiacese, this means that the Objective character for both Actions is one and the same. Telling Brainiac to do this is fairly simple:
47) Select the "Get Target From Action..." radio button in the Target Assignment window.
48) Enter "1" in the "Get Target From Action..." entry field.
That will instruct Brainiac to assign the same Objective character to the request Action as was used for Action 1 (the statement).
While we are here, we should also consider the matter of failure. What if the potential assassin refuses to attack the victim? A solution to this problem would be for the character initiating the Strategy to find another potential assassin. To set this behavior in motion, we can implement a simple loop in the strategy:
49) Enter "1" in the "If Unable, Go To Action..." field.
What could be more simple than that? This will instruct Brainiac to return to Action 1 (the statement) should the request fail.
50) Press the Enter key or click the OK button to save the changes.
The last step is to consider the targeting of the request Content Actions. Fortunately, we don't need to alter the Objective character of the "attack" Content Action; the default is the Strategy Objective character (the victim). However, the character doing the attacking should be the potential assassin singled out as the Objective character in Action 1. Recall that the "dummy" Content Action Objective character is the one who should be performing the requested "attack" Action, and the default here is the character who is initiating the Strategy. We will have to change this:
51) Highlight "dummy" Action 2B and click on the "Target And Conditional Branch..." button.
52) Select the "Get Target From Action..." radio button in the Target Assignment window.
53) Enter "1" in the "Get Target From Action..." entry field.
54) Press the Enter key or click the OK button to save the changes.
Are we there yet? Almost. To be able to correctly select candidate potential assassins for Action 1, we must restrict these candidates to those characters not listed in the Strategy. This will raise our chances of finding a candidate, although there is a chance of repetitive choices.
55) Highlight "statement" Action 1 and click on the "Target And Conditional Branch..." button.
56) Switch the Restrictions radio button to "Not Strategy Objective."
57) Press the Enter key or click the OK button to save the changes.
58) Press the Enter key or click the OK button again to save the Strategy.
That's it! You just created a fairly complex strategy, while learning about advanced branching and immediate and reference criteria.
Brainiac Native Verbal Interaction
For now, Brainiac BE supports five verbal Actions: Deal, Request, Statement, Tease and Threat. These Actions allow for more than it might seems first, and end-user programmers can add their own verbal Actions to the list.
Deal
Deal is a generic commercial Action ("trade offer" is used in the Brainiac BE Data Manager to set constraints for Deal). A Deal can be divided into two parts: the proposed Action and the requested Action. If either of the two Actions has a non-NULL pointer to an inventory item, the item is evaluated instead of used in an Action. This means that Deal can descrinearly every basic form of transaction; paying for a service, exchanging or buying items and exchanging services, to name a few. The evaluation of a Deal Action is also influenced by
the attitudes of the Dealing characters.
Request
Request is as universal as Deal, but it contains only one Action -- the requested Action. In other words, a Request it is the same as a Deal, but without a proposed Action.
Statement
A Statement reports an Action (only one Action for the moment) to another character. Why bother? Well, take a look at the conspiracy example for the use of a Statement to manipulate another character. A Statement can be either true or a lie. It can describe events that happened in the past, are happening now, or that can happen in the future.
The character receiving a Statement (the Statement Objective) will evaluate the reported Action and the reporting character. If the information is believed, attitudes may change.
In Brainiac BE, the reported Action is first defined in the Data Manager ("A"). The target of this Action defines the reported Action initiator. The second Action ("B") must be present, but only to define the reported Action Initiator. It is advisable to use the "dummy" Action, just to prevent confusion.
(All verbal actions by definition containing only one content Action, are defined in A-B, content Action - initiator holder fashion).
Tease
Tease does not provide much functionality. It just makes use of a small function for generating insults by comparing personal characteristics. For example, a physically strong character could call a weaker opponent "wimp," while a smarter character would refer to a dumber target as "idiot," and so on. Insults are sorted by the difference in abilities -- that is, the greatest difference comes first.
Threat
Threat resembles Deal in many aspects, except that both Actions are viewed as undesirable by the Objective character. The aim is to make the Objective character consider alternate Strategies to prevent the "proposed" Action on the part of the threatening character.
Goal is the motivation of an agent to do something. To start accomplishing tasks aimed at another agent, the potential initiator agent must find a goal definition record suitable for potential target. Criteria is, technically, goal record where importance attribute is 0 (N/A), but it is used for another purpose - to seek intermediate action objectives in strategy.
Goal structure contains merely goal ID and its basic importance before possible modifications. The full definition is
typedef struct {
ID Itself; //goal ID
percentage Importance; //basic goal importance
} Goal;
The full definition structure contains all the limiting values and the brief description.
struct _GoalDefNode {
Goal goal;
char Descr[26];
Core LoReqs, HiReqs; //limiting values structures
unsigned char CompType,
/*comparison type:
COMP_ABS (0) = absolute (target)
COMP_REL2EVAL (1) = relative to evaluator
COMP_REL2SOBJ (2) = relative to objective
COMP_REL2LINI (3) = relative to initiator
COMP_ABS_EVAL (4) = absolute (evaluator)*/
AttDir, //unused for now
IdFlag1; /*special ID flag:
FL1_LASTINIT (1) = for last action initiator
FL1_LASTOBJ (2) = for last action objective*/
ID IdFlag2; //special Action ID for ID flag
ID UserDefAttID; //user-defined attitude ID
ID AttRefAct; //referenced action ID (for the corresponding //attitude value)
ID IncGoalID; //included goal ID, for recoursive definitions
struct _GoalDefNode *next; //pointer to next node in the list
};
typedef struct _GoalDefNode* GoalDefNodeP;
Action is, as it sounds, a single action with defined Initiator and Objective, and optional ObjectiveItem. If ObjectiveItem pointer is not NULL, it is assumed that the action is inventory-oriented.
Properties (public only):
BOOL SkipChecks
Description
Methods (public only):
Action::Action();
Description:
Parameters:
Return values:
Action::Action(Action *InitBy);
Description:
Parameters:
Return values:
Action::Action(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,
percentage BasicAnarArg, percentage MinIntArg, percentage ReqCouArg,
percentage BasicAttitudeChangeArg, ID ActionIDArg, percentage MinAttArg,
percentage MaxAttArg, int (*ActionFnArg)(void*));
Description:
Parameters:
Return values:
Action::~Action()
Description:
Parameters:
Return values:
void Action::Init(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,
percentage BasicAnarArg, percentage MinIntArg, percentage ReqCouArg,
percentage BasicAttitudeChangeArg, ID ActionIDArg, percentage MinAttArg,
percentage MaxAttArg, int (*ActionFnArg)(void*));
Description:
Parameters:
Return values:
void Action::Init(Action *InitBy);
Description:
Parameters:
Return values:
void Action::SetActionFn(int (*)(void*)ActionFnArg);
Description:
Parameters:
Return values:
void Action::InitTargets(Core *InitiatorArg = NULL, Core *ObjectiveArg = NULL,
ItemScores *ObjectiveItemArg = NULL);
Description:
Parameters:
Return values:
void Action::ResetTargets();
Description:
Parameters:
Return values:
Core *Action::GetInitiator();
Description:
Parameters:
Return values:
Core *Action::GetObjective();
Description:
Parameters:
Return values:
ItemScores *Action::GetObjItem();
Description:
Parameters:
Return values:
Action *Action::GetReported1Ptr();
Description:
Parameters:
Return values:
Action *Action::GetReported2Ptr();
Description:
Parameters:
Return values:
void Action::SetReported1(Action *Reported1Arg);
Description:
Parameters:
Return values:
void Action::SetReported2(Action *Reported2Arg);
Description:
Parameters:
Return values:
void Action::InitScores(ActionType aType, percentage BasicDiffArg, percentage BasicWickArg,
percentage BasicAnarArg, percentage MinIntArg,
percentage ReqCouArg, percentage BasicAttitudeChangeArg,
percentage MinAttArg, percentage MaxAttArg);
Description:
Parameters:
Return values:
void Action::ResetScores();
Description:
Parameters:
Return values:
void Action::GetActualScores(percentage& ActualDiffArg, percentage& ActualWickArg,
percentage& ActualAnarArg, percentage& ActualAttChg);
Description:
Parameters:
Return values:
void Action::GetBasicScores(percentage& BasicDiffArg, percentage& BasicWickArg,
percentage& BasicAnarArg, percentage& BasicAttChg);
Description:
Parameters:
Return values:
void Action::GetSolidScores(percentage& MinIntArg, percentage& ReqCouArg);
Description:
Parameters:
Return values:
void Action::GetAttitudeLimits(percentage& LoAttArg, percentage&HiAttArg);
Description:
Parameters:
Return values:
ActionType Action::GetType();
Description:
Parameters:
Return values:
ActionError Action::Execute(void* vpArg, BOOL CheckMode = FALSE, unsigned char UseTrue = 0, percentage NeutralSideMeanness = 0);
Description:
Parameters:
bit 0 = Meanness
bit 1 = Wealth
bit 2 = Intelligence
Return values:
BOOL Action::IsReady();
Description:
Parameters:
Return values:
ID Action::GetID();
Description:
Parameters:
Return values:
void Action::SetTargetAssignmentCriteria(unsigned char TACArg);
Description:
Parameters:
Return values:
void Action::SetRefTAC(unsigned char RefTACArg);
Description:
Parameters:
Return values:
void Action::SetFailureGoto(unsigned char ActionOrder);
Description:
Parameter:
Return values:
unsigned char Action::GetTargetAssignmentCriteria();
Description:
Parameters:
Return values:
unsigned cAction::GetRefTAC();
Description:
Parameters:
Return values:
unsigned char Action::GetFailureGoto();
Description:
Parameters:
Return values:
percentage Action::GetDealValue();
Description:
Parameters:
Return values:
unsigned short Action::FillSaveBuffer(BYTE* bpBuffer);
Description:
Parameters:
Return values:
void Action::RestoreFromBuffer(BYTE *bpBuffer, Core **Population, unsigned short nPopLen,
ItemPtrArr* ipapAllInventories, unsigned short *nAllInvLens);
Description:
Parameters:
Return values:
Strategy is a way to achieve a certain goal via series of Actions. Brainiac strategies contain only single-linked straightforward list of Actions, but the class is able to manage strategies involving conditional branching and looping. Strategies, as well as Actions, are managed automatically by Agent class - normally, you don't have to call Strategy methods explicitly.
Properties:
Methods (public):
Strategy::Strategy();
Description:
Parameters:
Strategy::Strategy(Goal argGoal, ID argID);
Description:
Parameters:
Return values:
Strategy::~Strategy();
Description:
Parameters:
Return values:
void Strategy::Init(Goal argGoal);
Description:
Parameters:
Return values:
void Strategy::Init(Goal argGoal, ID argID);
Description:
Parameters:
Return values:
ActionError Strategy::ExecuteNextAction(void *vpArg, unsigned char UseTrue = 0, percentage NeutralSideMeanness = 0);
Description:
Parameters:
bit 0 = Combat Ability (Meanness)
bit 1 = Wealth
bit 2 = Intelligence
Return values:
Action *Strategy::GetNextAction();
Description:
Parameters:
Return values:
percentage Strategy::GetNextActionOrder();
Description:
Parameters:
Return values:
Action *Strategy::GetLastAction();
Description:
Parameters:
Return values:
percentage Strategy::GetLastActionOrder();
Description:
Parameters:
Return values:
void Strategy::UpdateNextActionTargets(Core *argInitiator,
Core *argObjective, ItemScores *argItem);
Description:
Parameters:
Return values:
BOOL Strategy::AppendAction(Action* apToAppend);
Description:
Parameters:
Return values:
Action Strategy::DelAction();
Description:
Parameters:
Return values:
ActionNodeP Strategy::FindAction(unsigned char ActionOrder);
Description:
Parameters:
Return values:
ActionNodeP Strategy::GetActionList();
Description:
Parameters:
Return values:
void Strategy::SetGoal(Goal argGoal);
Description:
Parameters:
Return values:
Goal Strategy::GetGoal();
Description:
Parameters:
Return values:
void Stra::SetObjective(Core *argObj);
Description:
Parameters:
Return values:
Core *Strategy::GetObjective();
Description:
Parameters:
Return values:
void Strategy::SetObjItem(ItemScores *argItem);
Description:
Parameters:
Return values:
ItemScores *Strategy::GetObjItem();
Description:
Parameters:
Return values:
percentage Strategy::GetImportance();
Description:
Parameters:
Return values:
void Strategy::CalcScores(percentage AdditionalImportanceModification = 0);
Description:
Parameters:
Return values:
void Strategy::FreeActionList();
Description:
Parameters:
Return values:
BOOL Strategy::PossibilityCheck();
Description:
Parameters:
Return values:
void Strategy::End();
Description:
Parameters:
Return values:
ID Strategy::GetID();
Description:
Parameters:
Return values:
void Strategy::SetNextActionAddress(ActionNodeP pActionNode);
Description:
Parameters:
Return values:
void Strategy::SetLastActionAddress(ActionNodeP pActionNode);
Description:
Parameters:
Return values:
void Strategy::SkipNextAction(BOOL ForceFailure = FALSE);
Description:
Parameters:
Return values:
BOOL Strategy::IsListed(ID ToCheck);
Description:
Parameters:
Return values:
unsigned short Strategy::FillSaveBuffer(BYTE *bpBuffer);
Description:
Parameters:
Return values:
void Strategy::RestoreFromBuffer(BYTE *bpBuffer, Core **Population, unsigned short nPopLen,
ItemPtrArr* ipapAllInventories, unsigned short *nAllInvLens);
Description:
Parameters:
Return values:
void Strategy::OverrideActionList(ActionNodeP pActionNode);
Description:
Parameters:
Return values:
void Strategy::ResetAllActionTargets();
Description:
Parameters:
Return values:
void Strategy::ReturnToLastAction();
Description:
Parameters:
Return values:
Agent is the implementation of the central Brainiac concept - autonomous agent acting and deciding by itself, scheduling and executing actions.
Properties (public only):
unsigned char FailuresCount;
unsigned char LoopFailuresCount;
static unsigned short AutoNumber;
Strategy CurrentStrategy;
Methods (public only):
Agent::Agent();
Description:
Parameters:
Return values:
Agent::Agent(percentage WickednessArg, percentage AnarchyArg);
Description:
Parameters:
Return values:
Agent::~Agent();
Description:
Parameters:
Return values:
void Agent::Init(percentage WickednessArg = 0, percentage AnarchyArg = 0);
Description:
Parameters:
Return values:
void Agent::SetImpression(percentage argMeanness, percentage argWealth,
percentage argBeauty, percentage argIntelligence, percentage argForeignness,
BOOL UseTrue = FALSE);
Description:
Parameters:
Return values:
void Agent::SetSolidScores(percentage argIntel, percentage argCourage);
Description:
Parameters:
Return values:
void Agent::GetImpression(percentage& argMeanness, perc& argWealth,
percentage& argBeauty, percentage& argIntelligence, percentage& argForeignness,
BOOL UseTrue = FALSE);
Description:
Parameters:
Return values:
void Agent::GetSolidScores(percentage& argIntel, percentage& argCourage);
Description:
Parameters:
percentage Agent::InitialAttitudeModification(const Core& OtherAgent,unsigned char UseWhich = 0);
Description:
Parameters:
Return values:
const AlignmentType Agent::GetAlType();
Description:
Parameters:
Return values:
char* Agent::GetAlName();
Description:
Parameters:
Return values:
ID Agent::GetID();
Description:
Parameters:
Return values:
percentage Agent::ItemAcquisitionImportance(ItemScores &ToEvaluate);
Description:
Parameters:
Return values:
BOOL Agent::Scan(Agent *paScanned,ItemPtrArr Items, unsigned short ItemArrayLen,
ID ScanGoalItselfArg = GOAL_NONE);
Description:
Parameters:
Return values:
BOOL Agent::ScanForCriterion(Agent *paScanned,
ItemPtrArr Items, unsigned short ItemArrayLen, GoalDefNodeP gp);
Description:
Parameters:
Return values:
long Agent::FindCriterionMatch(Agent **Candidates,unsigned short nCandArrLen,
ItemPtrArr *Items,unsigned short *ItemArrayLen,
ID ScanGoal = GOAL_NONE, percentage PassedRestrict = -1);
Description:
Parameters:
ALL_BUT_SELF - usual restriction. Allows scan of all Agents but self.
NOT_STR_OBJ - this restriction disallows self and strategy objective agent
NOT_LISTED_IN_STR - this restriction disallows self and everyone already listed in strategy (initiators, objectives, verbal action content objectives, etc.)
SELF_ONLY - this restriction exists only for picking inventory items owned by the scanning agent ("self").
Note: Even SELF_ONLY restriction doesn't provide automatic selection. Restrictions serve only to restrict.
Return values:
BOOL Agent::AssignTargetForNextAction(Agent**Population = NULL,unsigned short nPopLen = 0,
ItemPtrArr* ipapAllInventories = NULL,unsigned short *nInvSizes = 0);
Description:
Parameters:
Return values:
BOOL Agent::AssignTargetsForAction(Action *actpToAssign,
Agent**Population = NULL,unsigned short nPopLen = 0,
ItemPtrArr* ipapAllInventories = NULL,unsigned short *nInvSizes = 0,
Strategy *strpToUse = NULL);
Description:
Parameters:
Return values:
ActionError Agent::ExecuteNextAction(void *vpArg, Agent**Population = NULL,unsigned short nPopLen = 0,ItemPtrArr* ipapAllInventories = NULL,unsigned short *nInvSizes = 0);
Description:
Parameters:
Return values:
BOOL Agent::CalcResponse(Action& actInitial);
Description:
Parameters:
Return values:
percentage Agent::AttitudeToItem(ItemScores& ToEvaluate);
Description:
Parameters:
Return values:
BOOL Agent::PrimeAllActionTargets(Strategy *strToPrime);
Description:
Parameters:
Return values:
Core Agent::GetCore() const;
Description:
Parameters:
Return values:
Core *Agent::GetCoreAddress();
Description:
Parameters:
Return values:
void Agent::SetCore(Core & argCore);
Description:
Parameters:
Return values:
Core Agent::GetOriginalCore() const;
Description:
Parameters:
Return values:
void Agent::SetOriginalCore(Core &argCore);
Description:
Parameters:
Return values:
void Agent::ResetFromOriginal();
Description:
Parameters:
Return values:
void Agent::UpdateOriginalCore();
Description:
Parameters:
Return values:
BOOL Agent::CreateNewAttitude(Core &ToAdd);
Description:
Parameters:
Return values:
percentage Agent::AttitudeTo(Core &ToGet);
Description:
Parameters:
Return values:
percentage Agent::AttitudeTo(ID ToGet);
Description:
Parameters:
Return values:
BOOL Agent::SetAttitudeTo(ID ToSet, percentage NewAttitude,
unsigned char WhichOne = BOTH);
Description:
Parameters:
Return values:
BOOL Agent::IsNewStrategyMoreImportant(Strategy& NewStrategy);
Description:
Parameters:
Return values:
BOOL Agent::IsNewStrategyMoreImportant(percentage NewStrategyImportance);
Description:
Parameters:
Return values:
void Agent::SetSeemed_TrueToggles(BOOL UseTrueMeanness,
BOOL UseTrueWealth, BOOL UseTrueIntelligence,
BOOL argUseTrueAttitude);
Description:
Parameters:
Return values:
BOOL Agent::IsDead();
Description:
Parameters:
Return values:
void Agent::Die();
Description:
Parameters:
Return values:
BOOL Agent::AdoptStrategyFromOneAction(Action *ToBeExecuted,
unsigned char NewImportance);
Description:
Parameters:
Return values:
unsigned short Agent::VerifyCriteria(GoalDefNodeP gpCrit, Core *bsChk,
ItemPtrArr ipaInventory = NULL, unsigned short nInvSize = 0);
Description:
Parameters:
Return values:
BOOL Agent::IsStrategyStillRelevant(Agent **Candidates,unsigned short nCandArrLen,
ItemPtrArr* Items,
unsigned short *ItemArrayLen);
Description:
Parameters:
Return values:
BOOL Agent::PickStrategy(Goal StrGoal, Core *pbsObj, ItemScores *pisObj = NULL);
Description:
Parameters:
Return value:
void Agent::SetAttitudesRoot(Attitude *TreeRoot, BOOL bDoNotDelele = FALSE);
Description:
Parameters:
Return values:
void Agent::FillCritAttitudesArray(percepAtt[],Core *bsChk, GoalDefNodeP gp);
Description:
Parameters:
Return values:
unsigned short Agent::FillSaveBuffer(BYTE *pbBuffer);
Description:
Parameters:
Return values:
void Agent::RestoreFromBufferStep1(BYTE *pbBuffer,unsigned short nBufLen);
Description:
Parameters:
Return values:
void Agent::RestoreFromBufferStep2(BYTE *pbBuffer,unsigned short nBufLen,
Agent** papPopulation, unsigned short nPopSize,
ItemPtrArr* ipapItems, unsigned short *npInvSizes);
Description:
Parameters:
Return values:
percentage Agent::CalcNeutralSideMeanness(Agent **pbspPopulation,
unsigned short nPopSize, Action *actToExecute);
Description:
Parameters:
Return values:
unsigned char Agent::GetTrueStatsByte();
Description:
Parameters:
Return values:
BOOL Agent::WasStrategyFailure(Strategy *ToCheck);
Description:
Parameters:
Return values:
EventsRegistry class primarily stores failed strategies and actions in order to prevent agents from making the same mistakes twice. Besides, it can be also used to store completed events to keep track - like promise or scheduled part of a deal that must be completed. If UseHistory flag is FALSE, the built-in EventsRegistry object managed by the system is inactive. EventsRegistry uses EventEntry structure which is listed below:
typedef struct{
ID EventID;
ID ObjectiveID;
ID ObjItemID;
ID *Witnesses;
unsigned short WitnessesQty;
EventType _Type;
} EventEntry;
Properties (public):
None
Methods (public):
EventsRegistry::EventsRegistry();
Description:
Parameters:
Return values:
EventsRegistry::~EventsRegistry();
Description:
Parameters:
Return values:
void EventsRegistry::Register(ID InitiID,ID EvID,ID ObjID,ID ObjItID, EventType eType);
Description:
Parameters:
ACTION_PROMISE
ACTION_FAILURE
STRATEGY_FAILURE
Return values:
BOOL EventsRegistry::IsEventRegistered(ID InitiID,ID EvID,ID ObjID,ID ObjItID,EventType eType);
Description:
Parameters:
ACTION_PROMISE
ACTION_FAILURE
STRATEGY_FAILURE
Return values:
EventEntry *EventsRegistry::GetEventEntry(ID InitiID,ID EvID,ID ObjID,ID ObjItID,EventType eType);
Description:
Parameters:
ACTION_PROMISE
ACTION_FAILURE
STRATEGY_FAILURE
Return values:
void EventsRegistry::Unregister(ID InitiID,ID EvID,ID ObjID,ID ObjItID,EventType eType);
Description:
Parameters:
ACTION_PROMISE
ACTION_FAILURE
STRATEGY_FAILURE
Return values:
void EventsRegistry::Clear();
Description:
Parameters:
Return values:
PersonalLog class is a personal entry of EventsRegistry. The latter stores events by initiator.
Properties (public):
unsigned short MaxLogLen
Methods (public):
PersonalLog::PersonalLog();
Parameters:
Description:
Return values:
PersonalLog::~PersonalLog();
Parameters:
Description:
Return values:
BOOL PersonalLog::ReallocLog(int nNewLen);
Parameters:
Description:
Return values:
void PersonalLog::SetInitiatorID(ID NewInitiatorID);
Parameters:
Description:
Return values:
ID PersonalLog::GetInitiatorID();
Parameters:
Description:
Return values:
int PersonalLog::GetEventIndex(ID EvID, ID Obj, ID ObjItem, EventType eType);
Parameters:
Description:
Return values:
BOOL PersonalLog::WasEventWitness(ID EvID, ID Obj, ID ObjItem, EventType eType);
Parameters:
Description:
Return values:
int PersonalLog::GetPromiseIndex(ID EvID, ID Obj, ID ObjItem);
Description:
Parameters:
Return values:
int PersonalLog::GetFailedActionIndex(ID EvID, ID Obj, ID ObjItem);
Description:
Parameters:
Return values:
int PersonalLog::GetFailedStrategyIndex(ID EvID, ID Obj, ID ObjItem);
Description:
Parameters:
Return values:
EventEntry *PersonalLog::GetEvent(unsigned short nIndex);
Description:
Parameters:
Return values:
void PersonalLog::SetEvent(ID EvID, ID Obj, ID ObjItem, EventType eType, unsigned short nIndex);
Description:
Parameters:
Return values:
EventEntry *PersonalLog::AddEvent(ID EvID, ID Obj, ID ObjItem, EventType eType, unsigned short nIndex);
Description:
Parameters:
Return values:
void PersonalLog::RemoveEvent(ID EvID, ID Obj, ID ObjItem, EventType eType, unsigned short nIndex);
Description:
Parameters:
Return values:
void PersonalLog::DisconnectPointer();
Description:
Parameters:
Return values:
GoalDefNodeP GetGoalNode(ID GoalNodeID);
Description:
Parameters:
Return values:
ActionDefNodeP GetActionNode(ID ActionNodeID);
Description:
Parameters:
Return values:
StrategyDefNodeP GetStrategyNode(ID StrategyNodeID);
Description:
Parameters:
Return values:
percentage GetAttitude(ID AgentID, Attitude * AttTreeRoot, BOOL GetSEEMED = TRUE);
Description:
Parameters:
Return values:
BOOL AddAttitude(ID AgentID, percentage BothAttitudesValue, Attitude **AttTreeRoot);
Description:
Parameters:
Return values:
BOOL ModifyAttitude(ID AgentID, short ValueModifyBy, Attitude *AttTreeRoot,
unsigned char WhichOne = BOTH);
Description:
Parameters:
Return values:
BOOL UpdateAttitude(ID AgentID, percentage ValueToSet, Attitude **AttTreeRoot, unsigned char WhichOne = BOTH);
Description:
Parameters:
Return values:
void DelAttitudeTree(Attitude **AttTreeRoot);
Description:
Parameters:
Return values:
Attitude *CopyAttitudeTree(Attitude*AttTreeRoot);
Description:
Parameters:
Return values:
void Attitudes2String(Attitude *AttTreeRoot, char *szReceiveBuffer);
Description:
Parameters:
Return values:
BOOL InitActionLib((int(*)(void*))DefaultUserActionFunction);
Description:
Parameters:
Return values:
void FreeLibLists();
Description:
Parameters:
Return values:
percentage PersonalEvaluate(Action& ToEvaluate, Core& Evaluator);
Description:
Parameters:
Return values:
long PersonalAttitude2Action(Action& ToEvaluate, Core &Evaluator,
BOOL bSetAtt = TRUE);
Description:
Parameters:
Return values:
unsigned short BSFillSaveBuffer(Core ToSave, BYTE *pbBuffer);
Description:
Parameters:
Return values:
Core *FindBSAddress(ID ToFind, Core **Population,unsigned short nPopSize);
Description:
Parameters:
Return values:
ItemScores *FindItemAddress(ID ItemID,ID OwnerID,
unsigned short nPopSize,ItemPtrArr* ipapAllInventories,
unsigned short* nInvSizes);
Description:
Parameters:
Return values:
void BSRestoreFromBufferStep1(BYTE *pbBuffer, unsigned short nBufLen, Core* ToRestore);
Description:
Parameters:
Return values:
void BSRestoreFromBufferStep2(Core *ToRestore,Core **Population, unsigned short nPopSize);
Description:
Parameters:
Return values:
void SetDynamicTACAssumptionPopulation(Agent** Population, unsigned short nPopSize, ItemPtrArr*AllInventories, unsigned short *nInvSizes);
Description:
Parameters:
Return values:
void FreeDynamicTACAssumptionPopulation();
Description:
Parameters:
Return values:
void SetSoloAssumptionMode(BOOL NewSoloAssumptionMode);
Description:
Parameters:
Return values:
void SetSoloActionMode(BOOL NewSoloActionMode);
Description:
Parameters:
Return values:
void SetSuddenChangeUse(BOOL NewSuddenChangeUse);
Description:
Parameters:
Return values:
void SetHistoryUse(BOOL NewHistoryUse);
Description:
Parameters:
Return values:
void SetMaxFailures(unsigned short NewMaxFailures);
Description:
Parameters:
Return values:
void ClearHistory();
Description:
Parameters:
Return values:
void SetGoalItemAcquisitionID();
Description:
Parameters:
Return values: