Installation & Quick Start Guide

I have tried to keep this as easy as possible to allow existing projects to adopt the system. If you have any questions don't hesitate to email me at bbull@memeticai.org or post on the Memetic AI Forums.

When using an ERF you should...

When you get the Memetic AI Toolkit as an ERF, you will need to do a few things to get started.

  1. Create your new module.
  2. Import the memetic ERF.
  3. Setup the cached scripts.
  4. Attach cb_mod_load to the modules OnModuleLoad script callback
  5. Add a waypoint named "MemeVault" in a private area.
  6. Setup a memetic NPC.
  7. Optionally, setup up a reuseable trail system.

When starting with a sample module...

The example MemeticAI modules are provided to test the system and show of a few features new to this version of the toolkit. You may not want to start your own project with a memetic module. It generally contains extra files, example areas, and occasionally sample conversations.

Of course, you start from these modules the scripts are setup and areas and libraries are registered. You will still need to set up your own memetic NPCs and


More Installation Details

Script Caching

Bioware has recently introduced a new feature - script caching. This is a highly recommend feature that greatly improves the performance of the memetic toolkit. To enable script caching you will need to add each script that you want cached.

If you are using a premade memetic module these scripts will already be setup. If you are using an ERF you will need to add the all the default memetic scripts that are frequently called. It is generally recommended that you add each file with the prefix cb_ and lib_. These are the callback scripts and the libraries with the memetic functions that frequently called.

As you write your own libraries with your memetic functions and objects, remember to add these to this panel.

Module Startup Script

There is a small amount of setup to be done when a module starts up. To do this, the script, cb_mod_onload, needs to be added to the OnModuleLoad module event.

Within this script a number of things are done:

  1. Areas are registered for the optional trail and landmark system using Me

  2. The landmark system is initialised and the routing table is built.

  3. Libraries are loaded using MeLoadLibraries().

  4. Emitters may be defined, and attached to objects using MeAddEmitterByTag().

Setting up a Memetic NPC

Every NPC needs to have its callbacks replaced with memetic callbacks. These memetic versions all have the prefix cb_. They have very little code inside them. It is there job to call functions inside of your libraries.

Since there are several callbacks, it may be tedious to setup a memetic NPC. Instead, you may want to download the Memetic Callback Script Templates. These are premade sets of callbacks that can be attached by clicking the "Load Script Set" button. If you are going to create NPCs without templating them, this is very handy.

Memetic NPCs do not require a heartbeat script. In fact it is recommended that you don't attach cb_heartbeat. But also bare in mind that some day you may add a "behaviour generator" that requires a heartbeat callback. At this time, the toolkit does not ship with any of these and it's probably best just to leave it out. This will give you a performance increase.

Finally, Memetic NPCs are configured in much the same way a Bioware NPC is. You can add items, change abilities, create waypoint sets and modify their spawn script to adjust their behavior. The biggest difference you'll see right away is that you assemble their behavior by assigning them to a set of classes. No, not D&D classes, think of these as roles, or behavior traits.



While there are advanced ways to tweak your NPC's class, the common way is to set variables on the global variable, NPC_SELF. Avoid setting variables on OBJECT_SELF. In the future you will be able to detach an NPC's behavior model from one creature (OBJECT_SELF) and reattach it to a new creature (a new OBJECT_SELF). This will eventually allow NPCs and all of their state to be saved.

Some Frequently Asked Questions

What's the performance overhead - is this really processor intensive?

The Memetic AI Toolkit is designed to be modular and well engineered. Unfortunately generalized systems risk becoming over-engineered. When this happens, they and suffer from two drawbacks: first, they have additional data overhead to give you extra features (like variable inheritance) and second, they suffer from some CPU overhead to become modular (via. dispatchers, simulated pointers, etc.)

Unfortunately it's difficult to assess how bad this really is. The Memetic AI Toolkit does not use any heartbeat scripts - there is no polling and all NPC behaviors are executed efficiently by using the action queue as a main loop. Places where there are large amounts of shared data - like combat tables - are stored on shared class objects. So in many ways, the memory usage of the CODI combat AI is lessened by using the class system.

Most design decisions regarding efficiency boil down to CPU vs. memory. If you want the system to be less intensive use less loops, cache and precompute wherever possible. The Memetic AI Toolkit was written to preserve CPU at the expense of memory. Ultimately you'll have to try it yourself and decide if your server is fast enough to handle two hundred NPCs acting out their daily lives in real time.

At this time, it meets my performance needs and hopefully it will be sufficient for yours. If you find areas of apparent inefficency, or have test cases where the performance is obviously sub-par by all means post on the forums - it's the best way to help this project succeed.

What are libraries and why are they initialized?

