Skip to content

Commit

Permalink
update Open Source Docs from Roblox internal teams
Browse files Browse the repository at this point in the history
  • Loading branch information
rbx-open-source-docs[bot] committed Oct 23, 2024
1 parent e402d76 commit c3b1c31
Show file tree
Hide file tree
Showing 57 changed files with 677 additions and 188 deletions.
4 changes: 4 additions & 0 deletions content/common/navigation/engine/guides.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ navigation:
path: /scripting/multithreading
- title: Native Code Generation
path: /luau/native-code-gen
- title: Script Capabilities
path: /scripting/capabilities
- title: Security Tactics and Cheat Mitigation
path: /scripting/security/security-tactics
- title: Luau Reference
Expand Down Expand Up @@ -564,6 +566,8 @@ navigation:
path: /production/promotion/experience-events
- title: Player Invite Prompts
path: /production/promotion/invite-prompts
- title: Player Referral System
path: /production/promotion/referral-system
- title: Experience Notifications
path: /production/promotion/experience-notifications
- title: Nominating for the Discover Page
Expand Down
2 changes: 1 addition & 1 deletion content/en-us/art/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ Check out the following showcases made by Roblox and the community. Each of thes

<div class="container"
style={{position: "relative", paddingBottom: "56.25%", height: 0}}>
<img src="../assets/art/Thumbnail-Shrine.png" />
<img src="../assets/art/Shrine-Detailed.jpg" />
</div>
<Typography variant='h4'>Community Creations</Typography>
<Typography variant='body1' >Check out these amazing showcase experiences created members of the community!</Typography>
Expand Down
2 changes: 1 addition & 1 deletion content/en-us/art/overview-studio.md
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ For more information, see [Terrain](../parts/terrain.md).

Lighting can be categorized into the following:

- **Global lighting** - Refers to the luminescence from either the sun or moon in an outdoor environment. You can set the properties of your global lighting by adjusting the Lighting service. For additional hands-on instructions on adjusting global lighting, see the [Customize Global Lighting](../tutorials/core/building/customize-global-lighting.md) lesson of our Core Curriculum.
- **Global lighting** - Refers to the luminescence from either the sun or moon in an outdoor environment. You can set the properties of your global lighting by adjusting the Lighting service. For additional hands-on instructions on adjusting global lighting, see the [Customize Global Lighting](../tutorials/curriculums/core/building/customize-global-lighting.md) lesson of our Core Curriculum.
- **Local lighting** - Refers to light sources placed within your experiences, such as pointlights, spotlights, and surface lights. You can modify lighting scenarios based on different interior rooms or sections of your experience by using one or more light sources.

For additional information on modifying your environment's lighting, see [Lighting](../environment/lighting.md).
3 changes: 3 additions & 0 deletions content/en-us/assets/art/Shrine-Detailed.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

This file was deleted.

