Possible new features for SDR - need advice

Post » Wed May 11, 2016 8:21 pm

Hi all,



So over the years, I have been asked many times to build in the following features into SDR:


- Guards following people that have their weapon out or are sneaking

- Fresh kill / dead body alerts

- Near miss alerts

- Combat alerts



All of these things involve working with AI Packages, which I know next to nothing about and find very confusing. I've read through the CS.elderscrolls.com wiki, but I still don't really get what I need to do.



One of the issues is that all of these features are provided by other mods, and they all have strict requirements that they don't want anyone using any of their code. I can respect that.



That puts me in a bind, because I have to reinvent the wheel, and I can't really use the other mods as a template. In fact, I have intentionally avoided looking at them.



I'm not opposed to adding these features to SDR - especially since it would mean fewer additional .esps in my own load order. But I'm going to need some help from folks who are AI Package experts.



The way I see it, there are lots of challenges to doing this, which is why I have been avoiding it:



1. How does an "alert" work. For example, in the last three items, a fresh kill, near miss, or being in combat, could all result in a "we're being attacked" alert. Would that be some sort of spell? Would it be a function script? Presumably, there would have to be some sort of radius in which comrades could hear the shout. Would the radius be fixed, or would it be based on the "personality" of the shouter? How do I determine who hears it? And if someone does hear the shout, how do I determine how they react?


2. Let's say someone does hear the shout, would they fight, flee, wander, search? Presumably, they would run a find package in which the target was the person who shouted. Once they arrived, what would they do then? Just let things progress naturally? If he shouter is in combat, would they automatically go into combat, or at least alert? Or would they go into find mode and try to find the combat target of the shouter? What happens when they engage in combat?



3. How in the world do I determine a "near miss"? I can't even determine when a sword hits a wall (I wish I could, because it would add a detection bonus to finding the striker). When there is a near miss, does the target automatically detect it, or should there be an intelligence check. If they make their intelligence check, what do they do next? Presumably go into an alerted state, but I don't know how to do that either, unless it's the SetAlert function (which I guess makes sense). But all that does is draw their weapon. Is that enough? Do I add a wander package or a find package, and how does that work?



4. If someone is in combat, do they keep "shouting", or is it just when they first engage? Or maybe it's every few seconds?



5. If someone comes across a dead body, how do I determine the reaction? What if the person is already in combat, I would assume that they probably wouldn't care anymore. How do I track who has died and who has seen the dead body? If you've already come across the body before, there shouldn't be a second reaction.



As you can see, lots and lots and lots of problems. And frankly, it's not something I really want to tackle, or have time for.

User avatar
Matt Bee
 
Posts: 3441
Joined: Tue Jul 10, 2007 5:32 am

Post » Wed May 11, 2016 3:23 pm

IMHO:



1) An alert should give a big boost to the actor sneak skill, as it become aware of the threat and pay attention to everything around him.


If the boosted sneak skill allow him to detect an enemy (which may be the killer or the archer/mage who fired), he will immediately start combat with him, else it would act depending on its confidence/health: with high confidence, it will start to actively search around for the enemy; with low confidence it would take cover somewhere. In both cases, he will shout to call for help and reinforcements. Another factor may be the difference between his level and the killed actor's level (if a strong actor is killed, a weaker actor, may realize he has even fewer chances, if he's alone, and may choose to hide and stay quiet to avoid being detected by the killer).


If you need a radius, an area spell casted on the shouter is perfect and the radius may depend on the race. You may check the shout with the detection formula, so only the actors who can actually hear the sound will hear it. The reaction? Actors who hear the sound will enter in alert mode (but not combat mode) and will run toward the actor who shouted to see what's happening, then everything happens as in my idea above.



2) If the actor who shouted is in combat, we can assume he saw an enemy and when the reinforcements arrive (distance < threshold) he will reveal them last known enemy position, so everyone enters in combat (or they may detect the enemy themselves and enter in combat immediately). If the actor who shouted is not in combat, they would all actively start searching for any enemy around with a wander/find package. If anyone see the enemy, it will shout to alert anyone around so they stop searching and run to the actor who shouted (which is now in combat mode, so the first IF apply).



3) Detecting arrows... I was thinking: the player is the only one who usually miss a not in combat target, so I guess it's only worth to monitor his projectiles...


You may make the arrow play a low sound and check that sound with the detection formula (it must be very low, so only actors within ~activation range can hear it).



4 & 5) I suggest two levels of shouting made in specific situations:


- if an actor is not in alert mode and detects a threat (dead body, missing projectile, ...), then he enter in alert mode and do a "low" shout to alert his friends in the room or, if he's weaker than the dead actor, he's intelligent enough (Intelligence >= threshold) and he's alone (he doesn't detect his friends), he realize he has no chance, so he stay quiet and hide, hoping the killer doesn't find him and kill him as well.