Libraries are an enhanced to Bioware's ExecuteScript() function. They allow you run a specific function inside of the script, instead of just main(). Unfortunately to make this work properly every function inside the library must be registered. If look inside of every file named lib_ you will see a main() that has two parts to it: registration and dispatch.

When you load your library, the main() function in run with a global variable telling it to register the functions inside the script. Later when we want to call a function in the script, another global is used to specify which function to call. The main() function dispatches control to one of your registered functions based on this entry point variable.

Libraries are incredibly handy and are used through the system. It would be amazing if Bioware implemented ExecuteScript(string sScriptName, string sFunctionName, object oArgument) -- but they don't. So we make do.

Finally, the Memetic AI Toolkit is also an object-oriented language. NWScript, by default is an object-based language - you an manipulate objects but you cannot create custom object data structures. The Memetic AI Toolkit ships with several convenience functions for declaring a function in a library that is actually a member function to a memetic object. While this isn't important to a user, it is a crucial feature for memetic developers.

Let's just say that libraries are a useful, efficient extension of the ExecuteScript() and that you should fall in love with them now and ask Bioware for native support in NeverwinterNights 2.0.

What's a class; how do I configuring a class-based NPC?

A class is an object-oriented programming term - if it makes you feel any better call it a "role". Every memetic creature can belong to several classes. When a class is first declared, an invisible shared class-object is created. This hold variables that are shared amongst all the memetic creatures belonging to that class.

Classes also simplify the process of defining the modular behavior of your NPC. If you look inside of lib_classes you will see several examples of how to write a custom a class -- it's very easy. You will need to understand how to add a function to a library and register the name of the function. This is documented inside of every library.

Each PC has a spawn script (s_rat, s_boy, s_fighter, etc.) within this script you can manually add memetic objects to configure how the NPC behaves, or you can make the NPC belong to a given class. Once you have done this, you will need to refer to the class documentation to see what variables you can set on the NPC to configure its behavior.

I know this sounds a bit vague - but that's what a general, modular system give you: flexibility. Really the principle is sound. You write reusable classes for your NPCs. You post them to the Memetic AI website and document them. Other people take your classes, gradually building NPCs that act more and more realistic.

What's a trail or landmark; how do I use them?

Presently most module makers lay linear paths of waypoints using an NPC's tag. The Landmark & Trail System allows you to create a series of waypoint that meet at a "landmark" junction waypoint. One landmark from each area is registered, then the system is asked to build an internal routing table.

This process can be extremely lengthy as the algorithm is complex -- but very useful. Once the routing table is built, NPCs can be told to go to a destination landmark. They will follow the trail system, picking out a route that suits them best. In the future there will be route selection functions and convenience functions to at bias to one path or another. This will allow you to have merchants using safe trails, and thieves following dangerous trails.

Overall the trail system is intended for persistent worlds where a large number of NPCs will need to reuse pathways and the designers cannot afford to implement hundreds of waypoints. Once the trail and landmark waypoints are arranged, any NPC can use them however they see fit.

Please refer to the complete user documentation on how to build the trail system. At the present time there is only one trail meme (behavior) i_gotolandmark. This is an area that will be improved in future releases.

How do I get NPC conversations to work?

Because of the way dialogs are implemented, you must do a small amount of work to allow your NPCs to handle conversations properly. Unfortunately there is no way around this, otherwise your NPC will not resume his behavior once a conversation ends.

This is probably the single largest headache if you are moving your current persistent world system to use the Memetic AI Toolkit.

When a conversation ends normally you should call cb_talk_end. If the user aborts the conversation you should call cb_talk_abort.

The Memetic AI conversation system offers a few optional features, including conversation timeouts and custom busy messages when an NPC is already talking to another player.

What causes a memetic NPC to go "braindead"?

If ClearAllActions() is called on the NPC, or if the game engine clears an NPC's action queue - the NPC will stop working until it receives and event, engages in a conversation, is attacked, or otherwise has a callback called. The NPC calso also be restarted by calling MeRestartSystem() on the NPC. Since there are no heartbeat scripts and there is no way to identify when an action queue is cleared, there is no alternative. I have made a feature request to Bioware with five alternative solutions to this problem. Mostly notably, I am hoping that I will eventually by able to call ActionDoCommand() with a flag to prevent an action from being removed from the action queue.

Do my NPCs stall or stop working when players leave an area?

As of v1.30 and the SoU expansion pack, a new function call - SetAILevel() allows us to work around NPC's scheduler deficiencies. NPCs no longer go briandead when players leave and area. Fortunately this also opens up the possibility for an adaptive system for change the NPC's CPU usage.

Do you use the database for anything?

No. In coming releases I will be providing functions to save objects (and the variables on the object) as well as NPCs. This may also include an asynchronous transaction/committal system that will support both existing database systems.