vfig on 7/9/2018 at 17:04
I was seeking a single "perfect" system for conversation actors to hang around before a conversation, then go off and do something else after it—whether the conversation finished successfully, was aborted, or never even began due to a 2nd alert. I'd come up with what I thought was an elegant solution. I doubt that it's new, but it was useful for my learning process to develop it; and I'd be interested to hear how other FM authors tackle this design problem. And I also encountered a strange bug I'd never seen before (and still don't understand) where a conversation completely skipped one of its steps—but I'll come back to that.
My actors fall into two general classes, and I set up each NPC accordingly:
Those who should patrol after the conversation: I give them M-DoesPatrol, and make sure their patrol path is nearby (exactly as I would if they weren't in a conversation).
Those who should go and stand idle somewhere afterwards: I give them M-GoHome, and set their origin to the point they should wander off to.
Then I've got a metaproperty M-WaitForConversation, which I add after those, which disables both patrolling and returning to origin—so the NPCs just stand there. If the NPCs are 2nd or 3rd alerted before the conversation begins, they should return to their "after conversation" actions after calming down. So M-WaitForConversation has an alert cap with max level 2, and an alert response for level two (very high priority) that removes M-WaitForConversation and plays a very short motion (to cover up the short "freeze" between the pseudoscript finishing and the AI considering its next actions).
Finally, in step 00 of each conversation, I do nothing but tell each actor in turn to remove M-WaitForConversation; then step 01 actually makes them start talking and so on (I could do that in step 00 as well, but none of my conversations are long enough for that to be necessary).
This seems to work great, and means my conversation pseudoscripts are much simpler than before, when I used to have conversation steps to add AICurrentPatrol links and M-DoesPatrol metaproperties and so on. Setting up the AIs as normal but then suppressing their normal actions feels like a much saner way to do things.
Now for the bug:
I don't think it's related to the M-WaitForConversation metaproperty itself, but on one (and only one) of the conversations I set up this way, I noticed it always started at the second line of dialogue. It completely skipped the first line of dialogue and the motions. I double-checked the schemas and that I hadn't typoed the tags and so on, and they were all fine. The only thing different about this conversation was that it went on a bit longer than the others, but why would that matter? But step 01 just never happened. Even mprint actions in it got skipped.
Eventually I found out the immediate cause, though I still don't understand it. As I described above, step 00 of all these conversations was Actor One: Add/Remove Metaproperty, remove, M-WaitForConversation; Actor Two: Add/Remove Metaproperty, remove, M-WaitForConversation. Then step 01 was Actor One: Play sound… and so on. As long as I had both actors doing things in step 00, then step 01 just got skipped entirely. When I changed step 00 to be just actor 2 remove M-WaitForConversation, and put actor 1's remove M-WaitForConversation at the start of step 01, then step 01 was no longer skipped, and all seemed okay.
I don't understand why using multiple actors in a single step seems to cause this problem (what else is the Actor field for?); and worse, I don't understand why it was only happening with this conversation, and all the other conversations that use multiple actors in step 00 were fine.
Maybe I'm doing something ridiculously stupid? Or maybe it's just Dark Engine quirks?
Yandros on 7/9/2018 at 17:34
Dark engine quirks most likely. And yes, I'm serious. This sort of thing happens quite often without apparent reason. Glad you got it fixed; only thing I can think to suggest in the future is to add a brief delay for each actor (50-100 msecs) after they remove the metaprops, in step 00. Sometimes that can help the engine fully process the metaprop change before asking the actor to do the next step.
vfig on 12/9/2018 at 11:35
I wired up another conversation yesterday, and hit the same bug again. This time I tried your suggestion of a short delay: I put a short Wait for each actor in step 00 after the metaproperty removal, and then it worked fine.
Going to try that on all of them to see if it's consistent. If so, I'll use that everywhere by default. A tiny delay before the actors start to talk is just fine for a Conversation used for actual conversation.