Dialogic and NPCs using the wrong timelines

Godot Version

v4.5.1

Question

Hello, I’m working on a top-down RPG and am trying to make some more NPCs. I know it’s not best practice to make a new scene for every NPC, so I coded the main NPC script so I can edit things like the NPC’s name, sprite and the dialogic timeline they use for dialogue in the inspector once I’ve instanced them into the main scene. Here’s part of that script:

@tool
extends CharacterBody2D

# signals
signal chatting
signal stopchatting

# NPC Elements
@export var npc_name = ""
@export var npc_sprite: Texture
@export var dialogue = ""
var scene_path = "res://Scenes/NPC.tscn"
@export var speed = 30 # sets start state and gives move speed

# states
var current_state = IDLE
var dir = Vector2.DOWN
var is_roaming = true # makes the character move to begin with rather than being in chatting state
var player_in_chat_zone = false # to begin with, player is not in the chatting zone
enum {
	IDLE,
	NEW_DIR, # Adds states for the NPC to be in
	MOVE
}

# connects to dialogic
func _ready():
	Dialogic.signal_event.connect(_on_dialogic_signal)
	randomize()

# changing states and movement
func _process(delta): # this says what to do in each state
	if current_state == 0: # don't do anything in idle
		pass
	elif current_state == 1: # changes direction and sprite
		dir = choose([Vector2.RIGHT, Vector2.UP, Vector2.LEFT, Vector2.DOWN])
	elif current_state == 2 and is_roaming == true: # move based on direction and if not chatting
		if dir.x == -1:
			$AnimatedSprite2D.play("left_walk")
			move(delta)
			if velocity == Vector2.ZERO:
				$AnimatedSprite2D.play("left_idle")
		if dir.x == 1:
			$AnimatedSprite2D.play("right_walk")
			move(delta)
			if velocity == Vector2.ZERO:
				$AnimatedSprite2D.play("right_idle")
		if dir.y == -1:
			$AnimatedSprite2D.play("up_walk")
			move(delta)
			if velocity == Vector2.ZERO:
				$AnimatedSprite2D.play("up_idle")
		if dir.y == 1:
			$AnimatedSprite2D.play("down_Walk")
			move(delta)
			if velocity == Vector2.ZERO:
				$AnimatedSprite2D.play("default")
# talking
		if Input.is_action_just_pressed("ui_add") and player_in_chat_zone == true:
			current_state = IDLE
			chatting.emit()
			Dialogic.start(dialogue)
			print("interacting")
			is_roaming = false
			$AnimatedSprite2D.play("default")

# choose
func choose(array): # shuffles what option is chosen and chooses one from an array
	array.shuffle()
	return array.front()
		
# move
func move(delta): #makes it move if not having a chat
	if is_roaming == true:
		velocity = speed * dir
		move_and_slide()

# for chat detection
func _on_chat_detection_zone_body_entered(body):
		player_in_chat_zone = true
		
# detection zone
func _on_chat_detection_zone_body_exited(body):
		player_in_chat_zone = false
		is_roaming = true

# when the timer runs out, change the state
func _on_timer_timeout():
	if is_roaming == true:
		current_state = choose([IDLE, NEW_DIR, MOVE])
		print(current_state)

# stop talking when it's over, give item if it's supposed to
func _on_dialogic_signal(argument: String):
	if argument == "stopchatting":
		is_roaming = true
		stopchatting.emit()

Firstly, I haven’t worked out how to edit the NPC’s sprite using this method, that’s not the problem I’m asking about, but any suggestions there would be helpful too. As you can see in the screenshot below, I’ve got one NPC with the variable “dialogue” set to “timeline1”. I’ve also got another NPC instanced with “timeline2” in the same place.

When I play the game in the debugger, there’s a chance that NPC 2 uses timeline 1 when I speak to it. NPC 1 never seems to use timeline 2 and the chat_detection_zones around the NPCs are not large enough to be overlapping. I’m not sure what’s causing this and any suggestions would be appreciated!

Are you sure your chat zone only detects players? Maybe the body entering the zone is a wall/floor?

That was the issue I think, thank you!