- if an actor sees an enemy or if he's already in alert mode and detect another threat, then he enter in combat mode and do a "normal" shout to alert his friends nearby, even in near rooms.


- if an actor is in combat and he's losing against the enemies (health/level difference check), he do another "normal" shout.


So, if you encounter a second dead body (a new dead body while already in alert mode), the "alert mode" would become "combat mode".

User avatar
Evaa
 
Posts: 3502
Joined: Mon Dec 18, 2006 9:11 am

Post » Wed May 11, 2016 6:33 am

I'm your package expert! For what it's worth, you are free to use any resources in my vampire mod in your own, if you want to.


For instance, there's a script in my mod that makes it so that if you pass a civilian while you are Ethereal and he can see you, he will begin fleeing (guards will draw their weapon instead, but won't attack unless you talk to them). You could modify that to only work while you are sneaking, apply to guards only and use a follower package instead of a fleeing one. If the script detects that you are *not* sneaking, or that the guard cannot see you, or that a certain amount of time has passed, it will remove the package from him and he will resume his business.



Because I had trouble using OBSE arrays properly (was in the early days when they first added arrays, which didn't save properly in savegames) I did this by refwalking and adding scripted items to the inventory of anyone who was within a certain distance of you and fulfilled the conditions for the effect. The items would then add the effect to their holder, keep track of how long it was supposed to last and remove themselves + the effect when needed. This did persist in savegames and had the advantage of not ending when you left a cell (as magic effects would), so the civilian would not immediately re-enter if you scared him out of his home for instance. There is probably a better way to do it, but that is one approach.



For the follower package you could have a look at the road feeder packages, I think it's called vamproamerfollow.




As for the alerts, I would imagine something like the pseudo-code below for corpse checking. This example will make any character who checks a humanoid corpse and then sees the player within the next 20 seconds, attack them. Obviously that is too heavy-handed, you'll want to make sure that your companions don't do this, and ideally also that it only happens if you actually killed the corpse, but that's more advanced. In my mod I've made it so that if an actor is in combat, and their combat target is you, then they will count as "killed by you" if they die during that fight, for the purposes of determining crimes against vampire society.




Quest script, runs every 5 seconds



bool CellContainsDeadBodies
array CorpseCheckers

begin

set CellContainsDeadBodies to false
set CorpseCheckers to empty array

For each (get all humanoid refs in current player cell)
if (ref is dead)
set CellContainsDeadBodies to true
else if (ref.CanCorpseCheck)
(add ref to CorpseCheckers)
endif
end loop

if (CellContainsDeadBodies)
for each (ref in CorpseCheckers)
if (ref does not have a CorpseCheckerToken)
(give CorpseCheckerToken to ref)
endif
end loop
endif
end

CorpseCheckerToken item script: Runs every 2 seconds (the token item itself is an unplayable weightless quest item)



int SearchingForPlayer

begin gamemode
if (questname.CellContainsDeadBodies == false || actor who holds me is dead, or in combat, or not in same cell as player)
(remove myself from inventory)
(return)
endif

if (SearchingForPlayer > 0)
if (actor who holds me can see the player)
startcombat player
(remove myself from inventory)
(return)
else if (SearchingForPlayer < 10)
SearchingForPlayer ++
else
(remove myself from inventory)
(return)
endif
else if (actor who holds me is playing corpse check animation)
(set SearchingForPlayer to 1)
endif
end
User avatar
Chantelle Walker
 
Posts: 3385
Joined: Mon Oct 16, 2006 5:56 am

Post » Wed May 11, 2016 9:25 pm

What I can offer, if you are interested, is prepare mod to spit out all the information available on the packages nearby actors are running.



Well . . . I will do it anyway, I already have the basics. It is just a matter of isolating the scripts from the rest of my mod and remove dependencies.



The script prints to the console one semicolon delimited text line with all info I can gather about the AI package actors are running.


If you use Conscribe, you can copy those lines to a worksheet and easily see the AI package changes as things happen around you.



[EDIT] Typos

User avatar
Marta Wolko
 
Posts: 3383
Joined: Mon Aug 28, 2006 6:51 am

Post » Wed May 11, 2016 12:47 pm

Done - if you are interested, look for the "QQuix Conceptual - AI package Info reporter" file here >> Nexus link http://www.nexusmods.com/oblivion/mods/20878/?



Description is:



====================================

QQuix Conceptual - AI Package Info Reporter

May/2016 - Version Alpha 0.01

====================================

This is just an aid to help understanding how the game engine assigns, suspends and resumes AI packages on actors


This mod prints to the console one semicolon delimited text line per nearby actor, per frame, with all info I can gather about the AI package actors are running.


This mod is designed to users of ConScribe(*), as the lines are CSV formatted in order to be copied from the ConScribe log to a worksheet, so the package info is nicely spread over columns for easier reading.


Press the ‘Insert’ key to toggle this report on and off.



You may or may not print the line if it has the same information as the previous frame (the actor did not change package). This is turned on and off by pressing the ‘Delete’ key on the keyboard.


(*)ConScribe - /mods/26510/?


There is no readme file included

User avatar
Dean Brown
 
Posts: 3472
Joined: Fri Aug 31, 2007 10:17 pm

Post » Wed May 11, 2016 12:16 pm



Nice! I will check it out when I get a chance.

User avatar
Izzy Coleman
 
Posts: 3336
Joined: Tue Jun 20, 2006 3:34 am

Post » Wed May 11, 2016 9:57 pm

So here's my concept so far.


I anolyze the current ai package and procedure, which returns a number. 0 = Explore/Find, etc.

see: http://cs.elderscrolls.com/index.php?title=GetCurrentAIPackage

and also: http://cs.elderscrolls.com/index.php?title=GetCurrentAIProcedure



I have an array that assigns an "alert value" to each package and procedure. The values stack. So for example, if the package / procedure were combat/combat, they would have an alert of 4/4 = 8. If their package procedure was search/done, their alert would be 3/0 = 3.


In addition, if they are in sneak mode, the alert level goes up an additional 4 points.


The alert level is then multiplied by a game setting (default 2.0) to determine the bonus granted to detection in the Meta portion of the formula.


So for example, if someone is in combat/combat, they would get a bonus of (4 + 4) * 2 = 16 points.



This is just a "base alert level". There is also a separate "adjusted alert level" which can be caused by the other circumstances mentioned above (Fresh kills, near misses, hearing someone "shout for help".



As for the "shout for help", this is my thinking.


1. Actor has to be in combat or just attacked.


2. Check is made on the first attack and every four seconds in combat.


3. A random number from 0 to 100 is generated. If it is above the actor's "help me" threshold, they will "shout for help".


* I may make a special exception and see if I can replicate the circumstances which causes them to say "To arms!", because that's an obvious "shout", and it really annoys me when everyone near that person totally ignores them.


4. The "help me" threshold is the actor's Confidence modified by the percentage of their overall health. So the more damage they take, the more likely they are to shout.


4a. Debating whether or not to incorporate aggression as well. Maybe it's Confidence + Aggression, or (C+A)/2? Either way, as health dwindles, shout odds go up.


5. When the "shout" is made, it runs a check using GetHighActors.


6. The high actors have to be within "shout range" to hear it. Shout range is Confidence + Personality of shouter in feet. (*22 for units)


7. If the target actor is within range of the "shout", then they have to decide how to respond. Rather than make it super complicated, I think I will just run a GetDisposition between the target and the shouter: target.Getdisposition shouter


8. Then the target generates a random number between 0 and 100. If it is below their disposition towards the shouter, a "Find" package will be added with the shouter as the target, and must complete. Once they arrive at the destination of the shouter, their ai behavior returns to normal.


The next question is whether or not to also add "alert" tokens since I already have alert levels incorporated into ai procedures/packages.



If I add alert tokens, my thought is that there is a single alert token that is added multiple times, once for each level of alertness desired. Then, when calculating their alert adjustment, they just count how many alert tokens they have.

So, assuming everything I've stated so far works, then the question is, if someone receives a shout, do they automatically get an alert token, and if so, how long do they last? It seems like the simplest thing to do is just have a timer on the token, and when the token reaches "x" amount of time, it removes itself from it's owner.



Exceptions:


1. If the target of a shout is already in combat, they will ignore the shout.


2. If the target already has an SDR "FindShouter" package, they will ignore the shout.


General questions I don't have an answer to yet:

How long should an alert token stay with a person?


Should the tokens remove themselves once they have entered combat?

How many alert tokens should be added for a "shout for help"?


How many alert tokens for a near miss? (still not sure how I'm going to figure that out, and I have no ideas)


How many alert tokens for a fresh kill? (still not sure how I'm going to deal with that either, but I've thought of several approaches)


Note that in both the near miss and fresh kill scenarios, presumable the reaction to each will be an ai package of some sort which would presumably add some amount of alertness in the first place. So the number of tokens added needs to take that into account.



I *feel* like this might heading in the right direction, but I want to be sure. So feedback would be great.

User avatar
Len swann
 
Posts: 3466
Joined: Mon Jun 18, 2007 5:02 pm


Return to IV - Oblivion