Skip to content

Commit 4646a90

Browse files
update Open Source Docs from Roblox internal teams
1 parent c0a57c6 commit 4646a90

File tree

11 files changed

+135
-12
lines changed

11 files changed

+135
-12
lines changed

content/common/navigation/engine/guides.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,8 @@ navigation:
201201
section:
202202
- title: Overview
203203
path: /scripting/events/
204+
- title: Deferred Events
205+
path: /scripting/events/deferred
204206
- title: Bindable
205207
path: /scripting/events/bindable
206208
- title: Remote
Lines changed: 3 additions & 0 deletions
Loading

content/en-us/cloud/legacy.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,11 @@ This page summarizes the available operations and authentication types.
2020
- Base URL: `https://apis.roblox.com/legacy-badges`
2121
- Authentication types: OAuth 2.0 and API key
2222
- Additional Badges API endpoints without Open Cloud authentication support can be found [here](/cloud/legacy/badges/v1).
23-
- Robux might be required to create a badge. To identify the number of remaining free badges you can create in the specified universe for the current UTC day, use the `/v1/universes/{universeId}/free-badges-quota` endpoint.
23+
- Robux might be required to create a badge. To identify the number of remaining free badges you can create for the current UTC day in the specified universe, use the `/v1/universes/{universeId}/free-badges-quota` endpoint found [here](/cloud/legacy/badges/v1).
24+
2425
| **API** | **Path** | **Scope** |
2526
| :---------- | :-------------------------- | :---------------------------- |
26-
| UpdateBadge | `PATCH v1/badges/{badgeId}` | `legacy-universe.badge:write` |
27+
| UpdateBadge | `PATCH v1/badges/{badgeId}` | `legacy-universe.badge:write` or `legacy-universe.badge:manage-and-spend-robux` |
2728
| CreateBadge | `POST v1/universes/{universeId}/badges` | `legacy-universe.badge:manage-and-spend-robux` |
2829

2930
## Develop API

content/en-us/education/developer/beta-testing-experiences.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Beta Testing Experiences
33
description: Learn common methods of beta testing on Roblox, recommended for success metrics, and options for community feedback.
44
---
55

6-
Developers on the Roblox platform have a strong culture of conducting beta tests in order to get feedback from the community and to begin collecting analytics about their user base. There's several ways to collect user feedback, starting with closed betas and then moving to open betas after the initial feedback has been addressed.
6+
Developers on the Roblox platform have a strong culture of conducting beta tests in order to get feedback from the community and to begin collecting analytics about their user base. There are several ways to collect user feedback, starting with closed betas and then moving to open betas after the initial feedback has been addressed.
77

88
## Testing Options
99

@@ -276,7 +276,7 @@ A think-aloud is a method of studying the mental processes people use in a task.
276276

277277
## Analytics
278278

279-
Analytics gathered during a beta program are often used to gauge if a launch experience will be on track to meeting it's goals. For instance, many common Roblox experiences have specific goals for retention, monetization, and session time.
279+
Analytics gathered during a beta program are often used to gauge if a launch experience is on track to meeting its goals. For instance, many common Roblox experiences have specific goals for retention, monetization, and session time.
280280

281281
### Tracking Analytics
282282

content/en-us/production/monetization/price-optimization.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ title: Price Optimization
33
description: Price optimization finds the best price points for your passes and developer products, helping you earn more money over time.
44
---
55

6+
<Alert severity="error">
7+
Price optimization tests will not be available from December 6 2024 to January 6 2025. To make sure your prices are optimized before the holiday season, start a pricing test before December 6.
8+
</Alert>
9+
610
<iframe width="800" height="450" src="https://www.youtube-nocookie.com/embed/ULr3CZ8egP8" title="YouTube video player" frameborder="0" allow="accelerometer; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
711

812
<br />

