Changing the default behavior of walking

Started by Kara Jo Kalinowski, Sun 16/02/2025 22:54:53

Previous topic - Next topic

Kara Jo Kalinowski

So I was wondering how I would go about changing the default behavior of walking. By that, there have been a couple questions on Discord in which writing my own walk script *might* be the way to go, but it's a pretty big undertaking. I was trying to browse through the github to see how AGS handles default walks, which is a bit much to take in since things are happening throughout multiple files. But 2 things I was considering how to solve (things asked on the Discord server) are as follows:

1. How can I disable the "Up" animation while leaving Left, Down, and Right intact?

Here was my solution:

Code: ags
function late_repeatedly_execute_always()
{
  if (!old_moving && player.Moving)
  {
    old_moving = true;
    old_x = player.x;
    old_y = player.y;
  }
  if (player.Moving)
  {
    if (player.x != old_x || player.y != old_y)
    {
      if (player.x > old_x && player.y <= old_y ) 
      {
          player.Loop = eDirectionRight;
      }
      else if (player.x < old_x && player.y <= old_y) {
        player.Loop = eDirectionLeft;
      }
      else if (player.x == old_x && player.y <= old_y && player.Loop == eDirectionUp) {
        player.Loop = eDirectionRight;
      }
      
      old_x = player.x;
      old_y = player.y;
    }
  }
  old_moving = player.Moving;
}

This works, but with a problem. If player.x == old_x I don't know if the eventual path is going to be heading to the left or to the right. I have it assuming right, but it might wait a few frames, the x decreases, and then turn left.

2. How do I include a custom turning animation instead of using default animations?

I realized through testing that I could possibly play a different animation when the direction changes, but you can't call blocking animations within late_repeatedly_execute_always, and the default walk cycle is going to assume you are moving even if you stop to play an animation using custom code.

It would be a better solution if I could code my own walk cycle. How does AGS do it?

I see the following in the help file:

Code: ags
IAGSEngine.GetMovementPathWaypointCount 
IAGSEngine.GetMovementPathLastWaypoint 
IAGSEngine.GetMovementPathWaypointLocation 
IAGSEngine.GetMovementPathWaypointSpeed 

I don't know if those are things that I have access to using AGS code. If AGS walk is done by calculating waypoints and walking in straight lines (which I think is what's going on) is there a way to calculate those waypoints and then have me code how I want a character to walk? Or is there a way to see if the next waypoint is to the left or right of the current location? Or maybe there's a simpler solution to problems like these... Not just limited to these specific issues.

Crimson Wizard

#1
My first thought is that I would try avoiding Walk command and use Move instead, which does same pathfinding but does not play any automatic animations. Then use LockView / Animate / UnlockView to animate the character as you see fit.

The remaining problem is turning: Move won't halt for you to do the turning animation. Which probably means that you would have to do something along these lines:
* detect when the character starts to move into a new direction;
* stop character;
* play turning animation;
* call Move again, from the new starting point but with the same end point.


If you use AGS 4, then the situation will become easier, as AGS 4 exposes new Pathfinding API, which lets you to get the path beforehand and either move character segment by segment, or detect when the character approaches turn points.


Quote from: Kara Jo Kalinowski on Sun 16/02/2025 22:54:53I see the following in the help file:

Code: ags
IAGSEngine.GetMovementPathWaypointCount 
IAGSEngine.GetMovementPathLastWaypoint 
IAGSEngine.GetMovementPathWaypointLocation 
IAGSEngine.GetMovementPathWaypointSpeed 

These are from plugin API, not script API. Unfortunately, movement path was never exposed to script.

Kara Jo Kalinowski

Quote from: Crimson Wizard on Sun 16/02/2025 23:17:41My first thought is that I would try avoiding Walk command and use Move instead, which does same pathfinding but does not play any automatic animations. Then use LockView / Animate / UnlockView to animate the character as you see fit.

The remaining problem is turning: Move won't halt for you to do the turning animation. Which probably means that you would have to do something along these lines:
* detect when the character starts to move into a new direction;
* stop character;
* play turning animation;
* call Move again, from the new starting point but with the same end point.


If you use AGS 4, then the situation may become somewhat easier, as AGS 4 exposes new Pathfinding API, which lets you to get the path beforehand and either move character segment by segment, or detect when the character approaches turn points.


Quote from: Kara Jo Kalinowski on Sun 16/02/2025 22:54:53I see the following in the help file:

Code: ags
IAGSEngine.GetMovementPathWaypointCount 
IAGSEngine.GetMovementPathLastWaypoint 
IAGSEngine.GetMovementPathWaypointLocation 
IAGSEngine.GetMovementPathWaypointSpeed 

These are from plugin API, not script API. Unfortunately, movement path was never exposed to script.

The problem is going to be as I mentioned before, that when the character changes directions it's not immediately obvious where the destination is, so you wouldn't know where to turn. For example, a waypoint moving up 50 pixels and over 5 pixels is going to move vertically 10 pixels before changing x coordinate. So it has a similar problem to the code I pasted earlier.

Looks like AGS 4 might be the solution then... But do you think it would be unfeasible in AGS 3 to write a function to calculate the waypoints?

Crimson Wizard

#3
Quote from: Kara Jo Kalinowski on Sun 16/02/2025 23:47:58The problem is going to be as I mentioned before, that when the character changes directions it's not immediately obvious where the destination is, so you wouldn't know where to turn. For example, a waypoint moving up 50 pixels and over 5 pixels is going to move vertically 10 pixels before changing x coordinate. So it has a similar problem to the code I pasted earlier.

Here's a trick that was used in some other cases: use second invisible character, make it move along, and rely on its Loop.

EDIT: actually... why cannot you rely on the same character's loop in the first place? in the late_repeatedly_execute_always script that you posted.


No, this also won't work for the same reasons, because Loop may be imprecise and not tell actual direction of movement.

EDIT2: the only thing that comes to mind is to use a ghost character, who walks slightly faster, and lets "predict" real character's movement.
EDIT3: making this ghost character have DiagonalLoops on might improve direction prediction.


Quote from: Kara Jo Kalinowski on Sun 16/02/2025 23:47:58Looks like AGS 4 might be the solution then... But do you think it would be unfeasible in AGS 3 to write a function to calculate the waypoints?

If you mean, script your own pathfinding, then I suppose it's technically possible, but you will have to implement generation of navigation grid from a walkable mask (or your own custom navigation data), and a A* pathfinding algorithm.

EDIT4: Since the MovementPath is exposed to plugin API, you may write a plugin that exposes these functions to script in turn, and then write your script assuming a use of that plugin.

SMF spam blocked by CleanTalk