Annotated objects which drive behavior

Started by
85 comments, last by bishop_pass 20 years, 4 months ago
quote:Original post by bishop_pass

Furthermore, my interest has always been with attempting to create realistic behavior which is interesting to the player. That means focusing and using CPU cycles for NPCs which the character is interacting with. I personally don''t see the value in highly simplistic algorithms which can simulate 1,000 NPCs with little realism.
___________________________________



yes I agree...I''d rather have a small handful of deep, unique, autonomous NPCs than 1000s of cardboard cut-outs...and I still think a smaller number of intelligent NPCs means that the player will get to know them a little. The player would be able to remember an NPC easier. So fewer NPCs would be CPU efficient and good design-wise IMO
Need help? Well, go FAQ yourself. "Just don't look at the hole." -- Unspoken_Magi
Advertisement
This is great.

It seems alot like an expanded version of the AI used in the Creatures series (www.creatures.co.uk). I would take that route: ANNs. This could create amazing gameplay. Worlds could seem so real!

(http://www.ironfroggy.com/)
(http://www.ironfroggy.com/pinch)
(http://www.ironfroggy.com/)(http://www.ironfroggy.com/pinch)
bishop_pass:

"Furthermore, my interest has always been with attempting to create realistic behavior which is interesting to the player. That means focusing and using CPU cycles for NPCs which the character is interacting with. I personally don''t see the value in highly simplistic algorithms which can simulate 1,000 NPCs with little realism."

I never suggested making them more simplistic just more efficient. In other words why not have 1,000 intelligent NPC''s.

"What disturbs me the most among these boards is the constant refusal to seek newer and more complex algorithms under the mistaken belief that a little complexity means the macine will slow to a crawl. Do not shy away from a little complexity! You would be surprised at the horsepower available in today''s machines. One and two gigahertz is almost unimaginable."

What refusal? Isn''t the point of the board to exchange ideas and discuss them? I am stating a different way for you to accomplish the goal of your original post. If you disagree it is more efficient or not, that is your opinion as my statements reflect mine. It is up to u to interpret there accuracy in your mind, and if you find some truth in them then adopt them.

"An object has a functionality and if it is annotated in a data structure, it''s presence can suggest an idea to any character nearby."

That is a statement from your original post. Nowhere in there is a statement saying the data is bound to the object, or how a "suggestion" is accomplished. From reading your first post my mind formulated what is in my previous posts. Seeing that you read my previous posts where exactly is it u see me subtracting from any functionality u suggest? I didn''t, in fact I tryed to solve some of the problems pointed out by u and others in the thread. Since it seems you think I''m taking this thread in a different direction, if u''d like me to stop proposing other ideas as to how to get the same job done then ask.

-potential energy is easily made kinetic-

-potential energy is easily made kinetic-

Infinisearch - I''m taking you up on your stack idea. You''re sticking to it vehemently, and my previous attempts at addressing it seem to have failed. Keep in mind, I am NOT against a stack idea, stacks are very useful things, and could very well apply in at least part of the implementation of what we''re discussing here.

Here''s a recap of the original post:

quote:Original post by Infinisearch
Assumptions: NPC knows it has key to case,


Alarmbell 1. How does the NPC know it has the key to the case? It may seem unimportant, but it isn''t! The NPC has a key object, but in your system, all the key does is yell "I am a key" all the time. There is no knowledge within the key of applying to the diamond''s case. So how does the NPC know? Is the knowledge stored within the NPC? That would create trouble if you later wanted to add more keys, but keep your NPC. You''d have to update the NPC every time you added a key.
Is there some other mechanism by which the NPC "knows" that the key is for the case? If yes, what is that mechanism?

quote:Original post by Infinisearch
NPC ''saw'' or knew the diamond was there in the case, and is currently in a "get the diamond mode".


I''ll assume the NPC "saw" the object ( a "notice" message fired for the diamond), because you have not described another method for the NPC to know about the diamond. Now, you say the NPC is currently in a "get the diamond" mode. Why? Again, it seems like a trivial question, but since the diamond has no properties that it is communicating, why is the thief interested in getting the diamond?
With the implementation I had in mind, the thief would have a "motivation" attribute, set to "acquire wealth", and the diamond would know it was very valuable, so the diamond would tell the thief that it was very valuable, and the thief would decide to take it to satisfy it''s wealth goal. How do you see that working in your system?

quote:Original post by Infinisearch
Operation Push Get diamond, Push Open case, -can i open case:=yes- (get key) Pop open case, pop Get diamond, pop whatever i was doing before i went to get the diamond.


I think you''re missing a step there. The first operation you push is "Get Diamond". The action is blocked by the case around the diamond, which is why "Open Case" needs to be pushed. However, "Get Diamond" needs to remain on the stack until the diamond is actually in posession. Hrm, I''m thinking about this one. After "Push Get Diamond", there needs to be some form of feedback that tells the NPC to try something else first (i.e. push a new action onto the stack). This problem actually applies just as much to the previously suggested system I think. The diamond needs to have an internal state that marks that it is within a closed (and locked) container. But in your system, you''re not asking the diamond for anything, so you''d need another method, possibly a global method that returns obstacles. So "Get Diamond" returns "Obstacle Case Closed", which tells the NPC that there''s a case, which is blocking the action because it is closed. The NPC now pushes the action "Open Case" to remove the obstacle. The world could answer "Obstacle Case Locked", telling the NPC to unlock the case before opening and so on. Is that what you were envisioning?


Last little bit, about processor time:

quote:Original post by Infinisearch
I guess the examine function could be implemented through multiple threshold values, one for each sense but to much processor time is getting eaten up as is so i''ll stop here.


A threshold value adds a single conditional jump. Perhaps two, if you''re working with ranges and fuzzy logic. A conditional jump is not an expensive operation, and branch prediction may make it even less costly, so adding conditional tests does not add any significant processor time (consider that you''re only doing one of these tests per NPC per game tick!).
The real pitfall in this system is having an explosion of the number of objects to be tested, but that''s limited by perceptual ranges. Theoretically, a 1000 NPCs in a world with 1000 objects would equate to 1 million "examines" per game tick, but perceptual ranges will severely limit that number. It depends on how you implement things, but for instance in a tile-based world with at most 100 tiles in a visual range, the total number of "Examines" per game tick is 100*number of NPCs. That''s not really that big a number.

It's only funny 'till someone gets hurt.And then it's just hilarious.Unless it's you.
MadKeithV
Actually i didn''t stick to the stack idea, i said i liked bishops idea because it could easily be made into a priority tree. Where did u mention it? I had read your posts and saw no reference to it. If u didn''t realize it, I am suggesting that the objects only broadcast an ''i''m here message'', and maybe a couple more but not one for each possible use. See my post where i start out with "Bishop I understand what you..." for a better explaination of my suggestion.
The assumptions were stated for the sake of the example, to demonstate the power of the stack as an immediate solution to the diamond problem posed by Diodor. I agree the key topic has to be covered in more detail, but like I said I was just relating the stack to the Diamond example. Keys and locks should both have private data with a ''key'' field. An unsigned int will do, matching ''keys'' will allow a lock to be unlocked. But from the frame of reference of the NPC it either knows nothing or what it was told about the key. So if the NPC has the key in his/her inventory then the NPC associates another value to it. This value could drive its use, so if the NPC looked through its inventory and couldn''t find a key for that case it would either start trying unknown keys or a lockpick kit if it had one.
Why is the NPC in get diamond mode? There are plenty of reasons why, but each possibility is dependent on the context of why the NPC was in the room in the first place. In terms of implementation I had quickly brushed it aside as being a part of the agenda - super agenda system. (where each agenda has a stack.) But yes I had thought about something like your "aquire wealth" motivation. I kinda hint at it when I mention "If the NPC is currently Running for its life, why do all the processing of multiple messages when the NPC isn''t gonna/suppose to notice at the moment". Which implies a prioritizing of motivations, in this case safety.
In handling the open case issue, first let me say that get diamond is pushed because the case is locked. I''ll give the example more details, its like this: The NPC has an immediate agenda, lets say that he was on a quest to get the diamond and only knows that the diamond was in this room and on his way picked up a key. Now the NPC is in the room with the diamond. The key lies in the ''container objects'' i mentioned before. When i said the container objects takes over broadcasts notice I didn''t say its broadcasting i have a diamond in me. The case broadcasts i''m a glass case. The NPC calls its examine function with a parameter of glass case. The function ''will look'' in the glass case. At that point the NPC realizes the diamond is in the case. The NPC is still dealing with the case, and will realize that it is locked. That is why it pushed ''get diamond'' because it realized it had to open the case first.
In terms of CPU cycles, I had meant that in terms of the overall picture. Just because an NPC is not in view/range of the player that doesn''t mean the NPC can just be forgotten. While you could reduce the amount of processing for out of range NPC''s u can''t really cut it to zero. What about off screen objects, rooms with NPC''s in them, how do u differentiate which ones to evaluate and which ones not to. What about sending an NPC on a quest for you the player. What about two NPC''s trying to obtain the same object at the same time yet, and a few other problems. This is why I am sticking to my "just send an i''m here message" theory. All of these are going to require processing time. All these exceptions are going to take storage space, I''m just trying to make things as efficient as possible from the start. Besides the CPU is still responsible for multitasking, drivers, game logic, physics, and VSD.

-potential energy is easily made kinetic-

-potential energy is easily made kinetic-

quote:Original post by Infinisearch
Just because an NPC is not in view/range of the player that doesn't mean the NPC can just be forgotten.


I wasn't talking about the perceptual range of the PLAYER, I was talking about the perceptual range of the NPC...


You mention "context" in your post. Context is something that makes my hair stand on end. It's the Deus Ex Machina of all program functionality discussion.

"Yeah, this does something depending on the context of the caller". Which translates to "I really haven't got a clue but it's got to happen somehow!"

Needing "context" makes managing your NPCs a lot harder. Suddenly, you have to be really specific about quests and objectives. Your thief's objective is to get the diamond, which smells like a scripted event. My thief's objective is to get wealthy, which is also scripted, but allows for a lot more leeway when adding carefully selected objects into the world.


Well, onto a slightly more technical discussion, it's easier than this wishy-washy "conceptual" discussion.


How do I see my version of the system working?

The game ticks - at that point, it goes through the list of NPCs (all entities in the game that can perform actions).

[edit: damn this HTML stuff ]
  • For each NPC:
    • - potentially perceived objects: Get All Objects within Perceptual Range.
    • - For each potentially perceived object:
      • - potential affordances: Check affordance list against NPC's Motivation
      • - for each potential affordance:
        • - check if NPC's attributes allow for perception of this affordance, and to what level
        • -If the NPC perceives the affordance, communicate the affordance at the correct level of perception to the NPC.


The advantage is that NPCs only have to be defined as a set of motivations (that can change) and a set of attributes that have to do with perception of affordances. Everything else is encoded in the objects of the world.



Edited by - MadKeithV on January 23, 2002 6:07:09 AM
It's only funny 'till someone gets hurt.And then it's just hilarious.Unless it's you.
quote:Original post by Gaiiden
[Solving this problem is actually quite easy. If you make the mirror an object that can detect characters within it''s visual range and area, then it queries the NPC whether or not it wishes to be reflected, upon which the NPC can be programmed to reply yes or no.


I don''t really see how that would work, because it implies that every NPC has to know what "reflecting" is, while that is a property of a mirror. To the NPC, it would look like an object is asking it "Can I perform effect 212 on you?".

A possibility would be allowing "exceptions" to be encoded in newly introduced NPCs and objects (keep in mind, I''m assuming you''ve already distributed the original code to your customers, you can''t go back to it). The new "Vampire" NPC has an exception for the action "Reflect". For each affordance an object wants to offer an NPC, it then has to first check to see if that NPC has an exception for this object.

Downside: players can start encoding exceptions in their own characters, and you end up with a legion of non-reflecting invisible player characters


It's only funny 'till someone gets hurt.And then it's just hilarious.Unless it's you.
"I wasn't talking about the perceptual range of the PLAYER, I was talking about the perceptual range of the NPC..."

I wasn't refering to any statement you made about visibilty MadKeithV, i was saying that off screen NPC's need processing time too. It was in reference to CPU cycles, and while yes perceptual range will limit the amount of objects processed, its going to take processor time to determine whats inside each NPC perceptual range. When I said context, it translates to relation to the current agenda. In others words what if the player sent the NPC a quest to get this diamond, what if the NPC just happened on to it. The power of the annotated objects has to work either way. So I left it as context for the pupose of abstraction. You said it yourself we don't want scripts. I don't know what I should post in terms of technical details seeing how i'm on the 'send an i'm here message' only viewpoint. It's Bishop's thread and he thinks multiple messages is the way to go so I'll help out with your system if u want.

EDIT -What exactly do u mean by 'tick'

-potential energy is easily made kinetic-

Edited by - Infinisearch on January 23, 2002 6:44:15 AM

-potential energy is easily made kinetic-

quote:Original post by Infinisearch
EDIT -What exactly do u mean by 'tick'


By "tick" I mean the minimal unit of time in the game. For instance, attempting an action takes one tick. A single turn in a turn-based game is a tick, while in a real-time game, a tick probably amounts to a single frame of the animation.


Off-screen NPCs do need processing, I actually make no distinction between onscreen and offscreen NPCs. You could make that distinction though, if you built your game carefully enough. Really, all that matters is what the player sees (or better "perceives", because you could have a sense of smell and sense of hearing in the game as well). If you can make everything else up as you go along, you're fine! That really limits the amount of processing that you have to do. However, doing it correctly is hard, so for now, lets just say that it's a "living world", and everything goes on around you, regardless of you being there or not.
Figuring out what is "in" your perceptual range is not really an issue with regards to CPU usage, because it has to be done for ALL forms of even remotely intelligent and realistic AI. There is nothing more annoying than the bot-that-sees-through-walls, because it does not take into account perceptual range.


What do we need for certain? Two types of objects are in the system: Active Objects (like the NPCs) and Passive Objects (like the Diamond). The first optimisation is to only look at the world through the eyes of the Active Objects. They are making our world change, without them, nothing would happen. So, we HAVE to do something for each of the Active Objects for every "tick" of the game. I'll say turn from now on, instead of tick - simply put, each active object gets to take one turn in one turn of the game.

Each Active Object must have a goal. If it doesn't have a goal, it won't do anything, and would then be a passive object. Goals can change, but for now, just assume there's only one goal to reach. When it's the Active Object's turn to do it's processing, it wants to achieve its goal, or at least attempt to advance towards it.
One way of doing so (the way that seems most "logical" to human reasoning, because it's how WE work), is to examine everything that you can perceive (and check your memory, but lets say these active objects don't have memories, they are dumb), and see if there is anything there that will help you achieve your goal. The problem with this reasoning, is that each active object must have a huge database of objects that can occur in the world, and what they are good for. This database has to be different for each NPC, because not everyone knows everything. It also makes it hard to deal with "drop-in" objects, by which I mean objects that you add to the game later, when you've already shipped it to your customers. If you only have apples and oranges, and suddenly you decide to add bananas, then you must have had the forethought of including a "food" attribute in the game, or none of our active objects will realise that you can eat a banana.
The "food" attribute is really an affordance, one that says "You can eat me". Using the attribute makes life hard though, because a hungry Active Object will have to check all the objects around it to see if they have the food attribute. An object cannot "hide" its food attribute either - for instance, if a Caveman from the northern wastes was hungry, he probably should not recognise the banana as food. With affordances, and a simple "geography" or "culture" attribute in an Active Object, that's easy. The Banana would check to see if the Active Object's geography allow it to know that a banana is food. With simple attributes, the Caveman would have to "know" that it "doesn't know" the banana is food. That means, it had to know about the banana beforehand, which it didn't, because you only introduced it in Service Pack 1 ( ).
One way of solving it would be to add the bananas to the Active Object databases when you install Service Pack 1, but only add the bananas to the databases of Active Objects that are supposed to know them - but that's a lot of additional data which is redundant, because a banana remains a banana, regardless of whether you know about it or not.

Hrm, I don't know, perhaps I should make a detailed design of what I'm thinking of, and try to implement it!



Edited by - MadKeithV on January 23, 2002 7:15:23 AM
It's only funny 'till someone gets hurt.And then it's just hilarious.Unless it's you.
How do u envision the following for the system? This is to everyone following this thread.

0.Can NPC''s Learn?
1.Are ''uses'' of objects in the code or data domain of the game?
2.Is skill for ''Active Objects'' in the code or data domain? Since there is skill in different things what is the bestway to store this?
3.''Active Object'' memory? Lets say an NPC has to go get something at its house. How do it know where its house is?
4.What PC variables do u see coming in handy? Health, Hunger, Money,Strength...
5.Interaction... How is the player going to interact with NPC''s
6.How to handle cooperation between NPC''s?
7.How to handle deadlock situations?

---------------------
bishop_pass

For your ''agenda'' structure I suggest you start out with multiple roots like you have it but some need to be static. One for each of the PC ''need'' variables like health, hunger, and money in addition to a quest root. Have priorities attached to each root. This way the NPC can prioritize one agenda tree over another. For example getting food over the quest at hand.

-potential energy is easily made kinetic-

-potential energy is easily made kinetic-

This topic is closed to new replies.

Advertisement