Skip to content

Commit 421ea0f

Browse files
sync: update documentation sources (2026-03-05 19:17 UTC)
1 parent e392fe2 commit 421ea0f

39 files changed

Lines changed: 434 additions & 407 deletions

roblox/common/navigation/scale.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@ navigation:
1717
path: /production/publishing/badges
1818
- title: Events
1919
path: /production/promotion/experience-events
20+
- title: Recommendation systems
21+
path: /production/recommendation
2022
- title: Player invite prompts
2123
path: /production/promotion/invite-prompts
2224
- title: Connection referral system

roblox/en-us/art/characters/manually-update-catalog-heads.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -107,13 +107,16 @@ Fix your asset in Blender, or preferred 3D modeling software. In many cases, you
107107
5. Ensure the Blender animation start value is set to 0.
108108
6. Remove vertex colors. In Blender this can be done by clicking on the mesh and then under the data tab selecting color attributes and removing any that exist.
109109
<img src="../../assets/art/avatar/Delete-Vertex-Colors.png"/>
110-
7. Modify your head asset to pass validation:
110+
7. If needed, remove vertex color shading nodes for fbx export. The blender fbx exporter is more picky then glTF and won't accept nodes in between the texture input and the shader.
111+
<img src="../../assets/art/avatar/Remove-Vertex-Node-A.png"/>
112+
<img src="../../assets/art/avatar/Remove-Vertex-Node-B.png"/>
113+
8. Modify your head asset to [pass validation](./head-validation.md):
111114
1. Align cage eyes and mouth regions to the head.
112115
2. Ensure your head includes a rig, with poses keyframed and mapped to the FACs standard so that:
113116
1. Eyes must blink.
114117
2. Mouth must open and close.
115118
3. Face must express happy and sad.
116-
8. Export your updated head asset to FBX file format using the correct settings explained here (If you have PBR, you may want to use glTF).
119+
9. Export your updated head asset to FBX file format using the correct settings explained here (If you have PBR, you may want to use glTF).
117120
1. Setup textures for FBX export (if needed). Blender will import the glTF textures in such a way that they won't be able to be exported in an FBX file by default.
118121
1. To fix this go through each image and save it to your disk locally.
119122
<img src="../../assets/art/avatar/Blender-Save-Image-Workaround.png"/>
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading
Lines changed: 3 additions & 0 deletions
Loading

roblox/en-us/cloud/guides/configs.md