content/en-us/reference/engine/classes/Workspace.yaml

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -749,12 +749,17 @@ properties:
749749
immediately when the event fires, or deferred and then resumed at a later
750750
resumption point. Resumption points currently include:
751751
752-
- `Class.RunService.RenderStepped`
753-
- Waiting script resumption such as `Library.task.wait()`,
754-
`Library.task.spawn()`, and `Library.task.delay()`
755-
- `Class.RunService.Stepped`
752+
- Input processing (resumes once per input to be processed, see `Class.UserInputService`)
753+
- `Class.RunService.PreRender`
754+
- Legacy waiting script resumption such as `wait()`, `spawn()`, and `delay()`
755+
- `Class.RunService.PreAnimation`
756+
- `Class.RunService.PreSimulation`
757+
- `Class.RunService.PostSimulation`
758+
- Waiting script resumption such as `Library.task.wait()`, `Library.task.spawn()`, and `Library.task.delay()`
756759
- `Class.RunService.Heartbeat`
757760
- `Class.DataModel.BindToClose`
761+
762+
For more information, see [Deferred Events](../../../scripting/events/deferred.md).
758763
code_samples:
759764
type: SignalBehavior
760765
tags:

content/en-us/reference/engine/datatypes/Region3.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ constructors:
2626
- name: Region3.new
2727
summary: Returns a new `Datatype.Region3` using the provided vectors as boundaries.
2828
description: |-
29-
Returns a new `Datatype.Region3` given the `Datatype.Vector3` bounds of a the
29+
Returns a new `Datatype.Region3` given the `Datatype.Vector3` bounds of the
3030
rectangular prism volume.
3131
3232
Note that the order of the provided bounds matters: by switching them, the

