AIWander

Everything about development and the OpenMW source code.
User avatar
TorbenC
Posts: 146
Joined: 26 Aug 2012, 23:13

AIWander

Post by TorbenC »

*note when reading this: I know that there is no idle1 (it is just called 'idle'), I am calling the first idle animation idle1 for simplicities sake*

Hello all!

I've done quite a lot of observation of the AIWander package in vanilla Morrowind already and I've come up with a few things I want to share and get some opinions on, this opening post is mainly just for things that are known for sure as what happens, not theories. This thread will be updated as more things are found!

The parameters are as follow for AIWander:
AIWander r d t i1 i2 i3 i4 i5 i6 i7 i8 i9 rp

r = Range:
Range is the radius in which the actor is able to move in, if this is 0 then the actor will never move (it will not even try to select anything within 0 radius).

d = Duration:
Hours from the time the wandering action is invoked until the package is considered done. When this package is done, no new waypoints are selected for wandering, the current movement does not complete. Idle animations are reset instantly as well. The AI package dynamic records are floats - a 2 hour package invoked at gamehour 16.7065 ends when gamehour >= 18.7065.

t = Time of Day:
Uses centihours.
Operates only if the duration is not 0. Broken. The package will end earlier than the duration indicates if gamehour equals (timeofday/100), probably for use with idles. However, because a floating point exact compare is used, this never occurs.

i1 - i9 = idle1 - idle9:
These are the chances of the specific idle animation playing. 127 is the maximum value able to be plugged into these parameters, anything higher is set to 0. Determining which idle animation will be used takes advantage of a float % GMST (fIdleChanceMultiplier). If no animations catch the check then wandering occurs.

rp = repeat:
This is a bool value, it is defaulted to 0. If more then three parameters are passed (ie: AIWander 700 2 0 0) then it gets set to 1. You can pass this value as 0 even with more then three parameters but it requires specifying all 9 idles:
AIWander 500 2 0 10 20 30 40 50 60 70 80 90 0
This will make it not repeat even though idle parameters have been specified. When repeat is 1 after duration has ended the initiation time is reset and the duration runs again (it is unknown whether this happens only a certain number of times or infinity yet, this is being tested).

Now for the notes I have made so far:

The first idle parameter (idle1) is not accounted for:
For instance "AIWander 100 0 0 127 321 1000 128" Will make the NPC walk around in a range of 100 from where it was called and it will *never* stop and play an idle animation. 127 in the idle1 parameter looks like it would make the NPC stop and play idle1's animation (the default, standing still breathing), but because of idle1 not being used in the AIWander implementation this does not happen.

Duration/Time of Day
Time of Day will not be implemented do to it being completely broken (unless Zini requests it).
Duration ends when the hours stated have passed or midnight hits, it does not carry into the next day.

Interruptions
Now this is tricky to explain. Basically, I'll do this with examples, lets say you do this:
AIWander 50 0 0
This will make the NPC wander in a radius of 50 without stopping to do any idle animations. Now lets say that you wait a few seconds (waiting is unnecessary) and do this:
AITravel -1772 -1214 24
This will make the NPC walk to the specified location. Now, after the NPC reaches that position, lets say that you set a variable to end the script (the script will just return the moment it is started from now on). What happens when the AITravel finishes? Well, nothing. The NPC will actually just stand there and play the idle1 animation (default for nothing else happening) it doesn't return to the position where the previous AIWander call was made (see next example).

But now, let's say you did this:
AIWander 50 0 0
Just like in our last example, but instead of using AITravel let's say you do a position change:
position -1772 -1214 24 30
This will teleport the NPC to that position facing 30 degrees. Now after you call this, let's do the same thing as in the AITravel example, you end the script. What happens? Well, this isn't like the AITravel, instead, now the NPC will walk back within the radius of where the AIWander package was last called and resume wandering as stated.

Now, let's do another example with position:
AIWander 0 0 0
This time we tell the NPC to stay still and don't play any idle animations. Now we position:
position -1772 -1214 24 30
Okay, then we end the script like last time. Now what happens? Well, the NPC will not return to the area the previous AIWander package was called in. Why? Because the AIWander package was called with a radius of 0. This means that AIWander will never choose a position to walk to, thus when it is in a different place it will not choose a position in the radius that was set to walk to (if that makes sense), so it simply stands still where we positioned it.

Let's do one more:
AIWander 50 0 0
Okay, we started wandering, now let's change it up... First we'll do the position change command:
position -1772 -1214 24 30
Now, when this position change is completed we know the NPC will start walking to where the AIWander command was called, but if we call a new AIWander Package what will happen?
AIWander 50 0 0
What will happen? Well, it turns out this actually makes the NPC start wandering right where it is as apposed to walking back to the old AIWander position (this may look like common sense, but this is an important find considering the UESP is wrong about this).

That is all the examples on interrupts so far, there will be more.

Blockers:
The only currently known blocker of implementing AIWander is this:
AIWander isn't receiving its idle parameters properly
This needs to be fixed before AIWander can even really be properly tested (in a non hacky way).

Zini has fixed this bug, thank you!

A new blocker:
AIWander isn't being passed the repeat parameter: Bug #793
Fixed!