Lines changed: 26 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -18,29 +18,27 @@ All endpoints use your universe ID, which you can find on the [Creator Dashboard
1818

1919
For the full endpoint reference, request and response schemas, and error codes, see the [Cloud API reference](/cloud/reference).
2020

21-
## Repositories and namespaces
21+
## Repositories
2222

23-
Many requests to the configs endpoints require a **repository** in the path and a **namespace** in the request body. For example, this request adds a draft config:
23+
Requests to the configs endpoints use a **repository** in the path and an **entries** object in the request body. For example, this request adds a draft config:
2424

2525
```json
26-
PUT /creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/<REPOSITORY>
26+
PATCH /creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/<REPOSITORY>/draft
2727
{
28-
"namespaces": {
29-
"<NAMESPACE>": {
30-
"enableNewTutorial": true
31-
}
28+
"entries": {
29+
"enableNewTutorial": true
3230
}
3331
}
3432
```
3533

36-
- Repositories differ by product. They separate configs by system.
37-
- Namespaces are groupings within a product. They organize keys or mark them as being for some particular purpose.
34+
- **Repositories** differ by product and separate configs by system.
35+
- **Entries** are the config key-value pairs. You send and receive a single flat object of keys and values.
3836

39-
This guide covers in-experience configs, so all requests use `UniverseConfiguration` for repository and `UniverseConfigurations` for namespace. Repositories and namespaces will eventually expand to cover additional products and use cases.
37+
This guide covers in-experience configs, so all requests use `InExperienceConfig` for repository. Repositories will eventually expand to cover additional products and use cases.
4038

41-
| Use case | Repository | Supported namespaces |
42-
| --------------------- | ----------------------- | ------------------------ |
43-
| In-experience configs | `UniverseConfiguration` | `UniverseConfigurations` |
39+
| Use case | Repository |
40+
| --------------------- | -------------------- |
41+
| In-experience configs | `InExperienceConfig` |
4442

4543
## Create or update configs
4644

@@ -49,7 +47,7 @@ Before going live, config changes are staged as drafts. You can either set the e
4947
- **Starting from scratch or replacing everything** — Use the overwrite endpoint so that the payload is the full desired state. Any key you omit is treated as removed.
5048
- **Changing only some keys** — Use the partial update endpoint so only the keys you send are updated; everything else stays as-is.
5149

52-
This sample code sets `bossHealth` to `100` in the `UniverseConfigurations` namespace and uses the overwrite endpoint:
50+
This sample code sets `bossHealth` to `100` and uses the overwrite endpoint:
5351

5452
<Tabs>
5553
<TabItem key="1" label="Python">
@@ -59,15 +57,13 @@ import requests
5957

6058
API_KEY = "<API_KEY>"
6159
UNIVERSE_ID = "<UNIVERSE_ID>"
62-
BASE = f"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/{UNIVERSE_ID}/repositories/UniverseConfiguration"
60+
BASE = f"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/{UNIVERSE_ID}/repositories/InExperienceConfig"
6361
headers = {"x-api-key": API_KEY, "Content-Type": "application/json"}
6462

6563
# Optional: send previousDraftHash if you have an existing draft and want optimistic concurrency
6664
payload = {
67-
"namespaces": {
68-
"UniverseConfigurations": {
69-
"bossHealth": 100
70-
}
65+
"entries": {
66+
"bossHealth": 100
7167
}
7268
}
7369
r = requests.put(f"{BASE}/draft:overwrite", headers=headers, json=payload)
@@ -82,16 +78,16 @@ print("Draft staged. draftHash:", draft_hash)
8278

8379
```bash
8480
curl --request PUT \
85-
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/UniverseConfiguration/draft:overwrite" \
81+
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/InExperienceConfig/draft:overwrite" \
8682
--header "x-api-key: <API_KEY>" \
8783
--header "Content-Type: application/json" \
88-
--data '{"namespaces":{"UniverseConfigurations":{"bossHealth":100}}}'
84+
--data '{"entries":{"bossHealth":100}}'
8985
```
9086

9187
</TabItem>
9288
</Tabs>
9389

94-
The response includes the `draftHash` value. You need this hash in order to publish. If you prefer to only tweak a few keys in your draft, use the PATCH method on the `/draft` endpoint and only send the namespaces and keys you want to change.
90+
The response includes the `draftHash` value. You need this hash in order to publish. If you prefer to only tweak a few keys in your draft, use the PATCH method on the `/draft` endpoint and only send the entries (keys) you want to change.
9591

9692
### About draft hashes
9793

@@ -126,7 +122,7 @@ print("Published. configVersion:", result["configVersion"])
126122
```bash
127123
# Use the draftHash from the previous step
128124
curl --request POST \
129-
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/UniverseConfiguration/publish" \
125+
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/InExperienceConfig/publish" \
130126
--header "x-api-key: <API_KEY>" \
131127
--header "Content-Type: application/json" \
132128
--data '{
@@ -159,7 +155,7 @@ To confirm the change went through, fetch the latest published config. Use the v
159155
r = requests.get(BASE, headers=headers)
160156
r.raise_for_status()
161157
config = r.json()
162-
boss_health = config["namespaces"]["UniverseConfigurations"].get("bossHealth")
158+
boss_health = config["entries"].get("bossHealth")
163159
print("Published bossHealth:", boss_health) # Should be 100
164160

165161
# Or with full metadata:
@@ -171,14 +167,14 @@ print("Published bossHealth:", boss_health) # Should be 100
171167

172168
```bash
173169
curl --location \
174-
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/UniverseConfiguration" \
170+
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/InExperienceConfig" \
175171
--header "x-api-key: <API_KEY>"
176172
```
177173

178174
</TabItem>
179175
</Tabs>
180176

181-
Verify that `namespaces.UniverseConfigurations.bossHealth` (or your key) matches what you published.
177+
Verify that `entries.bossHealth` (or your key) matches what you published.
182178

183179
## View history and roll back
184180

@@ -202,7 +198,7 @@ for rev in data["revisions"]:
202198

203199
```bash
204200
curl --location \
205-
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/UniverseConfiguration/revisions?MaxPageSize=10" \
201+
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/InExperienceConfig/revisions?MaxPageSize=10" \
206202
--header "x-api-key: <API_KEY>"
207203
```
208204

@@ -238,12 +234,12 @@ print("Rollback published. configVersion:", r.json()["configVersion"])
238234
```bash
239235
# 1) Restore (returns a new draftHash)
240236
curl --request POST \
241-
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/UniverseConfiguration/revisions/<REVISION_ID>/restore" \
237+
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/InExperienceConfig/revisions/<REVISION_ID>/restore" \
242238
--header "x-api-key: <API_KEY>"
243239

244240
# 2) Publish the reverted draft using the draftHash from the response
245241
curl --request POST \
246-
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/UniverseConfiguration/publish" \
242+
"https://apis.roblox.com/creator-configs-public-api/v1/configs/universes/<UNIVERSE_ID>/repositories/InExperienceConfig/publish" \
247243
--header "x-api-key: <API_KEY>" \
248244
--header "Content-Type: application/json" \
249245
--data '{"draftHash":"<DRAFT_HASH>","message":"Rollback","deploymentStrategy":"Immediate"}'
@@ -257,7 +253,7 @@ curl --request POST \
257253
| Limit | Maximum |
258254
| ----------------------- | -------------- |
259255
| **Keys per repository** | 100 |
260-
| **Key length** | 250 characters |
256+
| **Key length** | 256 characters |
261257

262258
Requests that exceed these limits will fail. For type-specific value limits (e.g. string vs JSON) in your experience, see [Limits](../../production/configs.md#limits) in the experience configs guide.
263259

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
---
2+
title: Recommendation systems
3+
description: Use Roblox's built-in recommendation systems to create personalized curated content for individual users.
4+
---
5+
6+
Build custom recommendation systems in your experience to surface curated content such as 2D and 3D assets, minigames, other experiences, and more. The `Class.RecommendationService|Recommendation Service API` lets you log user activity, capture impressions, and deliver personalized results for virtually any type of engagement.
7+
8+
Some common use cases for recommendation systems include presenting users with an end-of-round suggestion interface, a menu overlay presenting personalized actions, or other implementations that present a unique set of choices, assets, locations, or experiences to the user.
9+
10+
Use the following universal steps and best practices to set up your recommendation system:
11+
12+
1. [Register your content](#register-your-content)
13+
2. [Log users impressions](#log-user-impressions)
14+
3. [Log quality actions](#log-quality-actions)
15+
4. [Fetch recommendations](#fetch-recommendations)
16+
5. [Monitor analytics](#monitor-analytics)
17+
18+
<Alert severity = 'warning'>
19+
This guide covers the process of implementing `Class.RecommendationService` in your experience. This content doesn't cover the process of creating the [UI](../ui/index.md), adding [assets](../assets.md), or [teleporting users](../projects/teleport.md). See additional documentation for those topics.
20+
</Alert>
21+
22+
## Register your content
23+
24+
<Alert severity = 'info'>
25+
There are many ways you can implement recommendations in your experience. The example settings in this guide are intended to recommend users various minigames within an experience, prioritizing recommendations most likely to **maximize quality play sessions**.
26+
27+
This type of recommendation system is often incorporated in a **carousel UI menu**, allowing users to scroll, select, and find more details about the activity they are about to jump into. Considerations for this type of interface are included in the settings below.
28+
29+
If creating your own system, you may need to use slightly different settings and configurations but follow the same basic steps.
30+
</Alert>
31+
32+
To populate content that your recommendation system can serve to users, use `Class.RecommendationService.RegisterItemAsync|RegisterItemAsync`. When registering an item, provide a `referenceId`, a developer-defined string that uniquely identifies the item in your own database. This referenceId is typically used to look up an item's metadata, such as the name, description, or asset ID, from your data store to display in the UI.
33+
34+
As a best practice, register items as soon as they are created to ensure the recommendation pool is always fresh.
35+
36+
## Log user impressions
37+
38+
Once the service knows about your items and starts suggesting them, tell the service when a user actually views the recommendations with `Class.RecommendationService.LogImpressionEvent|LogImpressionEvent`.
39+
40+
### When to log
41+
42+
A carousel-type UI is a common interface for displaying multiple playable options to a user. Use the following best practices to ensure your logging provides clean actionable data:
43+
44+
- **Single Log**: Log the impression **only once** per session for a specific item.
45+
- Do not log every time the item appears, as this creates noisy information that can interfere with your logging.
46+
- **Trigger**: You can choose to log when the item becomes fully visible in the menu or when the user interacts with the item, such as opening a Detail Page.
47+
48+
<Alert severity = 'warning'>
49+
<AlertTitle>The ID trap</AlertTitle>
50+
<br />Be extremely careful about which ID you pass to `Class.RecommendationService.LogImpressionEvent`. The service needs to link the event strictly to the specific recommendation instance it generated.
51+
52+
- **Do not** use a raw string or reference ID.
53+
- **Do** use the itemId that was returned to you by `Class.RecommendationService.RegisterItemAsync|RegisterItemAsync` or `Class.RecommendationService.GenerateItemListAsync|GenerateItemListAsync`.
54+
</Alert>
55+
56+
### Duration
57+
58+
Duration tracks the time of the impression. You can think of this as how long a user stared at the image or recommendation.
59+
60+
If you are not using video, you can set the **Duration** value to `1`. This ensures that you get clean consistent data that the "user viewed this item", which is typically the only logging you need for a static card.
61+
62+
## Log quality actions
63+
64+
When a user decides to interact with a recommendation, use `Class.RecommendationService.LogActionEvent|LogActionEvent`. In this example, simply clicking "Play" on the recommendation is not enough signal for a high-quality recommendation system. It's important to distinguish between an accidental click and a genuine session.
65+
66+
### Required action type
67+
68+
When you call `Class.RecommendationService.LogActionEvent|LogActionEvent`, you must specify the type of action occurring. To track action events that result in play sessions, use `Enum.RecommendationActionType.Play`.
69+
It's important to use the correct enum to tell the backend that a specific type of action is activated. For play-time related recommendations, `Enum.RecommendationActionType.Play` is strictly required to match the MaximizePlays configuration template used in the next step to fetch recommendations. If you use a different enum, the model will not register the event correctly for play-related actions.
70+
71+
### The "quality play" strategy
72+
73+
Depending on your experience, you may have different definitions on what constitutes "quality play". Use the following steps to help fine-tune what differentiates quality play in your situation.
74+
75+
1. **Track Internally**: When a user enters the mini-game, track their session time locally in your script.
76+
2. **Filter**: Define a threshold for satisfaction, such as playing for more than 60 seconds.
77+
3. **Log**: Only fire `Class.RecommendationService.LogActionEvent|LogActionEvent` if the user passes this threshold.
78+
79+
<Alert severity = 'error'>
80+
<AlertTitle>Strict rule: No "dummy" traffic</AlertTitle>
81+
82+
<br/> Only log actions for items that were actually served by the `Class.RecommendationService`.
83+
84+
- Do not log plays that came from Search, Random picks, or Past Plays.
85+
- Do not use "Dummy Tracing IDs" to force these into the system.
86+
87+
The model expects a realistic ratio. If you serve 1 impression but log 10 plays from external traffic, you confuse the training data and ruin the accuracy of your metrics.
88+
89+
</Alert>
90+
91+
## Fetch recommendations
92+
93+
To fetch recommendations, use `Class.RecommendationService.GenerateItemListAsync|GenerateItemListAsync`. `Class.RecommendationService.GenerateItemListAsync|GenerateItemListAsync` accepts a dictionary that includes various options for the recommendation list query. While many of these settings are straightforward, it's important to understand the supported `ConfigName` parameters to ensure you provide successful recommendations.
94+
95+
### ConfigName
96+
97+
You have several configurations available to you when fetching recommendations. In the current example designed to maximize recommendations based on the number of quality plays, use the `MaximizePlays` configuration. Depending on the use case, the `MaximizePlays` configuration is better than `MaximizeTimeSpent` as it additionally indexes on user satisfaction, rather than just time spent. This tells the system to return items that will most likely yield quality play.
98+
99+
For more information on each supported config, check out `Class.RecommendationService.GenerateItemListAsync|GenerateItemListAsync`.
100+
101+
## Monitor analytics
102+
103+
Once you have integrated the service, you can monitor its performance directly in the [Creator Hub](https://create.roblox.com/). To access your recommendation analytics:
104+
105+
1. In the [Creator Hub](https://create.roblox.com/), navigate to your experience page.
106+
2. In the sidebar, navigate to **Engagement** > **Recommendation Service**.
107+
<img src="../assets/analytics/recommendation-service.png" alt="Link to recommendation service metrics within Creator Hub" width="40%" />
108+
109+
Key metrics to watch:
110+
111+
- **Total Actions over time**: Are users actually engaging with the recommendations?
112+
- **Total Unique Users**: How many people are using the discovery feature?
113+
- **Average Items Impressed per User**: Are users scrolling through the carousel?
114+
- **Average Time Spent per User**: Is the quality of the recommendations keeping them in the experience longer?
115+
- In the example provided, **Duration** is set to `1`, so this specific metric isn't particularly valuable in that use-case. However, in other applications, such as videos, this can be a strong indicator for your impressions.
116+
117+
Keep in mind the settings and processes used in this recommendation system intended to maximize quality plays, particularly using 1 second duration for thumbnails, logging only quality plays, and strictly managing your IDs. By keeping your logging and impression data clean, you can recommend and fine-tune the content that best fits the unique experiences of your users.
118+
119+
While this flow covers the process for a recommendation system that maximizes playtime, you can use a similar order of operations and fundamental concepts to build out a recommendation service that fits your experience's needs.

roblox/en-us/reference/engine/classes/BaseScript.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,8 @@ properties:
127127
serialization:
128128
can_load: true
129129
can_save: true
130-
capabilities: []
130+
capabilities:
131+
- LoadUnownedAsset
131132
- name: BaseScript.RunContext
132133
summary: |
133134
Determines the context under which the script will run.

0 commit comments

Comments
 (0)