You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/en-us/production/monetization/developer-products.md
+72-10Lines changed: 72 additions & 10 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -11,7 +11,7 @@ A **developer product** is an item or ability that a user can purchase more than
11
11
For items or abilities that a user should only purchase **once**, such as a special weapon or a permanent power-up, see [Passes](../../production/monetization/game-passes.md).
12
12
</Alert>
13
13
14
-
## Create developer products
14
+
## Create a developer product
15
15
16
16
<Alertseverity="warning">
17
17
Before creating a developer product, make sure your experience has been [published](../../production/publishing/publish-experiences-and-places.md) and is accessible on Roblox.
@@ -28,10 +28,10 @@ To create a developer product:
28
28
7. Click **Create Developer Product**.
29
29
30
30
<Alertseverity="info">
31
-
If you want to use the developer product as a randomized reward, review the [randomized virtual item policy](./randomized-virtual-items-policy.md).
31
+
If you want to use the developer product as a randomized reward, review the [randomized virtual item policy](./virtual-items.md).
32
32
</Alert>
33
33
34
-
## Get developer product IDs
34
+
## Get the developer product ID
35
35
36
36
To use scripting, you need a developer product ID. To get the product ID:
37
37
@@ -41,15 +41,29 @@ To use scripting, you need a developer product ID. To get the product ID:
If you're using [price optimization](./price-optimization.md), make sure to place the script inside a `Class.LocalScript` so that users see personalized product prices.
48
48
</Alert>
49
49
50
+
Before selling developer products, make sure you are properly processing sales receipts and granting users their purchased products. To do so, you must:
51
+
52
+
- Use the `Class.MarketplaceService.ProcessReceipt|ProcessReceipt` API to check purchase receipts. `ProcessReceipt` automatically reads and acknowledges that a user has purchased a product outside of the experience.
53
+
- Validate each receipt for `User ID`, `Developer Product ID`, and the receipt status.
54
+
- If the receipt has a status of **Open**, grant the user the developer items they have purchased.
55
+
- Respond to the `ProcessReceipt` API with a message acknowledging the receipt and validating that the purchased items were granted.
56
+
57
+
You can sell developer products in two ways:
58
+
59
+
-[Inside your experience](#inside-your-experience)
60
+
-[Outside your experience](#outside-your-experience)
61
+
62
+
### Inside your experience
63
+
50
64
To implement and sell a developer product inside an experience, call `Class.MarketplaceService|MarketplaceService` functions.
51
65
52
-
Use `Class.MarketplaceService:GetProductInfo()|GetProductInfo()` to retrieve information about a developer product, like name and price, and then to display that product to users. You can sell the product inside your experience's marketplace, for example. For developer products, the second parameter must be `Enum.InfoType.Product`.
66
+
Use `Class.MarketplaceService:GetProductInfo()|GetProductInfo` to retrieve information about a developer product, like name and price, and then to display that product to users. You can sell the product inside your experience's marketplace, for example. For developer products, the second parameter must be `Enum.InfoType.Product`.
Use `Class.MarketplaceService:GetDeveloperProductsAsync()|GetDeveloperProductsAsync()` to retrieve all developer products associated with your experience. This function returns a `Class.Pages|Pages` object that you can inspect and filter to build things like an in-experience store or product list GUI.
87
+
Use `Class.MarketplaceService:GetDeveloperProductsAsync()|GetDeveloperProductsAsync` to retrieve all developer products associated with your experience. This function returns a `Class.Pages|Pages` object that you can inspect and filter to build things like an in-experience store or product list GUI.
@@ -88,7 +102,7 @@ if success and developerProducts then
88
102
end
89
103
```
90
104
91
-
Use `Class.MarketplaceService:PromptProductPurchase()|PromptProductPurchase()` to prompt product purchases inside your experience. You can call this function when a user performs actions like pressing a button or talking to a vendor NPC.
105
+
Use `Class.MarketplaceService:PromptProductPurchase()|PromptProductPurchase` to prompt product purchases inside your experience. You can call this function when a user performs actions like pressing a button or talking to a vendor NPC.
To enable developer product purchases outside your experience, you must work with the `Class.MarketplaceService.ProcessReceipt|ProcessReceipt` API. After a user makes a purchase in the Store tab of your experience details page, you must use `ProcessReceipt` to confirm their purchase and grant them their items once they enter your experience.
163
+
164
+
<Alertseverity="warning">
165
+
Do **not** use the `Class.MarketplaceService:PromptProductPurchaseFinished|PromptProductPurchaseFinished` event to process purchases. You must use the `ProcessReceipt` callback instead.
166
+
167
+
The firing of `PromptProductPurchaseFinished` does not mean that a user has successfully purchased an item.
168
+
</Alert>
169
+
170
+
#### Test mode
171
+
172
+
The **test mode** feature helps you validate your purchase flow by simulating a developer product purchase outside your experience. You should use test mode to make sure that you have implemented `ProcessReceipt` correctly before enabling external developer product sales.
173
+
174
+
The developer products you put up for sale in test mode can only be seen by you and by members of your group. They are not visible to users.
175
+
176
+
To test your implementation:
177
+
178
+
1. In the **Creator Hub**, go to **Monetization** > **Developer Products**.
179
+
2. Click the **⋮** menu and select **External Purchase Settings**.
180
+
3. In the **External Purchase Settings** page, click **Enable test mode**.
181
+
4. Once test mode is active, return to the **Developer Products** page and select a product to test.
182
+
5. In the **Basic Settings** page, select the **Allow external purchases** checkbox and save your changes.
183
+
6. Go to the **Store** tab of the experience details page and purchase the product you made available for sale.
184
+
7. Enter the experience and confirm that you have received the product you purchased. The receipt status of the `ProcessReceipt` API should update to **Closed**.
185
+
186
+
After you test your implemention, Roblox verifies that the test has been successfully completed and allows you to fully activate the feature to sell developer products outside your experiences.
187
+
188
+
For more information about the `ProcessReceipt` API and its implementation, see the `Class.MarketplaceService.ProcessReceipt|ProcessReceipt` page.
189
+
190
+
#### Enable external sales
191
+
192
+
<Alertseverity="info">
193
+
You can only enable external sales after you have used test mode to validate your purchase flow.
194
+
</Alert>
195
+
196
+
To enable external sales:
197
+
198
+
1. Go to the **External Purchase Settings** page.
199
+
2. Turn on **External Purchases**.
200
+
3. Return to the **Developer Products** page and select the products you want to sell outside of your experience.
201
+
4. In the **Basic Settings** page, select the **Allow external purchases** checkbox and save your changes.
202
+
5. Confirm that the products are now available for purchase in the **Store** tab of the experience details page.
203
+
204
+
To disable the external sale of a developer product, select the product on the **Developer Products** page and clear the **Allow external purchases** checkbox.
205
+
206
+
## Handle a developer product purchase
207
+
208
+
After a user purchases a developer product, you must handle and record the transaction. To do this, use a `Class.Script` within `Class.ServerScriptService` using the `ProcessReceipt` function.
147
209
148
-
After a user purchases a developer product, you must handle and record the transaction. To do this, use a `Class.Script` within `Class.ServerScriptService` using the `Class.MarketplaceService.ProcessReceipt()|ProcessReceipt()` function.
210
+
For more information about the `ProcessReceipt` API and its implementation, see the `Class.MarketplaceService.ProcessReceipt|ProcessReceipt` page.
@@ -218,7 +280,7 @@ The functions for handling each product ID must return `true` for the transactio
218
280
Although Roblox itself does **not** record the purchase history of developer products by specific users, you can request to [download sales data](../../production/analytics/analytics-dashboard.md#sales-data). If you want to track user-specific purchase history, it's your responsibility to [store the data](../../cloud-services/data-stores/index.md).
219
281
</Alert>
220
282
221
-
## Developer Product analytics
283
+
## Developer product analytics
222
284
223
285
Use developer product analytics to analyze the success of individual products, identify trends, and forecast potential future earnings.
Copy file name to clipboardExpand all lines: content/en-us/production/monetization/game-passes.md
+21-18Lines changed: 21 additions & 18 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -9,7 +9,7 @@ description: Passes let you charge users a one-time Robux fee to access privileg
9
9
For items that a player might purchase multiple times, such as potions, temporary power-ups, or in-experience currency, see [Developer Products](../../production/monetization/developer-products.md).
10
10
</Alert>
11
11
12
-
## Create passes
12
+
## Create a pass
13
13
14
14
<Alertseverity="warning">
15
15
Before creating a pass, make sure your experience has been [published](../../production/publishing/publish-experiences-and-places.md) and is accessible on Roblox.
@@ -40,10 +40,10 @@ To create a pass:
40
40
</GridContainer>
41
41
42
42
<Alertseverity="info">
43
-
If you want to use the pass as a randomized reward, review the [Randomized Virtual Item Policy](./randomized-virtual-items-policy.md).
43
+
If you want to use the pass as a randomized reward, review the [Randomized Virtual Item Policy](./virtual-items.md).
44
44
</Alert>
45
45
46
-
## Get pass IDs
46
+
## Get the pass ID
47
47
48
48
To use scripting, you need a pass ID. To get the pass ID:
49
49
@@ -53,27 +53,18 @@ To use scripting, you need a pass ID. To get the pass ID:
If you're using [price optimization](./price-optimization.md), make sure to place the script inside a `Class.LocalScript` so that users see personalized pass prices.
60
60
</Alert>
61
61
62
-
You can sell passes outside or inside an experience.
62
+
You can sell passes in two ways:
63
63
64
-
### Outside an experience
64
+
-[Inside your experience](#inside-your-experience)
65
+
-[Outside your experience](#outside-your-experience)
65
66
66
-
To sell a pass in an experience's **Store** page:
67
-
68
-
1. Go to **Monetization**⟩**Passes**.
69
-
2. Hover over the pass and click the **⋯** menu.
70
-
3. Select the pass you want to sell.
71
-
4. Select **Sales**.
72
-
5. Enable to **Item for Sale** toggle.
73
-
6. In the **Price in Robux** field, enter the amount of Robux you want to charge users for the pass. The price you enter affects how much Robux you earn per sale. The price you enter affects how much Robux you earn per sale. The minimum price is 1 Robux, and the maximum price is 1 billion Robux.
74
-
7. Click **Save Changes**. The pass populates in the experience's **Store** page.
75
-
76
-
### Inside an experience
67
+
### Inside your experience
77
68
78
69
To implement and sell a pass inside an experience, call `Class.MarketplaceService|MarketplaceService` functions.
Although Roblox itself does **not** record the purchase history of developer products by specific users, you can request to [download sales data](../../production/analytics/analytics-dashboard.md#sales-data). If you want to track user-specific purchase history, it's your responsibility to [store the data](../../cloud-services/data-stores/index.md).
163
154
</Alert>
164
155
156
+
### Outside your experience
157
+
158
+
To sell a pass on the **Store** tab of the experience details page:
159
+
160
+
1. Go to **Monetization** > **Passes**.
161
+
2. Hover over the pass and click the **⋯** menu.
162
+
3. Select the pass you want to sell.
163
+
4. Select **Sales**.
164
+
5. Enable to **Item for Sale** toggle.
165
+
6. In the **Price in Robux** field, enter the amount of Robux you want to charge users for the pass. The price you enter affects how much Robux you earn per sale. The price you enter affects how much Robux you earn per sale. The minimum price is 1 Robux, and the maximum price is 1 billion Robux.
166
+
7. Click **Save Changes**. The pass populates in the **Store** tab of the experience details page.
167
+
165
168
## Assign pass privileges
166
169
167
170
You must manually assign pass privileges to users that purchase your passes. To do this, use `Class.Players.PlayerAdded|PlayerAdded` when a user joins your experience to check if they already own the pass and to assign them the pass privileges.
@@ -212,7 +215,7 @@ With analytics, you can:
212
215
To access pass analytics:
213
216
214
217
1. Go to [Creations](https://create.roblox.com/dashboard/creations) and select an experience.
Copy file name to clipboardExpand all lines: content/en-us/studio/microprofiler/index.md
+10-6Lines changed: 10 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,7 +3,7 @@ title: MicroProfiler
3
3
description: The MicroProfiler is a Studio and client tool for optimizing your experience.
4
4
---
5
5
6
-
The **MicroProfiler** is an optimization tool available in Roblox Studio and the Roblox client that provides detailed timing information for [task scheduler](../../studio/microprofiler/task-scheduler.md) tasks called **tags**.
6
+
The **MicroProfiler** is a performance optimization and troubleshooting tool available in Roblox Studio and the Roblox client. It provides detailed timing information for [task scheduler](../../studio/microprofiler/task-scheduler.md) tasks called **tags**.
7
7
8
8
- For a list of common tasks, refer to the [tag reference](../../studio/microprofiler/tag-table.md).
9
9
- For a step-by-step example of using the MicroProfiler to identify a performance issue, see the [MicroProfiler walkthrough](../../studio/microprofiler/use-microprofiler.md).
@@ -16,7 +16,7 @@ When open, a menu bar is visible at the top of the 3D viewport. In the default m
16
16
17
17
<imgalt="The Microprofiler frame graph, showing blue frames and detailed frame information."src="../../assets/optimization/microprofiler/micro-frame.png"width="440px" />
18
18
19
-
Bars should generally be around the middle of the graph, but you might see sudden spikes (rapid increases in value). Spikes indicate that more time was taken to perform some task, usually because of an increased workload. For instance, creating a lot of moving parts requires more work from the physics simulation, which then needs more time to process motion and part contacts. The following image shows an example of a spike:
19
+
Bars should generally be around the middle of the graph, but you might see sudden spikes (rapid increases in values). Spikes indicate that more time was taken to perform some task, usually because of an increased workload. For instance, creating a lot of moving parts requires more work from the physics simulation, which then needs more time to process motion and part contacts. The following image shows an example of a spike:
20
20
21
21
<imgalt="The Microprofiler with several bars higher than others."src="../../assets/optimization/microprofiler/micro-spike.png"width="300px" />
22
22
@@ -34,7 +34,7 @@ There are three main thread types:
34
34
35
35
-**Main/Render**: Perhaps unintuitively, runs on the CPU. Processes input, `Class.Humanoid|Humanoids`, animations/tweening, physics ownership, sound, and waiting script resumes. Also updates Studio interfaces and coordinates the other threads.
36
36
37
-
-**Worker** ("RBX Worker"): Helps the main thread with networking, physics, and pathfinding. Due to the number of cores in modern CPUs, you likely have many worker threads.
37
+
-**Worker** ("RBX Worker"): Helps the main thread with networking, physics, and pathfinding. Due to the number of cores in modern CPUs, you likely have many worker threads, most of which are in a sleep state at any given time.
38
38
39
39
-**Render** ("GPU"): Follows a "prepare, perform, present" logic. Communicates with the graphics processing unit (GPU) of the device.
40
40
@@ -48,7 +48,7 @@ If your scripts are running complicated tasks, you can profile critical portions
48
48
49
49
```lua title="HardWorkScript"
50
50
debug.profilebegin("Hard Work")
51
-
--Here is where the code to be profiled should be
51
+
--Code to be profiled
52
52
debug.profileend()
53
53
```
54
54
@@ -135,9 +135,13 @@ In general, the MicroProfiler web UI works similarly to [detailed mode](./modes.
135
135
- Lighter portions of the preview bar and lighter labels on the timeline indicate portions of the frame with higher memory allocation.
136
136
- In X-ray mode, press <kbd>C</kbd> to show the total size of the memory allocations rather than the number of allocations.
137
137
138
-
- Use the **Export** menu to export a CPU or memory flame graph, a specialized visualization that aggregates all of the call stacks included in the dump. The flame graph is especially useful for identifying tasks that don't take particularly long to run (and are therefore hard to notice), but run so often that their processing time becomes significant.
138
+
- Use the **Export** menu to export a CPU or memory flame graph, a specialized visualization that aggregates all of the call stacks included in the dump, maintains the parent-child hierarchy, and sizes them based on duration. Flame graphs are especially useful for identifying tasks that don't take particularly long to run (and are therefore hard to notice), but run so often that their processing time becomes significant.
<imgalt="The MicroProfiler flame graph in the web UI."src="../../assets/optimization/microprofiler/micro-flame.png" />
141
+
142
+
You can also create flame graphs in Studio, although only for scripts (execution time and memory allocations). Compared to the web-based flame graphs, the ones in Studio are top-down rather than bottom-up and support dramatically longer capture times.
143
+
144
+
<imgalt="The MicroProfiler flame graph in Studio."src="../../assets/optimization/microprofiler/micro-studio-flame.png" />
141
145
142
146
- Drag and drop a second dump file into the web UI to generate a diff flame graph, which can help you identify improvements or regressions to your experience's performance over time. Click **Combine & Compare** to export a new HTML file.
Copy file name to clipboardExpand all lines: content/en-us/studio/microprofiler/tag-table.md
+4Lines changed: 4 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,6 +5,10 @@ description: A list of tags for the MicroProfiler.
5
5
6
6
The following is a list of common tags in the MicroProfiler, grouped by category. Understanding these tags can help you identify problematic code in your experience. The tables contain tag label, descriptions and performance advice for improving performance and optimizing your experience.
7
7
8
+
## Sleep
9
+
10
+
When threads aren't actively performing tasks, they enter a sleep state, with tags to indicate how long the thread was sleeping. At any given time, it's extremely common for most worker threads to be in a sleep state.
Copy file name to clipboardExpand all lines: content/en-us/studio/microprofiler/task-scheduler.md
+1-2Lines changed: 1 addition & 2 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -31,8 +31,7 @@ The most direct way to add frame-by-frame game tasks is through the following me
31
31
32
32
The task scheduler categorizes and completes tasks in the following order. Some tasks may not perform work in a frame, while others may run multiple times.
0 commit comments