Though this isn't exactly a blocker entirely, it blocks AIWander from starting unless it is from a script function:
This feature

Please discuss!
Huge thanks to Chris for the abundance of ideas and discussing the topic with me which lead to an even greater understanding of what AIWander is truly doing.
Another huge thanks to Hrnchamd for researching the Duration, Repeat, and TimeOfDay parameters as well as the implementation of selecting an idle animation or choosing to wander.
Last edited by TorbenC on 28 May 2013, 04:49, edited 11 times in total.
User avatar
TorbenC
Posts: 146
Joined: 26 Aug 2012, 23:13

Re: AIWander

Post by TorbenC »

Heavily updated the opening post, it's now actually worth reading. :)
User avatar
Zini
Posts: 5538
Joined: 06 Aug 2011, 15:16

Re: AIWander

Post by Zini »

The value type in the AiWander instruction code did not match. Fixed in master now. I assume that these additional values are int (we were using a non-functional mixture of ints and floats before). If they are floats instead, we need to change them in the other direction.

As for AI-package eccentricities, I always worked with the assumption that if you do something with a NPC via script that involves AI/moving while an AI package is running, something will break. If you can figure out patterns there that would be nice, but unless we hear angry yelling from the modding community, we can probably work with the breaking assumption and go for a simple implementation without too much additional research.
User avatar
TorbenC
Posts: 146
Joined: 26 Aug 2012, 23:13

Re: AIWander

Post by TorbenC »

Zini wrote:The value type in the AiWander instruction code did not match. Fixed in master now. I assume that these additional values are int (we were using a non-functional mixture of ints and floats before). If they are floats instead, we need to change them in the other direction.

As for AI-package eccentricities, I always worked with the assumption that if you do something with a NPC via script that involves AI/moving while an AI package is running, something will break. If you can figure out patterns there that would be nice, but unless we hear angry yelling from the modding community, we can probably work with the breaking assumption and go for a simple implementation without too much additional research.
Okay, thank you for fixing that (integers are correct) I made a pull request for one more small fix (thanks to Chris) that removes an extra 0 being passed.

Indeed, I'm trying to figure out all the patterns I can before I begin implementation.
User avatar
TorbenC
Posts: 146
Joined: 26 Aug 2012, 23:13

Re: AIWander

Post by TorbenC »

Alright, I've been testing non stop for about a week now (excluding 2 days I was away). I cannot for the life of me figure out how duration and time of day work.

This is driving me nuts, I initially thought I figured it out when I noticed putting in a duration of 5 made one of the NPCs in Seyda Neen choose to do something new (either stop and play idles or start moving around) every 5 seconds, then I implemented that and then tested what happened with a duration of 0, thought I had it all figured out.

Then I tried putting in a value of something high (12) into the AIWander call in vanilla, well... it certainly didn't wait 12 seconds before picking something new to do... it waited roughly 5-7. Now I don't understand, I've been doing tests over and over and over again and the entire implementation of duration seems to be random, it could indeed be a randomly selected number and the duration you enter would be the max value it can select from, I don't know, if that is the case then it only selects that number one time and uses it from that point on I think.

But then there is timeofday, now this I have literally no clue at all, nothing to go off of. I have tested for days just putting in different timeofday values, leaving the cell, staying in the cell and waiting, even leaving the game running for the amount of hours I put in, *nothing* seems to happen. I can even go as far as to say that timeofday looks like it doesn't do anything at all (remnants of previous implementation that weren't removed due to compatibility with scripts already written during development? Similar to how idle1 parameter functions... it doesn't).

So, while I still continue to test, I want to ask if anyone out there may have some kind of lead as to what these do. Even MWSFD and UESP don't really understand it.
User avatar
Greendogo
Posts: 1467
Joined: 26 Aug 2011, 02:04

Re: AIWander

Post by Greendogo »

I would post on the official Bethesda forums or over at Fliggerty's place. Someone is bound to know in one of those locations.
User avatar
TorbenC
Posts: 146
Joined: 26 Aug 2012, 23:13

Re: AIWander

Post by TorbenC »

Greendogo wrote:I would post on the official Bethesda forums or over at Fliggerty's place. Someone is bound to know in one of those locations.
Well, I held out as long as I could in that regard but I just made the threads :(

GHF
BGSF
User avatar
Greendogo
Posts: 1467
Joined: 26 Aug 2011, 02:04

Re: AIWander

Post by Greendogo »

You got a reply from Hrnchamd at GHF.
User avatar
TorbenC
Posts: 146
Joined: 26 Aug 2012, 23:13

Re: AIWander

Post by TorbenC »

Greendogo wrote:You got a reply from Hrnchamd at GHF.
Indeed I did, he's awesome :) Puts in to question the implementation of how long it takes for the NPC to choose between playing idles or moving though, my original opinion revolved around duration determining the time until a type of action was chosen in which 0 would be "random" but... nope :P
User avatar
TorbenC
Posts: 146
Joined: 26 Aug 2012, 23:13

Re: AIWander

Post by TorbenC »

New information on duration, timeofday, and a new parameter repeat has been added.
A blocker (Bug #793) has been added as well.

Research continues...
Post Reply