Need help understanding waiting within loops

  • I'm attempting to create some basic AI using a state machine, I'm fairly new to construct so please bear with me. I have it working up to the point where I need to increase a worker's load_Water value by 1 and subtract 1 from area.water every 1 sec. It increases instantly, i guess because it's looping but, at this stage my understanding of how to pause a loop for a certain amount of time is pretty foggy.

    Any advice would be much appreciated, thanks.

    https://www.dropbox.com/s/8zed7y7qq2wi52n/looping-problems.png?dl=0

    I'll try and knock up a capx if the image doesn't help.

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • It increases instantly

    You need to pass the loopindex as parameter throughout all functions related.

    Another thing is, Loopindex start with 0, so basically you have "wait 0 second" for the first one because 4*0.

  • thanks for your reply and it sounds like it might work but, unfortunately I don't know how to pass the loopindex as a parameter.

  • Download link is not working.

  • Sorry about that II have edited my first post

  • thanks for your reply and it sounds like it might work but, unfortunately I don't know how to pass the loopindex as a parameter.

    It's the same exact way like you did for worker.UID and area.UID, but this time you pass it as loopindex.

    I thought that was straightforward.

  • It probably is

    I just need to increase my understanding of how loops work.

    So, in the move_to_water function, when I call collecting_water I should add loopindex as a parameter?

    Then do I need to use this at "worker load_Water < worker.load_Water_max" for the wait?

  • Instead of using waits, you can reorganise some small things to make it work.

    Since you are using states for your workers it should at least from what I can see in the screenshot be fairly easy to do.

    In:

    function "Move_to_water"

    Worker within 0.1 degrees of area.angle

    you remove the wait 1 seconds and the function call to "Collecting_water"

    instead you do "Worker set FSMState to "collecting_water"" and if you don't already have an variable for your workers to hold the UID of the object they need to interact with. You can make one. So as you change the state of the worker you at the same time set the interaction variable to the Area.UID. Since you have already selected it when you call "Move_to_water" it should be easy.

    In the function "Collecting water" you remove the Set state to "Collecting water" as you have already done that.

    Then you remove the wait*4 loopindex as well.

    So to make it work, you make an event like this:

    Every 1 second

    Worker state = "Collecting water"

    For each Worker

    Call function "Collecting water" (Worker.UID, Worker.Interact_UID (Which is the area.UID in this case))

    So basically what you do is simplifying you functions and you get those nasty waits out of the way, and move the wait time outside the functions.

    The benefit of using an interact.UID for everything that the worker have to interact with, is that it makes it very easy to debug your program. As you can always check that this variable for a given worker is correct. And since it cant interact with more than one thing at the time. You could also use it if the worker for instant need to go eat and do that sitting in a chair. You simply set the interact variable to the chair UID.

    Another good idea I think is to use Booleans for states instead of text, not that it wont work with texts. But its just faster to work with as you don't have to remember how you wrote different things.

    So you could have a series of Booleans:

    FSM_Idle_wait

    FSM_Idle

    etc.

    Another tip is to use "flags" for your units, this will also make it easier and will let you control them a lot better.

    For instant if you use path finding to move your workers around.

    You can add the "On arrived" however it will trigger whenever a worker arrives at something. But if you use flags you can make it very easy to make them do what you want.

    "On arrived at chair"

    Worker.flag_going_to_eat = true

    Call function "worker eat"

    "On arrived at chair"

    Worker.flag_going_to_repair = true

    Call function "worker repair item"

    I always use at least 3 "Checks" when doing AI.

    Busy (Boolean) <Whenever a unit is not busy, it will look for something to do. This is the main variable for activating different states>

    Type (Boolean) <Can be very useful if you have different types of units, with different state machines. So Enemies use there own state machine)

    FSM_<Do something> (Boolean)

    Flag_<What action to perform> (Boolean)

    <State variable> (Boolean) <Very good if you for instant want to make a priority system, so if workers get hungry when hunger = 0 you can set something like "is_Hungry = true"

    For the state machine it self (If we should make one for workers):

    Unit type = Worker

    Worker is busy = false

    For each Worker

    <The order in which you set conditions will act as priority system>

    Check 1:

    Worker is hungry

    Worker is not busy

    Action 1:

    Set worker busy = true

    Worker set FSM_look_for_food = true

    Check 2:

    Worker is tired

    Worker is not busy

    Action 2:

    Set worker busy = true

    Worker set FSM_look_for_place_to_sleep = true

    Etc.

  • works perfectly, thanks so much for your time and advice. I'm going to go through it now and implement booleans as they seem far more straight forward. thanks again much appreciated!

  • Please when you get the time could you take a look at my new setup, it does seem far more stable and easier to manage am I going in the right direction and any tips on a priority system?

    https://www.dropbox.com/s/2g71o91svb1g6ld/ai-test.png?dl=0

  • I noticed I had not included the worker.id_interact within the function calls and have edited that now.

  • Please when you get the time could you take a look at my new setup, it does seem far more stable and easier to manage am I going in the right direction and any tips on a priority system?

    https://www.dropbox.com/s/2g71o91svb1g6ld/ai-test.png?dl=0

    Its quite hard to see if you are going in the right direction as I don't know your program, but if it works then I assume its fine. One thing that you might consider, unless you do it somewhere else, is in the function "Find area" to lock the area that a worker is moving to, I would imagine not doing that would at some point give you some conflicts with several workers trying to go to the same area.

    So when a worker is found set "sm_need_worker = false" for the area.

    Also in your for each events at the top, I would personally reorganize it a bit, here is an example:

    I would also advise you to start commenting your things, at some point if you don't, you will loose control. And it makes it a lot easier for yourself to later go in an make changes down the line.

Jump to:
Active Users
There are 1 visitors browsing this topic (0 users and 1 guests)