To be honest, I haven’t given this much deep thought yet but there seems to be two kinds of quest state:
!. Has some condition been satisfied when you need to do something. (ie: do you have the special key for the door, have you talked to NPC 1 before NPC 2, etc.)
2. Some condition triggers some other things to happen
I think about things from the perspective of “giant infinite worlds” and so I would try to put as many things in category (1) as possible. There is no overhead in that case. The player does something that requires the check and then something else happens. New dialog option, door opens, whatever.
Even some things you’d think would be in (2) can sometimes be moved to (1). “Retrieving the gem at the end of the dungeon spawns some critters at the beginning of the dungeon.” sounds like it would be (2) but if the game has ‘spawn areas’ or ‘spawn triggers’ then that could be conditional based on the gem being gone or whatever. So entering the encounter trigger would check for the other conditions.
…and that’s perhaps a poor example anyway because in Mythruna I could drop custom scripts on item events. So retrieving the gem means I “picked up” the gem which was an item event that could have had a custom script on it.
So a lot of it is “it depends”.
Listeners are usually the devil, though… especially if you add them ad hoc. You have to remember to clean them up again, they spawn a little garbage every time they are run, etc… In an ES, at the game level, it’s rare that I would even consider listeners.
…but I guess in the end the line between a script handler on an item and a listener is a fine one.
Another example while I’m here. “When all 10 critters X die, spawn in giant critter Y” There are multiple ways to attack that, too… either the spawn trigger manages its children (part of a system that maintains spawn trigger conditions… after all some spawns may require constant amounts of some monster). In which case the ‘closure’ of one spawn trigger is the condition that the other spawn trigger is waiting for. Alternately, sometimes the AI is managing ‘groups’ of mobs whether to slot them to avoid having all 10 attack the player at once or because there is some level of AI coordination. In which case, as each one dies they hand some state off to the next one. The last mob who dies has all 10 of the states and so his loot drop script would also spawn the boss.
There are a variety of ways to look at a problem but if you can structure them all in some player triggered or item triggered way (which can’t happen anyway except for some player interaction) then it means your world has no overhead where the player isn’t. And for an infinite world, that’s pretty crucial… which is why I think that way.