|
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.
|