3 changes: 3 additions & 0 deletions content/en-us/assets/landing/get-started/Racing-Detailed.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions content/en-us/assets/studio/properties/Folder-Sandboxed.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion content/en-us/cloud/open-cloud/usage-assets.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ Updating asset metadata using the **Update Asset** endpoint is not subject to th
<li>Up to 30 seconds of duration.</li>
<li>Up to 4096x2160 resolution.</li>
<li>Up to 375 MB.</li>
<li>Currently, only English audio and text is allowed.</li>
<li>Currently, only English and/or Spanish audio and text is allowed.</li>
<li>Up to 3 uploads per month if you're 13+ and ID-verified.</li>
</ul>
</td>
Expand Down
10 changes: 5 additions & 5 deletions content/en-us/get-started.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ knowledge. Give them a try and add on to them when you're ready!
<Grid item container wrap="nowrap" direction="column" style={{gap: 8, flex: 1}}>
<div class="container"
style={{position: "relative", paddingBottom: "56.25%", height: 0, marginBottom: 12}}>
<img src="/assets/landing/get-started/Laser-Tag-Template.png" />
<img src="/assets/landing/get-started/Laser-Tag-Template.jpg" />
</div>
<Typography variant='h4'>Laser Tag</Typography>
<Typography variant='body1' >Build your own **first-person shooter** with customizable blasters, round systems, and modular building assets to reconfigure a high-quality arena!</Typography>
Expand All @@ -103,7 +103,7 @@ knowledge. Give them a try and add on to them when you're ready!
<Grid item container wrap="nowrap" direction="column" style={{gap: 8, flex: 1}}>
<div class="container"
style={{position: "relative", paddingBottom: "56.25%", height: 0, marginBottom: 12}}>
<img src="/assets/landing/get-started/racing-template.png" />
<img src="/assets/landing/get-started/Racing-Detailed.jpg" />
</div>
<Typography variant='h4'>Racing</Typography>
<Typography variant='body1' >Build your own **kart racer** with a customizable driving mechanics, checkpoints, and modular winding track pieces that you can restructure for countless courses!</Typography>
Expand Down Expand Up @@ -133,7 +133,7 @@ that teaches you the skills you need to create and monetize your experiences.
<Typography variant='h4'>Core</Typography>
<Typography variant='body1' >Core teaches you how to build a simple 3D platformer where players collect coins to trade for jump power.</Typography>
<div style={{marginTop:16}}>
<a underline="none" href="./tutorials/core/">
<a underline="none" href="./tutorials/curriculums/core">
<Button variant="contained" color="secondary" size='large'
style={{marginRight:16, alignSelf: 'flex-start'}}>Create</Button>
</a>
Expand All @@ -151,7 +151,7 @@ that teaches you the skills you need to create and monetize your experiences.
<Typography variant='h4'>Environmental Art</Typography>
<Typography variant='body1' >Environmental Art teaches you how to create a high-quality environment for a laser tag experience.</Typography>
<div style={{marginTop:16}}>
<a underline="none" href="./tutorials/environmental-art">
<a underline="none" href="./tutorials/curriculums/environmental-art">
<Button variant="contained" color="secondary" size='large'
style={{marginRight:16, alignSelf: 'flex-start'}}>Create</Button>
</a>
Expand All @@ -169,7 +169,7 @@ that teaches you the skills you need to create and monetize your experiences.
<Typography variant='h4'>Gameplay Scripting</Typography>
<Typography variant='body1' >Gameplay Scripting teaches you how to organize and implement the scripting logic for large, complex project.</Typography>
<div style={{marginTop:16}}>
<a underline="none" href="./tutorials/gameplay-scripting/">
<a underline="none" href="./tutorials/curriculums/gameplay-scripting/">
<Button variant="contained" color="secondary" size='large'
style={{marginRight:16, alignSelf: 'flex-start'}}>Create</Button>
</a>
Expand Down
134 changes: 134 additions & 0 deletions content/en-us/production/promotion/referral-system.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
---
title: Player Referral System
description: Generate shareable referral links that allow players to invite friends to join them inside an experience.
---

<Alert severity="info">
This feature is still in beta. If you'd like to provide Roblox with feedback about this feature, join the [User Acquisition Referrals](https://www.guilded.gg/i/kbQ4Po42) Guilded group.
</Alert>

The referral system encourages existing players to bring new players into your experience, increasing player retention and overall engagement. Players can access and share referral links from [player invite prompts](./invite-prompts.md) or directly from the default in-experience invite menu.

As a developer, you can use these shareable referral links to:

- Track which players have successfully invited other players into your experience.
- Track which players have joined your experience using a referral link invitation from another player.
- Create and distribute rewards to both inviters and invitees.

