Let’s say NPC has a task to clean their desk. The task will consist of something like this:
Find cleaning equipment and navigate to it
Pick it up
Navigate to the dirty desk
Start wiping the desk with a cloth
Stop wiping
Navigate back to the storage room
Drop off the equipment
At any point, player can interrupt the NPC, and force them to stop what they’re doing so that they can start dialogue with them. After dialogue ends, the NPC must be able to resume their task (animations, sounds, particles, etc.). Additionally, NPC might have a unexpected event where they need to cancel their current task, so they must stop cleaning, navigate back to the storage room, and drop off the equipment at faster pace than normal. They also should be able to be interrupted when they are cancelling their task.
How could I approach such complex NPC behavior? I’ve been told to use finite state machine, but I’m not sure how enter, exit, and update would help me achieve scalable interruption, and cancellation behavior.
local foo = coroutine.create(task); -- assuming task is a function
Now, the task can be interrupted using “coroutine.yield()”.
Example code:
local function task()
print("hello");
coroutine.yield();
print("goodbye")
return
end
local foo = coroutine.create(task); -- assuming task is a function
local success = coroutine.resume(foo); -- prints "hello"
local success = coroutine.resume(foo); -- prints "goodbye"
Finite State Machines should be used to check for a desired output.
For example, if you want to do a run animation but you want to check that you’re not stunned, you’re not in the air, etc.
An alternate idea that may work is to use some sort of priority queueing system that queues tasks based on priority, then FIFO (higher priority tasks are executed first, and tasks of the same priority are executed on a FIFO basis).
Typical tasks should be queued with a low priority, and unexpected events should be queued with a higher priority so that the NPC is forced to execute those first.
which means it becomes the next task for the NPC to execute (it has the highest priority, as 5 > 1). As a consenquence, the next task will be the one that is interrupted, which means the NPC will simply resume what it was doing.
Handling animations/particles/etc. is up to you, as this action is separate from the task queueing system. You could just cancel the event when a higher-priority task is scheduled - there are many ways to attack this problem.