Making a dialog system with tokens that pause a certain amount of time?

hi! i have a dialog system i use for all of my games, and i’m trying to improve it a little. it’s a typewriter system, going letter by letter.

i’d like to make it so i can type {10} or something similar in the dialog, and have it read that, pause, and not show the token in the dialog. i can do the first two things, but not showing the token is where i’m completely stumped.

here’s my current typewriter code (in the dialog system), if that helps. i can’t really think of where i’d start to pull this off

for first, last in utf8.graphemes(label.Text) do 
		local grapheme = label.Text:sub(first, last) 
		index += 1
		if grapheme ~= " " then
			label.MaxVisibleGraphemes = index
			task.wait()
		end
	end

To hide text, you can set the TextLabel to RichText, then put your information inside rich text comments.

Comments have the following format:

"Hello,<!--This text won't show up--> world!"

You can read about rich text here:

Note that you’ll need to use regular indexes to find the rich text comments (comments don’t count as graphemes because they aren’t visible), so use the first and last indices.

1 Like

this sounds really helpful, but i just can’t think of how i’d actually make use it. maybe a function before displaying the text, looking at where these are and storing the positions in graphemes, then checking if we’re at the position every letter? but that sounds unoptimized… do you have any suggestions on specifics? or should i just go with that?

Assuming you don’t have pauses at the very start before any graphemes, you could do something like this:

format_start = "<!--"
format_end = "-->"
for first, last in utf8.graphemes(label.Text) do 
		local grapheme = label.Text:sub(first, last)

		local waitTime = 0  -- (Same as not putting a wait time: the minimum wait time is a Heartbeat, which is the default when none is given)
		-- If the next characters after the grapheme are <!--
		if label.Text:sub(last+1, last+string.len(format_start)+1) == format_start then
			-- Find a closing -->
			startIndex, endIndex = string.find(label.Text, format_end, last+string.len(format_start)+1)
			if startIndex then
				-- Get the text between the two
				numberString = label.Text:sub(last+string.len(format_start)+1, startIndex-1)
				-- If the text is a number update the `waitTime`
				number = tonumber(numberString)
				if number then
					waitTime = number
				end
			end
		end

		index += 1
		if grapheme ~= " " then
			label.MaxVisibleGraphemes = index
			task.wait(waitTime)
		end
	end

TL;DR: For each grapheme look for a wait indicator directly after the grapheme in the string. If there is one then wait.

That’s a good solution, though I would store the positions as regular text indices and use the text indicies returned by utf8.graphemes to compare (translating to grapheme indices sounds hard). The run time of that would still be linear/O(n) so it would run fast. Plus, the text isn’t ever massive and the operations are split between frames (because of the task.wait()) so optimizations aren’t very important.

1 Like

stared at this until i understood it, and it’s way simpler than i thought! thank you for all of the help!!

1 Like