Hello. I use a timer to prevent the player from speaking to an NPC again too quickly after the previous time. This enables me to use the same button to launch and end dialogue. Otherwise you’d get stuck in an endless loop or I’d have to have a different button to launch and end.
It worked in an earlier prototype. Now, putting the same events into a newer project, it’s not working and the condition “The Timer “sinceDialogueEnded” > 1 seconds” seems to never be true, even though I create/start the timer when dialogue ends ie. before I do a check on its value.
The dialogue system works without the timers (and with ‘A’ to launch dialogue and ‘X’ to end it); the fault is introduced when the timer conditions and actions are added.
Thanks in advance for any advice on getting this timer functionality to work as expected.
Edit: I create the timer when dialogue is running too, because it’s the only way I could get the behaviour to be consistent between npcs in my older prototype: preventing the player from talking to any npc for 1 second after ending dialogue with any npc.
I have not tested any solution and have never used the dialogue system. But he it’s not “true” because you reset the timer with x key press, directly before the condition is read.
Maybe the order of the events could help here.
Thank you, but that didn’t work. Even if the timer is the first condition the event is checking.
Edit: @jack I realised later that your advice helped me more than I thought at the time! I’m sorry for not realising it. The timer getting reset every time X is pressed was part of the issue. Thank you.
I managed to get it working by using a second timer. I’m not even sure how but it’s working exactly as I want it to, and I can use one button to launch, click through, and end dialogue, with a 1 second pause before you can talk to any npc again.
The secondary timer (‘scrollText’) was used in the typewriter style text display prototype I did, but my newer prototype shows full lines of dialogue that I reveal with an opacity tween, not individual scrolling characters. So I’ve added back in this timer, in the same places as it would be if I was still doing the typewriter set-up.
This secondary timer was originally used for two things: to control the speed letters appeared on screen, and to prevent players from closing the final line of dialogue before they had read it; to give people with their thumb held down, to make the text scroll quicker, time to lift it up. It checks that the timer has reached 0.5 seconds before the player can close/end the dialogue eg. dismiss the final line of dialogue and get control of your character back.
I just need to work out why the heck it works, though I’m glad it does.
Here are the updated events. If anyone knows why this works but the simpler version didn’t, I’d love to know.
Edit: in the traditional typewriter dialogue system, the scrollText timer is reset whenever a character (letter) appears on screen. So the last letter of the last line of text causes it to reset too. In my newer system, that uses full lines of text, it will be way over 0.5 seconds by the time the condition is checked because it doesn’t get reset at any point during dialogue: only when dialogue starts. Interestingly, if I don’t delete this timer in my ‘dialogue is not running’ event, no dialogue will launch at all when I preview the game.
Hello @worriedpixels ,
did you try to use the command in the dialog:
I suggest you to not use “when dialog run” condition because it is true every time but to manage the action using a command written in the dialog text.
I suggest you to read the wiki, especially the “Command” section
Thanks J. I am familiar with Yarn commands. I made some Yarn tutorials on YouTube a few months back, though admittedly I am a little rusty after a recent break.
I’m not sure how I could use a Yarn command to help me with the timer issue. Dialogue has to be running for a Yarn command to be reached in a node, but I need to measure time when dialogue is not running, and therefore when no nodes are being read. A timer starts when dialogue ends. It needs to reach a specified time for dialogue to be allowed to launch again. I have managed to do this by using 2 different timers… but I’m not sure how (see events above).
Edit: Thank you @jumpingj for your advice earlier. It’s working great now after several hours of experimenting. You were right about ‘dialogue is running’ condition being true every time; perhaps you meant it was being used in too many events - too many events having the same conditions be true at once - which was indeed the case. I’ve had 6 weeks away from game dev stuff and I feel like a complete beginner all over again!
I removed the scrollText timer and used a boolean variable instead, which also works. Initially the value is false. It changes to true when the player talks to any NPC. The ‘dialogue is not running’ event checks to see if the value is true before running. It is set back to false in that event’s actions.
I still don’t understand why this makes my ‘sinceDialogueEnded’ timer stuff work I’m glad it does, but I wish I understood why. So… problem solved? But I have no clue how.
This event says “every single frame dialogue is running, reset the “sinceDialogueEnded” timer”. It will never go past 0.016ms since it resets every frame.
So that dialogue ended timer will never get past 1 second.
Once dialgoue ends, this event is at the top of your event list:
Your bottom two events will always happen after this event does, since it is higher on the event list (all events occur from top of the list down, if their conditions are true.). Because of this it is extremely unlikely your bottom event will ever occur, because scrolltext is always likely to hit 0.5 seconds before sinceDialogueEnded hits > 1 second, and therefore sinceDialogueEnded will reset first.
That’s not the only thing that could be going on, but it is one potential issue with this set up.
Thank you for your reply. As in my last comment, I have since replaced the scrollText timer with a boolean variable. I have also removed the timer from the ‘dialogue is running’ event. The only place the sinceDialogueEnded timer is created now is once dialogue ends (the player exits the dialogue UI). And the only place it’s checked to be greater than 1 second is in a dialogue begins events (second branches, after the player has spoken to an NPC once already). It doesn’t work without the boolean (‘amITalking’). Re-ordering the ‘dialogue has finished’ event to underneath the dialogue launch events doesn’t change anything, unfortunately.
So it’s all working great now, even if I bash the X button to try to break it… but I don’t fully understand why it works. The boolean check made the difference. Without it, the second dialogue branches - the ones that check the timer - don’t launch.
Edit: I think I get it. It’ll help me to understand if I type it out. Thank you @Silver-Streak, your ‘top to bottom’ reminder was the key.
- When the player gets to the end of a dialogue, ‘dialogue is not running’ becomes true (when the last line of dialogue is printed). The game is just looking for the X key so it can get rid of the dialogue UI stuff (assuming I’m not using the magic boolean that fixed it).
- Once the X key is pressed all dialogue stuff vanishes or animates away.
- But the two conditions in that event will still be true when the player presses X to start a second dialogue.
- My ‘dialogue has ended’ stuff is happening again and again after the first time the player speaks to an NPC, never allowing the other events to trigger because they share the same conditions, and as you rightly pointed out, GDevelop reads from top to bottom. The timer is being restarted over and over, but the events below that check it never get a chance to.
- The amITalking boolean fixes the issue because the value will always be false when the player speaks to an NPC for the second time, preventing the dialogue end event from running.
Thank you for helping me think it through. I made it work, but I’m not sure I could have slept tonight until I understood why! Note to self: don’t have a 6 week break from gamedev stuff or your brain goes to mush.