ID:2217085
 
You may read this and think it's a bad idea or that I am raising the bar way too high for myself and maybe you're right, nevertheless, I'm determined to implement a certain system to my project and your input would be very much appreciated. You see I've been on BYOND for quite a while and only now am I attempting to learn the coding side of things.

I know bits and bobs and I'm very eager to learn, however it's incredibly difficult for me to learn these things myself or from snippets that aren't exactly broken down or explained in laymans terms and so I am in need of a little nudge in the right direction.

My Objective - Relatively Smart Chat Bots

Code:
    for(var/mob/M in view()) // if mob is in view
if(findtext(msg,M.name)) // and their name is said
for(var/t in chatchecker["Openers"])
if(findtext(msg,t)) // if they are told an opener
if(istype(M,/mob/NPC/A)) // and if they are NPC A
sleep(3)
I << "<B> [M.name]</B> replies: Hello"// they will respond
return

for(var/mob/M in view())
if(findtext(msg,M.name))
for(var/t in chatchecker["HRU-Queries"])
if(findtext(msg,t)) // if they are asked how they are
if(istype(M,/mob/NPC/A)) // and if they are NPC A
sleep(3)
I << "<B> [M.name]</B> replies: I'm fine thanks, you?"// they will respond
return

During runtime this will look something like...

Nakashima_Taiki says: Hi A
A replies: Hello

or

Nakashima_Taiki says: How are you A?
A replies: I'm fine thanks, you?


Problem description:
If I use an opener the NPC will reply, if I ask them how they are they will reply but if I ask both in one sentence the NPC will only reply "Hello" why is this? and what can I do to fix this issue?


Bonus Problems, Issues & Queries (You don't have to help with this part)
I'm trying to figure out how I would be able to ask an NPC about another NPC, i.e "Hey A, have you seen B around?" I can't work out how to do it without it finding B's name in the text and triggering B's response when in view... any tips?

Thanks in advance,
- Nakashima_Taiki


P . S
If any rules were broken during my post or the text stretches the screen I apologise, this is my first post.
That's because you have a return placed there.

About finding B. "Have you seen B?" for/var/mob/M in world() if(M.name=="B") done.
Wow, I really can't believe it was that simple aha, thank you!

As for finding B, I'm a little lost... sorry I'm a newbie.
I don't understand that properly, I'm doing something totally wrong...

 for(var/mob/M in view()) //for mobs in view
if(findtext(msg,M.name)) //that have their name said
for(var/t in chatchecker["WhereIs-Queries"])
if(findtext(msg,t)) // and who are asked a where question
for(var/mob/M in world()) //about a mob in world (This line is wrong, duplicate definition and in world is invalid)

I feel like I'm going down the wrong route for that

also mob names aren't static if that makes a difference I'm going to add in a name generator (and appearance generator) after because I want npcs that die to be replaced by npcs that have the same traits.

In response to Nakashima_taiki
No problem.

Sorry typed in that comment way too fast. for(var/mob/M in world). 'world' doesn't have parenthesis after.
I'm trying to figure out how I would be able to ask an NPC about another NPC, i.e "Hey A, have you seen B around?" I can't work out how to do it without it finding B's name in the text and triggering B's response when in view... any tips?

I think you may want to be less specific in what you want to do and/or how you do it.

If you absolutely have to have NPCs trigger via key text phrases, and also want players to be able to ask about certain NPCs -- that also have non-static names -- you are either going to have to:
  • Simplify AI triggering to use preset options of what you can do once you interact with it. For example, instead of asking (and hoping it's the right trigger phrase), "Where is [insert NPC name]?", a HUD box of some sort would appear with the NPC's greeting and options of conversation, e.g. "Where can I find [NPC name]?".
  • Setup NPCs to have some sort of unique id/tag attached to them so that other NPCs could refer to them not by name, but using their tag, without error. For example, if one type of NPC is always a Weapons Merchant, then their id/tag would be related to that because that's their function.


I've never made AI (in full at least), but it's something I'm going to have to do myself soon. My opinion is that focusing on making AI "smart" can easily turn into over-complication and it's generally unnecessary. What you really want is useful AI as it pertains to their function. With that said, I'd recommend going with approach #1 explained above. I've seen this method used in large games such as WoW and it's simple but effective.
@NSBR thank you!

@FKI thanks for that, I read it at first and was gonna moan that I didn't want to have to do it like that but to be honest it seems like the best way to go I guess.

I wanted to increase immersion as players type to other PCs so I thought they should be able to type to NPCs as though they were another player, I even had a way to make it easy for players to know commands but... more and more problems arise like if a NPC was called Hillary for example and I said Hey, Hillary it would trigger a greeting response twice. I solved that part but it made me realise that even though approach #1 is less immersive you were correct, overall it's a whole lot easier.
for/var/mob/M in world() if(M.name=="B") done.

Don't do this. There is never an instance where you should be searching through world for a specific NPC.

This is why tag exists.
Sorry Ter13 I know this is a bit late, I don't really have an understand of tags to be honest with you. Could you elaborate a little please?
searching for a mob in the world has to search through every single area, turf, object, and mob in the world to find the correct one.

for(var/mob/M in world) isn't just looking through every mob. It's checking every object in the world first, to see if it's a mob, and second to see if M.name satisfies your condition.

Locating a mob by its tag is significantly faster. Assuming 100 tagged objects, the maximum number of objects that locate("tag") would have to iterate over would be 7, thanks to the magic of binary search algorithms.


Tag is a variable that can be set to a string. You can then call locate("(tag here)") to get a reference to the object with the matching tag. This way, you don't have to loop over every object in the whole world.
To make a AI do what you want to do, you have to put your mindset on what you want the ai to do.

Basically, in a fight game (Mortal Kombat being the best example of this) when you block, the AI knows you block, so it will go the bottom (EX: A sweep kick.)

If you crouch and block, the AI knows to jump up and kick (Bypassing the block.)


what im trying to explain is simplely how a AI works. I have my own ways of doing AIs and things like this.

For your case,
So... About 12/13 weeks ago (...or possibly even before then?), I had guests over at my place & we had quite a few drinks between us and long story short, after being a little careless I ended up breaking my laptop, since then I've basically had to start the code again from scratch. -It Hurts- I've rebuilt quite a bit of the code now, it's still missing something I had in it before but I'll figure it out again soon enough. This time around I'll definitely going to get the coding of these NPCs down, though.

@Ter13: Thank you that is definitely the better option, I will begin looking at tags, @FKI mentioned them as well so I'm pretty sure they will be effective, is there anything else in particular that I might want to look at for my overall goal?

@DandomFighter: I think I understand what you mean, so the NPCs need to know if you are speaking to them in particular or just mentioning their name rather then just replying when their name's mentioned, right??




In response to Nakashima_taiki
Right