Forum rules - please read before posting.

Sequencing and scheduling NPC behaviors

I have a situation where after specking to an NPC, the overall state in the scene has to be moved forward and that NPC changes behavior from standing around to wandering from marker to marker.  

So far, I accomplished this through a local scene variable which is changed at the end of the initial conversation. I use the scene "on variable change" cutscene to check for changes in a variable, for each possible value of that variable, I have an Action: Run In Parallel action which runs my "Wander around" action list. I couldn't figure out any other way to change the "state" of the NPC. 

So my questions are:
Is this the best way to set these sorts of things up?  I'm not sure if this is robust enough to handle a situation where there are many such overall state changes.

Is there a better way, with AC to handle constructing NPC behaviors with AC? Imagine NPCs with several goals and player actions can alter this?  In my mind, the ideal situation would to simply have a component on my NPC which executes an action list regularly which determines what it's current action should be.

I'm imagining there could be many such situations where talking to an NPC results in that NPC running off to go do something and having to stick many such interactions into the On Variable Change cutscene would be unwieldy.  I'm interested in what the most robust solution would be, or if this calls for custom scripting or an additional plugin to augment AC?

Comments

  • My issue at the moment, with this setup at least, is that I can't figure out how to use the pause/kill actions to actually stop the active Move To Point action.  If the actionlist which initiated the move to point was in the On Start cutscene, do you have to pause the On Start Cutscene or do you try to pause the Asset file which On Start initiated? Or is there something else I'm missing? My ignorance here is strong.
  • Update:
    I managed to get pausing working after some more trial and error. Forgive me for flooding your board with messages. 

    My question about general structuring is still something I'm interested in though. General best practice.
  • I take it back, I had gotten pausing working and then it stopped working.  At the end of a use interaction, I have an Action List: Run, at the beginning of a different interaction, I have an Action List: Pause or Resume, but when this pause is invoked, the asset file which was started in the run doesn't pause.
  • edited August 2018
    Going to leave as precise a description of my use case as I can manage here for clarity.

    1: I have an NPC with a hotspot component. That hotspot has an in scene interaction set up which as a final action has a Action List: Run.

    2: The in Asset file Action List run by the aforementioned Action List: Run is set up as follows:
    https://imgur.com/zLxAxwk

    3: In a separate interaction which is triggered later I have the following:
    https://imgur.com/a/v8Ff5Dd

    Hopefully this is enough information to point out my error.


  • edited August 2018
    After more testing I'm beginning to think the issue is that the actions inside of an actionlist are not responsible for executing the logic of their namesake.  For example, am I correct in understanding that an Object: Transform moving an object some distance over X seconds only initiates the movement but the implementation of the Object: Transform doesn't itself do the movement?  I've been trying to get a pause/kill to stop movement happening from this sort of action and I'm beginning to see the behavior isn't intuitive.

    Edit: Yes, that seems to be the case that if you'd triggered a Character: Move To Point in an action list, paused it, then didn't do anything to interrupt whatever had been started in the previous action list that it will carry on doing whatever it was doing... 

    I guess that makes sense in some context but it's not clear enough and not at all intuitive considering the action list will wait on those actions.

    So with this in mind, is there a recommended way of stopping such things?  Should I place a marker at the feet of my NPCs so if they're in a movement I can tell them to move to the current location?  Something else which is better?  Right now I have a "Face object" action which is doing the job, but that's not always applicable.
  • I should start with something of a disclaimer that AC is targeted towards traditional adventure games, in which NPC behaviour is generally fairly basic.  NPCs don't have 'states' but merely the Actions they're commanded to do at any one time.

    If you want proper AI incorporated into your game, you may well want to look into incorporating another asset - or your own custom scripts.  The most accessible way of hooking custom code into AC is to rely on custom events - which trigger whenever AC performs some common task such as changing a variable's value or having a character speak.  It's also possible to write custom Actions and plug them into standard ActionLists, if you want further control.  A repository for user-made and add-on scripts can be found on the AC wiki.

    The "On Variable Change" Cutscene is a fairly old feature, and its usually better to simply run the appropriate follow-up ActionList after changing the Variable itself.  If you change the Variable's value a number of times, you can move both the Variable: Set and ActionList: Run Actions into a new Cutscene, and parameterise the variable's new value so that you can run this new Cutscene whenever you want to change it - and it'll automatically run the follow-up ActionList as well.

    Regarding pausing/resuming ActionLists - you need to pause the actual ActionList that you want to pause, not the one that triggers it.  You can display a list of all currently-running ActionLists by enabling the 'AC Status' box at the bottom of the Settings Manager.  Your second screenshot should indeed pause Search_Player_Tool, and you can use the Status box to determine if this is the case.

    I see that the Character: Face object Action, however, has no Character assigned.

    You are correct about the nature of the ActionList: Pause or resume Action - Actions within it cannot be paused mid-process, but the pausing of a list can be delayed until all currently-running Actions are complete.  Actions generally delegate the actual code they trigger to relevant scripts.  For example, the Object: Transform Action passes on the user-set data to the Moveable script, which processes it to handle the actual movement.  This allows for such features to be called through custom scripts and manipulated further via the API.

    This scenario, however, does raise a good point: when you resume the ActionList, it will continue on from the next Action that it was paused from.  Often this is desired, but in this case: if it pauses mid-movement, then the ActionList will start with the Engine: Wait Action when it resumes.

    Therefore, I will look into providing the option to resume an ActionList from the Action that was paused, as opposed to those "next" to those paused.  That should allow for the NPC to continue moving to his original destination upon moving.

    To stop an NPC moving, you can use the Character: Move along path Action with a Method value of Stop Moving.
  • Ahh brilliant. I appreciate your in depth response here. I found the issue with the character not being assigned, as you noted, some time after having made my last comment and it was a part of the issue. It compounded the problem of me having assumed that the nodes within the action lists were themselves responsible for executing the behavior in question.

    Luckily, my state needs are limited, and it mainly comes down to chaining action lists where each action list essentially knows which other lists have to be handled. That, in effect, is a state machine.  

    I think what you have here can manage what I need, and for that I'm grateful as I don't have time to integrate a third party logic package such as behavior trees or anything of the sort, but I could see that being useful.

    I think the package would see benefit from, at minimum, clarification of the execution context of action lists and making clear that a pause is not a pause on the activity of any actions previously triggered (However, a kill action really should be responsible for cascading the kill down through individual actions in a previously executed list. Or at least giving that option. That would give users the benefit of being able to do more advanced stately logic with the existing feature set. And while I haven't looked into the implementation internals at all, it would seem like if every action implemented an "OnKill" handler, then they could easily halt whatever activity deeper in the engine they've initiated?

    Food for thought. Thanks again.
  • You're welcome.  Certainly I agree that the Manual should elaborate on the usage of the Action.

    Having an "OnKill" handler is an interesting suggestion.  As an Action is effectively de-coupled from its effects, however, there is a potential for problems if two Actions are affecting the same system.  I will give it consideration, though, thanks for the suggestion.
Sign In or Register to comment.

Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Welcome to the official forum for Adventure Creator.