Hello,
I have very basic coding knowledge and am picking my way through learning more (and how to use Godot) a little bit at a time. I'm currently working through the basics of the player's behavior, input processing, and animation, and I've hit an error that I can't find the origin of.
The project is a top-down 2D game, and the player scene is based on this 2D Finite State Machine demo https://godotengine.org/asset-library/asset/516 . Here's the structure of the player scene:

(Ignore HoldIdle/HoldWalk/RayCast2D/CollisionShape2D, afaik they're irrelevant to the problem I'm trying to solve right now)
The player can move in 8 directions, and can face N/S/E/W; the facing direction is stored as a string in the Player script. It'll have other functions later, but right now it helps the AnimatedSprite play the appropriate animation, in conjunction with an "animation_requested" signal that states emit when the animation needs to change. Here's the script attached to AnimatedSprite:
extends AnimatedSprite
signal animation_played (name)
func play_facing(name):
var anim_name = name + "_" + owner.facing_direction
stop()
play(anim_name)
emit_signal("animation_played", anim_name)
Explanations:
The "animation_played" signal is attached to the AnimLabel tag for debugging, will get to that in a moment.
This function is connected to all the "animation_requested" signals from states; they pass it a state name.
The state name concatenated to the facing direction = an animation name.
I have 8 animations currently plugged in: idle_up/down/left/right, which are each just 1 frame, and walk_up/down/left/right, which are each 6 frames.

Here's the problem I'm having: the walking animations work perfectly fine, but the idle animations don't play when the idle state is entered. When the player stops moving and goes back into the idle state, it plays the walking animation for whatever direction it's currently facing (not just continuing the old walking animation, but restarting it; the animation "clips" back to the beginning when movement stops.)
uploaded GIF of the behavior to gyazo
I tried to narrow down where the problem was with those "Debug" labels. StateLabel gets a signal from the state machine and updates whenever the state changes (uses the same code as the 2D FSM Demo). AnimLabel gets its signal from the AnimatedSprite script as shown above. Facing gets its signal in the Player script, in the setter function for facing_direction:
var facing_direction = "down" setget set_facing_direction
# ...
func set_facing_direction(value)
facing_direction = value
emit_signal("facing_changed", facing_direction)
I assume the problem is happening somewhere before play_facing(), since like the gif shows, the state goes to Idle but the animation name is still walk_(whatever). This is where I'm stuck and can't find the source of the problem. The Idle state script emits its signal on enter():
func enter():
emit_signal("animation_requested", "idle")
...and then doesn't do anything on update except scan for input and change to the Walk state when it gets any.
The walking animation request signals are all confined to the Walk state, and right now the AnimatedSprite is only connected to signals from the Idle and Walk scripts.
What should I look at next to figure out why this is happening? Am I misusing AnimatedSprite somehow? Before I added the walking animations, I had the states using owner.getNode() to call play_facing() directly, with play_facing() still combining the state name with the player's facing to play an animation, and it grabbed the right idle animations then. The only things I changed were swapping out the call to play_facing() for the emit_signal(), having Walk pass "walk" instead of "idle" as the argument, and adding the four "walk_whatever" animations.