To implement a referral system, [set up a referral event](#set-up-a-referral-event) and [create referral rewards](#grant-referral-rewards). The `ReferredByPlayerId` property of `Class.Player:GetJoinData()|GetJoinData()` automatically populates for all types of invitations and gives you access to the user ID of the referring player. You can then access this data in the `Players.PlayerAdded` event to identify the inviter and grant rewards to the inviter and the invitee.

```lua
function onPlayerAdded(player)

local referredByPlayerId = player:GetJoinData().ReferredByPlayerId

local referrerEvent: RemoteEvent = ReplicatedStorage:FindFirstChild("ReferralReceivedEvent")
referrerEvent:FireClient(player, referredByPlayerId)
end

Players.PlayerAdded:Connect(onPlayerAdded)
```

## Set Up a Referral Event

To set up a referral event:

1. Set up a `RemoteEvent` in `ReplicatedStorage` to create a remote event to communicate with the client when a referral is received.
2. Retrieve the inviter's user ID using `ReferredByPlayerId` to track player joins and handle the referral logic in your server-side script during the `Players.PlayerAdded` event.

```lua
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Create or get the RemoteEvent for handling referrals
local referrerEvent: RemoteEvent = ReplicatedStorage:FindFirstChild("ReferralReceivedEvent")

-- Function that triggers when a player joins
function onPlayerAdded(player)
local joinData = player:GetJoinData()
local referredByPlayerId = joinData.ReferredByPlayerId

-- Check if the player was invited through a referral
if referredByPlayerId then
-- Fire the referral event to the client, passing the inviter's ID
referrerEvent:FireClient(player, referredByPlayerId)

-- Additional logic for rewarding inviter and invitee can be added here
-- e.g., rewardReferrer(referredByPlayerId)
-- e.g., rewardInvitee(player)
end
end

-- Connect the function to the PlayerAdded event
Players.PlayerAdded:Connect(onPlayerAdded)
```

## Grant Referral Rewards

To encourage participation, grant rewards to both inviters and invitees. For example, you can give inviters a badge or in-experience currency when their friend joins the experience, and give invitees a welcome reward for joining the experience through a referral link.

```lua
local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Create or get the RemoteEvent for handling referrals
local referrerEvent: RemoteEvent = ReplicatedStorage:FindFirstChild("ReferralReceivedEvent")

-- Function that triggers when a player joins
function onPlayerAdded(player)
local joinData = player:GetJoinData()
local referredByPlayerId = joinData.ReferredByPlayerId

-- Check if the player was invited through a referral
if referredByPlayerId then
-- Fire the referral event to the client, passing the inviter's ID
referrerEvent:FireClient(player, referredByPlayerId)

-- Reward the inviter
function rewardReferrer(referrerId)
local referrerPlayer = Players:GetPlayerByUserId(referrerId)
if referrerPlayer then
-- Grant the inviter their reward
-- Example: referrerPlayer.leaderstats.Coins.Value += 100
end
end

-- Reward the invitee
function rewardInvitee(player)
-- Grant the invitee their reward
-- Example: player.leaderstats.WelcomeBonus.Value += 50
end
end
end

-- Connect the function to the PlayerAdded event
Players.PlayerAdded:Connect(onPlayerAdded)
```

## Manage Abuse Prevention

You can implement safeguards to prevent players from exploiting the referral system.

- Offer one-time rewards to track invitees and make sure they're only rewarded once.
- Introduce a cooldown period before an inviter can submit another referral.
- Monitor unusual activity and implement corrective measures like banning users or canceling rewards.

```lua
-- Table to track players who have already been referred
local referredPlayers = {}

function onPlayerAdded(player)
local joinData = player:GetJoinData()
local referredByPlayerId = joinData.ReferredByPlayerId

-- Check if the player was invited and has not already used a referral
if referredByPlayerId and not referredPlayers[player.UserId] then
-- Mark the player as referred
referredPlayers[player.UserId] = true

-- Reward inviter and invitee
rewardReferrer(referredByPlayerId)
rewardInvitee(player)
end
end
```
10 changes: 7 additions & 3 deletions content/en-us/projects/assets/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,11 +102,15 @@ Within Studio, you can convert single assets or asset hierarchies into **package

For more information, see [Packages](../../projects/assets/packages.md).

## Asset Format Strings
## Asset URIs

Assets are reflected through formatted strings, each of which points to an online file or a file saved to the client's device. The basic structure is a **protocol** followed by `://` and a **string** that varies according to the protocol.
Assets and other content stored outside of the current place are identified through **Uniform Resource Identifiers** (URIs) which are formatted strings that point to a file stored online, within the Roblox application package, or saved to the client's device.

<span><Chip label='[Protocol]://[String]' color='primary' size='large' /></span>
The basic structure is a **scheme** followed by `://` and a **path** that varies according to the scheme.

<span><Chip label='[Scheme]://[Path]' color='primary' size='large' /></span><br/>

The Roblox engine supports several custom URI schemes for referencing content stored on the platform.

### rbxassetid

Expand Down
29 changes: 24 additions & 5 deletions content/en-us/reference/engine/classes/AssetService.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,14 @@ deprecation_message: ''
properties: []
methods:
- name: AssetService:CreateEditableImage
summary: ''
description: ''
summary: |
Creates a new `Class.EditableImage`.
description: |
Creates a new `Class.EditableImage`. By default, the resolution
is set at 512&times;512 but it can be specified via the returned object's
`Class.EditableImage.Size` parameter. If the device‑specific editable
memory budget is exhausted, creation will fail and this method will return
`nil`.
code_samples: []
parameters: []
returns:
Expand All @@ -32,8 +38,13 @@ methods:
capabilities: []
writeCapabilities: []
- name: AssetService:CreateEditableMesh
summary: ''
description: ''
summary: |
Creates a new, empty `Class.EditableMesh`.
description: |
Creates a new, empty `Class.EditableMesh`. Vertices,
triangles and their attributes can be added dynamically to it.
If the device‑specific editable memory budget is exhausted,
creation will fail and this method will return `nil`.
code_samples: []
parameters: []
returns:
Expand All @@ -54,6 +65,8 @@ methods:
texture. Non-asset texture IDs such as `rbxthumb://` are supported. If
using an image asset, it must be associated with and/or owned by a creator
of the experience, or it must have been created inside the experience.
If the device-specific editable memory budget is exhausted, creation
will fail and this method will return `nil`.
code_samples: []
parameters:
- name: textureId
Expand All @@ -78,7 +91,13 @@ methods:
content ID.
description: |
Returns a new `Class.EditableMesh` instance created from an existing mesh
content ID.
content ID. By default a `Class.EditableMesh` created from this method will
be fixed size such that mesh data can only be modified, not added nor removed.
A fixed size `Class.EditableMesh` consumes less memory and should be preferred
when possible.
If the device-specific editable memory budget is exhausted, creation
will fail and this method will return `nil`.
code_samples: []
parameters:
- name: meshId
Expand Down
38 changes: 24 additions & 14 deletions content/en-us/reference/engine/classes/EditableMesh.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,36 @@ memory_category: Instances
summary: |
Instance which allows for the runtime creation and manipulation of meshes.
description: |
`Class.EditableMesh` changes the applied visual mesh when parented to a
`EditableMesh` changes the applied visual mesh when linked to a
`Class.MeshPart`, allowing for querying and modification of the mesh both in
Studio and in experience.
An `Class.EditableMesh` can be created from an existing mesh ID using
`Class.AssetService:CreateEditableMeshAsync()`, or a blank
`Class.EditableMesh` can be created with `Datatype.Instance.new()`. It can
then be displayed, modified, and its collision model updated. Not all of the
steps are necessary; for example, you might want to create an
`Class.EditableMesh` just to raycast without ever displaying it.
An `EditableMesh` can be created from an existing 'DataType.Content' of a
'Class.MeshPart' or a mesh ID using `Class.AssetService:CreateEditableMeshAsync()`,
or a blank `EditableMesh` can be created with `Class.AssetService:CreateEditableMesh()`.
It can then be displayed, modified, and its collision model updated. Not all
of the steps are necessary; for example, you might want to create an
`EditableMesh` just to raycast without ever displaying it.
An `EditableMesh` is displayed when it's linked to a new `Class.MeshPart`,
through `Class.AssetService:CreateMeshPartAsync()`. You can create more `Class.MeshPart`
instances that reference the same `EditableMesh` content, or link to an existing
`Class.MeshPart` through `Class.MeshPart:ApplyMesh()`.
Calling `Class.AssetService:CreateMeshPartAsync()` will recalculate collision
and fluid geometry with any edits and update the existing `Class.MeshPart`. It
is generally recommended to do this at the end of a conceptual edit operation.
`Class.MeshPart:ApplyMesh()` will update the colission and fluid geometry of
the target `Class.MeshPart`.
An `Class.EditableMesh` is displayed when it's parented to a `Class.MeshPart`,
but only the part's appearance changes while the collision model remains the
same.
#### Stable Vertex/Face IDs
Many `Class.EditableMesh` methods take **vertex**, **normal**, **UV**,
Many `EditableMesh` methods take **vertex**, **normal**, **UV**,
**color** and **face** IDs. These are represented as integers in Luau but they
require some special handling. The main difference is that IDs are stable and
they remain the same even if other parts of the mesh change. For example, if
an `Class.EditableMesh` has five vertices `{1, 2, 3, 4, 5}` and you remove
an `EditableMesh` has five vertices `{1, 2, 3, 4, 5}` and you remove
vertex `4`, the new vertices will be `{1, 2, 3, 5}`.
Note that the IDs are not guaranteed to be in order and there may be holes in
Expand All @@ -53,6 +61,8 @@ description: |
example, this code will create a sharp cube:
```lua
local AssetService = game:GetService("AssetService")
-- Given 4 vertex IDs, adds a new normal and 2 triangles, making a sharp quad
local function addSharpQuad(eMesh, vid0, vid1, vid2, vid3)
local nid = eMesh:AddNormal() -- This creates a normal ID which is automatically computed
Expand All @@ -66,7 +76,7 @@ description: |
-- Makes a cube with creased edges between the 6 sides
local function makeSharpCube()
local eMesh = Instance.new("EditableMesh")
local eMesh = AssetService:CreateEditableMesh()
local v1 = eMesh:AddVertex(Vector3.new(0, 0, 0))
local v2 = eMesh:AddVertex(Vector3.new(1, 0, 0))
Expand Down Expand Up @@ -103,7 +113,7 @@ description: |
#### Limitations
`Class.EditableMesh` currently has a limit of 60,000 vertices and 20,000
`EditableMesh` currently has a limit of 60,000 vertices and 20,000
triangles. Attempting to add too many vertices or triangles will cause an
error.
code_samples: []
Expand Down
Loading

0 comments on commit c3b1c31

Please sign in to comment.