content/en-us/reference/engine/enums/SignalBehavior.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ description: |
66
Determines when the engine resumes event handlers. At some future point, the
77
default mode will be `Deferred` but opt-out will still be possible through use
88
of `Immediate`.
9+
10+
For more information, see [Deferred Events](../../../scripting/events/deferred.md).
911
code_samples:
1012
tags: []
1113
deprecation_message: ''
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
title: Deferred Engine Events
3+
description: Deferred engine events defer event handlers until certain resumption points.
4+
---
5+
6+
The `Class.Workspace.SignalBehavior` property controls whether event handlers are fired immediately or deferred. We recommend the `Enum.SignalBehavior.Deferred` option, which helps improve the performance and correctness of the engine. The event handlers for **deferred events** are resumed at the next [resumption point](#resumption-points), along with any newly triggered event handlers.
7+
8+
<Alert severity="info">
9+
The `Enum.SignalBehavior.Default` value of `Class.Workspace.SignalBehavior` is currently equivalent to `Enum.SignalBehavior.Immediate`, but will eventually switch to being equivalent to `Enum.SignalBehavior.Deferred`. Template places are directly set to `Enum.SignalBehavior.Deferred` by default.
10+
</Alert>
11+
12+
The following diagram compares the `Enum.SignalBehavior.Immediate|Immediate` event behavior and the `Enum.SignalBehavior.Deferred|Deferred` event behavior.
13+
14+
- With the `Immediate` behavior, if an event triggers another event, the second event handler fires immediately.
15+
- With the `Deferred` behavior, the second event is added to the back of a queue and run later.
16+
17+
The total time taken does not change, but the ordering is different.
18+
19+
<img alt="A comparison of three event handlers firing with Immediate and Deferred behavior" src="../../assets/scripting/scripts/ImmediateVsDeferredEvents.png" width="100%" />
20+
21+
"Re-entrancy" prevents events from continuously firing one another when they reach a certain depth. The current limit for this is 10.
22+
23+
## Deferred Event Benefits
24+
25+
The `Immediate` behavior has some disadvantages. For every instance added to your game, property that changes, or some other trigger that is invoked, the engine needs to run Lua code before anything else happens.
26+
27+
- To change 1,000 properties, 1,000 snippets of code potentially need to run after each change.
28+
- Strange, hard-to-diagnose bugs can occur, such as a removing event firing before something was even added.
29+
- Performance-critical systems can fire events requiring them to yield back and forth to Lua.
30+
- Event handlers can make changes to the place or trigger other events any time an event is fired.
31+
- An event can fire multiple times despite being redundant, such as a property changing twice.
32+
33+
By having specific portions of the engine life cycle in which Lua can run, the engine can gain improved performance by using a number of assumptions:
34+
35+
- Performance-critical systems don't need to yield to Lua, which leads to performance gains.
36+
- Unless the engine itself changes it, the place never changes outside of a resumption point.
37+
38+
## Resumption Points
39+
40+
After being deferred, an event handler is resumed at the next resumption point. Currently, the set of resumption points includes:
41+
42+
- Input processing (resumes once per input to be processed, see `Class.UserInputService`)
43+
- `Class.RunService.PreRender`
44+
- Legacy waiting script resumption such as `wait()`, `spawn()`, and `delay()`
45+
- `Class.RunService.PreAnimation`
46+
- `Class.RunService.PreSimulation`
47+
- `Class.RunService.PostSimulation`
48+
- Waiting script resumption such as `Library.task.wait()`, `Library.task.spawn()`, and `Library.task.delay()`
49+
- `Class.RunService.Heartbeat`
50+
- `Class.DataModel.BindToClose`
51+
52+
## Common Affected Code Patterns
53+
54+
With remote events, the following examples either stop working correctly or have subtly different behavior; they rely on events being resumed immediately.
55+
56+
### Triggering and Catching Events Mid-Execution
57+
58+
In this example, `false` is always returned when deferred events are enabled because the callback has not run. To work correctly, the thread must yield until at least when the event should have fired.
59+
60+
```lua
61+
local success = false
62+
event:Connect(function ()
63+
success = true
64+
end)
65+
doSomethingToTriggerEvent() -- Causes `event` to fire
66+
return success
67+
```
68+
69+
### Listening for the First Occurrence of an Event
70+
71+
```lua
72+
connection = event:Connect(function ()
73+
connection:Disconnect()
74+
-- do something
75+
end)
76+
```
77+
78+
With deferred events enabled, multiple event handler invocations can be queued before you disconnect from the event. Calling `Class.Instance.Disconnect()|Disconnect()` drops all pending event handler invocations—the same behavior that exists for immediate events.
79+
80+
<Alert severity="warning">
81+
Any other method of disconnection besides `Class.Instance.Disconnect()|Disconnect()`, such as calling `Class.Instance.Destroy()|Destroy()` on the `Class.Instance`, disconnects the signal immediately, but runs the associated event handler for any events that are still pending.
82+
</Alert>
83+
84+
Alternatively, use `Datatype.RBXScriptSignal.Once()|Once()` as a more convenient method for connecting to an event that you only need the first invocation of.
85+
86+
### Events That Change Ancestry or Properties
87+
88+
Deferred events cause events that handle a change in ancestry or a property to fire after the ancestry or property is changed:
89+
90+
```lua
91+
local part = Instance.new("Part", workspace)
92+
93+
local function onPartDestroying()
94+
print("In signal:", part:GetFullName(), #part:GetChildren())
95+
end
96+
97+
part.Destroying:Connect(onPartDestroying)
98+
part:Destroy()
99+
```
100+
101+
Because `Class.Instance.Destroy()|Destroy()` works immediately after the script that called it yields, the instance has already been destroyed by the time `onPartDestroying()` is called. For more examples, see `Class.Instance.Destroying`.

content/en-us/scripting/events/index.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ Due to the sheer number of events and client-server architecture, Roblox scripti
1111

1212
You don't have to listen for events or take any action in response to them, but the events are firing and available nevertheless. When you do want to respond to an event, you connect a function to it.
1313

14+
<Alert severity="info">
15+
Deferred events can help you ensure more performant and consistent event handling. See [Deferred Events](deferred.md) for more information.
16+
</Alert>
17+
1418
## Connecting Functions to Events
1519

1620
You connect a function to an event using `Datatype.RBXScriptSignal.Connect()|Connect()` to execute code each time the event fires. Most events pass arguments to their connected functions. For example, the `Class.BasePart.Touched` event passes the object that touched the part (such as a left hand or car wheel), and the `Class.Players.PlayerAdded` event passes the `Class.Player` that joined your experience.
@@ -78,7 +82,7 @@ connection = part.Touched:Connect(onPartTouched)
7882
If you only want to connect a function to an event once—that is, only run the function the first time the event fires—use the `Datatype.RBXScriptSignal.Once()|Once()` method as a more convenient alternative to connecting and disconnecting the function.
7983

8084
<Alert severity="info">
81-
When Luau destroys an event's object, such as the `Class.Player` object when a user leaves the experience, all of its connections disconnect automatically.
85+
When Luau destroys an event's object, such as the `Class.Player` object when a user leaves the experience, all of its ([non-deferred](deferred.md)) connections disconnect automatically.
8286
</Alert>
8387

8488
## Waiting for Events to Fire

0 commit comments

Comments
 (0)