Implementing memory in RPG agent
Could anyone out there give me some ideas on how to implement memory for a RPG NPC\agent? I was thinking about storing the values as an array, but I have got stuck. Basicly I make a call to see what just happened to the agent and store it in the array, occasionly erasing stuff from the memory. But I'm not even sure if I have that right. Sorry, I can't post my source right now, I might later. Ideas are good. I need them even if they aren't exactly like what I have posted here, like I said I'm stuck... did I mention that there is a deadline on this thing? Thanks guys. Oh, yeah, one last thing, I am using C++ only.
My Kung Fu is stronger.
neo88
[edited by - neo88 on November 25, 2003 4:21:38 PM]
My Kung Fu is stronger.May the Source be with you.neo88
A very basic memory could be implemented in an array, although it wouldn''t be very efficient for searching. Instead, you might think about creating a specialised data structure to house the sorts of memories that your agent can store. For example, you might consider classifying things that can be remembered into different classes; perhaps ''people'', ''events'', ''places'', etc. Then, your memory would have at least one attribute, being its class. So, for example, your agent, Penny, met Bob at the pub for a drink. The next morning, Penny might have the memories:
Memory 1
Class: event
Type: Social Gathering
Date: Monday 24th November
Time: evening
Memory 2
Class: people
Type: Bob
Date: Monday 24th November
Memory 3
Class: place
Type: Pub
Date: Monday 24th November
Time: evening
Now, if you were searching memories, you might want to find out what you did yesterday, so you search your set of memories for entries with a date of yesterday, finding these three entries. Alternatively, you might want to remember all of the people you have met in the past 5 days... or perhaps remember where you were at 8pm last night? Get the picture.
One way to implement this sort of idea is via a database that can be indexed by the attributes of its entries.
The problem you face is that such a database would fill up very quickly... that you''d have to lock the database while performing searches, meaning your agents couldn''t really interact with the world during this time (since they''d get new memories to put into the database) and your search time is going to scale with the amount of knowledge held.
Well, it''s something for you to think about.
Cheers,
Timkin
Memory 1
Class: event
Type: Social Gathering
Date: Monday 24th November
Time: evening
Memory 2
Class: people
Type: Bob
Date: Monday 24th November
Memory 3
Class: place
Type: Pub
Date: Monday 24th November
Time: evening
Now, if you were searching memories, you might want to find out what you did yesterday, so you search your set of memories for entries with a date of yesterday, finding these three entries. Alternatively, you might want to remember all of the people you have met in the past 5 days... or perhaps remember where you were at 8pm last night? Get the picture.
One way to implement this sort of idea is via a database that can be indexed by the attributes of its entries.
The problem you face is that such a database would fill up very quickly... that you''d have to lock the database while performing searches, meaning your agents couldn''t really interact with the world during this time (since they''d get new memories to put into the database) and your search time is going to scale with the amount of knowledge held.
Well, it''s something for you to think about.
Cheers,
Timkin
quote: Original post by neo88
Could anyone out there give me some ideas on how to implement memory for a RPG NPC\agent? I was thinking about storing the values as an array, but I have got stuck. Basicly I make a call to see what just happened to the agent and store it in the array, occasionly erasing stuff from the memory. But I''m not even sure if I have that right. Sorry, I can''t post my source right now, I might later. Ideas are good. I need them even if they aren''t exactly like what I have posted here, like I said I''m stuck... did I mention that there is a deadline on this thing? Thanks guys.
My Kung Fu is stronger.
neo88
Yeah, really depends on how much stuff you need them to remember, as it will get extremely large (which means slow searching) quickly.
Like previously suggested, you could store most of this stuff in a database with a class and/or type, date (if required), and time (if required), and possibly another flag for any extra info that is required for that specific type (or a set of flags).
struct ObjectMemory_C
{
unsigned char Class;
unsigned char Type;
unsigned long Date;
unsigned long Time;
unsigned long Misc[4]; //Store misc stuff for specific things
};
Then you can either use some sort of database in file, use an std::vector for storing these in memory (if you don''t have to much to remember). The smaller the structure, the smaller memory/disk space it will use, so if you don''t need a long for time, use a short, or same for date, use a short, and as for Misc, figure out what the most data that could be used is, and use that (making it variable size is an option if working from memory, but I wouldn''t do that in a database file, as it''ll slow it down more than help I think).
Wow, had brain overload there for a minute. What I have right now kinda sorta looks like the structure that Ready4Dis just posted. What I have is this:
int memory[100]; // can hold 100 memorys in all.
int set_flags[4]; // tells when to erase stuff from the memory
// array.
int dmemory; // deletes the memory-do every so many cycles
if (int set_flags = 4) {
// agent dies
getEvent();
getTime(); // other calls
AgentClose(); // Another call, this one is in the same class.
return memory; // should return NULL
} // end if
// This is all in class agent.
So, I just do this for a while ( the if loops ). I will post the complete source if I think it''s needed. The problem that I see with this is that you could get some very interesting memory problems if the array doesn''t do what it''s supposed to. The other thing is: the agent needs to be able to acces this array really fast when it''s fighting because if it''s fighting a player it has fought before, I want it ( the agent ) to be able to react better to the players strategy. It also needs to be able to delete the array really fast if it needs to. The main classes for the AI I have right now are: ArtInt.hpp, fear.hpp, agent.hpp, and PlayerAi.hpp. The ArtInt class defines the basic stuff like getEvent() and getTime(); etc. The others aren''t done yet. I do have a .doc file for them that I could post. Could I do this better/differently-I really want to be as CPU effecint as possible. Thanks guys.
My Kung Fu is stronger.
neo88
int memory[100]; // can hold 100 memorys in all.
int set_flags[4]; // tells when to erase stuff from the memory
// array.
int dmemory; // deletes the memory-do every so many cycles
if (int set_flags = 4) {
// agent dies
getEvent();
getTime(); // other calls
AgentClose(); // Another call, this one is in the same class.
return memory; // should return NULL
} // end if
// This is all in class agent.
So, I just do this for a while ( the if loops ). I will post the complete source if I think it''s needed. The problem that I see with this is that you could get some very interesting memory problems if the array doesn''t do what it''s supposed to. The other thing is: the agent needs to be able to acces this array really fast when it''s fighting because if it''s fighting a player it has fought before, I want it ( the agent ) to be able to react better to the players strategy. It also needs to be able to delete the array really fast if it needs to. The main classes for the AI I have right now are: ArtInt.hpp, fear.hpp, agent.hpp, and PlayerAi.hpp. The ArtInt class defines the basic stuff like getEvent() and getTime(); etc. The others aren''t done yet. I do have a .doc file for them that I could post. Could I do this better/differently-I really want to be as CPU effecint as possible. Thanks guys.
My Kung Fu is stronger.
neo88
My Kung Fu is stronger.May the Source be with you.neo88
First of all, please don''t take this as an attempt to put you down. I am simply stating a potentially useful opinion.
I don''t really understand the purpose of this, maybe you could give us some information about the type of game you have in mind (A perfectly good system for a FPS might be useless in a MMORPG)
I think you should reconsider having every agent keep seperate memory. Maybe you could have a central memory bank and have each agent have certain access priviliges to it, according to its experience with the player. This way agents will have access to enough information to make a more or less accurate assessment of the player''s actions (The last 100 moves might not be quite enough. and for each agent to keep the last 1000 moves of each player might be extremely wasteful)
What Is the information you want to keep anyway? Do you want to reanalyze the player''s actions to deduce his next action everytime? Maybe you can maintain some meta-information from previous analyses?
For example you can keep an NN for each player that tries to guess their next move. have it train online, then associate a certain degree of familiarity between an agent and a player that affects the possibility of the agent to use that NN.
This of course might not work if you want the memory for another purpose. Which brings me back to my original point. Why do you want this memory?
Peace Out!
I don''t really understand the purpose of this, maybe you could give us some information about the type of game you have in mind (A perfectly good system for a FPS might be useless in a MMORPG)
I think you should reconsider having every agent keep seperate memory. Maybe you could have a central memory bank and have each agent have certain access priviliges to it, according to its experience with the player. This way agents will have access to enough information to make a more or less accurate assessment of the player''s actions (The last 100 moves might not be quite enough. and for each agent to keep the last 1000 moves of each player might be extremely wasteful)
What Is the information you want to keep anyway? Do you want to reanalyze the player''s actions to deduce his next action everytime? Maybe you can maintain some meta-information from previous analyses?
For example you can keep an NN for each player that tries to guess their next move. have it train online, then associate a certain degree of familiarity between an agent and a player that affects the possibility of the agent to use that NN.
This of course might not work if you want the memory for another purpose. Which brings me back to my original point. Why do you want this memory?
Peace Out!
I want the memory to be able to remember what event has happened in the past: for instance, the agent has been attacked by the player, then it was hit several times in the legs. It stores these as an event. The agent can then access the memory array when it needs to. This should be able to help the agent react better to the player next time it meets him. Like I said I really need help here, so anything is much apperciated. The events by the way, are a class object ( as I tried to illustrate in the snippet of code in my previous post ). So you make a pointer to the array to access the event ( within the last 100 ) that you want the agent to remember. I do like you''re idea of a central memory bank that all of the agents can access. Could you have many instances of one agent though. I mean just create one agent and have it make copies of itself. Kinda like Agent Smith. Then you would only have one memory array.
My Kung Fu is stronger.
neo88
My Kung Fu is stronger.
neo88
My Kung Fu is stronger.May the Source be with you.neo88
For this to scale, you need to classify events as they happen, and stick them into the memory bank as pre-classified, pre-cooked, pre-processed events. Then you can easily search this memory bank whenever necessary.
Thus, an NPC agent that knows to run away from entities that has previously attacked it, would have a list of the last N attackers (if you like limiting things, else make N infinite :-) Whenever attacked, it would put the entity id of the attacker on the list. In the "onNoticingNewActor()" notification to your agent, it would check whether the list of baddies includes this actor, and if so, set its action mode to "run away from this dude."
Trying to go over-general will result in a very slow, cumbersome system that''s hard to debug and nobody likes. It''s much more useful to have a number of specific, configurable strategies, which each take in and process input data specifically for it, and then combine these strategies in a component-based way.
Thus, an NPC agent that knows to run away from entities that has previously attacked it, would have a list of the last N attackers (if you like limiting things, else make N infinite :-) Whenever attacked, it would put the entity id of the attacker on the list. In the "onNoticingNewActor()" notification to your agent, it would check whether the list of baddies includes this actor, and if so, set its action mode to "run away from this dude."
Trying to go over-general will result in a very slow, cumbersome system that''s hard to debug and nobody likes. It''s much more useful to have a number of specific, configurable strategies, which each take in and process input data specifically for it, and then combine these strategies in a component-based way.
enum Bool { True, False, FileNotFound };
I think we may be getting in to too many implementation details and assumptions here. For instance, if he has only a hand full of agents (for instance, 30 or so), then doing heavy recording and analysis may not be a problem.
Depending on the frequency of events, a fairly general system may not be a performance problem at all. What sort of a system would you consider too general? I am assuming all events to be tracked would be hard coded, but the systems to store them may be fairly general.
Timkins example seems extremely practical, yet very general.
Depending on the frequency of events, a fairly general system may not be a performance problem at all. What sort of a system would you consider too general? I am assuming all events to be tracked would be hard coded, but the systems to store them may be fairly general.
Timkins example seems extremely practical, yet very general.
I think we''re moving away from the point here. Basically he wants to experiement in AI and memory, make it simple to start with. Make it simple and make it work. It''ll be slow and unoptimal, but then when you get to version 4 of your system, you''ll be realising why the other posters have suggested certain things. Not only why, but you''ll have an idea of how you''ll implement them yourself into your existing code.
You''d probably want to look at things such as: "the player hit me twice with a stick, causing mostly damage to the body; but the gun caused more damage to my head with a single shot so I''ll avoid that more"
The memory here would be:
Weapon / Part / Damage Ratio
Stick / Body / 50
Gun / Head / 100
You probably wouldn''t need to keep track of each individual hit on the head, just a counter. As hplus said, classify them as they happen.
You''d probably want to look at things such as: "the player hit me twice with a stick, causing mostly damage to the body; but the gun caused more damage to my head with a single shot so I''ll avoid that more"
The memory here would be:
Weapon / Part / Damage Ratio
Stick / Body / 50
Gun / Head / 100
You probably wouldn''t need to keep track of each individual hit on the head, just a counter. As hplus said, classify them as they happen.
downgraded; If it is useful information, why not remember where they were hit? Basically, the point is to design this to do what you need, and not worry about performance until it becomes an issue.
Systems I have worked with have 30+ individuals updating at a time, with each storing perhaps hundreds of facts. Storing and using this information was not a problem at all; it wasn''t even close to being a bottleneck.
Just make it work. Don''t worry about constraints or performance until then.
Systems I have worked with have 30+ individuals updating at a time, with each storing perhaps hundreds of facts. Storing and using this information was not a problem at all; it wasn''t even close to being a bottleneck.
Just make it work. Don''t worry about constraints or performance until then.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement