TypeWriter effect goes too slow

i tried to use RunService.RenderedStepped:Wait() like this


but it have a error like this:

i also tried to definite the “RunService” in the script

What did you define RunService as?

the same as the MoudleScript, local RunService=game:GetService("RunService")

Also it isn’t RenderedStepped, it’s RenderStepped

ok, i will try it out one hour later cuz i have to go outside now

It’s RenderStepped, not RenderedStepped.

You have a typo.

Also, I’m not sure RenderStepped has a Wait method like that. Might be wrong, but I’ve always used it by binding functions to RenderStepped (See the documentation).

okay i will try it out later i need to go outside

It does have a Wait() method. It says it on the API

Really? Where?

I tried to look for it in RunService and in RunService.RenderStepped and couldn’t find it. I’ve even searched explicitly for it and found nothing.

Seems like bad documentation…

Also, this seems like a bad time to use RenderStepped. I would use Heartbeat or Stepped. This does not need to be happening before frame rendering… unless i guess you want a literal 1 frame delay?

EDIT: Googling it, I found this.

This confirms my suspicion that binding wait (which has a 30 FPS cap) to RenderStepped would be a bad idea (since now your game waits 1/30th of a second before rendering the frame… 30 FPS frame cap!)

EDIT 2: Apparently, that’s not how :wait works when it’s bound to events.

Apparently :wait() - as opposed to wait() - simply yields the thread until the function it’s bound to (in this case render stepped) finishes/returns, so in this case, it would actually be pretty useful.

Nifty! TIL

It is not bad documentation, you aren’t looking in the correct place. :Wait is a method of RBXScriptSignal, not RenderStepped specifically.

https://developer.roblox.com/en-us/api-reference/datatype/RBXScriptSignal

3 Likes

That makes sense, but how was I supposed to figure this out?

Seems like wizardry to know that “Event” is a nickname for RBXScriptSignal (is it?)

Why do these two methods (Wait() and Connect()) not show up as inherited methods when reading about an RBXScriptSignal-class event (i.e… :RenderStepped()), like how other classes show their inherited methods (i.e :FindFirstChild on any instance)?

I consider myself an experienced lua scripter, and never thought to search there; i’ve never seen it used like that.

This seems particularly bizarre given that wait() is a global method of it’s own, with totally different functionality (wait X seconds vs “fire when this event finishes firing”).

EDIT:

This is news to me, and it seems really useful. I’m guessing this fires 1 frame after the event finishes? Or does it fire on the same frame?

Just a small correction, but :Wait listens for when the event executes, and would return what the event returns (like with :Connect). You’re correct that it does yield the thread, but not quite that it yields until it “finishes/returns”; it listens for when the event executes. As an example

local Hit = Part.Touched:Wait();
print(Hit.Name, "Touched!");

EDIT

It’s not really “weird”; the wait method’s a sleep method, while the :Wait is a listener for when the event executes. You could argue that it has the thread “sleep”, but that’s not 100% accurate; one puts the thread to “sleep” for a duration, while the other’s listening for an event to execute.

1 Like

Maybe because it is meant to describe when this event is fired and what arguments its listener gets?

It wouldn’t make sense to document the same info on each event api reference page. RenderStepped is just a RBXScriptSignal, it doesn’t need any special documentation.

That is why when you go to a class that inherits from Instance but isn’t Instance itself, it links to the methods of Instance:

It doesn’t say

Oops! because there would be hundreds of duplicates of the same info for every other api reference page of classes. And it would imply its :ClearAllChildren method is non-inherited.

That is why it is not a member of RBXScriptSignal? Because it has a different purpose??

Maybe because it is meant to describe when this event is fired and what arguments its listener gets?

Forgive me, I’m not sure what you’re trying to say here.

Immediately below you say

It doesn’t say [] because there would be hundreds of duplicates of the same info for every other api reference page of classes. And it would imply its :ClearAllChildren method is non-inherited.

And yet, indeed, the API page for every class which inherits from Instance DOES list every inherited method.

That is why it is not a member of RBXScriptSignal? Because it has a different purpose??

Exactly, yet it has basically the same name…


The point is, this notation
RBXScriptSignal:Wait()

Implies that :Wait() is a method of RBXScriptSignal, the same way :FindFirstChild is an inherited method of Instance.

Thus, it seems odd to me that it’s not listed as an inherited method for all RBXScriptSignals explicitly. Case in point, I’ve read tons of roblox API and only ever figured this out through you calling me out. Cunningham’s Law, I guess.

Even if you don’t want to have this info on every RBXScriptSignal, surely this is at least relevant for the three functions usually used for timing (Heartbeat, Stepped, RenderStepped)?

Because RBXScriptSignal doesn’t have any inheritors neither doesn’t it inherit from any class, so it would be bloat to include it on all event documentation

It’s not really “weird”; the wait method’s a sleep method, while the :Wait is a listener for when the event executes. You could argue that it has the thread “sleep”, but that’s not 100% accurate; one puts the thread to “sleep” for a duration, while the other’s listening for an event to execute.

I understand this now, but my point stands that the two have different functionality, yet nearly identical names.

also, is :Wait not essentially “Wait for this to fire?” Isn’t that a synchronous “sleep” - as opposed to :Connect which would “execute whenever it fires, asynchronously”?

The global wait(n) yields the thread for approximately n seconds assuming n >= 1/30. rbx_script_signal:Wait() yields the thread until rbx_script_signal is fired. Which can take who knows how long depending on when whatever triggers it executes.

Different purposes. Just because they have similar names doesn’t mean they function identically in that sense.

Just use my typeWriting thing.

Game is open source for you to take the script and you can change the text type speed.

What do you mean it’s too slow? If you’re iterating each frame (<30ms) you’re writing pretty fast, is it even a typewriter anymore if you’re iterating faster than that? Do you just want to increase how many characters per step?

local function typewriter(str, packet, foo, callback)
   str = str or ''
   foo = foo or print
   packet = packet or {
       step = 1;
       wait = 0;
   }
   packet.step = packet.step or 1
   
   local l = #str
   local c = ''
   for i = 1, l, packet.step do
       c = c .. str:sub(i, i + (packet.step - 1))
       foo(c)
       if packet.wait then
          wait(packet.wait)
       end
   end
   
   if callback then
       callback(c)
   end
end

local configs = {
    step = 2; -- how many chars per wait time
    wait = 0; -- how many seconds to wait before each step
}

typewriter(
    'Hello, world! I can print like a typewriter!',
    configs,
    function (current_str) -- step function
       some_gui_frame.Text = current_str 
    end,
    function (finished_str) -- callback
        print('We finished typewriting the str')
    end
)
1 Like

Yup, I derped typing that. Because my answer was selected, I went back and fixed my spelling, and showed how RunService was declared.