1
\$\begingroup\$

My AI design is pretty simple. I have different entities that can be possessed either by the player or the AI. Those entities have an "Input" component that holds the states of the actual inputs, like right, left, up, down, fire. (and wasRight, wasLeft, wasUp, wasDown, wasFire to perform checks on whether the input was just triggered or not).

My PlayerController class is driving that component by reading inputs from either the keyboard or the gamepad.

In a similar way, my AIController comes up with that same input through logic functions.

Now I've hit a wall with this kind of approach when dealing with movement.

Let's say that I'm in 2D space and that I'm moving the AI horizontally. I am moving from (0, 0) to (10, 0) so I'm activating the "right" input all the way until I reach the (10, 0) position.

But if the speed of my entity is high, I might actually go over the position and trigger a movement back, and then again forward and so on as it can't actually settle. I know that I could just check if the previous movement was in the same direction and that if I went through the target I could just force the position to be in the exact spot that I want to reach. But it doesn't really look like a clean solution.

Is this approach completely wrong? I would like to try and keep it simple and modular at the same time.

\$\endgroup\$
2
\$\begingroup\$

Several possible solutions; one or a combination may be right for you.

Steering Behavior

Basically, in this case, that means that you AI needs to slow down as it approaches the target location. This would mean that you need non-binary movement commands, which might be good if you ever plan to support gamepads (thumbsticks) anyway.

Wider Targets

Essentially, add a tolerance to the target location. Then, overshooting is less likely to cause the oscillation. Also, this can avoid micro-oscillations caused by floating point inaccuracy. If you're already using tolerances, maybe make them bigger.

Physics/Controller Ticks

You mention that if "speed is high" the AI might overshoot. This speaks to a fundamental problem you have: your speed can be too high per update tick. For stable physics, you really want a max speed per tick (to avoid tunneling and other problems). If you need objects that move really fast, that just means that you need multiple physics ticks per frame.

This can then easily combine with the player controller and AI. Allow the controller and AI to update per physics tick. That lets the AI re-evaluate if it should stop much more frequently so even fast-moving AI entities will only move very small distances per check.

Doing this is particularly helpful with networking where you want to synchronize per-tick for smoothest behavior.

\$\endgroup\$
  • \$\begingroup\$ Tolerance is the first that came to mind. I'm already using a very small one. I could increase that but I would need to figure out how big it should be based on max speed of the entity I guess. I could just make it the same as the max speed as I already cap that to avoid problems like tunneling as you pointed out. \$\endgroup\$ – Valerio Santinelli Sep 7 '16 at 8:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.