Ah. When you change the text, it will fire this event, which will change the text, which will fire this event. This leads to an infinite loop that can lead to the error you are having. Try using a debounce
local debounce = false
if debounce == false then debounce = true
script.Parent.Text = string.rep('•', #script.Parent.Text)
if string.sub(script.Parent.Text, 1, 20) then
script.Parent.Text = string.sub(script.Parent.Text, 1, 20)
debounce = false
When the event fires, the debounce will prevent the event from running the code again until it has changed the text, so it wont loop
Make the text of the TextBox invisible, then add a TextLabel’s on top of it.
Then, use your original code, except instead of changing the TextBox’s text, change the TextLabel’s text instead.
This will also help you with being able to accurately read what the actual text is in your code (the TextBox’s text will be the original text), while displaying to the user the dots.
Then, you don’t have to change the TextBox’s text at all, you can just convert it to dots and display it on the TextLabel. It’ll accomplish the same thing without having to worry about max re-entry depth, debounces, or anything like that. It greatly simplifies the code.