diff --git a/.cursor/rules/atlas-project.mdc b/.cursor/rules/atlas-project.mdc
index f4bf39b1..bfcb536c 100644
--- a/.cursor/rules/atlas-project.mdc
+++ b/.cursor/rules/atlas-project.mdc
@@ -1,6 +1,5 @@
---
-globs: **/*.project.json5,**/*.project.json,**/*.meta.json5,**/*.meta.json,**/*.model.json5,**/*.model.json
-alwaysApply: false
+alwaysApply: true
---
# Atlas Project File Format
diff --git a/.cursor/rules/atlas.mdc b/.cursor/rules/atlas.mdc
index 5162e13f..4a94a3ac 100644
--- a/.cursor/rules/atlas.mdc
+++ b/.cursor/rules/atlas.mdc
@@ -1,5 +1,4 @@
---
-description: "Essential Atlas context: architecture, contribution workflow, and code conventions for this project."
alwaysApply: true
---
diff --git a/.cursor/rules/luau.mdc b/.cursor/rules/luau.mdc
index 8c939c4c..d860a62a 100644
--- a/.cursor/rules/luau.mdc
+++ b/.cursor/rules/luau.mdc
@@ -1,5 +1,4 @@
---
-description: Luau language syntax, type system, single-threaded model, and common gotchas
alwaysApply: true
---
# Luau Language Rules
diff --git a/.cursor/rules/luau/math-constants.md b/.cursor/rules/luau/math-constants.md
new file mode 100644
index 00000000..897b43fb
--- /dev/null
+++ b/.cursor/rules/luau/math-constants.md
@@ -0,0 +1,56 @@
+# Math constants
+
+## Summary
+
+Expand the constants provided in the `math` library.
+
+## Motivation
+
+With the introduction of [`math.isnan`](https://rfcs.luau.org/math-isnan-isfinite-isinf.html), Luau has the opportunity to add a new constant representing `NaN` (Not a Number).
+As linting support for Luau continues becoming more robust, we can discourage patterns like `0/0` to generate `NaN` and instead provide the constant directly through the math library.
+
+Without the `math.isnan` API, this could have created confusion in the past:
+```luau
+if maybeNan == math.nan do
+ print("This line will never be hit: comparing to NaN always returns false.")
+end
+```
+
+With the new API, however, this is now easier to use:
+```luau
+local maybeNan = math.nan
+if math.isnan(maybeNan) do
+ print("This line will be hit!")
+end
+```
+
+While adding `NaN`, we also have an opportunity to modernize the set of constants available through the `math` library.
+Some history:
+- Lua 5.0 (2003) introduced `math.pi`, representing the mathematical constant $\pi$.
+- Lua 5.1 (2006) introduced `math.huge`, mapping directly to infinity as defined by the [IEEE 754 standard](https://en.wikipedia.org/wiki/IEEE_754).
+- Lua 5.3 (2015) introduced integers and the `math.maxinteger` and `math.mininteger` constants alongside them.
+
+Luau currently only supports `math.pi` and `math.huge`.
+Integer types are not supported in Luau, so `math.maxinteger` and `math.mininteger` wouldn't make much sense, but adding other commonly used constants would be an easy value-add for users of the language.
+
+## Design
+
+In addition to `math.pi` and `math.huge`, we propose adding the following constants.
+
+- `math.nan`: some `NaN` value as defined by IEEE 754.
+ - The exact representation (payload and sign) is unspecified.
+ - Comparing to `math.nan` will always return `false`; lint rules recommend using `math.isnan`.
+- `math.e`: the mathematical constant $e = 2.71828182845904523536$.
+- `math.phi`: the golden ratio, defined as $\phi = 1.61803398874989484820$.
+- `math.sqrt2`: the square root of `2`, defined as equal to `math.sqrt(2)`.
+- `math.tau`: the mathematical constant $\tau$, defined as equal to `2 * math.pi`.
+## Drawbacks
+
+- The semantics of `math.nan` are unique and somewhat unexpected for users not already familiar with IEEE 754's floating-point arithmetic rules.
+- Adding new constants increases the API surface of the `math` library and diverges further from Lua 5.1.
+
+## Alternatives
+
+- Do nothing: continue requiring users to define their own constants (e.g., `local nan = 0/0`, `local e = math.exp(1)`).
+- Only add `math.nan` without the additional constants, deferring modernization for a future RFC.
+- Rely on these constants being provided through external libraries.
diff --git a/.cursor/rules/luau/type-long-integer.md b/.cursor/rules/luau/type-long-integer.md
new file mode 100644
index 00000000..a9b6ae8e
--- /dev/null
+++ b/.cursor/rules/luau/type-long-integer.md
@@ -0,0 +1,339 @@
+# 64-bit Integer Type
+
+## Summary
+
+A builtin 'integer' type to represent 64 bit integer numbers.
+
+## Motivation
+
+Current methods of representing 64-bit integers in Luau with default environment are done with high-low pairs or by splitting them among vectors which leads to poor ergonomics and may not be sufficient for cases where performance is important.
+
+In the case of a high-low pair implementation, each individual number takes 16 bytes (or 24) and needs to be be handled together which can be confusing.
+
+In the case of vector implementations, ergonomics are improved by storing the entire integer in one value however you have the same issues of implementation complexity and lack of integration with the type system.
+
+In both cases, performance is lacking compared to what could be provided by a native implementation.
+
+As Luau grows, the restriction to doubles will be an increasing pain point for any use case which involves a 64-bit integer.
+System support for 64-bit integers is ubiquitous and their use is widespread.
+
+Besides the above solutions in userland, runtimes are also able to define their own userdata for 64-bit integers. However, this requires each runtime to reimplement 64-bit integer support themselves, and carries with it the potential of significant differences in their semantics. Such an outcome would harm the ecosystem as a whole, requiring libraries to find a common API across all of their supported runtimes, or otherwise program around differences in their APIs.
+
+Further, representing 64-bit numbers as heap-allocated userdata is sufficient for correctness, but also adds a layer of indirection for something that could fit within the existing value size. In domains where the use of these numbers is more common, the performance characteristics of these varying implementation techniques could be problematic or even prohibitive.
+
+Userdata remain the right mechanism for complex or embedder-specific numeric types, but 64-bit integers have a sufficiently large problem domain to justify their inclusion as a core value type, and bring significant benefits for performance and interoperability in the overall Luau ecosystem.
+
+## Design
+
+This will be implemented a with new type called `integer`.
+
+An additional character may be specified at the end of numeric literals `i` which will signify an 64 bit integer literal.
+64 bit integer literals will support separators, hex, and binary values:
+
+```luau
+local a = 123i
+local b = 1_000i
+local c = 0xABABi
+local d = 0b1000_1000i
+```
+
+Integer literal numbers have to be exactly representable, overflow is a parsing error.
+
+Operations performing a string formatting of an integer should format the number as signed by default.
+
+Integer values will have a built-in equality comparison, but will not have any other operators or metamethods defined.
+
+Functions for creating and manipulating this type will exist in a new library called 'integer`.
+
+### Library
+
+`function integer.create(n: number): integer?`
+
+Converts a number to an integer.
+
+Returns `nil` If the double number cannot be represented as an integer exactly, i.e. it has a fractional part, is out of range or is NaN.
+
+This behavior is chosen to closely match `math.tointeger` from Lua 5.4 and can have a relatively efficient implementation.
+
+`function integer.fromstring(str: string, base: number?): integer?`
+
+Converts a string representation of a number into an integer.
+
+Number inside the string has to be an integer.
+String is allowed to have leading and trailing spaces and number can be preceded by a sign.
+If base is not specified, number can have a `0x` or `0X` prefix to be converted in base 16, otherwise base 10 is used.
+
+When base is specified, it has to be in range between 2 and 36 inclusive.
+In base 10 and base 16, number is allowed to have a `0x` or `0X` prefix.
+
+Returns `nil` if the string doesn't contain a number.
+
+This behavior is chosen to match `tonumber`, but excludes floating-point numbers.
+
+`function integer.tostring(n: integer): string`
+
+Converts an integer to a string representation.
+
+`function integer.tonumber(n: integer): number`
+
+Converts an integer to a double.
+
+If the value cannot be represented as a double exactly, round to nearest, tie to even rounding mode is used.
+
+`function integer.neg(a: integer): integer`
+
+Negates the value.
+Overflow wraps around according to rules of two-complement arithmetic.
+
+`function integer.add(a: integer, b: integer): integer`
+
+Adds `a` to `b`.
+Overflow wraps around according to rules of two-complement arithmetic.
+
+`function integer.sub(a: integer, b: integer): integer`
+
+Subtracts `b` from `a`.
+Overflow wraps around according to rules of two-complement arithmetic.
+
+`function integer.mul(a: integer, b: integer): integer`
+
+Multiplies `a` and `b`.
+Overflow wraps around according to rules of two-complement arithmetic.
+
+`function integer.div(a: integer, b: integer): integer`
+
+Performes signed truncated division of `a` by `b`.
+
+If `b` is 0, throws a division by zero error.
+
+If `a` is -2^63 and `b` is -1, throws an overflow error.
+
+`function integer.rem(a: integer, b: integer): integer`
+
+Computes remainder of the signed truncated division of `a` by `b`.
+
+If `b` is 0, throws a division by zero error.
+
+If `a` is -2^63 and `b` is -1, result is 0.
+
+`function integer.idiv(a: integer, b: integer): integer`
+
+Performes signed floored division of `a` by `b`.
+
+If `b` is 0, throws a division by zero error.
+
+If `a` is -2^63 and `b` is -1, throws an overflow error.
+
+`function integer.mod(a: integer, b: integer): integer`
+
+Performes signed floored modulus division of `a` by `b`.
+
+If `b` is 0, throws a division by zero error.
+
+If `a` is -2^63 and `b` is -1, result is 0.
+
+`function integer.udiv(a: integer, b: integer): integer`
+
+Performs unsigned division of `a` by `b`.
+
+If `b` is 0, throws an error.
+
+`function integer.urem(a: integer, b: integer): integer`
+
+Computes remainder of the unsigned division of `a` by `b`.
+
+If `b` is 0, throws an error.
+
+`function integer.min(a: integer, b: integer): integer`
+
+Returns the smallest of two integer numbers.
+
+`function integer.max(a: integer, b: integer): integer`
+
+Returns the largest of two integer numbers.
+
+`function integer.clamp(a: integer, min: integer, max: integer): integer`
+
+Returns `a` if the number is in `[min, max]` range; otherwise, returns `min` when `a < min`, and `max` otherwise.
+
+The function errors if `min > max`, consistent with `math.clamp`.
+
+`function integer.band(a: integer, b: integer): integer`
+
+Performs a bitwise and of `a` and `b`.
+
+`function integer.bor(a: integer, b: integer): integer`
+
+Performs a bitwise or of `a` and `b`.
+
+`function integer.bnot(a: integer): integer`
+
+Returns a bitwise negation of the input number.
+
+`function integer.bxor(a: integer, b: integer): integer`
+
+Performs a bitwise xor (exclusive or) of `a` and `b`.
+
+`function integer.lt(a: integer, b: integer): boolean`
+
+Compares signed less than (<) comparison of `a` and `b`.
+
+`function integer.le(a: integer, b: integer): boolean`
+
+Compares signed less than or equal (<=) comparison of `a` and `b`.
+
+`function integer.ult(a: integer, b: integer): boolean`
+
+Compares unsigned less than (<) comparison of `a` and `b`.
+
+`function integer.ule(a: integer, b: integer): boolean`
+
+Compares unsigned less than or equal (<=) comparison of `a` and `b`.
+
+`function integer.lshift(n: integer, i: integer): integer`
+
+Shifts `n` to the left by `i` bits (if `i` is negative, a right shift is performed instead).
+
+When `i` is outside of `[-63..63]` range, returns 0.
+
+`function integer.rshift(n: integer, i: integer): integer`
+
+Shifts `n` to the right by `i` bits (if `i` is negative, a left shift is performed instead).
+
+When `i` is outside of `[-63..63]` range, returns 0.
+
+`function integer.arshift(n: integer, i: integer): integer`
+
+Shifts `n` by `i` bits to the right (if `i` is negative, a left shift is performed instead).
+
+The most significant bit of `n` is propagated during the shift.
+
+When `i` is larger than 63, returns an integer with all bits set to the sign bit of `n`.
+
+When `i` is smaller than -63, 0 is returned.
+
+`function integer.lrotate(n: integer, i: integer): integer`
+
+Rotates `n` to the left by `i` bits (if `i` is negative, a right rotate is performed instead); the bits that are shifted past the bit width are shifted back from the right.
+
+`i` is interpreted modulo 64.
+
+`function integer.rrotate(n: integer, i: integer): integer`
+
+Rotates `n` to the right by `i` bits (if `i` is negative, a left rotate is performed instead); the bits that are shifted past the bit width are shifted back from the left.
+
+`i` is interpreted modulo 64.
+
+`function integer.extract(n: integer, f: integer, w: integer?): integer`
+
+Extracts bits of `n` at position `f` with a width of `w`.
+
+`w` defaults to 1, so a two-argument version of extract returns the bit value at position `f`.
+
+Bits are indexed starting at 0.
+`f` cannot be negative.
+`w` has to be positive (> 0).
+`f + w` must be less than or equal to 64.
+
+`function integer.replace(n: integer, r: integer, f: integer, w: integer?): integer`
+
+Replaces bits of `n` at position `f` and width `w` with `w` least significant bits of `r`.
+
+`w` defaults to 1, so a three-argument version of replace changes one bit at position `f` to `r` and returns the result.
+
+Bits are indexed starting at 0.
+`f` cannot be negative.
+`w` has to be positive (> 0).
+`f + w` must be less than or equal to 64.
+
+`function integer.btest(a: integer, b: integer): boolean`
+
+Perform a bitwise and `a` and `b` and returns true iff the result is not 0.
+
+`function integer.countrz(n: integer): integer`
+
+Returns the number of consecutive zero bits starting from the right-most (least significant) bit.
+Returns 64 if `n` is zero.
+
+`function integer.countlz(n: integer): integer`
+
+Returns the number of consecutive zero bits starting from the left-most (most significant) bit.
+Returns 64 if `n` is zero.
+
+`function integer.bswap(n: integer): integer`
+
+Returns `n` with the order of the bytes swapped.
+
+### Extensions to the buffer library
+
+Functions to read and write integer values are added.
+Functions use `integer` in the name as opposed to `i64` to signify the difference of the result/argument type from that of `number`.
+
+`function buffer.readinteger(b: buffer, offset: number): integer`
+
+Reads an integer out of a buffer at the given offset.
+
+`function buffer.writeinteger(b: buffer, offset: number, value: integer): ()`
+
+Writes an integer to a buffer at the given offset.
+
+### Extensions to the math library
+
+For parity with Lua 5.3+, two additional constants are added to the math library.
+
+`math.maxinteger`
+
+Integer value representing 2^63-1 (`9_223_372_036_854_775_807i`)
+
+`math.mininteger`
+
+Integer value representing -2^63 (`-9_223_372_036_854_775_808i`)
+
+### Extensions to the string library
+
+`string.format` function is updated to support integer arguments.
+
+'d', 'i' and '*' format specifiers will format integer as a signed 64 bit integer number.
+
+'o', 'u', 'x' and 'X' format specifiers will format integer as an unsigned 64 bit integer number.
+
+### C API
+
+`int64_t lua_tointeger64(lua_State *L, int idx, int* isinteger)`
+
+Returns a value of an integer at `idx` or 0 on failure.
+
+If `isinteger` is not a null pointer, writes 1 if the value at `idx` was an integer value and 0 on failure.
+
+`void lua_pushinteger64(lua_State *L, int64_t n)`
+
+Pushes a integer value on top of the stack.
+
+`int lua_isinteger64(lua_State *L, int idx)`
+
+Determines if a value at `idx` is an integer.
+
+This function is implemented as a C macro.
+
+`int64_t luaL_checkinteger64(lua_State *L, int narg)`
+
+Returns a value of an integer at `narg` or throws an error on failure.
+
+`int64_t luaL_optinteger64(lua_State *L, int narg, int64_t def)`
+
+Returns a value of an integer at `narg` or `def` if there is no value.
+
+Throws an error if there is a value but it is not an integer.
+
+`luaopen_integer(lua_State *L)`
+
+Registers the `integer` library.
+Included in `luaL_openlibs`.
+
+## Drawbacks
+
+This increases the complexity of the VM as it may need to implement separate paths for mathematical operations.
+
+## Alternatives
+
+Do nothing, the workarounds exist and are in use but this will restrict the areas Luau can be used without implementation burden or reliance on an externally maintained implementation of 64-bit integers.
diff --git a/.cursor/rules/persona.mdc b/.cursor/rules/persona.mdc
index 8faceef0..f667ceee 100644
--- a/.cursor/rules/persona.mdc
+++ b/.cursor/rules/persona.mdc
@@ -1,5 +1,4 @@
---
-description: Agent behavior constraints and communication style
alwaysApply: true
---
diff --git a/.cursor/rules/roblox.mdc b/.cursor/rules/roblox.mdc
index a0a26b91..476efa66 100644
--- a/.cursor/rules/roblox.mdc
+++ b/.cursor/rules/roblox.mdc
@@ -1,5 +1,4 @@
---
-description: Index for Roblox API documentation in .cursor/rules/roblox/
alwaysApply: true
---
diff --git a/.cursor/rules/roblox/common/navigation/documentation.yaml b/.cursor/rules/roblox/common/navigation/documentation.yaml
index 483f6cd1..e3853add 100644
--- a/.cursor/rules/roblox/common/navigation/documentation.yaml
+++ b/.cursor/rules/roblox/common/navigation/documentation.yaml
@@ -27,7 +27,7 @@ columns:
path: /production/analytics/
navigation: analytics.yaml
- title: Platform
- path: /platform
+ path: /get-started/
navigation: /platform.yaml
- title: Tutorials
navigation: /engine/tutorials.yaml
diff --git a/.cursor/rules/roblox/common/navigation/engine/guides.yaml b/.cursor/rules/roblox/common/navigation/engine/guides.yaml
index 5508291c..a71ca53e 100644
--- a/.cursor/rules/roblox/common/navigation/engine/guides.yaml
+++ b/.cursor/rules/roblox/common/navigation/engine/guides.yaml
@@ -144,6 +144,8 @@ navigation:
path: /physics/constraints/torque
- title: LineForce
path: /physics/constraints/line-force
+ - title: Animation
+ path: /physics/constraints/animation
- title: Sleep system
path: /physics/sleep-system
- title: Adaptive timestepping
diff --git a/.cursor/rules/roblox/common/navigation/platform.yaml b/.cursor/rules/roblox/common/navigation/platform.yaml
index 03a7f638..a72017cc 100644
--- a/.cursor/rules/roblox/common/navigation/platform.yaml
+++ b/.cursor/rules/roblox/common/navigation/platform.yaml
@@ -1,17 +1,28 @@
navigation:
- heading: Platform
-
- - title: Get started
- path: /get-started
+ - title: Get Started
+ path: /get-started/
+ section:
+ - title: Why should I develop on Roblox?
+ path: /get-started/why-build-on-roblox
+ - title: How is Roblox different from other platforms?
+ path: /get-started/how-is-roblox-different
+ - title: What tools does Roblox provide?
+ path: /get-started/tools
+ - title: How do I make money?
+ path: /get-started/monetization
+ - title: Recommended strategies
+ path: /get-started/strategies
+ - title: Start creating
+ path: /get-started/creating
+ - title: Resources
+ path: /get-started/resources
- title: Create
path: /platform
- title: Scale
path: /scale
- title: Monetize
path: /monetize
- section:
- - title: Earn on Roblox
- path: /production/earn-on-roblox
- title: Guidelines and policies
section:
- title: Safety on Roblox
diff --git a/.cursor/rules/roblox/en-us/art/accessories/clothing-specifications.md b/.cursor/rules/roblox/en-us/art/accessories/clothing-specifications.md
index f3fc717b..5f9abc09 100644
--- a/.cursor/rules/roblox/en-us/art/accessories/clothing-specifications.md
+++ b/.cursor/rules/roblox/en-us/art/accessories/clothing-specifications.md
@@ -142,7 +142,8 @@ Face accessories, such as hair, eyebrows, and eyelashes are unique accessories t
## Textures
-Textures created for accessories must meet Roblox's [texture specifications](../../art/modeling/texture-specifications.md). Keep in mind that smaller assets, such as accessories, can use smaller texture map sizes, such as **256×256px**, to optimize performance with virtually no loss in detail.
+- Textures for Marketplace assets can't exceed 2048x2048 resolution.
+- Textures created for accessories must meet Roblox's [texture specifications](../../art/modeling/texture-specifications.md). High resolution textures are automatically converted to lower-resolution textures to optimize performance.
## Layerable Properties
diff --git a/.cursor/rules/roblox/en-us/art/accessories/specifications.md b/.cursor/rules/roblox/en-us/art/accessories/specifications.md
index 8cb5da65..56edecc7 100644
--- a/.cursor/rules/roblox/en-us/art/accessories/specifications.md
+++ b/.cursor/rules/roblox/en-us/art/accessories/specifications.md
@@ -277,9 +277,8 @@ You can use tools like the [Accessory Fitting Tool](../../art/accessories/access
## Textures
-Textures created for accessories must meet Roblox's [texture specifications](../../art/modeling/texture-specifications.md).
-
-- Non-albedo maps (RGH, MTL, NOR) for rigid accessories cannot exceed 256x256.
+- Textures for Marketplace assets cannot exceed 2048x2048 resolution.
+- Textures created for accessories must meet Roblox's [texture specifications](../../art/modeling/texture-specifications.md).
## Attachment points
diff --git a/.cursor/rules/roblox/en-us/art/characters/specifications.md b/.cursor/rules/roblox/en-us/art/characters/specifications.md
index 95167a1a..6ec82822 100644
--- a/.cursor/rules/roblox/en-us/art/characters/specifications.md
+++ b/.cursor/rules/roblox/en-us/art/characters/specifications.md
@@ -652,7 +652,9 @@ For information on required facial animation support, see [head specifications](
## Textures
-Avatar characters must follow Roblox's [texture specifications](../../art/modeling/texture-specifications.md). Characters created for the Marketplace can take advantage of [custom skin tones](#custom-skin-tone) which use alpha layers allow users to select their own base color.
+- Textures for Marketplace assets can't exceed 2048x2048 resolution.
+- Textures created for accessories must meet Roblox's [texture specifications](../../art/modeling/texture-specifications.md). High resolution textures are automatically converted to lower-resolution textures to optimize performance.
+- Avatar characters must follow Roblox's [texture specifications](../../art/modeling/texture-specifications.md). Characters created for the Marketplace can take advantage of [custom skin tones](#custom-skin-tone) which use alpha layers allow users to select their own base color.
### Custom skin tone
diff --git a/.cursor/rules/roblox/en-us/art/modeling/surface-appearance.md b/.cursor/rules/roblox/en-us/art/modeling/surface-appearance.md
index ba90c20e..19b3eb2e 100644
--- a/.cursor/rules/roblox/en-us/art/modeling/surface-appearance.md
+++ b/.cursor/rules/roblox/en-us/art/modeling/surface-appearance.md
@@ -3,6 +3,8 @@ title: PBR textures
description: PBR textures are advanced textures using multiple texture maps.
---
+import BetaAlert from '../../includes/beta-features/beta-alert.md'
+
**Physically-Based Rendering** (PBR) textures allow you to represent realistic shading and lighting by using multiple types of texture images, or **maps**, on a single object. Combining multiple texture maps can more accurately simulate color, roughness, and reflectivity in any lighting environment and can enhance the visual elements of your assets and environment.
@@ -140,15 +142,39 @@ For objects that require partial or complete sections of transparency, such as g
You can apply transparency in two different behaviors by setting the following `Class.SurfaceAppearance.AlphaMode|AlphaMode` values:
-- [Overlay](#overlay) — Overlays the `Class.SurfaceAppearance.ColorMap|ColorMap` over the underlying mesh's `Class.MeshPart.Color`. Color maps using **Overlay** reveal the base color of the mesh anywhere transparency is present. This is the default setting.
+- [Opaque](#opaque) — Ignores the alpha channel of the `Class.SurfaceAppearance.ColorMap|ColorMap` and uses the color value directly from the color map.
+- [Overlay](#overlay) — Overlays the `Class.SurfaceAppearance.ColorMap|ColorMap` over the underlying mesh's `Class.MeshPart.Color`. Color maps using overlay mode reveal the base color of the mesh anywhere transparency is present. This is the default setting.
- [Transparency](#alpha-modes) — Removes the visible mesh based on transparency in the `ColorMap`. This renders the mesh see-through and does not reveal the original mesh color whenever transparency is present.
- [TintMask](#tintmask) — Blends the tinted `Class.SurfaceAppearance.ColorMap|ColorMap` over the un-tinted `Class.SurfaceAppearance.ColorMap|ColorMap`.
+##### Opaque
+
+
+
+You can use `Enum.AlphaMode.Opaque` mode to ignore the alpha channel of the `Class.SurfaceAppearance.ColorMap|ColorMap` altogether. In this case the alpha value is assumed to be 1 (fully opaque).
+
+The following example demonstrates how the `Enum.AlphaMode.Opaque|Opaque` mode works using a white object as reference:
+
+
+
+
+ Example color/albedo map with transparency
+
+
+
+ Example mesh object (white)
+
+
+
+ `Class.SurfaceAppearance.AlphaMode|AlphaMode` set to `Enum.AlphaMode.Opaque|Opaque` using reference map and material
+
+
+
##### Overlay
-You can use **Overlay** to reveal sections of the mesh's original color. Since the transparent areas of the color map expose the underlying color, you can design a unique texture map that partially or fully reveals the mesh's `Class.MeshPart.Color|Color` property for custom skin tones or other situations with unique colors.
+You can use `Enum.AlphaMode.Overlay` to reveal sections of the mesh's original color. Since the transparent areas of the color map expose the underlying color, you can design a unique texture map that partially or fully reveals the mesh's `Class.MeshPart.Color|Color` property for custom skin tones or other situations with unique colors.
-The following example demonstrates how the **Overlay** mode works using a white sphere reference:
+The following example demonstrates how the `Enum.AlphaMode.Overlay|Overlay` mode works using a white sphere reference:
@@ -161,11 +187,11 @@ The following example demonstrates how the **Overlay** mode works using a white
- `Class.SurfaceAppearance.AlphaMode|AlphaMode` set to **Overlay** using reference map and material
+ `Class.SurfaceAppearance.AlphaMode|AlphaMode` set to `Enum.AlphaMode.Overlay|Overlay` using reference map and material
-The following example uses the **Overlay** mode for custom characters, revealing the character's original skin-tone:
+The following example uses the `Enum.AlphaMode.Overlay|Overlay` mode for custom characters, revealing the character's original skin-tone:
@@ -174,7 +200,7 @@ The following example uses the **Overlay** mode for custom characters, revealing
-Several variations of characters with a single color map using **Overlay** mode
+Several variations of characters with a single color map using `Enum.AlphaMode.Overlay|Overlay` mode
@@ -182,7 +208,7 @@ See [custom skin tone](../../art/characters/specifications.md#custom-skin-tone)
##### Transparency
-You can use the **Transparency** mode to create complex or extremely fine objects, such as lace or netting, by removing visible parts of the mesh as an alternative to sculpting the mesh geometry. Since this does not affect the geometry of the mesh object, this can allow you to create detailed objects without the performance impact of an intricate mesh model.
+You can use the `Enum.AlphaMode.Transparency` mode to create complex or extremely fine objects, such as lace or netting, by removing visible parts of the mesh as an alternative to sculpting the mesh geometry. Since this does not affect the geometry of the mesh object, this can allow you to create detailed objects without the performance impact of an intricate mesh model.
The following example demonstrates how a partial and full transparency in this mode visually removes sections of the mesh:
@@ -221,7 +247,7 @@ The following example demonstrates how a partial and full transparency in this m
-There are two outcomes of `Enum.AlphaMode|Transparency` mode, depending on whether the `Class.MeshPart.Transparency` is set to `0` or **at least** `0.02`, although numerical precision may result in small values such as `0.01` triggering the opaque transparency.
+There are two outcomes of `Enum.AlphaMode.Transparency|Transparency` mode, depending on whether the `Class.MeshPart.Transparency` is set to `0` or **at least** `0.02`, although numerical precision may result in small values such as `0.01` triggering the opaque transparency.
- When alpha is used to cut out the shape of mostly opaque objects with hard edges such as foliage, lace fabric, and netting, set the `Class.MeshPart.Transparency` to `0`. When parts of the surface are fully opaque, the Roblox engine can render them with proper depth‑based occlusion. Opaque surfaces also generally work better with depth‑based effects like `Class.DepthOfFieldEffect`, glass and water refraction, and water reflection.
- When alpha is used to add detail to semi‑transparent objects or objects with smooth gradients of transparency, set the `Class.MeshPart.Transparency` to **at least** `0.02`. This improves the quality of blending for objects such as dirty windows and soft‑edged feathers, but it will not work with all effects.
diff --git a/.cursor/rules/roblox/en-us/assets/avatar/2k-Texture-Renders.zip b/.cursor/rules/roblox/en-us/assets/avatar/2k-Texture-Renders.zip
new file mode 100644
index 00000000..d96df080
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/avatar/2k-Texture-Renders.zip
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5e744bcca5cdbd072dcd60d7ac7ea57f5120535b8e0dc6c61a340bc8a48dd5f4
+size 353059568
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image1.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image1.png
new file mode 100644
index 00000000..05a8d6ec
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image1.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:76c9082a4d6c2a018367281b9d334921db46ea941b169f13ac2bc11abf0dc797
+size 2750997
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image10.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image10.png
new file mode 100644
index 00000000..9657a6d9
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image10.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:70810ab723611ddfaa3e5eb4c083957305705fe0a3bccf0172e6ff74b4a61317
+size 145292
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image11.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image11.png
new file mode 100644
index 00000000..693d151b
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image11.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ad871abf054b942f18d6b9706a5809538379cc7cfe510644d1f68d3fe3425633
+size 129402
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image12.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image12.png
new file mode 100644
index 00000000..560f9fab
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image12.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:30cf0564de491feab8d562b24a16591965cfa97b59e3a132c113aa6b3eb7d319
+size 70941
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image13.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image13.png
new file mode 100644
index 00000000..80b9854e
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image13.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a81ba2a1a2e2ae0fc885058c915e331893ceed912cac1254c4915826b436028f
+size 46340
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image14.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image14.png
new file mode 100644
index 00000000..8cf0fcdb
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image14.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7117ccf49dc072e89b0e69a90ef1e2d83ea22ace7d7ae65ae436bab6ee13a966
+size 1117027
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image15.jpg b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image15.jpg
new file mode 100644
index 00000000..f3c2e66e
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image15.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:918668cbcd41fbc173b2e35aaccd399ec033c00d30d074e8bf891a645d136376
+size 265039
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image16.jpg b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image16.jpg
new file mode 100644
index 00000000..4284f9f4
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image16.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:955470e94499f57a24c36af154443329edcb2bf8f71f0c761866a4c21911b3dd
+size 240939
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image17.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image17.png
new file mode 100644
index 00000000..7835a223
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image17.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:eb8622fb891b867d642ba45e843a643e43653ebdd8cd2ea36b3402c98a048a51
+size 315796
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image18.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image18.png
new file mode 100644
index 00000000..4c6545b2
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image18.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8a3e9bc7a72e6e9a1cc62fbd4c1709b3af9360eb9688d7490638dc5d247019d5
+size 2013316
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image19.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image19.png
new file mode 100644
index 00000000..0818cbf9
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image19.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bccbd83910720f1a5152a02b0d4441782df19453430a0345f71d1f658404de3d
+size 187780
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image2.jpg b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image2.jpg
new file mode 100644
index 00000000..ea178b60
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image2.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:41e4e5f7450f9e1be7500a2d7a8f14c6856fad50ef59d71e7ca572b58e135490
+size 1077476
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image20.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image20.png
new file mode 100644
index 00000000..cedd71b8
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image20.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:98057fe1a1cc8175a7f052267a3638d48a3e0f42270ed98ddf8e836c73e0d744
+size 267557
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image21.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image21.png
new file mode 100644
index 00000000..53fad468
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image21.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a0786316db482ee25364af853eed51876bfb81ab4786db17323ef265af5d56eb
+size 173660
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image22.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image22.png
new file mode 100644
index 00000000..98e852c1
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image22.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c16bd7f4c9bc37a637ad009313c0c5a751f2fd29561408db9aba40845a7b57c5
+size 844696
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image23.gif b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image23.gif
new file mode 100644
index 00000000..ce44ae45
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image23.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:85e1fd035de78a8ffc2bdc305c34b88bb3deebb4239f6c0f021d4d5750e92f60
+size 18031730
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image24.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image24.png
new file mode 100644
index 00000000..224a706e
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image24.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:aeb52ab29ae4c9a793a197451da5884dc2cb2a0baa9a31c971398c1b50b8ba38
+size 109093
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image25.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image25.png
new file mode 100644
index 00000000..2c621c64
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image25.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5188fc9bcaedd345b0fbbe4e183c55f6bac3e72262a28d6b1ac14dbfb50f3c6c
+size 216460
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image26.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image26.png
new file mode 100644
index 00000000..d47ba542
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image26.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:4f1198144379ee88204a500159dfb499b3ccee6a8e68f5cee5a9defa99286b20
+size 54884
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image27.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image27.png
new file mode 100644
index 00000000..11b9a35e
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image27.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:36d924b74162a2e6421db3cc0c4223da87a5a99a4f119e80cf18b97eb17d65d7
+size 1066242
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image28.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image28.png
new file mode 100644
index 00000000..091fee32
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image28.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e0b6f5c9d068ee3122a35c67c7628f0b1ab4493e23f6b68a0606150fc2b6c3cd
+size 4925536
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image29.gif b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image29.gif
new file mode 100644
index 00000000..d568d2a6
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image29.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1bf17a0b5e3ca1b7fa73def2a9bfd85df21708757cda49ce98c3ff860673f8d0
+size 40765240
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image3.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image3.png
new file mode 100644
index 00000000..13fbbc7a
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image3.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e36b717e5562c5c9a66b2f00eaa9750b397e28959f7f505ec8324f96159a5e39
+size 178534
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image30.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image30.png
new file mode 100644
index 00000000..e2c5f84b
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image30.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7150cf017752c682801bfdef709bf5e6638cee34e859f4cb4b36c9628c64ac38
+size 236647
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image31.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image31.png
new file mode 100644
index 00000000..50800665
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image31.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d52a00914cfdce2fc0442eba7a54ded193247f2626a46a6bee5230d2bfbe585b
+size 69756
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image32.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image32.png
new file mode 100644
index 00000000..481f2e91
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image32.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:fefd29af09fa54e9209f0ae93f8797892b15ba9819fac43e337f8496076ce1de
+size 53332
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image33.gif b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image33.gif
new file mode 100644
index 00000000..6ed3dec6
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image33.gif
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:85374f4c89ae4ebfe67614c0f8c230db1cf8c372bd72ae4d7ed5ce4caee14f8e
+size 18755456
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image34.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image34.png
new file mode 100644
index 00000000..87b6a9dc
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image34.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:bd88fe5badff1d52f8028fe644b5f89176f4f67d0c375d0239835355c67a7ffb
+size 262639
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image35.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image35.png
new file mode 100644
index 00000000..9759b7bd
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image35.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d5581bfe016052d6e52c601022394d7a10e80682a14e6b8dc7e5c51c826f4525
+size 44798
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image36.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image36.png
new file mode 100644
index 00000000..db2c4523
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image36.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:98e6bc16697cc21c923c0b35e213482eed92f47f7cd6325d4b87921cf1d4ee63
+size 167126
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image37.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image37.png
new file mode 100644
index 00000000..97bf1aa7
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image37.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e480949344eb622abf5ce522690c9628f2a580e1797d33a83a5be0415dc13bf9
+size 3029750
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image38.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image38.png
new file mode 100644
index 00000000..c2f6e0ec
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image38.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1fa29deefd40bd2d9483815031f5538cf703fe2648aff8834bcd680de78d633b
+size 126616
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image39.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image39.png
new file mode 100644
index 00000000..e92c7045
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image39.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b795366ded7792a4964e5c59645662031a48318954d63e2612e1fa0f964ef936
+size 450824
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image4.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image4.png
new file mode 100644
index 00000000..42d824d5
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image4.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c8c27305fada5e8a1aa1733246a5b87b8ea2acd866180f7dac34a1e61c3f0523
+size 165418
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image40.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image40.png
new file mode 100644
index 00000000..a480b072
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image40.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:765565deb33074ea5f93660873936db067a762630332e6d1bd392ea90be20b02
+size 109376
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image41.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image41.png
new file mode 100644
index 00000000..526444ae
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image41.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:1a0ad3f6b427d71bab4256847590b2e692af1e035e332de9ae030254894262e0
+size 589826
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image42.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image42.png
new file mode 100644
index 00000000..d1eea7ab
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image42.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dfd9f13a0f2ee429276c7455ce8d5dca41c328c1ca5b11fab9e2ee2243accb06
+size 3676154
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image43.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image43.png
new file mode 100644
index 00000000..f7f04660
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image43.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d1b005bc03997530b3aceaeb3df017e8d0869bba7e697e67e5c5702feee9ab88
+size 57886
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image44.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image44.png
new file mode 100644
index 00000000..dda01af9
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image44.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:af9f634df41ce54f01123fb11dd1af2b5e3e8093d4c7fb986255fbe5a0b99cd9
+size 5249243
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image45.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image45.png
new file mode 100644
index 00000000..6369324a
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image45.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c1309d258d20fd2dcad61a0b612be42a856c036ed54bd27d6b75c05fb3853bfe
+size 187533
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image46.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image46.png
new file mode 100644
index 00000000..4069dd7d
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image46.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:021edfda621770d17c7f861efbf5b4ad4ac1c51182dc3edc8b4a40c933c20420
+size 93610
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image47.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image47.png
new file mode 100644
index 00000000..4e94fa64
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image47.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5f9bb8633adb5593d6bd33111eb8ca7972b60b01851dac73e1ba82b6defa3f86
+size 1241629
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image48.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image48.png
new file mode 100644
index 00000000..8e58b214
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image48.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c3779cfcb818207d45783f5431026138fdfe2e5617bbf139e3a272ce460e2e9b
+size 189270
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image49.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image49.png
new file mode 100644
index 00000000..cf6ed578
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image49.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ff2210aa55c0f7ad127ba18efb26995eeed0376dadf08420a1c81e94f132adcf
+size 3877158
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image5.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image5.png
new file mode 100644
index 00000000..6ddd215b
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image5.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:14c12a3464c1c970c31912f0444cf59b3a574d5ab97df815feee6ba60d06c9c7
+size 441294
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image50.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image50.png
new file mode 100644
index 00000000..2e588682
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image50.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:df4f13605002ceb2702ee7fa6dcc31412746866f7c521b2b8dab808e28780cac
+size 1360643
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image51.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image51.png
new file mode 100644
index 00000000..b9548f3d
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image51.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:557c74590d011bf49a046f1061dc5155a2399766a02a21fcfd1b83632fddcb6a
+size 89372
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image6.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image6.png
new file mode 100644
index 00000000..8715330d
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image6.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b4d943dff04c4dce79616390951e8793ff2a857c00779b530be51b9684192b33
+size 390456
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image7.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image7.png
new file mode 100644
index 00000000..a2cbe149
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image7.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:961d4deca1a44e6a48a263f7b1618b676d9f0e3e9c2944063f428dcf5a7b08a0
+size 816454
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image8.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image8.png
new file mode 100644
index 00000000..d3ec2b35
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image8.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:af0eddb5a616851447e16211881c8c184da7104cfd39a45b4d628d33afefbd51
+size 2293973
diff --git a/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image9.png b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image9.png
new file mode 100644
index 00000000..b812a434
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/developer-jumpstart/image9.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:d63ea8c9322f391075b3730c8989bde2dc9f835c26c06d6cacf9565034f433ff
+size 163176
diff --git a/.cursor/rules/roblox/en-us/assets/landing/monetization/hero.png b/.cursor/rules/roblox/en-us/assets/landing/monetization/hero.png
new file mode 100644
index 00000000..cf6ed578
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/landing/monetization/hero.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:ff2210aa55c0f7ad127ba18efb26995eeed0376dadf08420a1c81e94f132adcf
+size 3877158
diff --git a/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial1.jpg b/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial1.jpg
new file mode 100644
index 00000000..6aad4372
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial1.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:8fd2373256bbfdc236ed4223cb47e524a74df36a422802a0574649c390575bcd
+size 967928
diff --git a/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial2.jpg b/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial2.jpg
new file mode 100644
index 00000000..73b3a30b
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial2.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b9acf01a291a3cece8ea76493c539c25fea1a52a0051d374836aa15b5c9e4d34
+size 6343420
diff --git a/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial3.png b/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial3.png
new file mode 100644
index 00000000..8a826a52
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial3.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:dbea877a77568ddb929d83f3319ab4c01dc5604456402395215551e062a70b99
+size 401951
diff --git a/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial4.png b/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial4.png
new file mode 100644
index 00000000..fb951139
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/landing/monetization/testimonial4.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a79478787194f8a64dc7752c13dee1e2090c59fa5a06b26a54c3fa7096a27974
+size 5267580
diff --git a/.cursor/rules/roblox/en-us/assets/modeling/surface-appearance/SurfaceAppearance-Opaque-After.jpg b/.cursor/rules/roblox/en-us/assets/modeling/surface-appearance/SurfaceAppearance-Opaque-After.jpg
new file mode 100644
index 00000000..9f0f432e
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/modeling/surface-appearance/SurfaceAppearance-Opaque-After.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:38d66b8622b26a10f3165b6376cede8bef4d642e295ab39e1317ba4fd1555e8f
+size 207939
diff --git a/.cursor/rules/roblox/en-us/assets/modeling/surface-appearance/SurfaceAppearance-Opaque-Before.jpg b/.cursor/rules/roblox/en-us/assets/modeling/surface-appearance/SurfaceAppearance-Opaque-Before.jpg
new file mode 100644
index 00000000..d741ff67
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/modeling/surface-appearance/SurfaceAppearance-Opaque-Before.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9c47b9a886f16e9a2fab955c09b162a9b834132ea51d539764b83545bd99a029
+size 176093
diff --git a/.cursor/rules/roblox/en-us/assets/modeling/surface-appearance/SurfaceAppearance-Opaque-ColorMap.jpg b/.cursor/rules/roblox/en-us/assets/modeling/surface-appearance/SurfaceAppearance-Opaque-ColorMap.jpg
new file mode 100644
index 00000000..f9b2dc88
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/modeling/surface-appearance/SurfaceAppearance-Opaque-ColorMap.jpg
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e9084b7c51326b59ea314aa6a7d05b1081f2cb3bd3a8bf146956e08af5e8ae19
+size 120982
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-AlignType-AllAxes.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-AlignType-AllAxes.mp4
deleted file mode 100644
index 1ff11435..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-AlignType-AllAxes.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:7b18ede5dcd31e8940590903ea63d41eb9a488bf7dfd25c019a706c5856e5db6
-size 3107410
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-AlignType-PrimaryAxisParallel.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-AlignType-PrimaryAxisParallel.mp4
deleted file mode 100644
index b3ba1b3e..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-AlignType-PrimaryAxisParallel.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:817a09c90efeb87129dd7ef5f244bf0af24cb60c9fa7d080f515e9906009fc6e
-size 3164377
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-AlignType.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-AlignType.mp4
new file mode 100644
index 00000000..45bebcea
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-AlignType.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:e513e39d96822e66c3fe244e007598748f93c97935be7e52042991fc08cccbee
+size 2611787
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-Demo.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-Demo.mp4
index 385530b4..6fe5427b 100644
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-Demo.mp4
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-Demo.mp4
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:cb424364a43fe2221737def0da9f369563a83721b6dd87a2514f5208246d0e5c
-size 2207883
+oid sha256:330bd3b467d10e3e34d15f39d5998eac18b33c503dcaa4aa44ab259706129e35
+size 2182967
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-ReactionTorqueEnabled-False.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-ReactionTorqueEnabled-False.mp4
deleted file mode 100644
index b04bb9db..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-ReactionTorqueEnabled-False.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:ab84f5f35233337f7197e4880b8f27248144dbe202c7dde0f3ea1cfbb7dbb21c
-size 1787417
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-ReactionTorqueEnabled-True.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-ReactionTorqueEnabled-True.mp4
deleted file mode 100644
index 4b6e30df..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-ReactionTorqueEnabled-True.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:ce8d7cdaba541e2184176e4fec21313a8a81f58a0656c1785e2a2c15acfcbe7f
-size 1808094
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-RigidityEnabled.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-RigidityEnabled.mp4
new file mode 100644
index 00000000..c3e50631
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignOrientation-RigidityEnabled.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:174e9f04557d08cf029a1e37ef0458e299bb733aef2d9feb590a0b0ffa64d0be
+size 2420977
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ApplyAtCenterOfMass-False.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ApplyAtCenterOfMass-False.mp4
deleted file mode 100644
index de349c5f..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ApplyAtCenterOfMass-False.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:e03d8b657e4b522e87abd70286de2b8b55708425b34bcacc9d47646b9df5b187
-size 2576298
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ApplyAtCenterOfMass-True.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ApplyAtCenterOfMass-True.mp4
deleted file mode 100644
index 827489a1..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ApplyAtCenterOfMass-True.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:7ae52275fa02a9f488a570a9e67e4639e60087288d09ce93d49cd9e00550f12c
-size 2375207
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-Demo.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-Demo.mp4
index 9dc0096f..32e439ed 100644
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-Demo.mp4
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-Demo.mp4
@@ -1,3 +1,3 @@
version https://git-lfs.github.com/spec/v1
-oid sha256:211fac7fb009995450a0a4b619face50489d13221349ab329b93d6220c4dc54e
-size 2162434
+oid sha256:4b1dd6cd61d3235363abd42e675341e5b42f2bfa5fff22edffdbf4fa0052facf
+size 2203263
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ReactionForceEnabled-False.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ReactionForceEnabled-False.mp4
deleted file mode 100644
index 9ac2d79e..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ReactionForceEnabled-False.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:825e29647b74e80d23d72932a2f487369b5545f2cd1fdd1e4f4a595c4e53666c
-size 1986224
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ReactionForceEnabled-True.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ReactionForceEnabled-True.mp4
deleted file mode 100644
index 8c96a834..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ReactionForceEnabled-True.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:667504455207cf83b81bfd20fe3185b0bb819f27a74a73c2b10385820bf6a716
-size 2023964
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ReactionForceEnabled.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ReactionForceEnabled.mp4
new file mode 100644
index 00000000..fd785f23
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/AlignPosition-ReactionForceEnabled.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:9ef0359b130a8526cd3cf392e26160afa2be69a2206f7238313ab90fa9b72f89
+size 2621444
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AnimationConstraint-Demo.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AnimationConstraint-Demo.mp4
new file mode 100644
index 00000000..505a41f9
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/AnimationConstraint-Demo.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:f3eb2fe7964c8b5d07d055a4dcbf777c153020787623d604a00d96d578b9831f
+size 2023529
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/AnimationConstraint-Transform.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/AnimationConstraint-Transform.mp4
new file mode 100644
index 00000000..56ec7785
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/AnimationConstraint-Transform.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:088dcca05844079c82a2166f27138659b6bc9059e3f227ee994936706ac7fef3
+size 1662204
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/BallInSocket-Demo.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/BallInSocket-Demo.mp4
deleted file mode 100644
index 0397de89..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/BallInSocket-Demo.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:3439a9b306fe3baba52e6271f657273a7faaaf7b32d98a6a8f369a78ddc13bb6
-size 2993628
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/BallInSocket-Limits-Tilt.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/BallInSocket-Limits-Tilt.mp4
deleted file mode 100644
index 3d5399e6..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/BallInSocket-Limits-Tilt.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:d49c29ad0f6685e8f34591928ecf0681fb4664d5b483a6f74d3addcbd552c9d7
-size 2344763
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/BallInSocket-Limits-Twist.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/BallInSocket-Limits-Twist.mp4
deleted file mode 100644
index 3ef1d9af..00000000
--- a/.cursor/rules/roblox/en-us/assets/physics/constraints/BallInSocket-Limits-Twist.mp4
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:b466865f8b9e39310fe413f721cef3df389f650a5aa404dca734c2a59e48deb3
-size 1384988
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/BallSocket-Demo.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/BallSocket-Demo.mp4
new file mode 100644
index 00000000..18f18351
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/BallSocket-Demo.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c8d8026eab69003f0c77ee09bc64fb0f346ce400b30663e6c0bba468ddca2ce5
+size 2386795
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/BallSocket-Limits-Tilt.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/BallSocket-Limits-Tilt.mp4
new file mode 100644
index 00000000..4b910788
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/BallSocket-Limits-Tilt.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:7c27938037a8804590118d1e7702b0de9b0ecff322c23e7eb99bb3b5adcf0895
+size 2477896
diff --git a/.cursor/rules/roblox/en-us/assets/physics/constraints/BallSocket-Limits-Twist.mp4 b/.cursor/rules/roblox/en-us/assets/physics/constraints/BallSocket-Limits-Twist.mp4
new file mode 100644
index 00000000..a282d2e3
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/physics/constraints/BallSocket-Limits-Twist.mp4
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:48eb94241539bce1f9a9c1ccfd5b2f3b8ea6e297573aa25f48dd69797dffffd0
+size 2584327
diff --git a/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Bulk-A.png b/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Bulk-A.png
new file mode 100644
index 00000000..e9256c6f
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Bulk-A.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:b9fad20a7b321d98119fbb9ef7e1d026993d861274788407220f1e1ed33af345
+size 107640
diff --git a/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Bulk-B.png b/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Bulk-B.png
new file mode 100644
index 00000000..1e46e00a
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Bulk-B.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:03509d1ddf8ae09e3aec8edfd5b385a09e1d5c5908f81da26582a1f2a1cedcfc
+size 32339
diff --git a/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Mobile-Marketplace.png b/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Mobile-Marketplace.png
new file mode 100644
index 00000000..72115cca
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Mobile-Marketplace.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:a284a2d6ef727f788cc258ce965b09f3923a165cb74d5992267524551999847c
+size 107638
diff --git a/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Per-Item.png b/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Per-Item.png
new file mode 100644
index 00000000..4d2c8052
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/assets/publishing/marketplace/Timed-Options-Per-Item.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:46b4962e6aa9e61129fd9e5cad812d3165e23825063c5b38d493d70b55bf5203
+size 137385
diff --git a/.cursor/rules/roblox/en-us/cloud-services/extended-services.md b/.cursor/rules/roblox/en-us/cloud-services/extended-services.md
index c151e9d4..35d0543f 100644
--- a/.cursor/rules/roblox/en-us/cloud-services/extended-services.md
+++ b/.cursor/rules/roblox/en-us/cloud-services/extended-services.md
@@ -91,98 +91,109 @@ For a detailed breakdown of your current pending balance costs, click **View Det
## Service pricing
-See the following table for Extended Services pricing.
+See the following table for Extended Services pricing:
-¹ GB per Hour = the storage consumption multiplied by the amount of time. For example, 100GB Hours might equate to "100GB x 1 hour" or "200GB x 0.5 hours".
+¹ GB per hour = the storage consumption multiplied by the amount of time. For example, 100GB hours might equate to "100GB x 1 hour" or "200GB x 0.5 hours".
## Supported countries
-Extended Services is available in the following countries.
+Extended Services is available in the following countries:
diff --git a/.cursor/rules/roblox/en-us/get-started.md b/.cursor/rules/roblox/en-us/get-started.md
deleted file mode 100644
index ec2f46c5..00000000
--- a/.cursor/rules/roblox/en-us/get-started.md
+++ /dev/null
@@ -1,205 +0,0 @@
----
-title: Get started on Roblox
-description: Learn how to get started quickly on Roblox
-hideInPageNavigation: true
----
-
-export const statsByline = "* Figures are as of Q4 2024";
-
-export const scaleStats = [
- { header: "85.3M", description: "Daily active users" },
- { header: "18.9M", description: "Monthly unique payers" },
- { header: "18.7B", description: "Quarterly hours engaged" },
- { header: "750M", description: "Yearly creator earnings" },
- { header: "18.9M", description: "DevX" },
- { header: "18.7B", description: "xyz" },
-];
-
-export const sections = [
-
- {
- title: "",
- description: "Getting started on Roblox is easy, and learning about the ecosystem only takes a few minutes. Better yet, you can start creating and sharing your creations in less than an hour with these resources.",
- content: [
- {
- title: "1. Learn about what you can do",
- description: "This video goes over some of the things you can build on Roblox and the tools you need to do it.",
- video: "https://www.youtube-nocookie.com/embed/vIiVbFiDbBE",
- links: [
- {text: "Watch overview", href: "https://www.youtube.com/watch?v=vIiVbFiDbBE" },
- ]
- },
- {
- title: "2. Get a Roblox account and the app",
- description: "The same Roblox account works for playing and creating. Sign up at roblox.com and download the app for your preferred device.",
- image: "./assets/landing/app.jpg",
- links: [
- {text: "Go to roblox.com", href: "https://www.roblox.com" },
- ]
- },
- {
- title: "3. Customize your avatar and play something",
- description: "The best way to understand Roblox is to use it! Customize your avatar with free or paid items and play a few of the millions of experiences.",
- image: "./assets/landing/avatar-play.jpg",
- links: [
- {text: "Browse avatar items", href: "https://www.roblox.com/catalog" },
- {text: "Browse experiences", href: "https://www.roblox.com/charts" },
- ]
- },
- {
- title: "4. Get Studio and take the tour",
- description: "Roblox Studio is your main creation tool and is supported on Windows and Mac. The onboarding tour gets you acclimated to basic workflows.",
- image: "./assets/landing/get-started/studio.png",
- links: [
- {text: "Roblox Studio setup", href: "./studio/setup" },
- ]
- }
- ]
- },
- {
- title: "Experiences",
- description: "Making an experience can seem intimidating, but we promise it's not too bad! Walk through the tutorial or watch the following videos to understand a bit more about how experiences work.",
- buttons: [
- { text: "See all docs", href: "./experiences" }
- ],
- content: [
- {
- title: "Create your first experience",
- description: "Create a simple 3D platformer while learning important Roblox building and scripting concepts.",
- image: "./assets/landing/core-experience.png",
- links: [
- { text: "Start creating", href: "./tutorials/curriculums/core/" },
- ]
- },
- {
- title: "Intro to world building",
- description: "Sit back and watch one of our 3D artists show you how to construct 3D worlds in Studio.",
- video: "https://www.youtube-nocookie.com/embed/SgPU84AqpkY",
- links: [
- { text: "Watch livestream", href: "https://youtu.be/SgPU84AqpkY" }
-
- ]
- },
- {
- title: "Intro to physics",
- description: "The Roblox engine simulates real-life materials, physics, collisions and more. Join one of our product managers for a overview of how the physics simulation works.",
- video: "https://www.youtube-nocookie.com/embed/9mXvhYSv7fc",
- links: [
- { text: "Watch livestream", href: "https://youtu.be/9mXvhYSv7fc" },
-
- ]
- },
- ]
- },
- {
- title: "Avatar items",
- description: "Making avatar items can sometimes be easier than making an experience. You can make a simple 2D t-shirt with an image editor without having to open Studio at all. If you're interested in 3D modeling, use Blender and Studio together to make a basic 3D accessory.",
- buttons: [
- { text: "See all docs", href: "./avatar" }
- ],
- content: [
- {
- title: "Avatar items overview",
- description: "Learn about all the different things you can create and allow users to equip for their avatars.",
- video: "https://www.youtube-nocookie.com/embed/EUDSIUmLjxA",
- links: [{ text: "Watch overview", href: "https://youtu.be/EUDSIUmLjxA" }]
- },
- {
- title: "Create a t-shirt",
- description: "A simple t-shirt is the easiest example of how to create an avatar item.",
- video: "https://www.youtube-nocookie.com/embed/r_unfGZT5Ps",
- links: [
- { text: "Watch how to do it", href: "https://youtu.be/r_unfGZT5Ps" },
- { text: "Guides", href: "./art/classic-clothing" }
- ]
- },
- {
- title: "Create a backpack accessory",
- description: "Learn how to create a backpack, which is an example of a 3D accessory. These accessories are simple, non-animated items that attach to a single point on an avatar's body.",
- video: "https://www.youtube-nocookie.com/embed/Eed29gV0hLA",
- links: [
- { text: "Watch how to do it", href: "https://youtu.be/Eed29gV0hLA" },
- { text: "Guides", href: "./art/accessories" }
- ]
- }
- ]
- },
-];
-
-{sections.map((section, index) => (
-
- {section.title && (
- {section.title}
- )}
-
-
- );
- })}
-
- )}
-
-))}
diff --git a/.cursor/rules/roblox/en-us/get-started/creating.md b/.cursor/rules/roblox/en-us/get-started/creating.md
new file mode 100644
index 00000000..1479ac62
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/get-started/creating.md
@@ -0,0 +1,194 @@
+---
+title: Get started creating on Roblox
+description: Learn how to create experiences and avatar items quickly on Roblox
+hideInPageNavigation: true
+---
+
+export const sections = [
+
+{
+title: "",
+description: "Getting started on Roblox is easy, and learning about the ecosystem only takes a few minutes. Better yet, you can start creating and sharing your creations in less than an hour with these resources.",
+content: [
+{
+title: "1. Learn about what you can do",
+description: "This video goes over some of the things you can build on Roblox and the tools you need to do it.",
+video: "https://www.youtube-nocookie.com/embed/vIiVbFiDbBE",
+links: [
+{text: "Watch overview", href: "https://www.youtube.com/watch?v=vIiVbFiDbBE" },
+]
+},
+{
+title: "2. Get a Roblox account and the app",
+description: "The same Roblox account works for playing and creating. Sign up at roblox.com and download the app for your preferred device.",
+image: "../assets/landing/app.jpg",
+links: [
+{text: "Go to roblox.com", href: "https://www.roblox.com" },
+]
+},
+{
+title: "3. Customize your avatar and play something",
+description: "The best way to understand Roblox is to use it! Customize your avatar with free or paid items and play a few of the millions of experiences.",
+image: "../assets/landing/avatar-play.jpg",
+links: [
+{text: "Browse avatar items", href: "https://www.roblox.com/catalog" },
+{text: "Browse experiences", href: "https://www.roblox.com/charts" },
+]
+},
+{
+title: "4. Get Studio and take the tour",
+description: "Roblox Studio is your main creation tool and is supported on Windows and Mac. The onboarding tour gets you acclimated to basic workflows.",
+image: "../assets/landing/get-started/studio.png",
+links: [
+{text: "Roblox Studio setup", href: "../studio/setup" },
+]
+}
+]
+},
+{
+title: "Experiences",
+description: "Making an experience can seem intimidating, but we promise it's not too bad! Walk through the tutorial or watch the following videos to understand a bit more about how experiences work.",
+buttons: [
+{ text: "See all docs", href: "../experiences" }
+],
+content: [
+{
+title: "Create your first experience",
+description: "Create a simple 3D platformer while learning important Roblox building and scripting concepts.",
+image: ".../assets/landing/core-experience.png",
+links: [
+{ text: "Start creating", href: "../tutorials/curriculums/core/" },
+]
+},
+{
+title: "Intro to world building",
+description: "Sit back and watch one of our 3D artists show you how to construct 3D worlds in Studio.",
+video: "https://www.youtube-nocookie.com/embed/SgPU84AqpkY",
+links: [
+{ text: "Watch livestream", href: "https://youtu.be/SgPU84AqpkY" }
+
+ ]
+ },
+ {
+ title: "Intro to physics",
+ description: "The Roblox engine simulates real-life materials, physics, collisions and more. Join one of our product managers for a overview of how the physics simulation works.",
+ video: "https://www.youtube-nocookie.com/embed/9mXvhYSv7fc",
+ links: [
+ { text: "Watch livestream", href: "https://youtu.be/9mXvhYSv7fc" },
+
+ ]
+ },
+ ]
+
+},
+{
+title: "Avatar items",
+description: "Making avatar items can sometimes be easier than making an experience. You can make a simple 2D t-shirt with an image editor without having to open Studio at all. If you're interested in 3D modeling, use Blender and Studio together to make a basic 3D accessory.",
+buttons: [
+{ text: "See all docs", href: "../avatar" }
+],
+content: [
+{
+title: "Avatar items overview",
+description: "Learn about all the different things you can create and allow users to equip for their avatars.",
+video: "https://www.youtube-nocookie.com/embed/EUDSIUmLjxA",
+links: [{ text: "Watch overview", href: "https://youtu.be/EUDSIUmLjxA" }]
+},
+{
+title: "Create a t-shirt",
+description: "A simple t-shirt is the easiest example of how to create an avatar item.",
+video: "https://www.youtube-nocookie.com/embed/r_unfGZT5Ps",
+links: [
+{ text: "Watch how to do it", href: "https://youtu.be/r_unfGZT5Ps" },
+{ text: "Guides", href: "../art/classic-clothing" }
+]
+},
+{
+title: "Create a backpack accessory",
+description: "Learn how to create a backpack, which is an example of a 3D accessory. These accessories are simple, non-animated items that attach to a single point on an avatar's body.",
+video: "https://www.youtube-nocookie.com/embed/Eed29gV0hLA",
+links: [
+{ text: "Watch how to do it", href: "https://youtu.be/Eed29gV0hLA" },
+{ text: "Guides", href: "../art/accessories" }
+]
+}
+]
+},
+];
+
+{sections.map((section, index) => (
+
+{section.title && (
+{section.title}
+)}
+
+
+
+ );
+ })}
+
+ )}
+
+
+))}
diff --git a/.cursor/rules/roblox/en-us/get-started/how-is-roblox-different.md b/.cursor/rules/roblox/en-us/get-started/how-is-roblox-different.md
new file mode 100644
index 00000000..58a65e4f
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/get-started/how-is-roblox-different.md
@@ -0,0 +1,87 @@
+---
+title: How is Roblox different from other platforms?
+description: Frictionless play, community collaboration, and reach beyond Roblox.
+hideInPageNavigation: true
+fullWidth: true
+---
+
+
Frictionless play
+
+
+
+
+
No complicated downloads
+ Roblox is built on the cloud, allowing users to join new experiences in seconds, without having to download massive files.
+
+
+
+
+
Automatic matchmaking
+ Users are automatically placed in servers with friends and other users from their region, making it easier than ever to connect with friends and make new ones.
+
+
+
+
+
Cross-platform support
+ Experiences can be published across all major devices, allowing players to play how they want, where they want, with whomever they want.
+
+
+
+
+
+
+
+
+
Collaborate with your players
+
+
+
+
+
Communities are part of the process
+ Due to the user-generated content (UGC) nature of Roblox, the community is much more involved, as many devs are also often community members. Cultivating a healthy community and involving users in development is key to success.
+
+
+
+
+
Benefit from direct feedback
+ Since Roblox enables creators to develop and publish updates quickly, they can efficiently gather feedback and iterate -- resulting in a deeper understanding of their audience and a more focused experience for users.
+
+
+
+
+
+
+
+
+
Reach beyond Roblox
+
+
+
+
+
Massive creator ecosystem
+ Roblox fuels a thriving community of content creators on platforms like YouTube and TikTok, generating views and driving engagement.
+
+
+
+
+
Engaged cross-platform audience
+ Roblox content resonates beyond the platform, with creators building loyal followings and extending reach to new players.
+
+
+
+
+
+
+
diff --git a/.cursor/rules/roblox/en-us/get-started/index.md b/.cursor/rules/roblox/en-us/get-started/index.md
new file mode 100644
index 00000000..57d0abc4
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/get-started/index.md
@@ -0,0 +1,104 @@
+---
+title: Get Started
+description: A guide for new Roblox developers. Explains why to develop on Roblox the platform, and how to get started.
+hideInPageNavigation: true
+---
+
+
+
+
Welcome to Roblox, we're glad youʼre here! Itʼs an exciting time to develop on Roblox. This guide is a crash course in all things Roblox, covering the most commonly asked questions by developers:
diff --git a/.cursor/rules/roblox/en-us/get-started/monetization.md b/.cursor/rules/roblox/en-us/get-started/monetization.md
new file mode 100644
index 00000000..1d6ced53
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/get-started/monetization.md
@@ -0,0 +1,257 @@
+---
+title: How do I make money?
+description: Creator Rewards, in-experience purchases, subscriptions, UGC, immersive ads, and more.
+hideInPageNavigation: true
+fullWidth: true
+---
+
+
Earn on Roblox
+
+
+
+
+
Diverse earning opportunities
+ We're excited to provide creators with a wide variety of ways to earn from their experiences, including subscriptions, in-app purchases, engagement rewards, and more. We're always evolving and adding new features to help you earn and succeed.
+
+
+
+
+
Developer Exchange Program (DevEx)
+ The DevEx program allows eligible creators to convert earned Robux into real-world currency. Once you've met the requirements, including having a minimum of 30,000 earned Robux, you can submit a request to cash out.
+
+
+
+
+
+
+
+
+
In-app purchases
+
+
+
+
+
Repeat purchases
+ Dev Products are a type of sale item that can be purchased multiple times, only with Robux. This is used for things like in-game purchases, boosts, etc. Dev Products generally monetize better, as they can be repeatedly purchased.
+
+
+
+
+
One-time purchases
+ [Game passes](../production/monetization/passes.md) are a type of sale item that can only be purchased once, only with Robux. This is useful for things like VIP passes, content bundles, or battle passes.
+
+
+
+
+
You receive 70% of Robux spent
+ The remaining 30% is Robloxʼs Marketplace Fee. To convert these Robux to a real currency, youʼll still need to withdraw it via DevEx.
+
+
+
+
+
+
+
+
+
Subscriptions
+
+
+
+
+
Subscriptions
+ [Subscriptions](../production/monetization/subscriptions.md) provide players with benefits for a recurring monthly fee. Common benefits include in-game currency, multipliers, and access to exclusive vehicles, weapons and clothing. Subscriptions auto-renew and are priced in local currency.
+
+
+
+
+
Subscriber analytics
+ The Creator dashboard allows you to track metrics including subscriber breakdown and cancellations, estimated revenue, subscriptions by platform, and platform earnings.
+
+
+
+
+
+
+
+
+
+
Creator rewards
+
+
+
+
+
Creator Rewards
+ Weʼre increasing our investment in the developer community by rewarding creators for producing engaging content and bringing new users to the platform.
+
+
+
+
+
Daily engagement
+ Earn a fixed payout of 5 Robux when a user who has spent at least $9.99 on the platform in the last 60 days (an "Active Spender") plays your game for 10 minutes or more. This reward applies to the first three experiences they play per day. *
+
+
+
+
+
Audience expansion
+ Earn a 35% revenue share on the first $100 in Robux purchases made by a new or returning user who finds your experience through a direct link or search, and plays for at least 10 minutes. _
+
+
+ _ Less Qualifying Purchases they have made in the 60 days after each time (if any) they have previously reactivated). Additional restrictions apply.
+
+
+
+
+
+
+
UGC avatar items
+
+
+
+
+
UGC for everyone
+ Previously restricted to approved creators, selling user-generated avatar clothing is now available to all creators who are age-verified and subscribe to Premium.
+
+
+
+
+
Creators receive 30%, sellers 40%
+ For items sold in the Avatar Marketplace, Roblox collects the 40% seller portion + a 30% market fee. If your item is sold from within another experience, the owner of that experience will collect the 40% seller portion instead.
+
+
+
+
+
Sell in your own experience
+ If you sell your UGC item within an experience you own, you will earn 30% for being the creator and 40% for being the seller, bringing your return to 70% of Robux spent.
+
+
+
+
+
+
+
+
+
Immersive ads
+
+
+
+
+
Advertise
+ Programmatically-served ad content from brands appear directly within your experiences. These native ads blend into the 3D environment, offering a seamless way to monetize your experience.
+
+
+
+
+
Ad formats
+ Integrate a [variety of formats](../production/promotion/advertise.md), including video ads that can autoplay or be click-to-play, image ads that are static billboards, and portal ads that can teleport users to an advertiser's experience.
+
+
+
+
+
How to earn
+ Creators are paid through a revenue share based on engagement. You can earn from video views, ad impressions, and successful teleports that are generated by the ads in your experience.
+
+
+
+
+
+
+
+
+
Brand integrations
+
+
+
+
+
Limited-time activations
+ Limited-time activations bring brands into an experience for a brief time – usually 2–4 weeks – through content like quests and avatar items. For a more authentic integration that players will respond to, be sure to choose brand partners that fit your experienceʼs vibe, aesthetics, and goals.
+
+
+
+
+
Make it meaningful
+ For a seamless and authentic brand integration, weave the brand into your game's [core loop](https://youtu.be/gkFKF9A-snY). This means the brand content should feel like a natural extension of the gameplay, enhancing the player's progression and overall experience.
+
+
+
+
+
+
+
+
+
Digital + physical merchandising
+
+
+
+
+
Sell physical goods
+ The new Roblox Commerce APIs enable creators and brands to sell physical products directly within their Roblox experiences, creating a virtual mall-like experience. Shopify is the first integrated partner.
+
+
+
+
+
Bridge digital & physical
+ The Approved Merchandiser Program (AMP) links physical product purchases with digital items on Roblox. Physical products with the AMP badge will include a code unlocking a unique digital item in the experience.
+
+
+
+
+
Empowering creators
+ By bridging the gap between virtual and real-world shopping, Roblox is opening up new avenues for revenue generation and brand building.
+
+
+
+
+
+
+
+
+
Price optimization
+
+
+
+
+
Automated price testing
+ Our [Price Optimization](../production/monetization/price-optimization.md) system intelligently experiments with different price points, showing them to subsets of your users to identify the sweet spot that maximizes your revenue.
+
+
+
+
+
Dynamic pricing
+ Keep your prices competitive with dynamically-scripted pricing. Our tools make flexible pricing strategies simple, allowing you to respond to market trends and player behavior in real time.
+
+
+
+
+
Data-driven decisions
+ Monitor both short-term and long-term impacts, and use our insights to help ensure that your pricing strategy drives sustainable growth and maximizes your overall earnings.
+
+
+
+
+
+
+
+
+
Regional pricing
+
+
+
+
+
Unlock international reach
+ Roblox's [Regional Pricing](https://corp.roblox.com/newsroom/2025/04/roblox-launches-regional-pricing-for-in-experience-items) automatically determines and sets optimal local prices for your in-experience items, making your content more accessible and appealing to players around the world.
+
+
+
+
+
Help boost worldwide spending
+ Early testing demonstrates substantial increases in user spending in regions like Mexico, Brazil, and the Philippines, demonstrating the power of localized pricing strategies.
+
+
+
+
+
+
+
+
diff --git a/.cursor/rules/roblox/en-us/get-started/resources.md b/.cursor/rules/roblox/en-us/get-started/resources.md
new file mode 100644
index 00000000..74b4c136
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/get-started/resources.md
@@ -0,0 +1,98 @@
+---
+title: Resources
+description: Get started with these resources, community feedback, growth strategies, and RDC.
+hideInPageNavigation: true
+fullWidth: true
+---
+
+
+ RDC offers creators a firsthand look into the future of Roblox with keynote presentations from our CEO David Baszucki and other Roblox leaders.
+
+
+
+
+
Breakout sessions
+ There are in-depth breakout sessions showcasing the latest technology that will empower creator success and lots of great networking opportunities.
+
+
+
+
+
Roblox Innovation Awards
+ This is where we also hold the Roblox Innovation Awards, an annual award show recognizing the yearʼs most innovative experiences and creators.
+
+
+
+
+
+Read more about RDC 2025
+
+
diff --git a/.cursor/rules/roblox/en-us/get-started/strategies.md b/.cursor/rules/roblox/en-us/get-started/strategies.md
new file mode 100644
index 00000000..f1cfbcfc
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/get-started/strategies.md
@@ -0,0 +1,554 @@
+---
+title: Recommended strategies
+description: Set your game up for success, build and test your MVP, and iterate.
+hideInPageNavigation: true
+fullWidth: true
+---
+
+
Set your game up for success
+
+
+
+
+
Assemble your Roblox dream team
+ Look for developers with expertise in game design, 3D modeling, scripting, and optimization from within the Roblox community. A seasoned developer can help navigate the technical complexities of Roblox and ensure your vision is executed effectively, leading to a higher quality and more engaging experience.
+
+
+
+
+
Be aware of popular games & genres
+ Understanding the preferences of the Roblox user base is essential when selecting a genre. Popular genres on Roblox include role-playing games, simulators, obstacle courses (obbies), and survival games. Choosing a proven genre will increase the likelihood of attracting and retaining players.
+
+
+
+
+
+
+
+
+
Understand your target audience
+
+
+
+
+
Play similar experiences
+ Itʼs important to have a good knowledge of popular Roblox experiences, especially those that are similar to yours. Why are users drawn to this experience? What keeps them interested?
+
+
+
+
+
Talk to players
+ Watch the chat or join an experienceʼs Discord server to see what players talk about. Feel free to join in and ask questions yourself.
+
+
+
+
+
Watch YouTube videos
+ If you donʼt have the time to get deep into an experience, watch videos on YouTube. These are often made by the community and can give you a good idea of what theyʼre interested in.
+
+
+
+
+
+
+
+
+
Define your KPIs
+
+
+
+
+
Identify goals
+ To measure the success of your Roblox experience, define your Key Performance Indicators (KPIs) before development begins. These metrics (such as engagement, retention, and monetization) should guide your design from the start to ensure your game supports its target goals.
+
+
+
+
+
Organic social growth KPIs
+ D1 Retention: Users who return to your game the day after their first session. Average Playtime Per User: The average amount of time that users spend in your game (Average Sessions/Day x Session Length).
+
+
+
+
+
Sustained growth KPIs
+ D7 & D30 Retention: Users who return 7 and 30 days after their first session. Conversion: The percentage of users who spend Robux in your experience. ARPPU: Average Revenue Per Paying User.
+
+
+
+
+
+
+
+
+
Design for multi-platform play
+
+
+
+
+
Playable anywhere
+ Roblox is played on a variety of devices, including PCs, mobile phones, and consoles. It's essential to design a user interface (UI) and user experience (UX) that works seamlessly across all platforms. The UI should be clean, intuitive, and easy to navigate, regardless of the device being used.
+
+
+
+
+
Massive mobile audience
+ Given Roblox's large mobile audience, ensure that your game is easily playable on a touchscreen with a well-designed mobile UI. Even for games with a higher percentage of PC players, such as shooters and RPGs, supporting mobile is still a best practice.
+
+
+
+
+
Optimize for performance
+ Many Roblox users play on low-end devices, so performance is essential. Non-performant games may struggle to grow and maintain a user base.
+ The [core loop](../production/game-design/core-loops.md) is the fundamental gameplay cycle that keeps players engaged and returning to your experience. It should consist of a series of actions and rewards that are satisfying, repeatable, and progressively challenging in order to motivate players to continue interacting with your experience.
+
+
+
+
+
Create a world they'll love
+ Create a visually appealing and engaging environment that immerses players in your experience. The environment should be easy to navigate, fun to explore, and encourage positive interactions. Provide opportunities for players to connect with each other, fostering a sense of community.
+
+
+
+
+
Think ahead
+ Plan long-term by designing with updates in mind. Implement reusable systems, such as quest, collection, or event frameworks that can be easily expanded. This approach will reduce development time and costs for future updates and ensure that your experience remains fresh and engaging.
+
+
+
+
+
+
+
+
+
Create a social, multiplayer experience
+
+
+
+
+
Friends play together
+ Users often play together as a group. Try to design your gameplay to support group play wherever possible and make it easy for friends to connect.
+
+
+
+
+
Make users into content
+ Designing for social interaction in games is not only good for growing your game, but it also serves as a form of content, taking some of the burden off of your team.
+
+
+
+
+
Design spaces for interaction
+ When youʼre building out your level, think about how players can find and interact with each other. If the map is huge, players may be spread too thin.
+
+
+
+
+
+
+
+
+
Get to the fun quickly
+
+
+
+
+
Get to the fun quickly
+ What makes your experience fun? What makes it different? Is it worth playing again? Users should be able to answer these questions within the first few minutes of playing your experience.
+
+
+
+
+
Avoid long tutorials
+ Roblox players like to get to the action immediately and figure it out on their own (or with friends). If you must have a tutorial, keep it short, contextual, and interactive.
+
+
+
+
+
Donʼt restrict socialization
+ Allow new players to socialize and learn from each other. Donʼt create barriers like individual server instances that prevent users from playing with friends.
+
+
+
+
+
+
+
+
+
Keep players invested
+
+
+
+
+
Give players goals
+ Keep players motivated by providing a mix of short-term, mid-term, and long-term goals that cater to different playstyles and encourage exploration. This variety will improve player retention and prevent them from losing interest.
+
+
+
+
+
Add progression to make content last
+ Progression systems give players a clear path toward their goals and a sense of accomplishment while slowing down their content consumption, giving you time to produce more.
+
+
+
+
+
Donʼt gate the fun
+ If you do add progression, make sure there is still enough content available upfront to ensure new users can have fun in their first play session. They should also have a clear understanding of what their next goal is and how to achieve it.
+
+
+
+
+
+ Season Pass Feature Package
+
+
+
+
Use F2P monetization practices
+
+
+
+
+
Give spenders options
+ Help maximize your monetization potential by providing a variety of virtual items at different price points. This strategy appeals to both casual spenders and dedicated fans. Consider adding a starter pack containing items that appeal to new players.
+
+
+
+
+
Design for repeat spend
+ Why would a player want to return and continue to spend, over time? As opposed to one-time purchases, players will spend much more on repeatable purchases (like consumable items) as thereʼs no limit to how much they can spend.
+
+
+
+
+
Optimize your storefront
+ Make your shop as transparent and frictionless as possible, so players understand what to buy, why, and how. Clearly communicate the value and availability of all items.
+ What are your core features? If youʼre making a game, what is your core loop? Whatʼs the minimal version of your experience that can demonstrate these features?
+
+
+
+
+
Get feedback early
+ While it may be tempting to build your fully realized experience, starting with MVP will allow you to get feedback and iterate early, resulting in a better final product.
+
+
+
+
+
Test your MVP
+ As soon as itʼs ready, get your MVP in playersʼ hands. Their early feedback is the key to identifying issues, finding the fun, and setting your game up for success with real Roblox players. Donʼt wait until itʼs too late to pivot.
+
+
+
+
+
+
+
+
+
Playtest early and often
+
+
+
+
+
Small group playtests
+ Give access to specific users only, which allows you to run small playtests. This option is good for testing whether players understand how to play and find the experience fun.
+
+
+
+
+
Limited-time public test
+ Release a test experience to the public, acquire a small amount of users, then remove the game after a set amount of time (a weekend, week, etc.) This option is great for getting organic growth metrics like D1 Retention and session length.
+
+
+
+
+
+
+
Closed group beta
+ The experience is playable by any user that joins your Group. This option is great for gathering community feedback, long-term retention, and monetization. However, it requires some existing community, and may be more friendly than an open test.
+
+
+
+
+
Open beta
+ The experience is open to everyone, but has a "Beta" tag in the title. This is very common on Roblox; however, there is no practical difference between open beta and a full release beyond setting player expectations.
+
+
+
+
+
+
Keep testing and iterating
+
+
+
+
+
Identify soft metrics
+ Comparing your analytics to your target [KPIs](https://www.youtube.com/watch?v=RfpMZZFy8Zw) will help you figure out what areas need improvement, whether itʼs retention, engagement, or monetization.
+
+
+
+
+
Gather community insight
+ Once you know what areas needs work, use your community to find out what is causing those problems.
+
+
+
+
+
Implement & evaluate
+ Once you identify a potential cause, make the necessary changes and test again. Go through this cycle until your KPIs are in line with your target.
+
+
+
+
+
+
+
+
+
+
Get community feedback
+
+
+
+
+
Start a community chat server
+ Be sure to set up your own social chat server, link it to your experience, and have moderation measures in place. This is where your dedicated community members will congregate.
+
+
+
+
+
Talk to your users
+ Ask your users what they think. What do they like? What donʼt they like? What could make it better? Users will be happy to answer, plus it will make them feel like you care.
+
+
+
+
+
Watch how users interact
+ Join your experience to observe what users do and what they talk about in the chat. Are they behaving how you would expect? Do they get confused at certain points? Are they interacting with other players?
+
+
+
+
+
+
+
Helpful Channels to Have in Your Community Chat Server
+
#Rules or #FAQ
Explains how the server works and the expected behavior
+
#Announcements
Post any updates or announcements here
+
#General
Area for general conversation
+
#Bugs
For players to report bugs
+
#Suggestions
For players to submit ideas and feedback
+
#Creative
For players to submit content & fan art
+
+
+
+
+
+
Be creator-friendly
+
+
+
+
+
Consider streamer needs
+ Design your game to be streamer-friendly. Ensure players can easily record videos without UI elements getting in the way, and create an experience that's engaging for viewers to watch on platforms like YouTube and Twitch.
+
+
+
+
+
Fuel excitement & speculation
+ Many experiences have built-in hidden secrets, backstories, and "surprise and delight" moments that encourage players to share and discuss the content, leading to more social media engagement.
+
+
+
+
+
Create shareable moments
+ In your experience, is there anything that users would want to share on TikTok or YouTube? Have they created something of their own? Are there achievements or "wow moments" worthy of posting on social media?
+
+
+
+
+
+
+
+
+
Build awareness through social media
+
+
+
+
+
Connect with creators
+ Many Roblox users learn about new experiences from their favorite YouTubers. Getting one or a few of these influencers to play your experience can help get some initial traction.
+
+
+
+
+
Find the right influencer
+ Influencers are more likely to cover your experience if it fits their audience – so do your research. If engaging with an influencer, be sure to follow the FTC's [Endorsement and Testimonial Guides](https://www.ftc.gov/sites/default/files/attachments/press-releases/ftc-publishes-final-guides-governing-endorsements-testimonials/091005revisedendorsementguides.pdf) and consult with your own legal counsel for specific advice.
+
+
+
+
+
Try targeted TikTok ads
+ TikTok has also proven to be a good way to raise awareness off platform. You can use their targeting tools to surface ads to users that are interested in similar content. Check out TikTokʼs [best practices for Roblox developers](https://activity-va.tiktok.com/magic/eco/runtime/release/689e44394a786f02edabc8a7).
+
+
+
+
+
+
+
+
+
Unlock organic growth
+
+
+
+
+
Most users come from Home
+ Beyond external sources like social media and word of mouth, Home is where a majority of discovery takes place and consists of recommendations that are algorithmically generated to optimize for engagement, long-term retention, and monetization on a per-user basis.
+
+
+
+
+
Data-defined placement
+ We take many factors and signals into account when generating recommendations for someone. Beyond user-focused personalization (age, device, location, etc.) we also look at how well an experience retains players, how much Robux and time players spend, and how often users return to play again.
+
+
+
+
+
Spread the word
+ The best way to maximize how much youʼre surfaced in recommendations is to create a strong experience with solid KPIs. Packaging (icon, thumbnail, media, description) can also help improve D1 retention and play through rate.
+
+
+
+
+
+
+
+
+
Use paid UA to build momentum
+
+
+
+
+
Use sponsored ads
+ Sponsored Ads appear in the "Sponsored" sort on the home page and within search results. Theyʼre great at getting users into experiences but arenʼt as good at targeting specific users.
+ If you do run an ad campaign, try to use Robux youʼve earned rather than purchasing Robux – the exchange rate is higher for purchased Robux.
+
+
+
+
+
+
+
+
+
Keep the content coming
+
+
+
+
+
Update to stay relevant
+ New content updates keep experiences from becoming stale and give players another reason to come back. They also give content creators new material to cover.
+
+
+
+
+
A consistent cadence forms habits
+ Establishing a consistent content cadence can encourage players to check in regularly. If itʼs sustainable for your team, aim for minor content updates every 1–2 weeks and major system updates every 2–3 months.
+
+
+
+
+
Plan for LiveOps from the start
+ Itʼs important to plan for liveops ahead of time. What would those updates include? How do you plan on delivering these updates regularly? Scope updates to fit your teamʼs capacity.
+
+
+
+
+
+
+
+
+
Generate buzz with limited-time content
+
+
+
+
+
Limited-time events add variety
+ Running seasonal events keeps your experience feeling fresh. Events can include thematic map updates, battle/season passes, holiday content and limited-time rewards.
+
+
+
+
+
Limited rewards create social value
+ Time-limited reward items create rarity. The rarer an item is, the more social value it has amongst players, driving more of them to seek out and earn those items.
+
+
+
+
+
Let players flex
+ Players will notice when other players have a special item or ability and ask "Howʼd you get that?!" This makes the owner feel special and encourages information sharing, which further increases the value of rare or limited items.
+
+
+
+
+
+
+
+
+
Plan & promote your updates
+
+
+
+
+
Plan for the long haul
+ Develop a roadmap outlining your content plans for the next 6 to 12 months, outlining regular content updates and new systems or major features that keep gameplay fresh. A well-defined roadmap will help you stay organized, manage resources, and communicate your vision to both your development team and your players.
+
+
+
+
+
Spread the word
+ Promote your updates across your social media channels and within the experience itself. Build anticipation by teasing new features, showcasing behind-the-scenes development, and engaging with your community.
+
+
+
+
+
Use update announcements
+ The integrated events system lets you create time-based events for your experience. Players can discover your events on the experience's detail page and through an event details page, and they can opt into notifications that they'll receive when your event begins.
+
+
+
+
+
+
+
diff --git a/.cursor/rules/roblox/en-us/get-started/tools.md b/.cursor/rules/roblox/en-us/get-started/tools.md
new file mode 100644
index 00000000..cbc0d6f1
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/get-started/tools.md
@@ -0,0 +1,207 @@
+---
+title: What tools does Roblox provide?
+description: Roblox Studio, Creator Hub, AI Assistant, matchmaking, discovery, and more.
+hideInPageNavigation: true
+fullWidth: true
+---
+
+
Dive into Roblox Studio
+
+
+
+
+
Your one-stop shop
+ Create 3D environments, add animations, build physics simulations, and program game logic with Lua.
+
+
+
+
+
Collaborate with Team Create
+ Multiple users can access and edit the same project simultaneously, making it easier to collaborate and communicate with teammates.
+
+
+
+
+
Test and publish directly from Studio
+ Test your creations and quickly iterate, then when youʼre ready, publish to Roblox with the click of a button.
+
+
+
+
+
+
+
+
+
Learn and grow with Creator Hub
+
+
+
+
+
Creator Dashboard
+ Access your experienceʼs engagement, retention, and monetization KPIs, free of charge.
+
+
+
+
+
Documentation
+ Hit the ground running with articles, tutorials and videos on topics ranging from design and implementation to analytics and LiveOps.
+
+
+
+
+
Developer Forum
+ Get advice from the community, file a bug report, and learn about the latest Roblox updates.
+
+
+
+
+
+
+
+
+
Creator Hub: Marketplace and Talent Hub
+
+
+
+
+
Marketplace
+ Find all the assets you need, from royalty-free music to community-made models and helpful plugins.
+
+
+
+
+
Talent Hub
+ Whether youʼre searching for artists, programmers or designers, you can find them and review their work on Talent Hub.
+
+
+
+
+
+
+
+
+
Meet your AI assistant
+
+
+
+
+
Supercharge your workflow
+ Our AI Assistant revolutionizes your development process by providing instant, context-aware support. Get immediate answers to your Roblox questions, generate and modify code snippets, and insert assets directly into your game, all within Studio.
+
+
+
+
+
Automate the mundane
+ AI Assistant empowers you to automate common actions such as bulk property modifications. By handling these time-consuming chores, Assistant frees you to concentrate on the higher-level design and innovative gameplay elements that make your experiences truly unique.
+
+
+
+
+
+
+
+
+
Imagine it, generate it
+
+
+
+
+
Generate 3D worlds
+ Roblox Cube is a groundbreaking generative AI system that lets you create 3D models and environments directly from text prompts, reducing the time and effort required for 3D asset creation.
+
+
+
+
+
Unlock player creativity
+ Cube empowers your players to personalize their gameplay in exciting new ways. By enabling the generation of unique 3D content within experiences, Cube opens the door for deeper player engagement and self-expression.
+
+
+
+
+
+
+
+
+
Master matchmaking
+
+
+
+
+
Fine-tune with signal control
+ Adjust the weight of [matchmaking](../matchmaking/customize-matchmaking.md) signals such as friends, occupancy, latency, and play history. Define up to two custom signals based on player attributes like skill level or game mode preference.
+
+
+
+
+
Configure and preview
+ The intuitive interface in Creator Hub lets you configure your settings with ease, and the built-in preview and test feature allows you to see the impact of your changes before they go live.
+
+
+
+
+
Optimize with integrated analytics
+ The dedicated analytics dashboard provides in-depth insights into signal metrics over time, allowing you to monitor the impact of your configurations on the player experience.
+
+
+
+
+
+
+
+
+
+
Unlock the power of discovery
+
+
+
+
+
Targeted discovery
+ Roblox's "Recommended for You" algorithm intelligently connects each user with their ideal experiences, fostering deep engagement, social interaction, and repeat plays.
+
+
+
+
+
Objective ranking
+ Experiences are ranked by key performance indicators like playtime and Robux spent. The Home Recommendations dashboard displays the relevant analytics for informed decision-making.
+
+
+
+
+
Quality content
+ Roblox is committed to continuously improving search functionality to better understand user intent and showcase the highest-quality content, ensuring that exceptional experiences get the attention they deserve.
+
+
+
+
+
+
+
+
+
Supercharge your growth
+
+
+
+
+
Targeted user acquisition
+ Roblox Sponsored Ads empower you to reach the players most likely to engage with your experience. With comprehensive audience selection options, you can tailor your campaigns to specific demographics and interests, delivering maximum impact and driving high-quality traffic to your game.
+
+
+
+
+
Managed promotions
+ Take control of your advertising strategy with flexible campaign scheduling and daily budget options. Roblox provides the tools you need to manage your ad spend effectively and track performance.
+
+
+
+
+
+
+
+
+
+
+
+Studio documentation
+First experience tutorial
+
+
diff --git a/.cursor/rules/roblox/en-us/get-started/why-build-on-roblox.md b/.cursor/rules/roblox/en-us/get-started/why-build-on-roblox.md
new file mode 100644
index 00000000..8d624296
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/get-started/why-build-on-roblox.md
@@ -0,0 +1,132 @@
+---
+title: Why should I develop on Roblox?
+description: Reasons to build on the Roblox platform—audience, tools, and opportunity.
+hideInPageNavigation: true
+fullWidth: true
+---
+
+
Where imagination meets a global audience
+
+
+
+
+
Massive global reach
+ Tap into a platform with 111.8 million daily active users (DAU), spanning 180 countries and 17 languages.
+ *As of Q1 2025
+
+
+
+
+
Deep user engagement
+ Capture attention on a platform where users spend an average of 2.7 hours per day, totaling 27.4 billion hours of engagement.
+ *As of Q1 2025
+
+
+
+
+
Proven developer success
+ On average, the top 10,000 developers earned over $97,000 in 2024.
+
+
+
+
+
+ DAU by Region (in millions)
+
+
+
+
Robust tools with no upfront costs
+
+
+
+
+
Hit the ground running
+ We provide services, developer support, and free tools such as Roblox Studio to help you get started immediately.
+
+
+
+
+
Keep it simple
+ We cover all hosting, storage, customer support, localization, payment processing, and platform fees, allowing you to focus on developing your experience.
+
+
+
+
+
+
+
+
+
Multiplayer made easy
+
+
+
+
+
Out of the box multiplayer
+ All experiences support multiplayer out of the gate. No need to write complicated backend code, no need to set up or pay for your own servers.
+
+
+
+
+
Servers support up to 100 players
+ You donʼt need a big team to create a big game. Creating large multiplayer experiences has never been easier.
+
+
+
+
+
Scale as you grow
+ Weʼve significantly increased the limits on free data storage and now offer creators the option to purchase additional service usage to support even larger experiences.
+
+
+
+
+
+
+
+
+
Publish, analyze, and iterate with ease
+
+
+
+
+
No publishing approvals
+ Assets are automatically moderated, so you can modify and publish your experience immediately across console, desktop, and mobile devices.
+
+
+
+
+
Get deep insights
+ Built-in Roblox analytics give you access to key retention, engagement, and monetization KPIs for free with no setup required.
+
+
+
+
+
Track your traffic
+ Acquire users with our paid UA system and get insights into how users are finding your game to optimize your UA strategy.
+
+
+
+
+
+
+
+
diff --git a/.cursor/rules/roblox/en-us/luau/comments.md b/.cursor/rules/roblox/en-us/luau/comments.md
index 71272108..9038248d 100644
--- a/.cursor/rules/roblox/en-us/luau/comments.md
+++ b/.cursor/rules/roblox/en-us/luau/comments.md
@@ -6,7 +6,7 @@ description: Comments are text that the Luau parser ignores at runtime.
A **comment** is text that the Luau parser ignores at runtime.
-Roblox Studio has a similarly-named [comments](../projects/collaboration.md#studio-comments) feature that is unrelated to code comments in Luau.
+Roblox Studio has a similarly-named [comments](../projects/collaboration.md#comments) feature that is unrelated to code comments in Luau.
## Single-line comments
diff --git a/.cursor/rules/roblox/en-us/marketplace/marketplace-fees-and-commissions.md b/.cursor/rules/roblox/en-us/marketplace/marketplace-fees-and-commissions.md
index 406ba904..b944c9f8 100644
--- a/.cursor/rules/roblox/en-us/marketplace/marketplace-fees-and-commissions.md
+++ b/.cursor/rules/roblox/en-us/marketplace/marketplace-fees-and-commissions.md
@@ -453,6 +453,41 @@ To protect against automated purchases, Roblox sets purchase limits for Limiteds
- A maximum of 3 successful purchases per user per item.
- For in-experience purchases, users must be in the experience for 60 seconds to successfully complete a purchase.
+## Timed options
+
+
+At this time, timed options are available for 3D shirts, pants, and sweater categories.
+
+
+Timed options allows users to purchase your items for a period of time of either 3, 7, or 14 days at a cheaper cost. You can enable or disable timed options for your Marketplace assets [in bulk](#in-bulk) or [per item](#per-item).
+
+
+
+
With timed options enabled, users gain access to multiple purchase options for each available time range.
+
+
+### In bulk
+
+To toggle timed options for multiple assets:
+
+1. Navigate to your [Creations](https://create.roblox.com/dashboard/creations) page > Avatar items.
+2. Filter by avatar asset type, such as **Clothing**.
+3. On the top right, select the **Timed option** button.
+
+
+4. Follow the prompts to confirm the bulk selection and timed option settings.
+
+
+
+### Per item
+
+To toggle timed options for individual assets:
+
+1. In your [Creations](https://create.roblox.com/dashboard/creations) tab, navigate to the individual asset's **Manage Item** page.
+2. Toggle the timed option for your asset.
+
+3. When complete, click the **Save Changes** button.
+
## Price ranges
Depending on the 3D asset type, you must set the price of the item within the marketplace price range. If you are selling a [Limited](#limiteds) item, you can set your item price as **0**, or any value after the **Limiteds Price Floor**.
diff --git a/.cursor/rules/roblox/en-us/physics/constraints/align-orientation.md b/.cursor/rules/roblox/en-us/physics/constraints/align-orientation.md
index 42c678c2..da223b27 100644
--- a/.cursor/rules/roblox/en-us/physics/constraints/align-orientation.md
+++ b/.cursor/rules/roblox/en-us/physics/constraints/align-orientation.md
@@ -4,53 +4,39 @@ description: The AlignOrientation constraint applies torque to align two attachm
---
-For an overview on creating, visualizing, and simulating mover constraints, including `Class.AlignOrientation`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
+For an overview on creating, visualizing, and simulating mover constraints, including `Class.AlignOrientation`, see [mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
The `Class.AlignOrientation` constraint applies torque to align two attachments, or to align one attachment with a goal orientation. As indicated by the name, it only affects the **orientation** of the attachments, not their position (to align attachments **positionally**, see [AlignPosition](../../physics/constraints/align-position.md)).
-
+
-By default, the constraint only applies torque to `Class.Constraint.Attachment0|Attachment0`, although this behavior can be controlled through `Class.AlignOrientation.ReactionTorqueEnabled|ReactionTorqueEnabled`.
+By default, the constraint only applies torque to `Class.Constraint.Attachment0|Attachment0`, although this behavior can be controlled through the constraint's [reactionary torque](#reactionary-torque).
## Affected axes
-The axes affected by torque are controlled through the constraint's `Class.AlignOrientation.AlignType|AlignType` property. When set to `Enum.AlignType|PrimaryAxisParallel`, `Enum.AlignType|PrimaryAxisPerpendicular` or `Enum.AlignType|PrimaryAxisLookAt`, torque will only occur when the primary axes become misaligned. Otherwise, the constraint will apply torque about all 3 axes to achieve alignment.
+The axes affected by torque are controlled through the constraint's `Class.AlignOrientation.AlignType|AlignType` property. When set to `Enum.AlignType.AllAxes|AllAxes` (default), the constraint will apply torque about all 3 axes to achieve alignment. When set to `Enum.AlignType.PrimaryAxisParallel|PrimaryAxisParallel`, `Enum.AlignType.PrimaryAxisPerpendicular|PrimaryAxisPerpendicular`, or `Enum.AlignType.PrimaryAxisLookAt|PrimaryAxisLookAt`, torque will only occur when the **primary** axes become misaligned.
-
-
-
- AlignType = **AllAxes**
-
-
-
- AlignType = **PrimaryAxisParallel**
-
-
-
-## Reactionary torque
-
-By default, the constraint only applies torque to `Class.Constraint.Attachment0|Attachment0` while `Class.Constraint.Attachment1|Attachment1` remains unaffected. If desired, torque can be applied to both attachments in **equal and opposite directions** by enabling `Class.AlignOrientation.ReactionTorqueEnabled|ReactionTorqueEnabled`.
-
-
-
-
- ReactionTorqueEnabled = **false**
-
-
-
- ReactionTorqueEnabled = **true**
-
-
+
+
+
## Torque magnitude
-You can configure the `Class.AlignOrientation` constraint to apply the maximum torque that constraints allow through the `Class.AlignOrientation.RigidityEnabled|RigidityEnabled` property. When true, the physics solver reacts as quickly as possible to complete the alignment. When false, the torque is determined by `Class.AlignOrientation.MaxTorque|MaxTorque`, `Class.AlignOrientation.MaxAngularVelocity|MaxAngularVelocity`, and `Class.AlignOrientation.Responsiveness|Responsiveness`.
+You can configure the `Class.AlignOrientation` constraint to apply the maximum torque that constraints allow through the `Class.AlignOrientation.RigidityEnabled|RigidityEnabled` property. When `true`, the physics solver reacts as quickly as possible to complete the alignment. When `false`, the torque is determined by `Class.AlignOrientation.MaxTorque|MaxTorque`, `Class.AlignOrientation.MaxAngularVelocity|MaxAngularVelocity`, and `Class.AlignOrientation.Responsiveness|Responsiveness`.
+
+
+
+
+
+## Reactionary torque
+
+By default, the constraint only applies torque to `Class.Constraint.Attachment0|Attachment0` while `Class.Constraint.Attachment1|Attachment1` remains unaffected. If desired, torque can be applied to **both** attachments in **equal and opposite directions** by enabling `Class.AlignOrientation.ReactionTorqueEnabled|ReactionTorqueEnabled`.
## Attachment mode
-The `Class.AlignOrientation.Mode|Mode` property specifies whether the constraint uses **one** or **two** attachments in calculating its goal. By default, this is **TwoAttachment**, meaning that the constraint attempts to match the orientation of `Class.Constraint.Attachment0|Attachment0` with the orientation of `Class.Constraint.Attachment1|Attachment1`, disregarding `Class.AlignOrientation.CFrame|CFrame`, `Class.AlignOrientation.PrimaryAxis|PrimaryAxis`, and `Class.AlignOrientation.SecondaryAxis|SecondaryAxis`.
+The `Class.AlignOrientation.Mode|Mode` property specifies whether the constraint uses **one** or **two** attachments in calculating its goal. By default, this is `Enum.OrientationAlignmentMode.TwoAttachment|TwoAttachment`, meaning that the constraint attempts to match the orientation of `Class.Constraint.Attachment0|Attachment0` with the orientation of `Class.Constraint.Attachment1|Attachment1`, disregarding `Class.AlignOrientation.CFrame|CFrame`, `Class.AlignOrientation.PrimaryAxis|PrimaryAxis`, and `Class.AlignOrientation.SecondaryAxis|SecondaryAxis`.
-If set to **OneAttachment**, the constraint disregards `Class.Constraint.Attachment1|Attachment1` and attempts to match the orientation of `Class.Constraint.Attachment0|Attachment0` with the orientation of `Class.AlignOrientation.CFrame|CFrame`, or match the attachment's `Class.Attachment.Axis|Axis` and `Class.Attachment.SecondaryAxis|SecondaryAxis` with the constraint's `Class.AlignOrientation.PrimaryAxis|PrimaryAxis` and `Class.AlignOrientation.SecondaryAxis|SecondaryAxis` properties respectively.
+If set to `Enum.OrientationAlignmentMode.OneAttachment|OneAttachment`, the constraint disregards `Class.Constraint.Attachment1|Attachment1` and attempts to match the orientation of `Class.Constraint.Attachment0|Attachment0` with the orientation of `Class.AlignOrientation.CFrame|CFrame`, or match the attachment's `Class.Attachment.Axis|Axis` and `Class.Attachment.SecondaryAxis|SecondaryAxis` with the constraint's `Class.AlignOrientation.PrimaryAxis|PrimaryAxis` and `Class.AlignOrientation.SecondaryAxis|SecondaryAxis` properties respectively.
diff --git a/.cursor/rules/roblox/en-us/physics/constraints/align-position.md b/.cursor/rules/roblox/en-us/physics/constraints/align-position.md
index 6f48a1b3..59ed6833 100644
--- a/.cursor/rules/roblox/en-us/physics/constraints/align-position.md
+++ b/.cursor/rules/roblox/en-us/physics/constraints/align-position.md
@@ -4,51 +4,33 @@ description: The AlignPosition constraint applies force to move two attachments
---
-For an overview on creating, visualizing, and simulating mover constraints, including `Class.AlignPosition`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
+For an overview on creating, visualizing, and simulating mover constraints, including `Class.AlignPosition`, see [mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
An `Class.AlignPosition` constraint applies force to move two attachments together, or to move one attachment to a goal position. As indicated by the name, it only affects the **position** of the attachments, not their orientation (to align attachments by **orientation**, see [AlignOrientation](../../physics/constraints/align-orientation.md)).
-
+
-By default, the constraint only applies force to `Class.Constraint.Attachment0|Attachment0`, although this behavior can be controlled through `Class.AlignPosition.ReactionForceEnabled|ReactionForceEnabled`.
+By default, the constraint only applies force to `Class.Constraint.Attachment0|Attachment0`, although this behavior can be controlled through the constraint's [reactionary force](#reactionary-force).
## Force location
By default, force is applied to the parent of `Class.Constraint.Attachment0|Attachment0` at that attachment's location, meaning that if the parent's center of mass is not aligned with the direction of the force, torque will be applied as well as force. Alternatively, force can be applied to the parents' center of mass by toggling on `Class.AlignPosition.ApplyAtCenterOfMass|ApplyAtCenterOfMass`.
-
-
-
- ApplyAtCenterOfMass = **false**
-
-
-
- ApplyAtCenterOfMass = **true**
-
-
+## Force magnitude
+
+You can configure the `Class.AlignPosition` constraint to apply the maximum force that constraints allow through the `Class.AlignPosition.RigidityEnabled|RigidityEnabled` property. When `true`, the physics solver reacts as quickly as possible to complete the alignment. When `false`, the force is determined by `Class.AlignPosition.MaxForce|MaxForce`, `Class.AlignPosition.MaxVelocity|MaxVelocity`, and `Class.AlignPosition.Responsiveness|Responsiveness`.
## Reactionary force
-By default, the constraint only applies force to `Class.Constraint.Attachment0|Attachment0` while `Class.Constraint.Attachment1|Attachment1` remains unaffected. If desired, force can be applied to both attachments in **equal and opposite directions** by enabling `Class.AlignPosition.ReactionForceEnabled|ReactionForceEnabled`.
+By default, the constraint only applies force to `Class.Constraint.Attachment0|Attachment0` while `Class.Constraint.Attachment1|Attachment1` remains unaffected. If desired, force can be applied to **both** attachments in **equal and opposite directions** by enabling `Class.AlignPosition.ReactionForceEnabled|ReactionForceEnabled`.
-
-
-
- ReactionForceEnabled = **false**
-
-
-
- ReactionForceEnabled = **true**
-
-
-
-## Force magnitude
-
-You can configure the `Class.AlignPosition` constraint to apply the maximum force that constraints allow through the `Class.AlignPosition.RigidityEnabled|RigidityEnabled` property. When true, the physics solver reacts as quickly as possible to complete the alignment. When false, the force is determined by `Class.AlignPosition.MaxForce|MaxForce`, `Class.AlignPosition.MaxVelocity|MaxVelocity`, and `Class.AlignPosition.Responsiveness|Responsiveness`.
+
+
+
## Attachment mode
-The `Class.AlignPosition.Mode|Mode` property specifies whether the constraint uses **one** or **two** attachments in calculating its goal. By default, this is `Enum.PositionAlignmentMode|TwoAttachment`, meaning that the constraint disregards `Class.AlignPosition.Position|Position` and attempts to move `Class.Constraint.Attachment0|Attachment0` to the position of `Class.Constraint.Attachment1|Attachment1`. If set to `Enum.PositionAlignmentMode|OneAttachment`, the constraint disregards `Class.Constraint.Attachment1|Attachment1` and attempts to move `Class.Constraint.Attachment0|Attachment0` to `Class.AlignPosition.Position|Position`.
+The `Class.AlignPosition.Mode|Mode` property specifies whether the constraint uses **one** or **two** attachments in calculating its goal. By default, this is `Enum.PositionAlignmentMode.TwoAttachment|TwoAttachment`, meaning that the constraint disregards `Class.AlignPosition.Position|Position` and attempts to move `Class.Constraint.Attachment0|Attachment0` to the position of `Class.Constraint.Attachment1|Attachment1`. If set to `Enum.PositionAlignmentMode.OneAttachment|OneAttachment`, the constraint disregards `Class.Constraint.Attachment1|Attachment1` and attempts to move `Class.Constraint.Attachment0|Attachment0` to `Class.AlignPosition.Position|Position`.
diff --git a/.cursor/rules/roblox/en-us/physics/constraints/angular-velocity.md b/.cursor/rules/roblox/en-us/physics/constraints/angular-velocity.md
index b577482e..0fec305b 100644
--- a/.cursor/rules/roblox/en-us/physics/constraints/angular-velocity.md
+++ b/.cursor/rules/roblox/en-us/physics/constraints/angular-velocity.md
@@ -4,7 +4,7 @@ description: The AngularVelocity constraint applies torque on an assembly to mai
---
-For an overview on creating, visualizing, and simulating mover constraints, including `Class.AngularVelocity`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
+For an overview on creating, visualizing, and simulating mover constraints, including `Class.AngularVelocity`, see [mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
An `Class.AngularVelocity` constraint applies torque on an assembly to maintain a constant angular velocity.
diff --git a/.cursor/rules/roblox/en-us/physics/constraints/animation.md b/.cursor/rules/roblox/en-us/physics/constraints/animation.md
new file mode 100644
index 00000000..39ac3690
--- /dev/null
+++ b/.cursor/rules/roblox/en-us/physics/constraints/animation.md
@@ -0,0 +1,28 @@
+---
+title: AnimationConstraint
+description: AnimationConstraint aligns two base parts with an animate-able kinematic or force-based joint.
+---
+
+
+For an overview on creating, visualizing, and simulating mover constraints, including `Class.AnimationConstraint`, see [mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
+
+
+An `Class.AnimationConstraint` constrains its `Class.Attachment|Attachments` by an offset [transform](#transform). It can be either [kinematic](#kinematic) for snap‑to behavior or it can follow the target trajectory using [force and torque](#force-and-torque). limited by `Class.AnimationConstraint.MaxForce|MaxForce` and `Class.AnimationConstraint.MaxTorque|MaxTorque`.
+
+
+
+## Transform
+
+The constraint's `Class.AnimationConstraint.Transform|Transform` is the internal `Datatype.CFrame` that's manipulated when the constraint is being animated. How this transform is reached depends on the constraint's [kinematic](#kinematic) setting.
+
+
+
+
+
+## Kinematic
+
+When the constraint's `Class.AnimationConstraint.IsKinematic|IsKinematic` property is `true`, the connected parts snap to the [transform](#transform) instantly and precisely without participating in physics simulation. When `false`, the connected parts follow the trajectory using [force and torque](#force-and-torque).
+
+## Force and torque
+
+If the constraint is not [kinematic](#kinematic), the connected parts follow a trajectory toward the [transform](#transform) using a maximum force/torque limited by `Class.AnimationConstraint.MaxForce|MaxForce` and `Class.AnimationConstraint.MaxTorque|MaxTorque` respectively.
diff --git a/.cursor/rules/roblox/en-us/physics/constraints/ball-socket.md b/.cursor/rules/roblox/en-us/physics/constraints/ball-socket.md
index e3469699..ae617512 100644
--- a/.cursor/rules/roblox/en-us/physics/constraints/ball-socket.md
+++ b/.cursor/rules/roblox/en-us/physics/constraints/ball-socket.md
@@ -9,25 +9,26 @@ For an overview on creating, visualizing, and simulating mechanical constraints,
A `Class.BallSocketConstraint` forces its two attachments into the same position and allows them to freely rotate about all three axes. However, you can enable limits to restrict both tilt and twist.
-
+
## Limits
You can set limits to restrict both **tilt** and **twist** of a ball socket, similar to how a human's head can tilt and turn within a limited axial range. Enabling the `Class.BallSocketConstraint.LimitsEnabled|LimitsEnabled` property exposes the `Class.BallSocketConstraint.UpperAngle|UpperAngle` value to restrict **tilt** within a cone; it also exposes the `Class.BallSocketConstraint.TwistLimitsEnabled|TwistLimitsEnabled` property which, when enabled, lets you restrict **twist** rotation through the `Class.BallSocketConstraint.TwistLowerAngle|TwistLowerAngle` and `Class.BallSocketConstraint.TwistUpperAngle|TwistUpperAngle` limits.
-
-
-
- UpperAngle = **30**
-
-
-
- TwistLimitsEnabled = **true**
-
-
+
+
+Constraint with `Class.BallSocketConstraint.LimitsEnabled|LimitsEnabled` set to `true` and `Class.BallSocketConstraint.UpperAngle|UpperAngle` set to `15`
+
-Enabling `Class.BallSocketConstraint.LimitsEnabled|LimitsEnabled` also exposes the `Class.BallSocketConstraint.Restitution|Restitution` value which defines the elasticity of the attachments at their tilt and/or twist limits.
+
+
+Constraint with `Class.BallSocketConstraint.LimitsEnabled|LimitsEnabled` and `Class.BallSocketConstraint.TwistLimitsEnabled|TwistLimitsEnabled` set to `true`, `Class.BallSocketConstraint.TwistLowerAngle|TwistLowerAngle` set to `-60`, and `Class.BallSocketConstraint.TwistUpperAngle|TwistUpperAngle` set to `0`
+
+Enabling `Class.BallSocketConstraint.LimitsEnabled|LimitsEnabled` also exposes the `Class.BallSocketConstraint.Restitution|Restitution` value which defines the elasticity of the attachments at their tilt and/or twist limits.
+
+
+
When `Class.BallSocketConstraint.LimitsEnabled|LimitsEnabled` is enabled, orientation of a ball socket's attachments affects how it rotates. To ensure rotation occurs around the desired axis, each attachment's `Class.Attachment.Axis|Axis`, visualized by the yellow arrow, should point in the same direction.
diff --git a/.cursor/rules/roblox/en-us/physics/constraints/line-force.md b/.cursor/rules/roblox/en-us/physics/constraints/line-force.md
index 6aade607..6c17703c 100644
--- a/.cursor/rules/roblox/en-us/physics/constraints/line-force.md
+++ b/.cursor/rules/roblox/en-us/physics/constraints/line-force.md
@@ -4,7 +4,7 @@ description: The LineForce constraint applies force along the theoretical line c
---
-For an overview on creating, visualizing, and simulating mover constraints, including `Class.LineForce`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
+For an overview on creating, visualizing, and simulating mover constraints, including `Class.LineForce`, see [mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
The `Class.LineForce` constraint applies force along the theoretical line connecting its two `Class.Attachment|Attachments`. As the end points (attachments) move, the direction of force will change accordingly.
diff --git a/.cursor/rules/roblox/en-us/physics/constraints/linear-velocity.md b/.cursor/rules/roblox/en-us/physics/constraints/linear-velocity.md
index 7d461f24..bddd3a32 100644
--- a/.cursor/rules/roblox/en-us/physics/constraints/linear-velocity.md
+++ b/.cursor/rules/roblox/en-us/physics/constraints/linear-velocity.md
@@ -4,7 +4,7 @@ description: The LinearVelocity constraint applies force on an assembly to maint
---
-For an overview on creating, visualizing, and simulating mover constraints, including `Class.LinearVelocity`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
+For an overview on creating, visualizing, and simulating mover constraints, including `Class.LinearVelocity`, see [mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
A `Class.LinearVelocity` constraint applies force on an assembly to maintain a constant velocity. It can be set to apply force along a `Datatype.Vector3`, line, or 2D plane.
diff --git a/.cursor/rules/roblox/en-us/physics/constraints/torque.md b/.cursor/rules/roblox/en-us/physics/constraints/torque.md
index e00f74fb..60a39e9f 100644
--- a/.cursor/rules/roblox/en-us/physics/constraints/torque.md
+++ b/.cursor/rules/roblox/en-us/physics/constraints/torque.md
@@ -4,7 +4,7 @@ description: The Torque constraint applies constant torque on an assembly from i
---
-For an overview on creating, visualizing, and simulating mover constraints, including `Class.Torque`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
+For an overview on creating, visualizing, and simulating mover constraints, including `Class.Torque`, see [mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
A `Class.Torque` constraint applies constant torque on an assembly from its center of mass.
diff --git a/.cursor/rules/roblox/en-us/physics/constraints/vector-force.md b/.cursor/rules/roblox/en-us/physics/constraints/vector-force.md
index 89f3e883..8c760639 100644
--- a/.cursor/rules/roblox/en-us/physics/constraints/vector-force.md
+++ b/.cursor/rules/roblox/en-us/physics/constraints/vector-force.md
@@ -4,7 +4,7 @@ description: The VectorForce constraint applies constant linear force on an asse
---
-For an overview on creating, visualizing, and simulating mover constraints, including `Class.VectorForce`, see [Mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
+For an overview on creating, visualizing, and simulating mover constraints, including `Class.VectorForce`, see [mover constraints](../../physics/mover-constraints.md). Also see [Roblox units](../../physics/units.md) to understand how Roblox units compare to metric units.
The `Class.VectorForce` constraint applies constant linear force on an assembly. The direction and strength of the force is determined by a `Datatype.Vector3` and can be relative to an attachment on the part, another attachment, or the world coordinate system.
diff --git a/.cursor/rules/roblox/en-us/physics/mechanical-constraints.md b/.cursor/rules/roblox/en-us/physics/mechanical-constraints.md
index 59c6977c..9aae151b 100644
--- a/.cursor/rules/roblox/en-us/physics/mechanical-constraints.md
+++ b/.cursor/rules/roblox/en-us/physics/mechanical-constraints.md
@@ -15,9 +15,9 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-
+
-[BallSocketConstraint](../physics/constraints/ball-socket.md) forces its two attachments into the same position and allows them to freely rotate about all three axes, with optional limits to restrict both tilt and twist
+`Class.BallSocketConstraint` forces its two attachments into the same position and allows them to freely rotate about all three axes, with optional limits to restrict both tilt and twist
@@ -29,7 +29,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[HingeConstraint](../physics/constraints/hinge.md) allows its two attachments to rotate about one axis, with optional assigned power for motor or servo behavior
+`Class.HingeConstraint` allows its two attachments to rotate about one axis, with optional assigned power for motor or servo behavior
@@ -41,7 +41,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[PrismaticConstraint](../physics/constraints/prismatic.md) allows two attachments to slide along one axis but not rotate, with optional assigned power for mechanisms like sliding doors and elevator platforms
+`Class.PrismaticConstraint` allows two attachments to slide along one axis but not rotate, with optional assigned power for mechanisms like sliding doors and elevator platforms
@@ -53,7 +53,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[CylindricalConstraint](../physics/constraints/cylindrical.md) allows its attachments to slide along one axis and rotate about another axis, with optional assigned angular and/or linear power
+`Class.CylindricalConstraint` allows its attachments to slide along one axis and rotate about another axis, with optional assigned angular and/or linear power
@@ -65,7 +65,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[SpringConstraint](../physics/constraints/spring.md) applies a force on its attachments based on spring and damper behavior, with an optional minimum/maximum length
+`Class.SpringConstraint` applies a force on its attachments based on spring and damper behavior, with an optional minimum/maximum length
@@ -77,7 +77,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[TorsionSpringConstraint](../physics/constraints/torsion-spring.md) applies torque based on a relative angle and relative angular velocity, in an attempt to bring two axes from two parts together
+`Class.TorsionSpringConstraint` applies torque based on a relative angle and relative angular velocity, in an attempt to bring two axes from two parts together
@@ -89,7 +89,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[UniversalConstraint](../physics/constraints/universal.md) ensures two axes on two assemblies remain perpendicular, useful for applications such as vehicle power transmission to rear drive shafts, robotics, and more
+`Class.UniversalConstraint` ensures two axes on two assemblies remain perpendicular, useful for applications such as vehicle power transmission to rear drive shafts, robotics, and more
@@ -101,7 +101,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[RopeConstraint](../physics/constraints/rope.md) prevents two attachments from separating further than a defined length, with optional behavior as an extending or contracting winch
+`Class.RopeConstraint` prevents two attachments from separating further than a defined length, with optional behavior as an extending or contracting winch
@@ -113,7 +113,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[RodConstraint](../physics/constraints/rod.md) keeps two attachments separated by a defined length, with optional limits on rotational tilt
+`Class.RodConstraint` keeps two attachments separated by a defined length, with optional limits on rotational tilt
@@ -125,7 +125,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[PlaneConstraint](../physics/constraints/plane.md) moves two attachments into a position/orientation along a plane, and both attachments remain free to translate and rotate unless otherwise constrained
+`Class.PlaneConstraint` moves two attachments into a position/orientation along a plane, and both attachments remain free to translate and rotate unless otherwise constrained
@@ -135,7 +135,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[WeldConstraint](../physics/constraints/weld.md) connects two `Class.BasePart|BaseParts` and ensures they stay in the same relative position and orientation to each other, even if they are not touching
+`Class.WeldConstraint` connects two `Class.BasePart|BaseParts` and ensures they stay in the same relative position and orientation to each other, even if they are not touching
@@ -145,7 +145,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[RigidConstraint](../physics/constraints/rigid.md) connects two `Class.Attachment|Attachments` or `Class.Bone|Bones` and ensures they stay in the same relative position/orientation to each other, even if they are not touching
+`Class.RigidConstraint` connects two `Class.Attachment|Attachments` or `Class.Bone|Bones` and ensures they stay in the same relative position/orientation to each other, even if they are not touching
@@ -155,7 +155,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that be
-[NoCollisionConstraint](../physics/constraints/no-collision.md) prevents collisions between two specific parts, but those parts may still register collisions with the rest of the world
+`Class.NoCollisionConstraint` prevents collisions between two specific parts, but those parts may still register collisions with the rest of the world
diff --git a/.cursor/rules/roblox/en-us/physics/mover-constraints.md b/.cursor/rules/roblox/en-us/physics/mover-constraints.md
index f86941bb..eba1df38 100644
--- a/.cursor/rules/roblox/en-us/physics/mover-constraints.md
+++ b/.cursor/rules/roblox/en-us/physics/mover-constraints.md
@@ -17,7 +17,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that ap
-[LinearVelocity](../physics/constraints/linear-velocity.md) applies force on an assembly to maintain a constant velocity along a 3D vector, line, or 2D plane
+`Class.LinearVelocity` applies force on an assembly to maintain a constant velocity along a 3D vector, line, or 2D plane
@@ -29,7 +29,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that ap
-[AngularVelocity](../physics/constraints/angular-velocity.md) applies torque on an assembly to maintain a constant angular velocity
+`Class.AngularVelocity` applies torque on an assembly to maintain a constant angular velocity
@@ -41,7 +41,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that ap
-[AlignPosition](../physics/constraints/align-position.md) applies force to move two attachments together, or to move one attachment to a goal position
+`Class.AlignPosition` applies force to move two attachments together, or to move one attachment to a goal position
@@ -53,7 +53,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that ap
-[AlignOrientation](../physics/constraints/align-orientation.md) applies torque to align two attachments, or to align one attachment with a goal orientation
+`Class.AlignOrientation` applies torque to align two attachments, or to align one attachment with a goal orientation
@@ -65,7 +65,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that ap
-[VectorForce](../physics/constraints/vector-force.md) applies constant linear force on an assembly
+`Class.VectorForce` applies constant linear force on an assembly
@@ -77,7 +77,7 @@ The physics engine includes the following `Class.Constraint|Constraints` that ap
-[Torque](../physics/constraints/torque.md) applies constant torque on an assembly from its center of mass
+`Class.Torque` applies constant torque on an assembly from its center of mass
@@ -89,7 +89,19 @@ The physics engine includes the following `Class.Constraint|Constraints` that ap
-[LineForce](../physics/constraints/line-force.md) applies force along the theoretical line connecting its two attachments
+`Class.LineForce` applies force along the theoretical line connecting its two attachments
+
+
+
+
+
+
+
+
+
+
+
+`Class.AnimationConstraint` constrains its `Class.Attachment|Attachments` by an offset transform `Datatype.CFrame`.
diff --git a/.cursor/rules/roblox/en-us/production/earn-on-roblox.md b/.cursor/rules/roblox/en-us/production/earn-on-roblox.md
deleted file mode 100644
index 42c947f5..00000000
--- a/.cursor/rules/roblox/en-us/production/earn-on-roblox.md
+++ /dev/null
@@ -1,300 +0,0 @@
----
-title: Earn on Roblox
-description: Explains how Roblox's economy and virtual currency works.
----
-
-Roblox's goal is to enable the creation of anything, anywhere, by anyone, and we are constantly
-investing in new tools and services to empower our creator community. We give our creators, from an
-individual to a large studio, diverse ways to earn on Roblox by creating content and experiences,
-specifically:
-
-- [Develop an experience](#develop-an-experience)
- - [In-experience purchases](#in-experience-purchases)
- - [Immersive ads](#immersive-ads)
-- [Creator Rewards](#creator-rewards)
-- [Create, sell, and resell certain avatar items](#create-sell-and-resell-certain-avatar-items)
-- [Create and sell Studio plugins and models](#create-and-sell-studio-plugins-and-models)
-
-This page provides information about different ways to earn on Roblox and how to [convert earned Robux to cash](#convert-earned-robux-to-cash) through the [Developer Exchange][Link_Developer_Exchange] program.
-
-
-
-†† 30,000 earned Robux required to cash out through the Developer Exchange program
-
-
-## Economy powered by creators
-
-We are building one of the world's largest immersive platforms with 151.5M global daily active users (DAUs) in 17 languages across 180 countries, available across platforms including mobile, desktop, consoles, and VR headsets. In 2024, approximately 60% of our daily active users were 13 and over, and users aged 17 and over accounted for 44% of our daily active users. In 2024, our community visited over 14 million experiences. In the third quarter of 2025 alone, users spent 39.6 billion hours on our platform.
-
-
-
-
-
⑴
-
-
-
-
⑵
-
-
-
-
We are one of the biggest virtual economies⑶
-Roblox's GDP ⑷ has grown to become as large as that of some countries. Our success is directly tied to the success of our creators. Roblox earns money by selling Robux which users spend in‑experience and on items and assets in our marketplaces, all created by you.
-
-
We exist to serve our community
-We're always searching for new ways to increase creators' earnings. In 2024, our creator community earned \$923 million. We've paid our developer community \$3.3 billion since 2018.
-
-
As a result, creators can focus on creating
-We are seeing healthy growth across creators and studios of varying sizes. Since 2019, the average annual earnings of the top 10 and top 1000 creators has increased by ~5.5 and ~6.8 times, respectively. ⑸
-
-
-
-⑴ DAUs as of the quarter ended September 30, 2025.
-⑵ Payouts for the year ended December 31, 2024.
-⑶ Based on readily available public data for daily active users of virtual worlds.
-⑷ Measured based on Roblox's annual bookings, which measures total economic activity on our platform.
-⑸ Of the millions of creators monetizing on Roblox, over 24,500 were part of our DevEx program, with the median creator participating in DevEx receiving \$1,575 USD during the twelve months ended December 31, 2024.
-
-## Develop an experience
-
-Building successful content takes time and effort, but there is low risk and low upfront cost to building an experience on Roblox. You pay **after** earning on Roblox and we provide the tools, services, and support to help you build the most immersive experiences. Roblox has a robust community and [developer forum](https://devforum.roblox.com/) to guide and support you along the way.
-
-### Low upfront costs; publish globally in seconds
-
-
Instant publishing to reach a global audience
-Unlike other platforms where you wait days or weeks for approvals, you can modify your Roblox experiences and publish immediately in multiple languages and on all popular platforms — iOS, Android, Mac, Windows, PlayStation, and Xbox.
-
-
Platform-driven discovery and rapid viral growth
-Our platform, with 151.5 million daily active users (DAUs) now able to see and join experiences with no additional downloads required, provides opportunity for rapid growth. Creators can take advantage of our organic channels, our rich social graph and network effect, seamless exploration between experiences and our cost effective [Roblox ads](../production/promotion/advertise-on-roblox.md).
-
-
Rapid iteration and scaling with no upfront costs
-With your content live and in front of lots of users, we provide a rapid and rich feedback loop on how users are engaging with your work. This feedback loop is facilitated both by our integrated [analytics](../production/analytics/index.md) system and by our monetization mechanisms. On the cost side, we handle infrastructure hosting, storage, customer support, localization, payment processing, moderation, and platform costs. You do not have to worry about standing up multiplayer servers or scaling them as your experience goes viral. Off Roblox, you often have to take care of these expenses and manage these operations yourself.
-
-
Pay after you earn on Roblox
-On other platforms, you can incur expenses such as storage, hosting, and infrastructure before you earn any money or even start building. On Roblox, developing an experience has minimal risk as you are charged for these expenses after you monetize.
-
-### Average cash payouts
-
-One of our goals is to drive as much money to our creators as possible while maintaining reasonable margins for our company to develop, maintain, and improve the tools and technology that support our community.
-
-On average, 67% of all spending in experiences supports or goes to developers. The below applies to Robux spending within experiences only; it excludes developer subscriptions which are a relatively small portion of the business today.
-
-- We pay out 40% to cover costs supporting experiences — like infrastructure hosting, storage, customer support, localization, payment processing, and moderation — which other platforms generally pass on to developers.
-- This enables us to return 28%\* directly to the developers.
-- That leaves 33% to cover Roblox's ongoing services and operating costs, future-looking investments in the platform, and margins.
-
-This chart illustrates the estimated utilization of each dollar spent in an experience on Roblox. Note that the chart doesn't reflect our expenses as disclosed in our GAAP financial statements.
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
This percentage is the experience developer's earnings based on transactions in the experience, after cashing out through our [Developer Exchange][Link_Developer_Exchange] program (before any developer spending on the Roblox platform for services such as ads). Each developer's earnings share may differ. Earnings share may also differ by payment channel; users can now receive up to 25% more Robux when purchasing through gift cards, computer, or web. This extra Robux translates into higher revenue shares on Robux purchased on those channels.
-
-
-
-
-
-
-
-
-
-
-
-
Developers also get extra Robux for simply building an engaging experience through the [Creator Rewards](../creator-rewards.md) program.
-
This percentage reflects our platform average, though the actual percent of earnings from Creator Rewards varies from experience to experience based on the engagement level in the experience.
-
We are a platform and therefore we do not make experiences that compete with our creators for these payouts.
-
-
-
-
-
-
-
-
-
-
-
-
Roblox covers this on your behalf. This reflects the processing payment fees related to all purchases and refunds of Robux. These fees are paid directly to Apple (iOS), Google and Amazon (Android), Sony, Meta, and Microsoft (Xbox and Microsoft Store).
-
These costs also include processing fees associated with other payment methods, such as credit card or PayPal, as well as costs associated with the sale of our prepaid cards.
-
If you developed outside of Roblox, you may have to cover these fees on your own and manage chargebacks and fraud and process refunds.
-
-
-
-
-
-
-
-
-
-
-
-
Roblox covers this on your behalf. These costs relate to Roblox's maintenance of the servers that host all Roblox experiences, as well as platform-wide customer support, user and experience moderation, user acquisition, translation, and local compliance. If you develop outside of Roblox, you may have to pay for hosting, servers, moderation, and customer service on your own. You also have to dedicate time to managing these services; on Roblox you can focus on building your experience.
-
-
-
-
-
-
-
-
-
-
-
-
These costs relate to future-looking investments in the Roblox platform. This includes investments in the people building out new capabilities and tools for our platform which will allow you to be more innovative, build more engaging experiences, help bring in new users, and make creating on Roblox much easier.
-
-
-
-
-
-
-
-
-
-
-
-
Roblox uses some of this to cover ongoing services and operating costs.
-
-
-
-\*28% returned directly to the developers of experiences per dollar spent in experience assumes the full amount of Robux earned are exchanged through the DevEx program, and not spent on the platform. Figures are as of December 31, 2024.
-
-
-### Experience monetization
-
-Once you've developed an experience, you can earn through the following methods:
-
-#### In-experience purchases
-
-- [Subscriptions](./monetization/subscriptions.md) within experiences offer you the ability to earn from your experience through subscription-based offerings and business models.
-- [Developer Products](../production/monetization/developer-products.md), which are items or abilities that a user can purchase, such as in-experience currency.
-- [Passes](../production/monetization/passes.md) for access to special privileges within an experience, such as entry to a restricted area or a permanent power‑up. When you sell your own passes in your experience, you earn 70% of the Robux spent. You can also sell passes within your experience that were made by other creators; in this case, you earn a 10% affiliate fee on the Robux spent within your experience, and the original creator of the pass earns 60%.
-- [Private servers](../production/monetization/private-servers.md) for users to play with just connections (subscription-based access fees).
-
-#### Creator Rewards
-
-Developers earn extra Robux for simply building an engaging experience. Roblox calculates
-[payouts](../creator-rewards.md) based on how Active Spenders use your experience on a daily basis, and these payouts happen
-automatically as a way to reward engaging experiences.
-
-#### Immersive ads
-
-[Immersive ads](../production/monetization/immersive-ads.md) allow developers to place high-quality, native ad units in their experience that will programmatically serve ads. Creators are paid through a revenue share for the video views, impressions, and teleports generated.
-
-## Create, sell, and resell certain avatar items
-
-Millions of users already visit the [Marketplace][Link_Marketplace] every day. [Eligible](../marketplace/marketplace-policy.md#creator-requirements) creators can [create](../marketplace/publish-to-marketplace.md) and sell [accessories](../art/accessories/index.md), [clothing](../art/accessories/index.md), and [avatar bodies and heads](../art//characters/index.md) in the Marketplace or in their own or other developers' experiences. We have a breadth of ways users can discover and buy your creations, whether through searching the Marketplace or enabling developers to promote and sell your items. Users can purchase your item within an experience using the [Avatar Inspect Menu](../players/avatar-inspect-menu.md) or in templates such as [UGC Homestore](../resources/templates.md#ugc-homestore). You can also increase the discoverability of your 3D user-generated content within the Marketplace through [sponsored item](../production/promotion/sponsor-items.md) ads.
-
-After you pay any applicable upload and publishing fees and submit a new asset for approval, the moderation team reviews your asset and, if approved, you'll be able to publish your asset to the Marketplace.
-
-You receive a commission every time a user purchases your item. When community items are sold in the marketplace, a portion of the sales is split between the item creator and Roblox. If the item is sold within an experience, the revenue share will additionally be split with the owner of the experience who we refer to as an "affiliate." An affiliate earns commission for marketing another user's creations.
-
-As follows is an overview of our commission structure. To learn more about fees and commissions for the Marketplace, see [Marketplace fees and commissions](../marketplace/marketplace-fees-and-commissions.md).
-
-
-
-
-
-
-
-- Creator of the virtual item receives **30%**
-- Affiliate (Roblox) receives **40%**
-- Platform receives **30%**
-
-These commissions also apply to the original sale of [Limiteds](../marketplace/marketplace-fees-and-commissions.md#limiteds). When setting assets on sale, you can [configure](../marketplace/publish-to-marketplace.md#marketplace-settings) your creation as a Limited item to set an available quantity for that asset. Limiteds require a [per-unit fee](../marketplace/marketplace-fees-and-commissions.md#per-unit-fee) and can be [resold](../marketplace/marketplace-fees-and-commissions.md#reselling) by [Roblox Premium](https://www.roblox.com/premium/membership) members. At this time, only Roblox-created Limiteds are tradeable.
-
-
-
-
-
-
-
-
-
-While anyone can buy a Limited item, only Roblox [Premium][Link_Premium_Membership] subscribers can resell them. Every time a creator's Limited item is resold, the creator benefits from a 10% original creator commission on the value of each resale.
-
-- Reseller receives **50%**
-- Creator receives **10%**
-- Affiliate receives **10%**
-- Platform receives **30%**
-
-After purchasing a Limited, there is up to a 30‑day holding period when the item cannot be resold. Robux acquired from trading or selling items that you didn't create are not considered earned and are ineligible for the [Developer Exchange][Link_Developer_Exchange] program.
-
-
-
-
-
-
-
-
-## Create and sell Studio plugins and models
-
-You can create and sell Studio [plugins](../studio/plugins.md) and [models](../parts/models.md) to the creator community through the [Creator Store](../production/creator-store.md). A [plugin](../studio/plugins.md) is an extension that adds additional functionality to Studio, and a [model](../parts/models.md) is a reusable asset type. You can offer both to other creators on the [Creator Store](../production/creator-store.md) for free, or you can sell them for **United States Dollars** (the minimum price is \$4.99 for plugins and \$2.99 for models). Roblox offers a market-leading revenue share for these sales, as only taxes and payment processing fees are deducted. For more information, see [Sell on the Creator Store](../production/sell-on-creator-store.md).
-
-## Join the Creator Affiliate Program
-
-
-To join the Creator Affiliate Program, you must be 13+ and reside in a country supported by the [Developer Exchange][Link_Developer_Exchange] program.
-
-
-The [Creator Affiliate Program](https://create.roblox.com/affiliate) is a pilot program that lets you earn Robux using affiliate links. With it, you can:
-
-- Generate affiliate share links for any Roblox experience, including other developers' experiences, through the Creator Hub.
-- Promote your affiliate links off-platform on social media channels.
-- Earn revenue in Robux whenever new users create a Roblox account and purchase Robux using your affiliate link. A new user is someone who doesn't already have an alternative Roblox account.
-- Exchange your Robux earnings for real-world money using the Developer Exchange program.
-
-When a user creates a Roblox account using your affiliate link and then buys Robux, you can receive up to 50% of the value of their Robux purchases during their first six months on the platform, for a maximum revenue of \$100 USD per new user. For example, if a new user joins Roblox and purchases \$100 USD of Robux, you can earn up to \$50 USD, minus certain fees like taxes and VAT.
-
-You receive your revenue in Robux, which you can exchange for real-world money through Developer Exchange.
-
-## Convert earned Robux to cash
-
-Once you earn Robux, you can continue to use it in our platform to buy developer assets, plugins, [advertising](../production/promotion/advertise-on-roblox.md), in-experience items, or virtual items. In addition, when you have at least 30,000 earned Robux in your account, you may be eligible to exchange your earned Robux for real currency using the [Developer Exchange][Link_Developer_Exchange] program.
-
-To learn more about strategies to earn Robux, see [Monetization](../production/monetization/index.md).
-
-## Frequently asked questions
-
-
-
-Who can earn on Roblox?
-
-
-Any user can earn Robux on Roblox, however you must be a creator who is 13 years of age or older and have the requisite minimum amount of earned Robux in your account in order to convert your earned Robux to real currency through the [Developer Exchange][Link_Developer_Exchange] program. You must also meet certain other requirements such as having a verified email address and being in good standing within the community. Also, only those over the age of 18 may purchase Robux or engage in other real-money transactions on the platform per Roblox's [Terms of Use](https://www.roblox.com/info/terms).
-
-Users, unlike creators, cannot convert in-experience virtual currency for real-world currency on Roblox. Creators do have the ability to convert (if, for example, they earn Robux via an experience they create) but Robux acquired from trading or reselling virtual items is not eligible to be converted.
-
-
-
-
-
-Other platforms advertise giving a higher share to their creators, why is that?
-
-
-Every platform reports their creator share a bit differently. When you compare creator shares across platforms, you should consider:
-
-- **The breadth of business models** — While some platforms may have a high creator share, the opportunities to earn and the ways to earn may be limited, making the absolute earning potential on the platform smaller.
-- **The platform may also be competing for engagement and payouts** — Some platforms are actually also creators on their platform and therefore compete with their creators for engagement. Roblox does not.
-- **Other platform benefits** — Creator shares can be high but consider other benefits that the platform provides such as costs that they are paying on your behalf, the scale and diversity of their audience, the devices/platforms they are available on, the types of creators that are earning, and more.
-- **The total size of the payout pool** — Understand the total size of the platform's payout pool. Other platforms may invest less in growing their user base and making their products accessible in new markets across the globe. This may allow them to pay developers a higher share, but at the expense of slower growth and less total earnings being put in creators' pockets.
-
-
-
-[Link_Developer_Exchange]: https://create.roblox.com/dashboard/devex
-[Link_Premium_Membership]: https://www.roblox.com/premium/membership
-[Link_Marketplace]: https://www.roblox.com/catalog?Category=1&salesTypeFilter=1
diff --git a/.cursor/rules/roblox/en-us/reference/cloud/cloud.docs.json b/.cursor/rules/roblox/en-us/reference/cloud/cloud.docs.json
index bd18f2ae..a6c97200 100644
--- a/.cursor/rules/roblox/en-us/reference/cloud/cloud.docs.json
+++ b/.cursor/rules/roblox/en-us/reference/cloud/cloud.docs.json
@@ -308,6 +308,344 @@
]
}
},
+ "/cloud/v2/groups/{group_id}/forum-categories": {
+ "get": {
+ "tags": ["Cloud"],
+ "summary": "List Group Forum Categories",
+ "description": "Lists forum categories in the group.",
+ "operationId": "Cloud_ListGroupForumCategories",
+ "parameters": [
+ {
+ "name": "group_id",
+ "in": "path",
+ "description": "The group ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "maxPageSize",
+ "in": "query",
+ "description": "The maximum number of group forum categories to return. The service might\nreturn fewer than this value. If unspecified, at most 10 group forum\ncategories are returned. The maximum value is 10 and higher values are set\nto 10.",
+ "schema": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "examples": {
+ "maxPageSize": {
+ "description": "An integer between 1 and 10, inclusive",
+ "value": 10
+ }
+ }
+ },
+ {
+ "name": "pageToken",
+ "in": "query",
+ "description": "A page token, received from a previous call, to retrieve a subsequent page.\n\nWhen paginating, all other parameters provided to the subsequent call must\nmatch the call that provided the page token.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "filter",
+ "in": "query",
+ "description": "This field may be set in order to filter the resources returned.\n\nFiltering conforms to Common Expression Language (CEL). Only the boolean\nfield `archived` and `==` operator are supported. If `archived=false`,\narchived categories are not returned. The default value is `false`.\nExample: `\"filter=archived==true\"`",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListGroupForumCategoriesResponse"
+ }
+ }
+ }
+ }
+ },
+ "x-visibility": "BETA",
+ "x-roblox-engine-usability": {
+ "apiKeyWithHttpService": true
+ },
+ "x-roblox-scopes": [
+ {
+ "name": "group-forum:read"
+ }
+ ],
+ "x-roblox-docs": {
+ "category": "Users and groups",
+ "methodProperties": {
+ "scopes": ["group-forum:read"]
+ },
+ "resource": {
+ "$ref": "#/components/schemas/GroupForumCategory",
+ "name": "GroupForumCategory"
+ }
+ },
+ "x-roblox-stability": "BETA",
+ "x-roblox-rate-limits": {
+ "perApiKeyOwner": {
+ "period": "MINUTE",
+ "maxInPeriod": 150
+ },
+ "perOauth2Authorization": {
+ "period": "MINUTE",
+ "maxInPeriod": 30
+ }
+ },
+ "security": [
+ {
+ "roblox-api-key": []
+ },
+ {
+ "roblox-oauth2": []
+ }
+ ]
+ }
+ },
+ "/cloud/v2/groups/{group_id}/forum-categories/{forum_category_id}/posts": {
+ "get": {
+ "tags": ["Cloud"],
+ "summary": "List Group Forum Posts",
+ "description": "Lists forum posts in the group's forum category.",
+ "operationId": "Cloud_ListGroupForumPosts",
+ "parameters": [
+ {
+ "name": "group_id",
+ "in": "path",
+ "description": "The group ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "forum_category_id",
+ "in": "path",
+ "description": "The forum-category ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "maxPageSize",
+ "in": "query",
+ "description": "The maximum number of group forum posts to return. The service might return\nfewer than this value. If unspecified, at most 10 group forum posts are\nreturned. The maximum value is 100 and higher values are set to 100.",
+ "schema": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "examples": {
+ "maxPageSize": {
+ "description": "An integer between 1 and 100, inclusive",
+ "value": 10
+ }
+ }
+ },
+ {
+ "name": "pageToken",
+ "in": "query",
+ "description": "A page token, received from a previous call, to retrieve a subsequent page.\n\nWhen paginating, all other parameters provided to the subsequent call must\nmatch the call that provided the page token.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "filter",
+ "in": "query",
+ "description": "This field may be set in order to filter the resources returned.\n\nFiltering conforms to Common Expression Language (CEL). Only the query\n`filter=pinned==true` is supported, where only pinned posts are returned.\n`filter=pinned==false`is not supported.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "view",
+ "in": "query",
+ "description": "The view in which to retrieve the group forum post.\n\nSupports FULL and FULL_WITH_FIRST_COMMENT.\n\nDefaults to FULL.\n\nPossible values:\n\n | Value | Description |\n | --- | --- |\n | VIEW_UNSPECIFIED | The group forum post view is not specified; the default will be used. |\n | FULL | Includes all fields but does not dereference `first_comment`. Only the `path` field is populated. |\n | FULL_WITH_FIRST_COMMENT | Includes all fields and also fully populates `first_comment`. The default view. |",
+ "schema": {
+ "example": "VIEW_UNSPECIFIED",
+ "enum": ["VIEW_UNSPECIFIED", "FULL", "FULL_WITH_FIRST_COMMENT"],
+ "type": "string",
+ "format": "enum"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListGroupForumPostsResponse"
+ }
+ }
+ }
+ }
+ },
+ "x-visibility": "BETA",
+ "x-roblox-engine-usability": {
+ "apiKeyWithHttpService": true
+ },
+ "x-roblox-scopes": [
+ {
+ "name": "group-forum:read"
+ }
+ ],
+ "x-roblox-docs": {
+ "category": "Users and groups",
+ "methodProperties": {
+ "scopes": ["group-forum:read"]
+ },
+ "resource": {
+ "$ref": "#/components/schemas/GroupForumPost",
+ "name": "GroupForumPost"
+ }
+ },
+ "x-roblox-stability": "BETA",
+ "x-roblox-rate-limits": {
+ "perApiKeyOwner": {
+ "period": "MINUTE",
+ "maxInPeriod": 150
+ },
+ "perOauth2Authorization": {
+ "period": "MINUTE",
+ "maxInPeriod": 30
+ }
+ },
+ "security": [
+ {
+ "roblox-api-key": []
+ },
+ {
+ "roblox-oauth2": []
+ }
+ ]
+ }
+ },
+ "/cloud/v2/groups/{group_id}/forum-categories/{forum_category_id}/posts/{post_id}/comments": {
+ "get": {
+ "tags": ["Cloud"],
+ "summary": "List Group Forum Comments",
+ "description": "Lists forum comments on a group's forum post.",
+ "operationId": "Cloud_ListGroupForumComments",
+ "parameters": [
+ {
+ "name": "group_id",
+ "in": "path",
+ "description": "The group ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "forum_category_id",
+ "in": "path",
+ "description": "The forum-category ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "post_id",
+ "in": "path",
+ "description": "The post ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "maxPageSize",
+ "in": "query",
+ "description": "The maximum number of group forum comments to return. The service might\nreturn fewer than this value. If unspecified, at most 10 group forum\ncomments are returned. The maximum value is 100 and higher values are set\nto 100.",
+ "schema": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "examples": {
+ "maxPageSize": {
+ "description": "An integer between 1 and 100, inclusive",
+ "value": 10
+ }
+ }
+ },
+ {
+ "name": "pageToken",
+ "in": "query",
+ "description": "A page token, received from a previous call, to retrieve a subsequent page.\n\nWhen paginating, all other parameters provided to the subsequent call must\nmatch the call that provided the page token.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "filter",
+ "in": "query",
+ "description": "This field may be set in order to filter the resources returned.\n\nFiltering conforms to Common Expression Language (CEL). Only the string\nfield `repliesToCommentId` and the `==` operator are supported.\nIf `repliesToCommentId` is specified, only comments that respond to the\ncomment are returned. The default value is `''`. If\n`repliesToCommentId=''`, only comments responding directly to the post are\nreturned. Example:\n`\"filter=repliesToCommentId==01234567-89ab-cdef-0123-456789abcdef\"`",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListGroupForumCommentsResponse"
+ }
+ }
+ }
+ }
+ },
+ "x-visibility": "BETA",
+ "x-roblox-engine-usability": {
+ "apiKeyWithHttpService": true
+ },
+ "x-roblox-scopes": [
+ {
+ "name": "group-forum:read"
+ }
+ ],
+ "x-roblox-docs": {
+ "category": "Users and groups",
+ "methodProperties": {
+ "scopes": ["group-forum:read"]
+ },
+ "resource": {
+ "$ref": "#/components/schemas/GroupForumComment",
+ "name": "GroupForumComment"
+ }
+ },
+ "x-roblox-stability": "BETA",
+ "x-roblox-rate-limits": {
+ "perApiKeyOwner": {
+ "period": "MINUTE",
+ "maxInPeriod": 150
+ },
+ "perOauth2Authorization": {
+ "period": "MINUTE",
+ "maxInPeriod": 30
+ }
+ },
+ "security": [
+ {
+ "roblox-api-key": []
+ },
+ {
+ "roblox-oauth2": []
+ }
+ ]
+ }
+ },
"/cloud/v2/groups/{group_id}/join-requests": {
"get": {
"tags": ["Cloud"],
@@ -6943,6 +7281,48 @@
},
"x-resource": true
},
+ "ContentMessage": {
+ "type": "object",
+ "properties": {
+ "createTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the message was created.",
+ "format": "date-time"
+ },
+ "updateTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the message was last updated.",
+ "format": "date-time"
+ },
+ "plainText": {
+ "type": "string",
+ "description": "The plain text content of the message."
+ },
+ "author": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who created the message."
+ },
+ "messageReaction": {
+ "readOnly": true,
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/MessageReaction"
+ },
+ "description": "The reactions to the message, if this feature is enabled for this message."
+ }
+ },
+ "description": "Represents the content of a message.",
+ "x-oneOf": {
+ "Author": ["author"],
+ "content": ["plainText"]
+ }
+ },
"CreatorStoreProduct": {
"type": "object",
"properties": {
@@ -7386,6 +7766,175 @@
"Owner": ["owner"]
}
},
+ "GroupForumCategory": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "example": "groups/123/forum-categories/01234567-89ab-cdef-0123-456789abcdef",
+ "type": "string",
+ "description": "The resource path of the group forum category.\n\nFormat: `groups/{group_id}/forum-categories/{group_forum_category_id}`"
+ },
+ "createTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum category was created.",
+ "format": "date-time"
+ },
+ "updateTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum category was last updated.",
+ "format": "date-time"
+ },
+ "groupForumCategoryId": {
+ "readOnly": true,
+ "type": "string",
+ "description": "The id of the group forum category."
+ },
+ "displayName": {
+ "type": "string",
+ "description": "The display name of the group forum category."
+ },
+ "creator": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who created the group forum category."
+ },
+ "archiveTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum category was archived.",
+ "format": "date-time"
+ },
+ "archiver": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who archived the group forum category."
+ }
+ },
+ "description": "Represents a forum category within a group for user discussions.",
+ "x-aep-resource": {
+ "patterns": [
+ "groups/{group_id}/forum-categories/{group_forum_category_id}"
+ ],
+ "plural": "group-forum-categories",
+ "singular": "group-forum-category"
+ },
+ "x-resource": true
+ },
+ "GroupForumComment": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "example": "groups/123/forum-categories/01234567-89ab-cdef-0123-456789abcdef/posts/01234567-89ab-cdef-0123-456789abcdef/comments/01234567-89ab-cdef-0123-456789abcdef",
+ "type": "string",
+ "description": "The resource path of the group forum comment.\n\nFormat:\n`groups/{group_id}/forum-categories/{group_forum_category_id}/posts/{group_forum_post_id}/comments/{group_forum_comment_id}`"
+ },
+ "groupForumCommentId": {
+ "readOnly": true,
+ "type": "string",
+ "description": "The id of the group forum comment."
+ },
+ "message": {
+ "$ref": "#/components/schemas/ContentMessage",
+ "description": "The message content of the group forum comment."
+ }
+ },
+ "description": "Represents a forum comment on a group's forum post.",
+ "x-aep-resource": {
+ "patterns": [
+ "groups/{group_id}/forum-categories/{group_forum_category_id}/posts/{group_forum_post_id}/comments/{group_forum_comment_id}"
+ ],
+ "plural": "group-forum-comments",
+ "singular": "group-forum-comment"
+ },
+ "x-resource": true
+ },
+ "GroupForumPost": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "example": "groups/123/forum-categories/01234567-89ab-cdef-0123-456789abcdef/posts/01234567-89ab-cdef-0123-456789abcdef",
+ "type": "string",
+ "description": "The resource path of the group forum post.\n\nFormat:\n`groups/{group_id}/forum-categories/{group_forum_category_id}/posts/{group_forum_post_id}`"
+ },
+ "createTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum post was created.",
+ "format": "date-time"
+ },
+ "updateTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum post was last updated.",
+ "format": "date-time"
+ },
+ "pinned": {
+ "example": true,
+ "type": "boolean",
+ "description": "Whether the group forum post is pinned."
+ },
+ "locked": {
+ "example": true,
+ "type": "boolean",
+ "description": "Whether the group forum post is locked."
+ },
+ "groupForumPostId": {
+ "readOnly": true,
+ "type": "string",
+ "description": "The id of the group forum post."
+ },
+ "title": {
+ "type": "string",
+ "description": "The title of the group forum post."
+ },
+ "firstComment": {
+ "$ref": "#/components/schemas/GroupForumComment",
+ "description": "The resource path of the group forum post's first comment, which holds the\npost content.\n\nBy default, the `first_comment` field is fully populated. This **will not**\ndereference resource references within the first comment, such as\n`GroupForumComment.author`; only the `path` subfield of these fields will\nbe populated. However, if only the `path` field of the first comment is\nneeded, you can specify the FULL view."
+ },
+ "author": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who created the group forum post."
+ },
+ "archiveTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum post was archived.",
+ "format": "date-time"
+ },
+ "archiver": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who archived the group forum post."
+ },
+ "commentCount": {
+ "type": "integer",
+ "description": "The number of comments on the group forum post. This includes the first\ncomment (post content).",
+ "format": "int64"
+ }
+ },
+ "description": "Represents a forum post within a group's forum category.",
+ "x-aep-resource": {
+ "patterns": [
+ "groups/{group_id}/forum-categories/{group_forum_category_id}/posts/{group_forum_post_id}"
+ ],
+ "plural": "group-forum-posts",
+ "singular": "group-forum-post"
+ },
+ "x-resource": true
+ },
"GroupJoinRequest": {
"type": "object",
"properties": {
@@ -8069,6 +8618,57 @@
},
"description": "A list of DataStores in the parent collection."
},
+ "ListGroupForumCategoriesResponse": {
+ "type": "object",
+ "properties": {
+ "groupForumCategories": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/GroupForumCategory"
+ },
+ "description": "The GroupForumCategories from the specified Group."
+ },
+ "nextPageToken": {
+ "type": "string",
+ "description": "A token that you can send as a `pageToken` parameter to retrieve the next\npage. If this field is omitted, there are no subsequent pages."
+ }
+ },
+ "description": "A list of GroupForumCategories in the parent collection."
+ },
+ "ListGroupForumCommentsResponse": {
+ "type": "object",
+ "properties": {
+ "groupForumComments": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/GroupForumComment"
+ },
+ "description": "The GroupForumComments from the specified GroupForumPost."
+ },
+ "nextPageToken": {
+ "type": "string",
+ "description": "A token that you can send as a `pageToken` parameter to retrieve the next\npage. If this field is omitted, there are no subsequent pages."
+ }
+ },
+ "description": "A list of GroupForumComments in the parent collection."
+ },
+ "ListGroupForumPostsResponse": {
+ "type": "object",
+ "properties": {
+ "groupForumPosts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/GroupForumPost"
+ },
+ "description": "The GroupForumPosts from the specified GroupForumCategory."
+ },
+ "nextPageToken": {
+ "type": "string",
+ "description": "A token that you can send as a `pageToken` parameter to retrieve the next\npage. If this field is omitted, there are no subsequent pages."
+ }
+ },
+ "description": "A list of GroupForumPosts in the parent collection."
+ },
"ListGroupJoinRequestsResponse": {
"type": "object",
"properties": {
@@ -8600,6 +9200,23 @@
"sortKey": ["stringSortKey", "numericSortKey"]
}
},
+ "MessageReaction": {
+ "type": "object",
+ "properties": {
+ "emoteId": {
+ "readOnly": true,
+ "type": "string",
+ "description": "The id of the emote."
+ },
+ "count": {
+ "readOnly": true,
+ "type": "integer",
+ "description": "The count of reactions for this emote.",
+ "format": "int64"
+ }
+ },
+ "description": "Represents the reaction to a message."
+ },
"Money": {
"type": "object",
"properties": {
@@ -9788,6 +10405,7 @@
"scopes": {
"creator-store-product:write": "creator-store-product:write",
"creator-store-product:read": "creator-store-product:read",
+ "group-forum:read": "group-forum:read",
"group:read": "group:read",
"group:write": "group:write",
"universe:write": "universe:write",
diff --git a/.cursor/rules/roblox/en-us/reference/cloud/messaging-service/v1.json b/.cursor/rules/roblox/en-us/reference/cloud/messaging-service/v1.json
index 1655f910..40c239bf 100644
--- a/.cursor/rules/roblox/en-us/reference/cloud/messaging-service/v1.json
+++ b/.cursor/rules/roblox/en-us/reference/cloud/messaging-service/v1.json
@@ -18,6 +18,7 @@
"operationId": "CrossServerMessaging_Publish",
"x-roblox-cloud-api-operation-name": "Publish a Message",
"x-roblox-stability": "BETA",
+ "summary": "Publish a cross-server message to a universe",
"description": "Publish a message to a pre-defined topic of an experience, with the size of the message up to 1,024 characters (1 KB). Requires the **Publish** permission for API keys and the **universe-messaging-service:publish** scope for OAuth 2.0 apps. See [Cross-server messaging](/cloud-services/cross-server-messaging.md#subscribe-users-to-receive-messages) for defining and subscribing users to a topic.",
"parameters": [
{
diff --git a/.cursor/rules/roblox/en-us/reference/cloud/openapi.json b/.cursor/rules/roblox/en-us/reference/cloud/openapi.json
index 1b4becbd..855f6b7f 100644
--- a/.cursor/rules/roblox/en-us/reference/cloud/openapi.json
+++ b/.cursor/rules/roblox/en-us/reference/cloud/openapi.json
@@ -316,6 +316,350 @@
}
}
},
+ "/cloud/v2/groups/{group_id}/forum-categories": {
+ "get": {
+ "tags": ["Groups"],
+ "summary": "List Group Forum Categories",
+ "description": "Lists forum categories in the group.",
+ "operationId": "Cloud_ListGroupForumCategories",
+ "parameters": [
+ {
+ "name": "group_id",
+ "in": "path",
+ "description": "The group ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "maxPageSize",
+ "in": "query",
+ "description": "The maximum number of group forum categories to return. The service might\nreturn fewer than this value. If unspecified, at most 10 group forum\ncategories are returned. The maximum value is 10 and higher values are set\nto 10.",
+ "schema": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "examples": {
+ "maxPageSize": {
+ "description": "An integer between 1 and 10, inclusive",
+ "value": 10
+ }
+ }
+ },
+ {
+ "name": "pageToken",
+ "in": "query",
+ "description": "A page token, received from a previous call, to retrieve a subsequent page.\n\nWhen paginating, all other parameters provided to the subsequent call must\nmatch the call that provided the page token.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "filter",
+ "in": "query",
+ "description": "This field may be set in order to filter the resources returned.\n\nFiltering conforms to Common Expression Language (CEL). Only the boolean\nfield `archived` and `==` operator are supported. If `archived=false`,\narchived categories are not returned. The default value is `false`.\nExample: `\"filter=archived==true\"`",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListGroupForumCategoriesResponse"
+ }
+ }
+ }
+ }
+ },
+ "x-roblox-engine-usability": {
+ "apiKeyWithHttpService": false
+ },
+ "x-roblox-scopes": [
+ {
+ "name": "group-forum:read"
+ }
+ ],
+ "x-roblox-docs": {
+ "category": "Users and groups",
+ "methodProperties": {
+ "scopes": ["group-forum:read"]
+ },
+ "resource": {
+ "$ref": "#/components/schemas/GroupForumCategory",
+ "name": "GroupForumCategory"
+ }
+ },
+ "x-roblox-stability": "BETA",
+ "x-roblox-rate-limits": {
+ "perApiKeyOwner": {
+ "period": "MINUTE",
+ "maxInPeriod": 150
+ },
+ "perOauth2Authorization": {
+ "period": "MINUTE",
+ "maxInPeriod": 30
+ }
+ },
+ "security": [
+ {
+ "roblox-api-key": []
+ },
+ {
+ "roblox-oauth2": []
+ }
+ ],
+ "externalDocs": {
+ "url": "https://create.roblox.com/docs/cloud/reference/features/groups#Cloud_ListGroupForumCategories"
+ }
+ }
+ },
+ "/cloud/v2/groups/{group_id}/forum-categories/{forum_category_id}/posts": {
+ "get": {
+ "tags": ["Groups"],
+ "summary": "List Group Forum Posts",
+ "description": "Lists forum posts in the group's forum category.",
+ "operationId": "Cloud_ListGroupForumPosts",
+ "parameters": [
+ {
+ "name": "group_id",
+ "in": "path",
+ "description": "The group ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "forum_category_id",
+ "in": "path",
+ "description": "The forum-category ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "maxPageSize",
+ "in": "query",
+ "description": "The maximum number of group forum posts to return. The service might return\nfewer than this value. If unspecified, at most 10 group forum posts are\nreturned. The maximum value is 100 and higher values are set to 100.",
+ "schema": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "examples": {
+ "maxPageSize": {
+ "description": "An integer between 1 and 100, inclusive",
+ "value": 10
+ }
+ }
+ },
+ {
+ "name": "pageToken",
+ "in": "query",
+ "description": "A page token, received from a previous call, to retrieve a subsequent page.\n\nWhen paginating, all other parameters provided to the subsequent call must\nmatch the call that provided the page token.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "filter",
+ "in": "query",
+ "description": "This field may be set in order to filter the resources returned.\n\nFiltering conforms to Common Expression Language (CEL). Only the query\n`filter=pinned==true` is supported, where only pinned posts are returned.\n`filter=pinned==false`is not supported.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "view",
+ "in": "query",
+ "description": "The view in which to retrieve the group forum post.\n\nSupports FULL and FULL_WITH_FIRST_COMMENT.\n\nDefaults to FULL.\n\nPossible values:\n\n | Value | Description |\n | --- | --- |\n | VIEW_UNSPECIFIED | The group forum post view is not specified; the default will be used. |\n | FULL | Includes all fields but does not dereference `first_comment`. Only the `path` field is populated. |\n | FULL_WITH_FIRST_COMMENT | Includes all fields and also fully populates `first_comment`. The default view. |",
+ "schema": {
+ "example": "VIEW_UNSPECIFIED",
+ "enum": ["VIEW_UNSPECIFIED", "FULL", "FULL_WITH_FIRST_COMMENT"],
+ "type": "string",
+ "format": "enum"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListGroupForumPostsResponse"
+ }
+ }
+ }
+ }
+ },
+ "x-roblox-engine-usability": {
+ "apiKeyWithHttpService": false
+ },
+ "x-roblox-scopes": [
+ {
+ "name": "group-forum:read"
+ }
+ ],
+ "x-roblox-docs": {
+ "category": "Users and groups",
+ "methodProperties": {
+ "scopes": ["group-forum:read"]
+ },
+ "resource": {
+ "$ref": "#/components/schemas/GroupForumPost",
+ "name": "GroupForumPost"
+ }
+ },
+ "x-roblox-stability": "BETA",
+ "x-roblox-rate-limits": {
+ "perApiKeyOwner": {
+ "period": "MINUTE",
+ "maxInPeriod": 150
+ },
+ "perOauth2Authorization": {
+ "period": "MINUTE",
+ "maxInPeriod": 30
+ }
+ },
+ "security": [
+ {
+ "roblox-api-key": []
+ },
+ {
+ "roblox-oauth2": []
+ }
+ ],
+ "externalDocs": {
+ "url": "https://create.roblox.com/docs/cloud/reference/features/groups#Cloud_ListGroupForumPosts"
+ }
+ }
+ },
+ "/cloud/v2/groups/{group_id}/forum-categories/{forum_category_id}/posts/{post_id}/comments": {
+ "get": {
+ "tags": ["Groups"],
+ "summary": "List Group Forum Comments",
+ "description": "Lists forum comments on a group's forum post.",
+ "operationId": "Cloud_ListGroupForumComments",
+ "parameters": [
+ {
+ "name": "group_id",
+ "in": "path",
+ "description": "The group ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "forum_category_id",
+ "in": "path",
+ "description": "The forum-category ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "post_id",
+ "in": "path",
+ "description": "The post ID.",
+ "required": true,
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "maxPageSize",
+ "in": "query",
+ "description": "The maximum number of group forum comments to return. The service might\nreturn fewer than this value. If unspecified, at most 10 group forum\ncomments are returned. The maximum value is 100 and higher values are set\nto 100.",
+ "schema": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "examples": {
+ "maxPageSize": {
+ "description": "An integer between 1 and 100, inclusive",
+ "value": 10
+ }
+ }
+ },
+ {
+ "name": "pageToken",
+ "in": "query",
+ "description": "A page token, received from a previous call, to retrieve a subsequent page.\n\nWhen paginating, all other parameters provided to the subsequent call must\nmatch the call that provided the page token.",
+ "schema": {
+ "type": "string"
+ }
+ },
+ {
+ "name": "filter",
+ "in": "query",
+ "description": "This field may be set in order to filter the resources returned.\n\nFiltering conforms to Common Expression Language (CEL). Only the string\nfield `repliesToCommentId` and the `==` operator are supported.\nIf `repliesToCommentId` is specified, only comments that respond to the\ncomment are returned. The default value is `''`. If\n`repliesToCommentId=''`, only comments responding directly to the post are\nreturned. Example:\n`\"filter=repliesToCommentId==01234567-89ab-cdef-0123-456789abcdef\"`",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/ListGroupForumCommentsResponse"
+ }
+ }
+ }
+ }
+ },
+ "x-roblox-engine-usability": {
+ "apiKeyWithHttpService": false
+ },
+ "x-roblox-scopes": [
+ {
+ "name": "group-forum:read"
+ }
+ ],
+ "x-roblox-docs": {
+ "category": "Users and groups",
+ "methodProperties": {
+ "scopes": ["group-forum:read"]
+ },
+ "resource": {
+ "$ref": "#/components/schemas/GroupForumComment",
+ "name": "GroupForumComment"
+ }
+ },
+ "x-roblox-stability": "BETA",
+ "x-roblox-rate-limits": {
+ "perApiKeyOwner": {
+ "period": "MINUTE",
+ "maxInPeriod": 150
+ },
+ "perOauth2Authorization": {
+ "period": "MINUTE",
+ "maxInPeriod": 30
+ }
+ },
+ "security": [
+ {
+ "roblox-api-key": []
+ },
+ {
+ "roblox-oauth2": []
+ }
+ ],
+ "externalDocs": {
+ "url": "https://create.roblox.com/docs/cloud/reference/features/groups#Cloud_ListGroupForumComments"
+ }
+ }
+ },
"/cloud/v2/groups/{group_id}/join-requests": {
"get": {
"tags": ["Groups"],
@@ -9969,6 +10313,7 @@
"operationId": "CrossServerMessaging_Publish",
"x-roblox-cloud-api-operation-name": "Publish a Message",
"x-roblox-stability": "BETA",
+ "summary": "Publish a cross-server message to a universe",
"description": "Publish a message to a pre-defined topic of an experience, with the size of the message up to 1,024 characters (1 KB). Requires the **Publish** permission for API keys and the **universe-messaging-service:publish** scope for OAuth 2.0 apps. See [Cross-server messaging](/cloud-services/cross-server-messaging.md#subscribe-users-to-receive-messages) for defining and subscribing users to a topic.",
"parameters": [
{
@@ -15352,6 +15697,11 @@
"roblox-oauth2": []
}
],
+ "x-roblox-scopes": [
+ {
+ "name": "legacy-asset:manage"
+ }
+ ],
"externalDocs": {
"url": "https://create.roblox.com/docs/cloud/reference/features/assets#get_asset_delivery_api_v1_assetId__assetId_"
}
@@ -15539,6 +15889,11 @@
"roblox-oauth2": []
}
],
+ "x-roblox-scopes": [
+ {
+ "name": "legacy-asset:manage"
+ }
+ ],
"externalDocs": {
"url": "https://create.roblox.com/docs/cloud/reference/features/assets#get_asset_delivery_api_v1_assetId__assetId__version__versionNumber_"
}
@@ -18861,6 +19216,64 @@
}
}
},
+ "/v1/passkey/finish-ar-preauth-registration": {
+ "post": {
+ "summary": "Finishes account recovery pre-auth passkey registration by validating the recovery session,\r\ndeactivating the user's password, and completing passkey registration.",
+ "requestBody": {
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Roblox.Authentication.Api.Models.Request.FinishARPreAuthPasskeyRegistrationRequest"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Roblox.Authentication.Api.Models.Request.FinishARPreAuthPasskeyRegistrationRequest"
+ }
+ }
+ },
+ "description": "The request body containing recovery session and passkey details.",
+ "required": true
+ },
+ "responses": {
+ "200": {
+ "description": "OK",
+ "content": {
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Roblox.Web.WebAPI.ApiEmptyResponseModel"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/Roblox.Web.WebAPI.ApiEmptyResponseModel"
+ }
+ }
+ }
+ },
+ "400": {
+ "description": "0: An unknown error occurred with the request."
+ },
+ "401": {
+ "description": "0: An unknown error occurred with the request."
+ },
+ "403": {
+ "description": "0: Token Validation Failed\r\n1: Reached limit of pass keys registered."
+ },
+ "500": {
+ "description": "0: An unknown error occurred with the request."
+ },
+ "503": {
+ "description": "2: Feature disabled."
+ }
+ },
+ "servers": [
+ {
+ "url": "https://auth.roblox.com"
+ }
+ ]
+ }
+ },
"/v1/passkey/finish-preauth-registration": {
"post": {
"tags": ["Accounts"],
@@ -21770,25 +22183,6 @@
"type": "integer",
"format": "int64"
}
- },
- {
- "in": "header",
- "name": "RequestUserIdIsInGameServer",
- "description": "Whether the user with the request userId is present in the game server.",
- "required": true,
- "schema": {
- "type": "boolean"
- }
- },
- {
- "in": "header",
- "name": "Roblox-Place-Id",
- "description": "Place identifier of the requesting place.",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int64"
- }
}
],
"responses": {
@@ -21842,25 +22236,6 @@
"type": "integer"
}
}
- },
- {
- "in": "header",
- "name": "RequestUserIdIsInGameServer",
- "description": "Whether the user with the request userId is present in the game server.",
- "required": true,
- "schema": {
- "type": "boolean"
- }
- },
- {
- "in": "header",
- "name": "Roblox-Place-Id",
- "description": "Place identifier of the requesting place.",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int64"
- }
}
],
"responses": {
@@ -28601,133 +28976,6 @@
}
}
},
- "/v1/my/trusted-friends/{userId}/status": {
- "get": {
- "tags": ["Connections"],
- "summary": "Gets trusted friend status of a specified user against the requesting user.",
- "parameters": [
- {
- "in": "path",
- "name": "userId",
- "description": "The user to check the trusted friend status for.",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Friends.Api.TrustedFriendStatusResponse"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Friends.Api.TrustedFriendStatusResponse"
- }
- }
- }
- },
- "400": {
- "description": "1: The target user is invalid or does not exist."
- },
- "401": {
- "description": "0: Authorization has been denied for this request."
- }
- },
- "servers": [
- {
- "url": "https://friends.roblox.com"
- }
- ],
- "x-roblox-engine-usability": {
- "apiKeyWithHttpService": false
- },
- "security": [
- {
- "roblox-legacy-cookie": []
- }
- ],
- "externalDocs": {
- "url": "https://create.roblox.com/docs/cloud/reference/features/friends#friends_get_v1_my_trusted_friends__userId__status"
- }
- }
- },
- "/v1/user/{userId}/multiget-are-trusted-friends": {
- "get": {
- "tags": ["Connections"],
- "summary": "Check if the requesting user is trusted friends with the specified users.",
- "parameters": [
- {
- "in": "path",
- "name": "userId",
- "description": "The requesting userId.",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int64"
- }
- },
- {
- "in": "query",
- "name": "userIds",
- "description": "The user ids to check against with the requesting user.",
- "required": true,
- "style": "form",
- "explode": false,
- "schema": {
- "type": "array",
- "items": {
- "format": "int64",
- "type": "integer"
- }
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Friends.Api.MultigetAreTrustedFriendsResponse"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Friends.Api.MultigetAreTrustedFriendsResponse"
- }
- }
- }
- },
- "400": {
- "description": "1: The target user is invalid or does not exist."
- }
- },
- "servers": [
- {
- "url": "https://friends.roblox.com"
- }
- ],
- "x-roblox-engine-usability": {
- "apiKeyWithHttpService": false
- },
- "security": [
- {},
- {
- "roblox-legacy-cookie": []
- }
- ],
- "externalDocs": {
- "url": "https://create.roblox.com/docs/cloud/reference/features/friends#friends_get_v1_user__userId__multiget_are_trusted_friends"
- }
- }
- },
"/v1/user/friend-requests/count": {
"get": {
"tags": ["Connections"],
@@ -39228,6 +39476,9 @@
},
"400": {
"description": "8: The universe IDs specified are invalid.\r\n9: Too many universe IDs were requested."
+ },
+ "429": {
+ "description": "4: Too many requests have been made."
}
},
"servers": [
@@ -39716,145 +39967,6 @@
]
}
},
- "/v1/games/{universeId}/votes": {
- "get": {
- "tags": ["Interactions", "Universes"],
- "summary": "Get the game vote status",
- "parameters": [
- {
- "in": "path",
- "name": "universeId",
- "description": "The id of the universe we get vote status from.",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Games.Api.Models.Response.GameVoteResponse"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Games.Api.Models.Response.GameVoteResponse"
- }
- }
- }
- },
- "400": {
- "description": "2: The universe's root place is invalid.\r\n3: The asset is not voteable."
- },
- "404": {
- "description": "1: The requested universe does not exist."
- },
- "429": {
- "description": "10: Internal service busy. Please try again later."
- },
- "500": {
- "description": "0: An unknown error occurred."
- }
- },
- "deprecated": true,
- "servers": [
- {
- "url": "https://games.roblox.com"
- }
- ],
- "x-roblox-engine-usability": {
- "apiKeyWithHttpService": false
- },
- "security": [
- {},
- {
- "roblox-legacy-cookie": []
- }
- ],
- "description": "Use https://games.roblox.com/docs#!/Votes/get_v1_games_votes instead",
- "externalDocs": {
- "url": "https://create.roblox.com/docs/cloud/reference/features/interactions#games_get_v1_games__universeId__votes"
- },
- "x-roblox-recommended-alternatives": [
- {
- "url": "https://games.roblox.com/v1/games/votes",
- "httpMethod": "GET",
- "documentationUrl": "https://create.roblox.com/docs/cloud/reference/features/interactions#games_get_v1_games_votes"
- }
- ]
- }
- },
- "/v1/games/{universeId}/votes/user": {
- "get": {
- "tags": ["Interactions", "Universes"],
- "summary": "Get the user's vote status for a game",
- "parameters": [
- {
- "in": "path",
- "name": "universeId",
- "description": "The id of the universe we get user vote status from.",
- "required": true,
- "schema": {
- "type": "integer",
- "format": "int64"
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Games.Api.Models.Response.UserGameVoteResponse"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Games.Api.Models.Response.UserGameVoteResponse"
- }
- }
- }
- },
- "400": {
- "description": "2: The universe's root place is invalid.\r\n3: The asset is not voteable."
- },
- "401": {
- "description": "0: Authorization has been denied for this request."
- },
- "404": {
- "description": "1: The requested universe does not exist."
- },
- "429": {
- "description": "10: Internal service busy. Please try again later."
- },
- "500": {
- "description": "0: An unknown error occurred."
- }
- },
- "servers": [
- {
- "url": "https://games.roblox.com"
- }
- ],
- "x-roblox-engine-usability": {
- "apiKeyWithHttpService": false
- },
- "security": [
- {
- "roblox-legacy-cookie": []
- }
- ],
- "externalDocs": {
- "url": "https://create.roblox.com/docs/cloud/reference/features/interactions#games_get_v1_games__universeId__votes_user"
- }
- }
- },
"/v1/games/games-product-info": {
"get": {
"tags": ["Universes"],
@@ -40131,72 +40243,6 @@
}
}
},
- "/v1/games/votes": {
- "get": {
- "tags": ["Interactions", "Universes"],
- "summary": "Gets a list of universe vote status",
- "parameters": [
- {
- "in": "query",
- "name": "universeIds",
- "description": "A list of universe Ids. Cannot exceed a maximum of 50 IDs.",
- "required": true,
- "style": "form",
- "explode": false,
- "schema": {
- "type": "array",
- "items": {
- "format": "int64",
- "type": "integer"
- }
- }
- }
- ],
- "responses": {
- "200": {
- "description": "OK",
- "content": {
- "application/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Web.WebAPI.Models.ApiArrayResponse_Roblox.Games.Api.Models.Response.GameVoteResponse_"
- }
- },
- "text/json": {
- "schema": {
- "$ref": "#/components/schemas/Roblox.Web.WebAPI.Models.ApiArrayResponse_Roblox.Games.Api.Models.Response.GameVoteResponse_"
- }
- }
- }
- },
- "400": {
- "description": "3: The asset is not voteable.\r\n8: No universe IDs were specified.\r\n9: Too many universe IDs were requested."
- },
- "429": {
- "description": "10: Internal service busy. Please try again later."
- },
- "500": {
- "description": "0: An unknown error occurred."
- }
- },
- "servers": [
- {
- "url": "https://games.roblox.com"
- }
- ],
- "x-roblox-engine-usability": {
- "apiKeyWithHttpService": false
- },
- "security": [
- {},
- {
- "roblox-legacy-cookie": []
- }
- ],
- "externalDocs": {
- "url": "https://create.roblox.com/docs/cloud/reference/features/interactions#games_get_v1_games_votes"
- }
- }
- },
"/v1/private-servers/enabled-in-universe/{universeId}": {
"get": {
"tags": ["Private servers", "Universes"],
@@ -40313,7 +40359,7 @@
}
}
},
- "/v2/groups/{groupId}/gamesV2#GroupsApi": {
+ "/v2/groups/{groupId}/gamesV2": {
"get": {
"tags": ["Groups", "Universes"],
"summary": "Gets experiences created by the specified group id.",
@@ -40408,7 +40454,7 @@
}
}
},
- "/v2/groups/{groupId}/games#GroupsApi": {
+ "/v2/groups/{groupId}/games": {
"get": {
"tags": ["Groups", "Universes"],
"summary": "Gets experiences created by the specified group id.",
@@ -43889,12 +43935,12 @@
"content": {
"application/json": {
"schema": {
- "$ref": "#/components/schemas/Roblox.Web.WebAPI.Models.ApiArrayResponse_Roblox.Groups.Api.SocialLinkResponse_"
+ "$ref": "#/components/schemas/Roblox.Groups.Api.GetSocialLinkResponse"
}
},
"text/json": {
"schema": {
- "$ref": "#/components/schemas/Roblox.Web.WebAPI.Models.ApiArrayResponse_Roblox.Groups.Api.SocialLinkResponse_"
+ "$ref": "#/components/schemas/Roblox.Groups.Api.GetSocialLinkResponse"
}
}
}
@@ -53726,7 +53772,12 @@
"x-roblox-engine-usability": {
"apiKeyWithHttpService": false
},
- "security": [{}],
+ "security": [
+ {},
+ {
+ "roblox-legacy-cookie": []
+ }
+ ],
"externalDocs": {
"url": "https://create.roblox.com/docs/cloud/reference/features/assets#thumbnails_get_v1_assets_thumbnail_3d"
}
@@ -54755,7 +54806,12 @@
"x-roblox-engine-usability": {
"apiKeyWithHttpService": false
},
- "security": [{}],
+ "security": [
+ {},
+ {
+ "roblox-legacy-cookie": []
+ }
+ ],
"externalDocs": {
"url": "https://create.roblox.com/docs/cloud/reference/features/avatars#thumbnails_get_v1_users_avatar_3d"
}
@@ -61008,7 +61064,7 @@
"x-roblox-stability": "BETA",
"x-roblox-rate-limits": {
"perApiKeyOwner": {
- "period": "DAY",
+ "period": "MINUTE",
"maxInPeriod": 100
}
},
@@ -64654,7 +64710,7 @@
}
}
},
- "/v1/games/{universeId}/user-votes#VotingApi": {
+ "/v1/games/{universeId}/user-votes": {
"patch": {
"tags": ["Interactions", "Universes"],
"operationId": "Voting_VoteGame",
@@ -64757,7 +64813,207 @@
}
}
},
- "/v1/vip-servers/{id}/permissions#PrivateServersApi": {
+ "/v1/games/{universeId}/votes": {
+ "get": {
+ "tags": ["Interactions", "Universes"],
+ "operationId": "Voting_GetGameVoteStatus",
+ "parameters": [
+ {
+ "name": "universeId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "integer",
+ "format": "int64"
+ }
+ },
+ {
+ "name": "Roblox-Api-Key",
+ "in": "header",
+ "description": "Api Key (UUID).",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Success",
+ "content": {
+ "text/plain": {
+ "schema": {
+ "$ref": "#/components/schemas/GameVoteResponse"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GameVoteResponse"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GameVoteResponse"
+ }
+ }
+ }
+ }
+ },
+ "servers": [
+ {
+ "url": "https://games.roblox.com"
+ }
+ ],
+ "x-roblox-engine-usability": {
+ "apiKeyWithHttpService": false
+ },
+ "security": [
+ {},
+ {
+ "roblox-legacy-cookie": []
+ }
+ ],
+ "externalDocs": {
+ "url": "https://create.roblox.com/docs/cloud/reference/features/interactions#Voting_GetGameVoteStatus"
+ },
+ "x-roblox-recommended-alternatives": [
+ {
+ "url": "https://games.roblox.com/v1/games/votes",
+ "httpMethod": "GET",
+ "documentationUrl": "https://create.roblox.com/docs/cloud/reference/features/interactions#Voting_MultiGetGameVoteStatus"
+ }
+ ]
+ }
+ },
+ "/v1/games/{universeId}/votes/user": {
+ "get": {
+ "tags": ["Interactions", "Universes"],
+ "operationId": "Voting_GetGameVoteStatusForUser",
+ "parameters": [
+ {
+ "name": "universeId",
+ "in": "path",
+ "required": true,
+ "schema": {
+ "type": "integer",
+ "format": "int64"
+ }
+ },
+ {
+ "name": "Roblox-Api-Key",
+ "in": "header",
+ "description": "Api Key (UUID).",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Success",
+ "content": {
+ "text/plain": {
+ "schema": {
+ "$ref": "#/components/schemas/UserGameVoteResponse"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserGameVoteResponse"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/UserGameVoteResponse"
+ }
+ }
+ }
+ }
+ },
+ "servers": [
+ {
+ "url": "https://games.roblox.com"
+ }
+ ],
+ "x-roblox-engine-usability": {
+ "apiKeyWithHttpService": false
+ },
+ "security": [
+ {
+ "roblox-legacy-cookie": []
+ }
+ ],
+ "externalDocs": {
+ "url": "https://create.roblox.com/docs/cloud/reference/features/interactions#Voting_GetGameVoteStatusForUser"
+ }
+ }
+ },
+ "/v1/games/votes": {
+ "get": {
+ "tags": ["Interactions", "Universes"],
+ "operationId": "Voting_MultiGetGameVoteStatus",
+ "parameters": [
+ {
+ "name": "universeIds",
+ "in": "query",
+ "schema": {
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int64"
+ }
+ }
+ },
+ {
+ "name": "Roblox-Api-Key",
+ "in": "header",
+ "description": "Api Key (UUID).",
+ "schema": {
+ "type": "string"
+ }
+ }
+ ],
+ "responses": {
+ "200": {
+ "description": "Success",
+ "content": {
+ "text/plain": {
+ "schema": {
+ "$ref": "#/components/schemas/GameVoteResponseApiArrayResponse"
+ }
+ },
+ "application/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GameVoteResponseApiArrayResponse"
+ }
+ },
+ "text/json": {
+ "schema": {
+ "$ref": "#/components/schemas/GameVoteResponseApiArrayResponse"
+ }
+ }
+ }
+ }
+ },
+ "servers": [
+ {
+ "url": "https://games.roblox.com"
+ }
+ ],
+ "x-roblox-engine-usability": {
+ "apiKeyWithHttpService": false
+ },
+ "security": [
+ {},
+ {
+ "roblox-legacy-cookie": []
+ }
+ ],
+ "externalDocs": {
+ "url": "https://create.roblox.com/docs/cloud/reference/features/interactions#Voting_MultiGetGameVoteStatus"
+ }
+ }
+ },
+ "/v1/vip-servers/{id}/permissions": {
"patch": {
"tags": ["Groups", "Private servers", "Universes"],
"operationId": "PrivateServers_UpdatePrivateServerPermissions",
@@ -64833,7 +65089,7 @@
}
}
},
- "/v1/vip-servers/{id}/subscription#PrivateServersApi": {
+ "/v1/vip-servers/{id}/subscription": {
"patch": {
"tags": ["Private servers", "Universes"],
"operationId": "PrivateServers_UpdatePrivateServerSubscription",
@@ -64909,7 +65165,7 @@
}
}
},
- "/v1/vip-servers/{id}#PrivateServersApi": {
+ "/v1/vip-servers/{id}": {
"get": {
"tags": ["Metadata", "Private servers", "Universes"],
"operationId": "PrivateServers_GetPrivateServer",
@@ -65028,7 +65284,7 @@
}
}
},
- "/v1/games/vip-servers/{universeId}#PrivateServersApi": {
+ "/v1/games/vip-servers/{universeId}": {
"post": {
"tags": ["Private servers", "Universes"],
"operationId": "PrivateServers_CreatePrivateServer",
@@ -65104,7 +65360,7 @@
}
}
},
- "/v1/vip-server/can-invite/{userId}#PrivateServersApi": {
+ "/v1/vip-server/can-invite/{userId}": {
"get": {
"tags": ["Private servers", "Users"],
"operationId": "PrivateServers_CanInviteUser",
@@ -65214,7 +65470,7 @@
}
}
},
- "/v1/private-servers/my-private-servers#PrivateServersApi": {
+ "/v1/private-servers/my-private-servers": {
"get": {
"tags": ["Private servers", "Universes"],
"operationId": "PrivateServersApi.PrivateServers_GetMyPrivateServers",
@@ -65412,6 +65668,48 @@
},
"x-resource": true
},
+ "ContentMessage": {
+ "type": "object",
+ "properties": {
+ "createTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the message was created.",
+ "format": "date-time"
+ },
+ "updateTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the message was last updated.",
+ "format": "date-time"
+ },
+ "plainText": {
+ "type": "string",
+ "description": "The plain text content of the message."
+ },
+ "author": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who created the message."
+ },
+ "messageReaction": {
+ "readOnly": true,
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/MessageReaction"
+ },
+ "description": "The reactions to the message, if this feature is enabled for this message."
+ }
+ },
+ "description": "Represents the content of a message.",
+ "x-oneOf": {
+ "Author": ["author"],
+ "content": ["plainText"]
+ }
+ },
"CreatorStoreProduct": {
"type": "object",
"properties": {
@@ -65855,6 +66153,175 @@
"Owner": ["owner"]
}
},
+ "GroupForumCategory": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "example": "groups/123/forum-categories/01234567-89ab-cdef-0123-456789abcdef",
+ "type": "string",
+ "description": "The resource path of the group forum category.\n\nFormat: `groups/{group_id}/forum-categories/{group_forum_category_id}`"
+ },
+ "createTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum category was created.",
+ "format": "date-time"
+ },
+ "updateTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum category was last updated.",
+ "format": "date-time"
+ },
+ "groupForumCategoryId": {
+ "readOnly": true,
+ "type": "string",
+ "description": "The id of the group forum category."
+ },
+ "displayName": {
+ "type": "string",
+ "description": "The display name of the group forum category."
+ },
+ "creator": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who created the group forum category."
+ },
+ "archiveTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum category was archived.",
+ "format": "date-time"
+ },
+ "archiver": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who archived the group forum category."
+ }
+ },
+ "description": "Represents a forum category within a group for user discussions.",
+ "x-aep-resource": {
+ "patterns": [
+ "groups/{group_id}/forum-categories/{group_forum_category_id}"
+ ],
+ "plural": "group-forum-categories",
+ "singular": "group-forum-category"
+ },
+ "x-resource": true
+ },
+ "GroupForumComment": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "example": "groups/123/forum-categories/01234567-89ab-cdef-0123-456789abcdef/posts/01234567-89ab-cdef-0123-456789abcdef/comments/01234567-89ab-cdef-0123-456789abcdef",
+ "type": "string",
+ "description": "The resource path of the group forum comment.\n\nFormat:\n`groups/{group_id}/forum-categories/{group_forum_category_id}/posts/{group_forum_post_id}/comments/{group_forum_comment_id}`"
+ },
+ "groupForumCommentId": {
+ "readOnly": true,
+ "type": "string",
+ "description": "The id of the group forum comment."
+ },
+ "message": {
+ "$ref": "#/components/schemas/ContentMessage",
+ "description": "The message content of the group forum comment."
+ }
+ },
+ "description": "Represents a forum comment on a group's forum post.",
+ "x-aep-resource": {
+ "patterns": [
+ "groups/{group_id}/forum-categories/{group_forum_category_id}/posts/{group_forum_post_id}/comments/{group_forum_comment_id}"
+ ],
+ "plural": "group-forum-comments",
+ "singular": "group-forum-comment"
+ },
+ "x-resource": true
+ },
+ "GroupForumPost": {
+ "type": "object",
+ "properties": {
+ "path": {
+ "example": "groups/123/forum-categories/01234567-89ab-cdef-0123-456789abcdef/posts/01234567-89ab-cdef-0123-456789abcdef",
+ "type": "string",
+ "description": "The resource path of the group forum post.\n\nFormat:\n`groups/{group_id}/forum-categories/{group_forum_category_id}/posts/{group_forum_post_id}`"
+ },
+ "createTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum post was created.",
+ "format": "date-time"
+ },
+ "updateTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum post was last updated.",
+ "format": "date-time"
+ },
+ "pinned": {
+ "example": true,
+ "type": "boolean",
+ "description": "Whether the group forum post is pinned."
+ },
+ "locked": {
+ "example": true,
+ "type": "boolean",
+ "description": "Whether the group forum post is locked."
+ },
+ "groupForumPostId": {
+ "readOnly": true,
+ "type": "string",
+ "description": "The id of the group forum post."
+ },
+ "title": {
+ "type": "string",
+ "description": "The title of the group forum post."
+ },
+ "firstComment": {
+ "$ref": "#/components/schemas/GroupForumComment",
+ "description": "The resource path of the group forum post's first comment, which holds the\npost content.\n\nBy default, the `first_comment` field is fully populated. This **will not**\ndereference resource references within the first comment, such as\n`GroupForumComment.author`; only the `path` subfield of these fields will\nbe populated. However, if only the `path` field of the first comment is\nneeded, you can specify the FULL view."
+ },
+ "author": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who created the group forum post."
+ },
+ "archiveTime": {
+ "readOnly": true,
+ "example": "2023-07-05T12:34:56Z",
+ "type": "string",
+ "description": "The timestamp when the group forum post was archived.",
+ "format": "date-time"
+ },
+ "archiver": {
+ "readOnly": true,
+ "example": "users/156",
+ "type": "string",
+ "description": "The resource path of the user who archived the group forum post."
+ },
+ "commentCount": {
+ "type": "integer",
+ "description": "The number of comments on the group forum post. This includes the first\ncomment (post content).",
+ "format": "int64"
+ }
+ },
+ "description": "Represents a forum post within a group's forum category.",
+ "x-aep-resource": {
+ "patterns": [
+ "groups/{group_id}/forum-categories/{group_forum_category_id}/posts/{group_forum_post_id}"
+ ],
+ "plural": "group-forum-posts",
+ "singular": "group-forum-post"
+ },
+ "x-resource": true
+ },
"GroupJoinRequest": {
"type": "object",
"properties": {
@@ -66538,6 +67005,57 @@
},
"description": "A list of DataStores in the parent collection."
},
+ "ListGroupForumCategoriesResponse": {
+ "type": "object",
+ "properties": {
+ "groupForumCategories": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/GroupForumCategory"
+ },
+ "description": "The GroupForumCategories from the specified Group."
+ },
+ "nextPageToken": {
+ "type": "string",
+ "description": "A token that you can send as a `pageToken` parameter to retrieve the next\npage. If this field is omitted, there are no subsequent pages."
+ }
+ },
+ "description": "A list of GroupForumCategories in the parent collection."
+ },
+ "ListGroupForumCommentsResponse": {
+ "type": "object",
+ "properties": {
+ "groupForumComments": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/GroupForumComment"
+ },
+ "description": "The GroupForumComments from the specified GroupForumPost."
+ },
+ "nextPageToken": {
+ "type": "string",
+ "description": "A token that you can send as a `pageToken` parameter to retrieve the next\npage. If this field is omitted, there are no subsequent pages."
+ }
+ },
+ "description": "A list of GroupForumComments in the parent collection."
+ },
+ "ListGroupForumPostsResponse": {
+ "type": "object",
+ "properties": {
+ "groupForumPosts": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/GroupForumPost"
+ },
+ "description": "The GroupForumPosts from the specified GroupForumCategory."
+ },
+ "nextPageToken": {
+ "type": "string",
+ "description": "A token that you can send as a `pageToken` parameter to retrieve the next\npage. If this field is omitted, there are no subsequent pages."
+ }
+ },
+ "description": "A list of GroupForumPosts in the parent collection."
+ },
"ListGroupJoinRequestsResponse": {
"type": "object",
"properties": {
@@ -67069,6 +67587,23 @@
"sortKey": ["stringSortKey", "numericSortKey"]
}
},
+ "MessageReaction": {
+ "type": "object",
+ "properties": {
+ "emoteId": {
+ "readOnly": true,
+ "type": "string",
+ "description": "The id of the emote."
+ },
+ "count": {
+ "readOnly": true,
+ "type": "integer",
+ "description": "The count of reactions for this emote.",
+ "format": "int64"
+ }
+ },
+ "description": "Represents the reaction to a message."
+ },
"Money": {
"type": "object",
"properties": {
@@ -71105,6 +71640,25 @@
},
"additionalProperties": false
},
+ "Roblox.Authentication.Api.Models.Request.FinishARPreAuthPasskeyRegistrationRequest": {
+ "type": "object",
+ "properties": {
+ "recoverySession": {
+ "type": "string"
+ },
+ "passkeySessionId": {
+ "type": "string"
+ },
+ "passkeyRegistrationResponse": {
+ "type": "string"
+ },
+ "userId": {
+ "format": "int64",
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ },
"Roblox.Authentication.Api.Models.Request.FinishPasskeyPreauthRegistrationRequest": {
"type": "object",
"properties": {
@@ -71539,6 +72093,10 @@
],
"type": "integer"
},
+ "staticFacialAnimation": {
+ "description": "Indicates user choice for facial animation.\r\nstaticFacialAnimation=false, implies the toggle as on and face will animate.\r\nApplicable for dynamic head assets.",
+ "type": "boolean"
+ },
"version": {
"format": "int32",
"description": "Client-authoritative meta model format version\r\n- default is always 1",
@@ -74161,6 +74719,11 @@
"additionalProperties": {
"type": "string"
}
+ },
+ "versionV2": {
+ "format": "int64",
+ "description": "VersionV2 of the OTA asset.",
+ "type": "integer"
}
},
"additionalProperties": false
@@ -76124,21 +76687,6 @@
},
"additionalProperties": false
},
- "Roblox.Friends.Api.MultigetAreTrustedFriendsResponse": {
- "description": "Response model for MultigetAreTrustedFriendsRequest",
- "type": "object",
- "properties": {
- "trustedFriendsId": {
- "description": "List of trusted friend ids",
- "type": "array",
- "items": {
- "format": "int64",
- "type": "integer"
- }
- }
- },
- "additionalProperties": false
- },
"Roblox.Friends.Api.PendingFriendRequestCountModel": {
"description": "Response model for Pending Friend Request Count",
"type": "object",
@@ -76151,19 +76699,6 @@
},
"additionalProperties": false
},
- "Roblox.Friends.Api.TrustedFriendStatusResponse": {
- "description": "The trusted friend status response model",
- "type": "object",
- "properties": {
- "status": {
- "format": "int32",
- "description": "The trusted friend status. ['Invalid' = 0, 'NotFriends' = 1, 'Friends' = 2, 'TrustedFriends' = 3, 'RequestSent' = 4, 'RequestReceived' = 5, 'RequestIgnored' = 6]",
- "enum": [0, 1, 2, 3, 4, 5, 6],
- "type": "integer"
- }
- },
- "additionalProperties": false
- },
"Roblox.Web.Captcha.Models.Request.CaptchaTokenRequest": {
"type": "object",
"properties": {
@@ -78352,28 +78887,6 @@
},
"additionalProperties": false
},
- "Roblox.Games.Api.Models.Response.GameVoteResponse": {
- "description": "Response model for getting the game vote",
- "type": "object",
- "properties": {
- "id": {
- "format": "int64",
- "description": "The game universe id",
- "type": "integer"
- },
- "upVotes": {
- "format": "int64",
- "description": "The game up votes",
- "type": "integer"
- },
- "downVotes": {
- "format": "int64",
- "description": "The game down votes",
- "type": "integer"
- }
- },
- "additionalProperties": false
- },
"Roblox.Games.Api.Models.Response.GetPrivateServerListResponse": {
"type": "object",
"properties": {
@@ -78546,25 +79059,6 @@
},
"additionalProperties": false
},
- "Roblox.Games.Api.Models.Response.UserGameVoteResponse": {
- "description": "Response model for getting the user vote status for a game",
- "type": "object",
- "properties": {
- "canVote": {
- "description": "Whether the user can vote the game",
- "type": "boolean"
- },
- "userVote": {
- "description": "The user's vote status for the game",
- "type": "boolean"
- },
- "reasonForNotVoteable": {
- "description": "The reason why the user can't vote",
- "type": "string"
- }
- },
- "additionalProperties": false
- },
"Roblox.Games.Api.Models.Response.VerifiedBadgeUserResponse": {
"description": "A response model specific to multi-get user.",
"type": "object",
@@ -78685,18 +79179,6 @@
},
"additionalProperties": false
},
- "Roblox.Web.WebAPI.Models.ApiArrayResponse_Roblox.Games.Api.Models.Response.GameVoteResponse_": {
- "type": "object",
- "properties": {
- "data": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Roblox.Games.Api.Models.Response.GameVoteResponse"
- }
- }
- },
- "additionalProperties": false
- },
"Roblox.Web.WebAPI.Models.ApiPageResponse_Roblox.Web.Responses.Games.GameServerResponse_": {
"type": "object",
"properties": {
@@ -79092,6 +79574,24 @@
},
"additionalProperties": false
},
+ "Roblox.Groups.Api.GetSocialLinkResponse": {
+ "description": "A social link response from a create request",
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/Roblox.Groups.Api.SocialLinkResponse"
+ }
+ },
+ "socialLinksVerificationStatus": {
+ "format": "int32",
+ "enum": [0, 1, 2, 3],
+ "type": "integer"
+ }
+ },
+ "additionalProperties": false
+ },
"Roblox.Groups.Api.GroupAllRolesResponse": {
"description": "A group roles response model",
"type": "object",
@@ -80785,18 +81285,6 @@
},
"additionalProperties": false
},
- "Roblox.Web.WebAPI.Models.ApiArrayResponse_Roblox.Groups.Api.SocialLinkResponse_": {
- "type": "object",
- "properties": {
- "data": {
- "type": "array",
- "items": {
- "$ref": "#/components/schemas/Roblox.Groups.Api.SocialLinkResponse"
- }
- }
- },
- "additionalProperties": false
- },
"Roblox.Web.WebAPI.Models.ApiArrayResponse_Roblox.Groups.Api.UserGroupMembershipResponse_": {
"type": "object",
"properties": {
@@ -83669,6 +84157,10 @@
"accessContext": {
"description": "Access context for asset permission checks (only relevant for Asset thumbnail types)",
"type": "string"
+ },
+ "headShape": {
+ "description": "Head shape for dynamic head thumbnails (only relevant for Asset thumbnail types with dynamic head)",
+ "type": "string"
}
},
"additionalProperties": false
@@ -84745,6 +85237,10 @@
"isDelayedUiEnabled": {
"description": "Whether the delayed UI is enabled.",
"type": "boolean"
+ },
+ "is2svRecoveryEnabled": {
+ "description": "Whether to expose 2SV recovery through the 2SV challenge modal.",
+ "type": "boolean"
}
},
"additionalProperties": false
@@ -85687,6 +86183,18 @@
"description": "Representation of a creator store asset.",
"nullable": true
},
+ "CreatorStoreCapabilitiesModel": {
+ "type": "object",
+ "properties": {
+ "shouldSandbox": {
+ "type": "boolean",
+ "description": "Controls whether the model will be sandboxed upon insertion when it has scripts."
+ }
+ },
+ "additionalProperties": false,
+ "description": "Represents the capabilities that a model has (e.g. sandboxing).\r\nOnly present for model asset types; AMRS includes it in the response when available.",
+ "nullable": true
+ },
"ToolboxService.CreatorStoreProduct": {
"type": "object",
"properties": {
@@ -85993,6 +86501,15 @@
],
"description": "The number of studio Instance types in the model.\r\nSee [Instance](https://create.roblox.com/docs/reference/engine/classes/Instance).\r\nThese are broken down into specific types, such as MeshPart, Part, Script,\r\nTool, Animation, etc.",
"nullable": true
+ },
+ "capabilities": {
+ "allOf": [
+ {
+ "$ref": "#/components/schemas/CreatorStoreCapabilitiesModel"
+ }
+ ],
+ "description": "Script capabilities for the asset (sandboxing)",
+ "nullable": true
}
},
"additionalProperties": false,
@@ -87801,6 +88318,20 @@
"type": "integer",
"description": "If BleedOffServers=true, how long will we allow old servers to stay up before shutting them down.\r\nValid values: 1 - 60 minutes",
"format": "int32"
+ },
+ "placeIdToVersions": {
+ "type": "object",
+ "additionalProperties": {
+ "uniqueItems": true,
+ "type": "array",
+ "items": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "nullable": true
+ },
+ "description": "Optional. A mapping of PlaceId to the specific versions to restart/bleed off for that place.\r\nWhen set for a place, only servers running those exact versions will be affected.\r\nIf a place is not in this dictionary or has an empty set, behavior falls back to CloseOldVersionsOnly logic.",
+ "nullable": true
}
},
"additionalProperties": false,
@@ -88319,6 +88850,24 @@
"isInUniverse": {
"type": "boolean",
"description": "Indicates whether the place is still part of the universe.\r\nA place may have active games but is no longer in the universe if it has been removed from the universe."
+ },
+ "versionToPlayerCounts": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "description": "Player counts broken down by place version.\r\nKey is the place version, value is the number of players on that version.",
+ "nullable": true
+ },
+ "versionToInstanceCounts": {
+ "type": "object",
+ "additionalProperties": {
+ "type": "integer",
+ "format": "int32"
+ },
+ "description": "Instance counts broken down by place version.\r\nKey is the place version, value is the number of instances on that version.",
+ "nullable": true
}
},
"additionalProperties": false,
@@ -88726,6 +89275,37 @@
"additionalProperties": false,
"description": "The response for updating a matchmaking server attribute definition."
},
+ "GameVoteResponse": {
+ "type": "object",
+ "properties": {
+ "id": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "upVotes": {
+ "type": "integer",
+ "format": "int64"
+ },
+ "downVotes": {
+ "type": "integer",
+ "format": "int64"
+ }
+ },
+ "additionalProperties": false
+ },
+ "GameVoteResponseApiArrayResponse": {
+ "type": "object",
+ "properties": {
+ "data": {
+ "type": "array",
+ "items": {
+ "$ref": "#/components/schemas/GameVoteResponse"
+ },
+ "nullable": true
+ }
+ },
+ "additionalProperties": false
+ },
"UserGameVoteRequest": {
"type": "object",
"properties": {
@@ -88736,6 +89316,23 @@
},
"additionalProperties": false
},
+ "UserGameVoteResponse": {
+ "type": "object",
+ "properties": {
+ "canVote": {
+ "type": "boolean"
+ },
+ "userVote": {
+ "type": "boolean",
+ "nullable": true
+ },
+ "reasonForNotVoteable": {
+ "type": "string",
+ "nullable": true
+ }
+ },
+ "additionalProperties": false
+ },
"CanInviteUserResponse": {
"type": "object",
"properties": {
@@ -90049,9 +90646,7 @@
"friends_get_v1_my_friends_requests",
"friends_delete_v1_my_new_friend_requests",
"friends_get_v1_my_new_friend_requests_count",
- "friends_get_v1_my_trusted_friends__userId__status",
"friends_post_v1_user__userId__multiget_are_friends",
- "friends_get_v1_user__userId__multiget_are_trusted_friends",
"friends_get_v1_user_friend_requests_count",
"friends_post_v1_user_friend_requests_decline_all",
"friends_post_v1_users__requesterUserId__accept_friend_request",
@@ -90133,6 +90728,9 @@
"Cloud_ListGroupRoles",
"Cloud_GetGroupRole",
"Cloud_GetGroupShout",
+ "Cloud_ListGroupForumCategories",
+ "Cloud_ListGroupForumPosts",
+ "Cloud_ListGroupForumComments",
"get_legacy_develop_v1_user_groups_canmanage",
"develop_get_v1_user_groups_canmanage",
"get_legacy_groups_v1_groups__groupId__audit_log",
@@ -90278,9 +90876,9 @@
"games_post_v1_games__universeId__favorites",
"games_get_v1_games__universeId__favorites_count",
"Voting_VoteGame",
- "games_get_v1_games__universeId__votes",
- "games_get_v1_games__universeId__votes_user",
- "games_get_v1_games_votes",
+ "Voting_GetGameVoteStatus",
+ "Voting_GetGameVoteStatusForUser",
+ "Voting_MultiGetGameVoteStatus",
"games_get_v2_users__userId__favorite_games",
"inventory_get_v1_users__userId__categories_favorites"
]
@@ -90968,14 +91566,14 @@
"games_get_v1_games__universeId__favorites_count",
"games_get_v1_games__universeId__media",
"Voting_VoteGame",
- "games_get_v1_games__universeId__votes",
- "games_get_v1_games__universeId__votes_user",
+ "Voting_GetGameVoteStatus",
+ "Voting_GetGameVoteStatusForUser",
"games_get_v1_games_games_product_info",
"games_get_v1_games_multiget_place_details",
"games_get_v1_games_multiget_playability_status",
"games_get_v1_games_recommendations_game__universeId_",
"PrivateServers_CreatePrivateServer",
- "games_get_v1_games_votes",
+ "Voting_MultiGetGameVoteStatus",
"games_get_v1_private_servers_enabled_in_universe__universeId_",
"PrivateServersApi.PrivateServers_GetMyPrivateServers",
"PrivateServers_GetPrivateServer",
diff --git a/.cursor/rules/roblox/en-us/reference/engine/STUDIO_VERSION b/.cursor/rules/roblox/en-us/reference/engine/STUDIO_VERSION
index 4ec4c834..5dcd9fa1 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/STUDIO_VERSION
+++ b/.cursor/rules/roblox/en-us/reference/engine/STUDIO_VERSION
@@ -1,2 +1,2 @@
-0.707.0.7070732
-version-207b4196e6334893
\ No newline at end of file
+0.708.0.7080878
+version-6df69e4610344376
\ No newline at end of file
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/AdGui.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/AdGui.yaml
index 873ab807..d318758e 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/AdGui.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/AdGui.yaml
@@ -50,6 +50,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Monetization
- name: AdGui.FallbackImage
summary: ''
description: ''
@@ -86,6 +87,7 @@ properties:
can_save: false
capabilities:
- UI
+ - Monetization
methods: []
events: []
callbacks:
@@ -115,4 +117,5 @@ callbacks:
thread_safety: Unsafe
capabilities:
- UI
+ - Monetization
writeCapabilities: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/AdService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/AdService.yaml
index 3dbfbdc0..7f934397 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/AdService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/AdService.yaml
@@ -39,7 +39,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Monetization
- name: AdService:GetAdAvailabilityNowAsync
summary: |
Checks if a video ad is available to be played to the current user inside
@@ -63,7 +64,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Monetization
- name: AdService:RegisterAdOpportunityAsync
summary: |
Tracks how many times a user had the chance to watch a video ad and the
@@ -91,7 +93,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Monetization
- name: AdService:ShowRewardedVideoAdAsync
summary: |
Plays the video ad to the current user inside the experience.
@@ -126,7 +129,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Monetization
- name: AdService:ShowVideoAd
summary: |
Show mobile video advertisements.
@@ -144,7 +149,8 @@ methods:
no longer operational.
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Monetization
- name: AdService:UnregisterAdOpportunity
summary: ''
description: ''
@@ -161,7 +167,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Monetization
events:
- name: AdService.VideoAdClosed
summary: |
@@ -180,5 +187,6 @@ events:
`Class.AdService.VideoAdClosed|VideoAdClosed` has been decommissioned and
is no longer operational.
security: None
- capabilities: []
+ capabilities:
+ - Monetization
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/AnalyticsService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/AnalyticsService.yaml
index dfbe5542..097a5702 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/AnalyticsService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/AnalyticsService.yaml
@@ -121,7 +121,8 @@ methods:
summary: ''
tags:
- Deprecated
- deprecation_message: ''
+ deprecation_message: |
+ This deprecated property is a variant of `Class.AnalyticsService:LogCustomEvent()` which should be used instead.
security: None
thread_safety: Unsafe
capabilities:
@@ -179,10 +180,9 @@ methods:
This function has been deprecated in favor of more descriptive methods,
including:
- - `Class.AnalyticsService:FireCustomEvent()`
- - `Class.AnalyticsService:FireInGameEconomyEvent()`
- - `Class.AnalyticsService:FireLogEvent()`
- - `Class.AnalyticsService:FirePlayerProgressionEvent()`
+ - `Class.AnalyticsService:LogCustomEvent()`
+ - `Class.AnalyticsService:LogEconomyEvent()`
+ - `Class.AnalyticsService:LogProgressionEvent()`
security: None
thread_safety: Unsafe
capabilities:
@@ -302,7 +302,8 @@ methods:
No return.
tags:
- Deprecated
- deprecation_message: ''
+ deprecation_message: |
+ This deprecated property is a variant of `Class.AnalyticsService:LogEconomyEvent()` which should be used instead.
security: None
thread_safety: Unsafe
capabilities:
@@ -540,7 +541,8 @@ methods:
No return.
tags:
- Deprecated
- deprecation_message: ''
+ deprecation_message: |
+ This deprecated property is a variant of `Class.AnalyticsService:LogProgressionEvent()` which should be used instead.
security: None
thread_safety: Unsafe
capabilities:
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/AudioDeviceInput.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/AudioDeviceInput.yaml
index dc0efeb9..0b43c2dd 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/AudioDeviceInput.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/AudioDeviceInput.yaml
@@ -51,7 +51,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
- name: AudioDeviceInput.Active
summary: |
Controls whether the physical device is actively recording.
@@ -73,7 +75,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
- name: AudioDeviceInput.IsReady
summary: |
Denotes whether this `Class.AudioDeviceInput` is ready to produce sound.
@@ -94,7 +98,9 @@ properties:
serialization:
can_load: false
can_save: true
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
- name: AudioDeviceInput.Muted
summary: |
Controls whether this `Class.AudioDeviceInput` is muted.
@@ -119,7 +125,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
- name: AudioDeviceInput.Player
summary: |
Determines whose device is producing sound.
@@ -140,7 +148,10 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
+ - Players
- name: AudioDeviceInput.Volume
summary: |
Volume level which is multiplied onto the output audio stream.
@@ -159,7 +170,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
methods:
- name: AudioDeviceInput:GetConnectedWires
summary: |
@@ -183,7 +196,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
- name: AudioDeviceInput:GetInputPins
summary: |
Gets the list of pins that `Class.Wire` can use in `Class.Wire.TargetName`
@@ -203,7 +218,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
- name: AudioDeviceInput:GetOutputPins
summary: |
Gets the list of pins that `Class.Wire` can use in `Class.Wire.SourceName`
@@ -223,7 +240,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
- name: AudioDeviceInput:GetUserIdAccessList
summary: |
Returns a list of user IDs that are either permitted to hear or blocked
@@ -241,7 +260,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
- name: AudioDeviceInput:SetUserIdAccessList
summary: |
Sets a list of user IDs that are either permitted to hear or blocked from
@@ -266,7 +287,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
events:
- name: AudioDeviceInput.WiringChanged
summary: |
@@ -302,5 +325,7 @@ events:
tags: []
deprecation_message: ''
security: None
- capabilities: []
+ capabilities:
+ - Audio
+ - Input
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/AudioSpeechToText.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/AudioSpeechToText.yaml
index ff80eb3d..1334ab3f 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/AudioSpeechToText.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/AudioSpeechToText.yaml
@@ -14,7 +14,8 @@ description: |
Roblox uses the following formula to throttle requests for this API based on
the number of players in your experience:
- `max requests per minute per experience = 1 + (5 * number_of_concurrent_users)`.
+ `max requests per minute per experience = 1 + (5 * number_of_concurrent_users)`. You can purchase additional usage using
+ [Extended Services](../../../cloud-services/extended-services.md).
For more information, see
[Speech-to-text](../../../audio/objects.md#speech-to-text).
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/AvatarCreationService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/AvatarCreationService.yaml
index 6b57e97a..7205e2d1 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/AvatarCreationService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/AvatarCreationService.yaml
@@ -71,7 +71,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - DynamicGeneration
- name: AvatarCreationService:GenerateAvatar2DPreviewAsync
summary: |
Creates a 2D avatar preview and returns a previewId.
@@ -119,7 +120,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - DynamicGeneration
- name: AvatarCreationService:GenerateAvatarAsync
summary: |
Generates an avatar and returns a generationId.
@@ -165,7 +167,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - DynamicGeneration
- name: AvatarCreationService:GetBatchTokenDetailsAsync
summary: |
Gets the avatar creation token details for a list of avatar creation
@@ -208,7 +211,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Monetization
- name: AvatarCreationService:GetValidationRules
summary: |
Gets data regarding rules that assets must abide by to pass UGC
@@ -400,7 +404,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - DynamicGeneration
- name: AvatarCreationService:LoadGeneratedAvatarAsync
summary: |
Loads a generated avatar using an avatar generation ID.
@@ -441,7 +446,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - DynamicGeneration
- name: AvatarCreationService:PrepareAvatarForPreviewAsync
summary: |
Prepares in-experience avatar for preview.
@@ -475,7 +481,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Avatar
- name: AvatarCreationService:PromptCreateAvatarAssetAsync
summary: |
Prompts a `Class.Player` to purchase and create an avatar asset from an
@@ -668,7 +675,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetCreateUpdate
+ - Monetization
- name: AvatarCreationService:PromptSelectAvatarGenerationImageAsync
summary: |
Prompt the `Class.Player` to take a selfie and return the FileId.
@@ -709,7 +718,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - SensitiveInput
- name: AvatarCreationService:RequestAvatarGenerationSessionAsync
summary: |
Request an AvatarGeneration session for a `Class.Player`.
@@ -779,7 +789,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - DynamicGeneration
- name: AvatarCreationService:ValidateUGCAccessoryAsync
summary: |
Studio only. Runs UGC validation for an `Enum.AccessoryType`.
@@ -976,5 +987,6 @@ events:
tags: []
deprecation_message: ''
security: None
- capabilities: []
+ capabilities:
+ - DynamicGeneration
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/AvatarEditorService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/AvatarEditorService.yaml
index 569b2116..85b72b25 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/AvatarEditorService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/AvatarEditorService.yaml
@@ -393,7 +393,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Avatar
- name: AvatarEditorService:CheckApplyDefaultClothing
summary: |
Used to apply default clothing to the `Class.HumanoidDescription` if
@@ -417,7 +418,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Avatar
- name: AvatarEditorService:ConformToAvatarRulesAsync
summary: ''
description: ''
@@ -435,7 +437,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Avatar
- name: AvatarEditorService:ConformToAvatarRules
summary: ''
description: ''
@@ -454,7 +457,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Avatar
- name: AvatarEditorService:GetAccessoryType
summary: ''
description: ''
@@ -587,7 +591,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:GetBatchItemDetails
summary: |
Gets the item details for a list of items at once.
@@ -616,7 +621,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:GetFavoriteAsync
summary: |
Returns if the `Class.Players.LocalPlayer` has favorited the given bundle
@@ -645,7 +651,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - AssetRead
- name: AvatarEditorService:GetFavorite
summary: |
Returns if the `Class.Players.LocalPlayer` has favorited the given bundle
@@ -673,7 +681,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - AssetRead
- name: AvatarEditorService:GetInventoryAsync
summary: |
Returns an `Class.InventoryPages` object with information about owned
@@ -711,7 +721,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - AssetRead
- name: AvatarEditorService:GetInventory
summary: |
Returns an `Class.InventoryPages` object with information about owned
@@ -734,7 +746,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - AssetRead
- name: AvatarEditorService:GetItemDetailsAsync
summary: |
Returns the item details for the given item.
@@ -800,7 +814,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:GetItemDetails
summary: |
Returns the item details for the given item.
@@ -829,7 +844,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:GetOutfitDetailsAsync
summary: |
Returns the outfit details for the given outfit.
@@ -892,7 +908,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:GetOutfitDetails
summary: |
Returns the outfit details for the given outfit.
@@ -915,7 +932,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:GetOutfitsAsync
summary: |
Returns outfit data for the `Class.Players.LocalPlayer`.
@@ -983,7 +1001,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - AssetRead
- name: AvatarEditorService:GetOutfits
summary: |
Returns outfit data for the `Class.Players.LocalPlayer`.
@@ -1007,7 +1027,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - AssetRead
- name: AvatarEditorService:GetRecommendedAssetsAsync
summary: |
Returns a list of recommended assets based on a given `Enum.AssetType` and
@@ -1073,7 +1095,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:GetRecommendedAssets
summary: |
Returns a list of recommended assets based on a given `Enum.AssetType` and
@@ -1105,7 +1128,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:GetRecommendedBundlesAsync
summary: |
Returns a list of recommended bundles for a given bundle id.
@@ -1164,7 +1188,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:GetRecommendedBundles
summary: |
Returns a list of recommended bundles for a given bundle id.
@@ -1186,7 +1211,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:PromptAllowInventoryReadAccess
summary: |
Prompts the `Class.Players.LocalPlayer` to allow the developer to read
@@ -1209,7 +1235,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - AssetRead
- name: AvatarEditorService:PromptCreateOutfit
summary: |
Prompts the `Class.Players.LocalPlayer` to save the given
@@ -1239,7 +1267,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - PlatformAvatarEditing
- name: AvatarEditorService:PromptDeleteOutfit
summary: |
Prompts the `Class.Players.LocalPlayer` to delete the given outfit.
@@ -1261,7 +1291,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - PlatformAvatarEditing
- name: AvatarEditorService:PromptRenameOutfit
summary: |
Prompts the `Class.Players.LocalPlayer` to rename the given outfit.
@@ -1283,7 +1315,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - PlatformAvatarEditing
- name: AvatarEditorService:PromptSaveAvatar
summary: |
Prompts the `Class.Players.LocalPlayer` to update their avatar based on
@@ -1345,7 +1379,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - PlatformAvatarEditing
- name: AvatarEditorService:PromptUpdateOutfit
summary: |
Prompts the `Class.Players.LocalPlayer` to update the given outfit.
@@ -1376,7 +1412,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - PlatformAvatarEditing
- name: AvatarEditorService:SearchCatalogAsync
summary: |
Returns a `Class.CatalogPages` object containing the result of the given
@@ -1403,7 +1441,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
- name: AvatarEditorService:SearchCatalog
summary: |
Returns a `Class.CatalogPages` object containing the result of the given
@@ -1425,7 +1464,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - AssetRead
events:
- name: AvatarEditorService.PromptAllowInventoryReadAccessCompleted
summary: |
@@ -1448,7 +1488,9 @@ events:
tags: []
deprecation_message: ''
security: None
- capabilities: []
+ capabilities:
+ - Players
+ - AssetRead
- name: AvatarEditorService.PromptCreateOutfitCompleted
summary: |
Fires when the PromptSaveOutfit operation is completed.
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/ChangeHistoryService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/ChangeHistoryService.yaml
index 4d50d108..e2d90363 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/ChangeHistoryService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/ChangeHistoryService.yaml
@@ -46,7 +46,7 @@ methods:
Identifies the recording from the previous call to
`Class.ChangeHistoryService:TryBeginRecording()|TryBeginRecording()`.
If the operation is
- `Enum.ChangeHistoryService.FinishRecordingOperation.Cancel`, this
+ `Enum.FinishRecordingOperation.Cancel`, this
value is ignored, and the recording is determined by context.
- name: operation
type: FinishRecordingOperation
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/ExperienceNotificationService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/ExperienceNotificationService.yaml
index 7cd43b73..af368661 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/ExperienceNotificationService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/ExperienceNotificationService.yaml
@@ -61,7 +61,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - Social
- name: ExperienceNotificationService:PromptOptIn
summary: |
Shows an in-experience prompt for the local player to enable
@@ -95,7 +97,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
+ - Social
events:
- name: ExperienceNotificationService.OptInPromptClosed
summary: |
@@ -117,5 +121,7 @@ events:
tags: []
deprecation_message: ''
security: None
- capabilities: []
+ capabilities:
+ - Players
+ - Social
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/Explosion.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/Explosion.yaml
index 14843596..342f90eb 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/Explosion.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/Explosion.yaml
@@ -97,7 +97,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - AvatarBehavior
- name: Explosion.BlastRadius
summary: |
This property determines the radius of the `Class.Explosion`, in studs.
@@ -133,7 +134,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - AvatarBehavior
- name: Explosion.DestroyJointRadiusPercent
summary: |
Used to set the proportion of the `Class.Explosion.BlastRadius`, between 0
@@ -168,7 +170,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - AvatarBehavior
- name: Explosion.ExplosionType
summary: |
This property determines how the `Class.Explosion` will interact with
@@ -201,7 +204,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - AvatarBehavior
- name: Explosion.LocalTransparencyModifier
summary: ''
description: ''
@@ -219,7 +223,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - AvatarBehavior
- name: Explosion.Position
summary: |
This property is the position of the center of the `Class.Explosion`. It
@@ -256,7 +261,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - AvatarBehavior
- name: Explosion.TimeScale
summary: |
Value between 0 and 1 that controls the speed of the particle effect.
@@ -276,7 +282,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - AvatarBehavior
- name: Explosion.Visible
summary: |
This property determines whether or not the visual effect of an
@@ -305,7 +312,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - AvatarBehavior
methods: []
events:
- name: Explosion.Hit
@@ -349,5 +357,6 @@ events:
tags: []
deprecation_message: ''
security: None
- capabilities: []
+ capabilities:
+ - AvatarBehavior
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/ForceField.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/ForceField.yaml
index 68c589b0..c0d8a93e 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/ForceField.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/ForceField.yaml
@@ -71,7 +71,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - AvatarBehavior
methods: []
events: []
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/GuiService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/GuiService.yaml
index 037b505a..0ca4e082 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/GuiService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/GuiService.yaml
@@ -44,7 +44,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - UI
+ - Input
- name: GuiService.CoreGuiNavigationEnabled
summary: |
Toggles whether or not objects in the `Class.CoreGui` can be navigated
@@ -66,7 +68,9 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - UI
+ - Input
- name: GuiService.GuiNavigationEnabled
summary: |
Used to enable and disable the default controller GUI navigation.
@@ -84,7 +88,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - UI
+ - Input
- name: GuiService.IsModalDialog
summary: |
Indicates whether a modal dialog is visible.
@@ -107,7 +113,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService.IsWindows
summary: |
Indicates whether the user is playing on a computer running Windows.
@@ -130,7 +137,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService.MenuIsOpen
summary: |
Returns `true` if any menu of `Class.CoreGui` is open.
@@ -150,7 +158,8 @@ properties:
serialization:
can_load: false
can_save: true
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService.PreferredTextSize
summary: |
Gets the player's preferred text size as an `Enum.PreferredTextSize`
@@ -211,7 +220,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService.PreferredTransparency
summary: |
Gets the player's preferred transparency as a number between `0` and `1`.
@@ -247,7 +257,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService.ReducedMotionEnabled
summary: |
Returns `true` if the player has enabled reduced motion.
@@ -273,7 +284,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService.SelectedObject
summary: |
Sets the `Class.GuiObject` currently being focused on by the GUI
@@ -299,7 +311,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - UI
+ - Input
- name: GuiService.TopbarInset
summary: |
Used to determine the absolute size and position of unobstructed area
@@ -330,7 +344,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService.TouchControlsEnabled
summary: |
Used to enable and disable touch controls and touch control display UI.
@@ -350,7 +365,9 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - UI
+ - Input
- name: GuiService.ViewportDisplaySize
summary: |
Read-only property which represents the physical rendering size of the
@@ -375,7 +392,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - UI
methods:
- name: GuiService:AddSelectionParent
summary: |
@@ -406,7 +424,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:AddSelectionTuple
summary: |
**AddSelectionTuple** works similarly to
@@ -449,7 +468,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:CloseInspectMenu
summary: |
Closes the avatar inspection menu, if open.
@@ -476,7 +496,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:DismissNotification
summary: ''
description: ''
@@ -493,7 +514,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:GetEmotesMenuOpen
summary: |
Checks if the player emotes menu is open.
@@ -511,7 +533,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:GetGameplayPausedNotificationEnabled
summary: |
Returns whether or not the `Class.Player.GameplayPaused` notification has
@@ -534,7 +557,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:GetGuiInset
summary: |
Returns two `Datatype.Vector2` values representing the inset of user GUIs
@@ -559,7 +583,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:GetInspectMenuEnabled
summary: |
Returns whether the avatar inspection menu is enabled.
@@ -579,7 +604,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:InspectPlayerFromHumanoidDescription
summary: |
Allows the avatar inspection menu to appear showing the assets listed in a
@@ -615,7 +641,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Avatar
- name: GuiService:InspectPlayerFromUserId
summary: |
Allows the avatar inspection menu to appear showing the user that has the
@@ -645,7 +673,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Avatar
- name: GuiService:IsTenFootInterface
summary: |
Returns `true` if the client is using the ten foot interface, a special
@@ -666,7 +696,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:RemoveSelectionGroup
summary: |
Removes a group that was created with
@@ -690,7 +721,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:Select
summary: |
Sets `Class.GuiService.SelectedObject` to a child of a provided instance
@@ -716,7 +748,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:SendNotification
summary: ''
description: ''
@@ -733,7 +766,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:SetEmotesMenuOpen
summary: |
Opens or closes the player emotes menu.
@@ -752,7 +786,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:SetGameplayPausedNotificationEnabled
summary: |
Lets you disable the built-in notification when a player's gameplay is
@@ -781,7 +816,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService:SetInspectMenuEnabled
summary: |
Allows you to enable or disable the avatar inspection menu.
@@ -803,7 +839,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
events:
- name: GuiService.MenuClosed
summary: |
@@ -815,7 +852,8 @@ events:
tags: []
deprecation_message: ''
security: None
- capabilities: []
+ capabilities:
+ - UI
- name: GuiService.MenuOpened
summary: |
Fires when the user **opens** the Roblox `Class.CoreGui` escape menu.
@@ -826,5 +864,6 @@ events:
tags: []
deprecation_message: ''
security: None
- capabilities: []
+ capabilities:
+ - UI
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/Humanoid.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/Humanoid.yaml
index a2698510..09191f8d 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/Humanoid.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/Humanoid.yaml
@@ -85,6 +85,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.AutomaticScalingEnabled
summary: |
When Enabled, AutomaticScalingEnabled causes the size of the character to
@@ -165,6 +166,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.BreakJointsOnDeath
summary: |
Determines whether the humanoid's joints break when in the
@@ -186,6 +188,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.CameraOffset
summary: |
An offset applied to the Camera's subject position when its CameraSubject
@@ -214,6 +217,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.CollisionType
summary: |
Selects the `Enum.HumanoidCollisionType` for R15 and Rthro non-player
@@ -360,6 +364,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.FloorMaterial
summary: |
Describes the `Enum.Material` that the `Class.Humanoid` is currently
@@ -412,6 +417,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.Health
summary: |
Describes the current health of the Humanoid on the range [0,
@@ -469,6 +475,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.HealthDisplayDistance
summary: |
Used in conjunction with the
@@ -600,6 +607,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.JumpHeight
summary: |
Provides control over the height that the `Class.Humanoid` jumps to.
@@ -631,6 +639,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.JumpPower
summary: |
Determines how much upwards force is applied to the `Class.Humanoid` when
@@ -666,6 +675,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.LeftLeg
summary: |
A reference to the humanoid's _Left Leg_ part.
@@ -717,6 +727,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.maxHealth
summary: ''
description: ''
@@ -767,6 +778,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.MoveDirection
summary: |
Describes the direction that the `Class.Humanoid` is walking in.
@@ -794,6 +806,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.NameDisplayDistance
summary: |
Used in conjunction with the `Class.Humanoid.DisplayDistanceType` property
@@ -878,6 +891,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.RequiresNeck
summary: |
Allows developers to disable the behavior where a player
@@ -901,6 +915,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.RightLeg
summary: |
A reference to the humanoid's _Right Leg_ part.
@@ -984,6 +999,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.SeatPart
summary: |
A reference to the seat that a `Class.Humanoid` is currently sitting in,
@@ -1014,6 +1030,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.Sit
summary: |
Describes whether the `Class.Humanoid` is currently sitting.
@@ -1045,6 +1062,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.TargetPoint
summary: |
Describes the 3D position where the `Class.Player` controlling the
@@ -1076,6 +1094,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.Torso
summary: |
A reference to a humanoid's root driving part.
@@ -1128,6 +1147,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.WalkSpeed
summary: |
Describes the humanoid's maximum movement speed in studs per second.
@@ -1168,6 +1188,7 @@ properties:
can_save: true
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.WalkToPart
summary: |
A reference to a part whose position is trying to be reached by a
@@ -1204,6 +1225,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.WalkToPoint
summary: |
The position that a humanoid is trying to reach, after a call to
@@ -1235,6 +1257,7 @@ properties:
can_save: false
capabilities:
- Avatar
+ - AvatarBehavior
methods:
- name: Humanoid:AddAccessory
summary: |
@@ -1522,6 +1545,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:ChangeState
summary: |
Sets the `Class.Humanoid` to enter the given `Enum.HumanoidStateType`.
@@ -1572,6 +1596,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:EquipTool
summary: |
Makes the `Class.Humanoid` equip the given `Class.Tool`.
@@ -1602,6 +1627,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:GetAccessories
summary: |
Returns an array of `Class.Accessory` objects that the humanoid's parent
@@ -1701,6 +1727,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:GetLimb
summary: |
Returns the `Enum.Limb` enum that is associated with the given
@@ -1740,6 +1767,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:GetMoveVelocity
summary: ''
description: ''
@@ -1754,6 +1782,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:GetPlayingAnimationTracks
summary: |
Returns an array of all `Class.AnimationTrack|AnimationTracks` that are
@@ -1805,6 +1834,7 @@ methods:
thread_safety: Safe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:GetStateEnabled
summary: |
Returns whether a `Enum.HumanoidStateType` is enabled for the
@@ -1844,6 +1874,7 @@ methods:
thread_safety: Safe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:GetStatuses
summary: |
Returns a table of the Humanoid's statuses, and custom statuses.
@@ -2016,6 +2047,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:MoveTo
summary: |
Causes the `Class.Humanoid` to attempt to walk to the given location by
@@ -2076,6 +2108,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:PlayEmoteAsync
summary: |
Plays emotes and returns if was successfully ran.
@@ -2101,6 +2134,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:PlayEmote
summary: |
Plays emotes and returns if was successfully ran.
@@ -2126,6 +2160,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:RemoveAccessories
summary: |
Removes all `Class.Accessory` objects worn by the humanoid's parent.
@@ -2276,6 +2311,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:TakeDamage
summary: |
Lowers the `Class.Humanoid.Health` of the `Class.Humanoid` by the given
@@ -2323,6 +2359,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid:takeDamage
summary: ''
description: ''
@@ -2372,6 +2409,7 @@ methods:
thread_safety: Unsafe
capabilities:
- Avatar
+ - AvatarBehavior
events:
- name: Humanoid.AnimationPlayed
summary: |
@@ -2458,6 +2496,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.CustomStatusAdded
summary: |
Fired when a status is added to the Humanoid.
@@ -2520,6 +2559,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.FallingDown
summary: |
Fires when the `Class.Humanoid` enters or leaves the `FallingDown`
@@ -2545,6 +2585,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.FreeFalling
summary: |
Fires when the `Class.Humanoid` enters or leaves the `Freefall`
@@ -2574,6 +2615,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.GettingUp
summary: |
Fires when the `Class.Humanoid` enters or leaves the `GettingUp`
@@ -2605,6 +2647,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.HealthChanged
summary: |
Fires when the `Class.Humanoid.Health` changes (or when the
@@ -2631,6 +2674,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.Jumping
summary: |
Fires when the `Class.Humanoid` enters and leaves the `Jumping`
@@ -2660,6 +2704,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.MoveToFinished
summary: |
Fires when the `Class.Humanoid` finishes walking to a goal declared by
@@ -2693,6 +2738,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.PlatformStanding
summary: |
Fires when the `Class.Humanoid` enters or leaves the `PlatformStanding`
@@ -2724,6 +2770,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.Ragdoll
summary: |
Fires when the `Class.Humanoid` enters or leaves the `Ragdoll`
@@ -2755,6 +2802,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.Running
summary: |
Fires when the speed at which a `Class.Humanoid` is running changes.
@@ -2787,6 +2835,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.Seated
summary: |
Fired when a `Class.Humanoid` either sits in a `Class.Seat` or
@@ -2828,6 +2877,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.StateChanged
summary: |
Fires when the state of the `Class.Humanoid` is changed.
@@ -2865,6 +2915,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.StateEnabledChanged
summary: |
Fires when `Class.Humanoid:SetStateEnabled()` is called on the
@@ -2901,6 +2952,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.StatusAdded
summary: |
Fired when a status is added to the Humanoid.
@@ -2977,6 +3029,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.Swimming
summary: |
Fires when the speed at which a `Class.Humanoid` is swimming in
@@ -3011,6 +3064,7 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
- name: Humanoid.Touched
summary: |
Fires when one of the humanoid's limbs come in contact with another
@@ -3063,4 +3117,5 @@ events:
security: None
capabilities:
- Avatar
+ - AvatarBehavior
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/InputBinding.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/InputBinding.yaml
index c866ebf1..0309835b 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/InputBinding.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/InputBinding.yaml
@@ -5,8 +5,9 @@
name: InputBinding
type: class
memory_category: Instances
-summary: Defines which hardware binding should trigger the parent `Class.InputAction`.
-description: |-
+summary: |
+ Defines which hardware binding should trigger the parent `Class.InputAction`.
+description: |
An `InputBinding` defines which hardware binding should trigger the parent
`Class.InputAction`, for example a key press, gamepad button, or tap on a
touch‑enabled device. There can be multiple `InputBinding` instances parented
@@ -19,10 +20,10 @@ tags: []
deprecation_message: ''
properties:
- name: InputBinding.Backward
- summary: |-
+ summary: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally
"backward" inputs to the parent `Class.InputAction`.
- description: |-
+ description: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally
"backward" inputs to `Class.InputAction:GetState()|GetState()` and the
`Class.InputAction.StateChanged|StateChanged` event of the parent
@@ -45,10 +46,10 @@ properties:
capabilities:
- Input
- name: InputBinding.Down
- summary: |-
+ summary: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally "down"
inputs to the parent `Class.InputAction`.
- description: |-
+ description: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally "down"
inputs to `Class.InputAction:GetState()|GetState()` and the
`Class.InputAction.StateChanged|StateChanged` event of the parent
@@ -85,10 +86,10 @@ properties:
capabilities:
- Input
- name: InputBinding.Forward
- summary: |-
+ summary: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally
"forward" inputs to the parent `Class.InputAction`.
- description: |-
+ description: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally
"forward" inputs to `Class.InputAction:GetState()|GetState()` and the
`Class.InputAction.StateChanged|StateChanged` event of the parent
@@ -111,10 +112,10 @@ properties:
capabilities:
- Input
- name: InputBinding.KeyCode
- summary: |-
+ summary: |
Specifies the `Enum.KeyCode` which triggers the parent
`Class.InputAction`.
- description: |-
+ description: |
Specifies the `Enum.KeyCode` which triggers the parent
`Class.InputAction`. The code type should match the input action's
`Class.InputAction.Type|Type`, for example `Enum.KeyCode.E` for an action
@@ -138,10 +139,10 @@ properties:
capabilities:
- Input
- name: InputBinding.Left
- summary: |-
+ summary: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally "left"
inputs to the parent `Class.InputAction`.
- description: |-
+ description: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally "left"
inputs to `Class.InputAction:GetState()|GetState()` and the
`Class.InputAction.StateChanged|StateChanged` event of the parent
@@ -174,10 +175,10 @@ properties:
capabilities:
- Input
- name: InputBinding.PressedThreshold
- summary: |-
+ summary: |
Numerical value above which to fire an `Class.InputAction` with a
`Class.InputAction.Type|Type` of `Enum.InputActionType|Bool`.
- description: |-
+ description: |
Numerical value above which to fire an `Class.InputAction` with a
`Class.InputAction.Type|Type` of `Enum.InputActionType|Bool`, for example
when a gamepad trigger such as `Enum.KeyCode.ButtonL2` exceeds `0.5`
@@ -201,15 +202,21 @@ properties:
capabilities:
- Input
- name: InputBinding.PrimaryModifier
- summary: Specifies a primary `Enum.KeyCode` that must be pressed for the binding to activate.
- description: |-
- Specifies a `Enum.KeyCode` that serves as a required modifier for the binding. The `Class.InputBinding`
- will only trigger the parent `Class.InputAction` if this input is pressed prior to
- `Class.InputBinding.KeyCode|KeyCode`, `Class.InputBinding.UIButton|UIButton`, or composite directions.
+ summary: |
+ Specifies a primary `Enum.KeyCode` that must be pressed for the binding to
+ activate.
+ description: |
+ Specifies a `Enum.KeyCode` that serves as a required modifier for the
+ binding. The `Class.InputBinding` will only trigger the parent
+ `Class.InputAction` if this input is pressed prior to
+ `Class.InputBinding.KeyCode|KeyCode`,
+ `Class.InputBinding.UIButton|UIButton`, or composite directions.
- There is no ordering requirement between `Class.InputBinding.PrimaryModifier|PrimaryModifier` and
- `Class.InputBinding.SecondaryModifier|SecondaryModifier`. If both properties are set, both modifiers
- must be pressed to activate the binding, but the order in which they are pressed does not matter.
+ There is no ordering requirement between
+ `Class.InputBinding.PrimaryModifier|PrimaryModifier` and
+ `Class.InputBinding.SecondaryModifier|SecondaryModifier`. If both
+ properties are set, both modifiers must be pressed to activate the
+ binding, but the order in which they are pressed does not matter.
If set to `Enum.KeyCode.Unknown`, no primary modifier is required.
code_samples: []
@@ -227,10 +234,10 @@ properties:
capabilities:
- Input
- name: InputBinding.ReleasedThreshold
- summary: |-
+ summary: |
Numerical value below which to fire an `Class.InputAction` with a
`Class.InputAction.Type|Type` of `Enum.InputActionType|Bool`.
- description: |-
+ description: |
Numerical value below which to fire an `Class.InputAction` with a
`Class.InputAction.Type|Type` of `Enum.InputActionType|Bool`, for example
when a gamepad trigger such as `Enum.KeyCode.ButtonL2` falls below `0.5`
@@ -254,18 +261,22 @@ properties:
capabilities:
- Input
- name: InputBinding.ResponseCurve
- summary: Numerical value to configure scaling for more precise thumbstick aiming.
- description: |-
- A numerical value to control the sensitivity of gamepad thumbstick input by applying
- a quadratic response curve. Commonly used for camera control to make small thumbstick inputs more
- precise, while ramping up quickly to allow for large movements with higher magnitude input.
+ summary: |
+ Numerical value to configure scaling for more precise thumbstick aiming.
+ description: |
+ A numerical value to control the sensitivity of gamepad thumbstick input
+ by applying a quadratic response curve. Commonly used for camera control
+ to make small thumbstick inputs more precise, while ramping up quickly to
+ allow for large movements with higher magnitude input.
- Ranges between `1` to `10`, with higher values providing a more intense curve.
- Default is `1`, at which input is returned exactly as received.
+ Ranges between `1` to `10`, with higher values providing a more intense
+ curve. Default is `1`, at which input is returned exactly as received.
Only applicable when the parent action's `Class.InputAction.Type|Type` is
- `Enum.InputActionType|Direction2D` and the `Class.InputBinding.KeyCode|KeyCode`
- is `Enum.KeyCode.Thumbstick1|Thumbstick1` or `Enum.KeyCode.Thumbstick2|Thumbstick2`.
+ `Enum.InputActionType|Direction2D` and the
+ `Class.InputBinding.KeyCode|KeyCode` is
+ `Enum.KeyCode.Thumbstick1|Thumbstick1` or
+ `Enum.KeyCode.Thumbstick2|Thumbstick2`.
code_samples: []
type: float
tags: []
@@ -281,10 +292,10 @@ properties:
capabilities:
- Input
- name: InputBinding.Right
- summary: |-
+ summary: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally
"right" inputs to the parent `Class.InputAction`.
- description: |-
+ description: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally
"right" inputs to `Class.InputAction:GetState()|GetState()` and the
`Class.InputAction.StateChanged|StateChanged` event of the parent
@@ -317,10 +328,10 @@ properties:
capabilities:
- Input
- name: InputBinding.Scale
- summary: |-
+ summary: |
Amount by which to linearly scale the values of a directional
`Class.InputAction`.
- description: |-
+ description: |
Amount by which to linearly scale the values of an `Class.InputAction`
with `Class.InputAction.Type|Type` of `Enum.InputActionType|Direction1D`,
`Enum.InputActionType|Direction2D`, or `Enum.InputActionType|Direction3D`.
@@ -339,15 +350,21 @@ properties:
capabilities:
- Input
- name: InputBinding.SecondaryModifier
- summary: Specifies a secondary `Enum.KeyCode` that must be pressed for the binding to activate.
- description: |-
- Specifies a `Enum.KeyCode` that serves as a required modifier for the binding. The `Class.InputBinding`
- will only trigger the parent `Class.InputAction` if this input is pressed prior to
- `Class.InputBinding.KeyCode|KeyCode`, `Class.InputBinding.UIButton|UIButton`, or composite directions.
+ summary: |
+ Specifies a secondary `Enum.KeyCode` that must be pressed for the binding
+ to activate.
+ description: |
+ Specifies a `Enum.KeyCode` that serves as a required modifier for the
+ binding. The `Class.InputBinding` will only trigger the parent
+ `Class.InputAction` if this input is pressed prior to
+ `Class.InputBinding.KeyCode|KeyCode`,
+ `Class.InputBinding.UIButton|UIButton`, or composite directions.
- There is no ordering requirement between `Class.InputBinding.PrimaryModifier|PrimaryModifier` and
- `Class.InputBinding.SecondaryModifier|SecondaryModifier`. If both properties are set, both modifiers
- must be pressed to activate the binding, but the order in which they are pressed does not matter.
+ There is no ordering requirement between
+ `Class.InputBinding.PrimaryModifier|PrimaryModifier` and
+ `Class.InputBinding.SecondaryModifier|SecondaryModifier`. If both
+ properties are set, both modifiers must be pressed to activate the
+ binding, but the order in which they are pressed does not matter.
If set to `Enum.KeyCode.Unknown`, no secondary modifier is required.
code_samples: []
@@ -365,8 +382,10 @@ properties:
capabilities:
- Input
- name: InputBinding.UIButton
- summary: Connects a `Class.GuiButton` to a boolean action.
- description: '`Class.GuiButton` to connect to a boolean action.'
+ summary: |
+ Connects a `Class.GuiButton` to a boolean action.
+ description: |
+ `Class.GuiButton` to connect to a boolean action.
code_samples: []
type: GuiButton
tags: []
@@ -382,10 +401,10 @@ properties:
capabilities:
- Input
- name: InputBinding.Up
- summary: |-
+ summary: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally "up"
inputs to the parent `Class.InputAction`.
- description: |-
+ description: |
Specifies an alternate `Enum.KeyCode` for dispatching directionally "up"
inputs to `Class.InputAction:GetState()|GetState()` and the
`Class.InputAction.StateChanged|StateChanged` event of the parent
@@ -422,10 +441,10 @@ properties:
capabilities:
- Input
- name: InputBinding.Vector2Scale
- summary: |-
+ summary: |
Amount by which to linearly scale the values of a two-directional
`Class.InputAction`.
- description: |-
+ description: |
Amount by which to linearly scale the values of an `Class.InputAction`
with `Class.InputAction.Type|Type` of `Enum.InputActionType|Direction2D`.
code_samples: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/MaterialService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/MaterialService.yaml
index 1728aada..44be921b 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/MaterialService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/MaterialService.yaml
@@ -64,7 +64,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.BasaltName
summary: |
Specify `Class.MaterialVariant` name to override built-in Basalt.
@@ -85,7 +86,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.BrickName
summary: |
Specify `Class.MaterialVariant` name to override built-in Brick.
@@ -106,7 +108,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.CardboardName
summary: ''
description: ''
@@ -123,7 +126,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.CarpetName
summary: ''
description: ''
@@ -140,7 +144,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.CeramicTilesName
summary: ''
description: ''
@@ -157,7 +162,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.ClayRoofTilesName
summary: ''
description: ''
@@ -174,7 +180,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.CobblestoneName
summary: |
Specify `Class.MaterialVariant` name to override built-in Cobblestone.
@@ -195,7 +202,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.ConcreteName
summary: |
Specify `Class.MaterialVariant` name to override built-in Concrete.
@@ -216,7 +224,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.CorrodedMetalName
summary: |
Specify `Class.MaterialVariant` name to override built-in CorrodedMetal.
@@ -237,7 +246,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.CrackedLavaName
summary: |
Specify `Class.MaterialVariant` name to override built-in CrackedLava.
@@ -258,7 +268,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.DiamondPlateName
summary: |
Specify `Class.MaterialVariant` name to override built-in DiamondPlate.
@@ -279,7 +290,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.FabricName
summary: |
Specify `Class.MaterialVariant` name to override built-in Fabric.
@@ -300,7 +312,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.FoilName
summary: |
Specify `Class.MaterialVariant` name to override built-in Foil.
@@ -321,7 +334,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.GlacierName
summary: |
Specify `Class.MaterialVariant` name to override built-in Glacier.
@@ -342,7 +356,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.GraniteName
summary: |
Specify `Class.MaterialVariant` name to override built-in Granite.
@@ -363,7 +378,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.GrassName
summary: |
Specify `Class.MaterialVariant` name to override built-in Grass.
@@ -384,7 +400,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.GroundName
summary: |
Specify `Class.MaterialVariant` name to override built-in Ground.
@@ -405,7 +422,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.IceName
summary: |
Specify `Class.MaterialVariant` name to override built-in Ice.
@@ -426,7 +444,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.LeafyGrassName
summary: |
Specify `Class.MaterialVariant` name to override built-in LeafyGrass.
@@ -447,7 +466,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.LeatherName
summary: ''
description: ''
@@ -464,7 +484,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.LimestoneName
summary: |
Specify `Class.MaterialVariant` name to override built-in Limestone.
@@ -485,7 +506,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.MarbleName
summary: |
Specify `Class.MaterialVariant` name to override built-in Marble.
@@ -506,7 +528,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.MetalName
summary: |
Specify `Class.MaterialVariant` name to override built-in Metal.
@@ -527,7 +550,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.MudName
summary: |
Specify `Class.MaterialVariant` name to override built-in Mud.
@@ -548,7 +572,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.PavementName
summary: |
Specify `Class.MaterialVariant` name to override built-in Pavement.
@@ -569,7 +594,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.PebbleName
summary: |
Specify `Class.MaterialVariant` name to override built-in Pebble.
@@ -590,7 +616,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.PlasterName
summary: ''
description: ''
@@ -607,7 +634,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.PlasticName
summary: |
Specify `Class.MaterialVariant` name to override built-in Plastic.
@@ -628,7 +656,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.RockName
summary: |
Specify `Class.MaterialVariant` name to override built-in Rock.
@@ -649,7 +678,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.RoofShinglesName
summary: ''
description: ''
@@ -666,7 +696,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.RubberName
summary: ''
description: ''
@@ -683,7 +714,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.SaltName
summary: |
Specify `Class.MaterialVariant` name to override built-in Salt.
@@ -704,7 +736,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.SandName
summary: |
Specify `Class.MaterialVariant` name to override built-in Sand.
@@ -725,7 +758,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.SandstoneName
summary: |
Specify `Class.MaterialVariant` name to override built-in Sandstone.
@@ -746,7 +780,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.SlateName
summary: |
Specify `Class.MaterialVariant` name to override built-in Slate.
@@ -767,7 +802,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.SmoothPlasticName
summary: |
Specify `Class.MaterialVariant` name to override built-in SmoothPlastic.
@@ -788,7 +824,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.SnowName
summary: |
Specify `Class.MaterialVariant` name to override built-in Snow.
@@ -809,7 +846,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.Use2022Materials
summary: |
Switch built-in material pack.
@@ -829,7 +867,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.WoodName
summary: |
Specify `Class.MaterialVariant` name to override built-in Wood.
@@ -850,7 +889,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService.WoodPlanksName
summary: |
Specify `Class.MaterialVariant` name to override built-in WoodPlanks.
@@ -871,7 +911,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
methods:
- name: MaterialService:GetBaseMaterialOverride
summary: |
@@ -893,7 +934,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService:GetMaterialVariant
summary: |
Get the effective MaterialVariant reference given a name and Material.
@@ -921,7 +963,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialService:SetBaseMaterialOverride
summary: |
Set a `Class.MaterialVariant` name that overrides a built-in material.
@@ -946,6 +989,7 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Material
events: []
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/MaterialVariant.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/MaterialVariant.yaml
index d99bd65b..7742e26c 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/MaterialVariant.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/MaterialVariant.yaml
@@ -56,7 +56,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.BaseMaterial
summary: |
Category Material this variant belongs to.
@@ -74,7 +75,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.ColorMap
summary: |
Determines the color of the surface.
@@ -93,7 +95,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.ColorMapContent
summary: |
Determines the color of the surface. Only supports asset URIs as textures.
@@ -112,7 +115,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.CustomPhysicalProperties
summary: ''
description: ''
@@ -128,7 +132,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.EmissiveMaskContent
summary: |
Determines the emissivity across the surface.
@@ -153,7 +158,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.EmissiveStrength
summary: |
Determines the strength of emissive contribution.
@@ -179,7 +185,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.EmissiveTint
summary: |
Determines the tinting color for emissive contribution.
@@ -197,7 +204,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.MaterialPattern
summary: |
Determines texture tiling method.
@@ -215,7 +223,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.MetalnessMap
summary: |
Determines which parts of the surface are metal and are non-metal.
@@ -248,7 +257,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.MetalnessMapContent
summary: |
Determines which parts of the surface are metal and are non-metal. Only
@@ -282,7 +292,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.NormalMap
summary: |
Modifies the lighting of the surface by adding bumps, dents, cracks, and
@@ -334,7 +345,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.NormalMapContent
summary: |
Modifies the lighting of the surface by adding bumps, dents, cracks, and
@@ -386,7 +398,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.RoughnessMap
summary: |
Determines the apparent roughness across the surface.
@@ -411,7 +424,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.RoughnessMapContent
summary: |
Determines the apparent roughness across the surface. Only supports asset
@@ -437,7 +451,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
- name: MaterialVariant.StudsPerTile
summary: |
Determines the scale of textures.
@@ -456,7 +471,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Material
methods: []
events: []
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/NetworkReplicator.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/NetworkReplicator.yaml
index 0907d143..c46f1147 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/NetworkReplicator.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/NetworkReplicator.yaml
@@ -37,6 +37,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Network
+ - Players
events: []
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/NetworkSettings.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/NetworkSettings.yaml
index 839b8ee0..8415e112 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/NetworkSettings.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/NetworkSettings.yaml
@@ -39,7 +39,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.FreeMemoryMBytes
summary: |
Describes how much free memory is available, in MiBs.
@@ -61,7 +62,8 @@ properties:
serialization:
can_load: false
can_save: false
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.HttpProxyEnabled
summary: ''
description: ''
@@ -77,7 +79,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.HttpProxyURL
summary: ''
description: ''
@@ -93,7 +96,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.IncomingReplicationLag
summary: |
Simulates additional network latency in the network receiving path.
@@ -112,7 +116,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.PrintJoinSizeBreakdown
summary: |
Prints diagnostic information about data sent on connect.
@@ -134,7 +139,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.PrintPhysicsErrors
summary: |
Whether debug messages will be printed to the output pertaining to physics
@@ -172,7 +178,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.PrintStreamInstanceQuota
summary: |
Whether debug information is printed to the output regarding the
@@ -221,7 +228,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.RandomizeJoinInstanceOrder
summary: |
Special facility to help catch bugs related to how your experience loads.
@@ -242,7 +250,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.RenderStreamedRegions
summary: |
Whether regions of space that are being streamed to the client will be
@@ -263,7 +272,8 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Network
- name: NetworkSettings.ShowActiveAnimationAsset
summary: |
Whether a label will be shown above each player character's head, showing
@@ -284,7 +294,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Network
+ - Animation
methods: []
events: []
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/PlayerScripts.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/PlayerScripts.yaml
index 1bb5dabc..b13aa37c 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/PlayerScripts.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/PlayerScripts.yaml
@@ -45,7 +45,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
- name: PlayerScripts:ClearComputerMovementModes
summary: |
Unregisters all ComputerMovementMode enums from the experience's settings
@@ -62,7 +63,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Input
+ - Players
- name: PlayerScripts:ClearTouchCameraMovementModes
summary: |
Unregisters all TouchCameraMovementMode enums from the experience's
@@ -79,7 +82,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
- name: PlayerScripts:ClearTouchMovementModes
summary: |
Unregisters all TouchMovementMode enums from the experience's settings
@@ -96,7 +100,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Input
+ - Players
- name: PlayerScripts:RegisterComputerCameraMovementMode
summary: |
Registers that a computer camera movement mode is available to be selected
@@ -117,7 +123,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
- name: PlayerScripts:RegisterComputerMovementMode
summary: |
Registers that a computer movement mode is available to be selected from
@@ -138,7 +145,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Input
+ - Players
- name: PlayerScripts:RegisterTouchCameraMovementMode
summary: |
Registers that a touch camera movement mode is available to be selected
@@ -159,7 +168,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Players
- name: PlayerScripts:RegisterTouchMovementMode
summary: |
Registers that a touch movement mode is available to be selected from the
@@ -180,6 +190,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Input
+ - Players
events: []
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/ProximityPrompt.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/ProximityPrompt.yaml
index 2809cc8b..2ace2489 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/ProximityPrompt.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/ProximityPrompt.yaml
@@ -91,6 +91,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.AutoLocalize
summary: |
Whether the prompt's `Class.ProximityPrompt.ActionText` and
@@ -116,6 +117,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.ClickablePrompt
summary: |
Whether the prompt can be activated by clicking/tapping on the prompt UI.
@@ -137,6 +139,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.Enabled
summary: |
Whether or not this prompt should be shown.
@@ -157,6 +160,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.Exclusivity
summary: |
Used to customize which prompts can be shown at the same time.
@@ -177,6 +181,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.GamepadKeyCode
summary: |
The gamepad button the player should press to trigger the prompt.
@@ -198,6 +203,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.HoldDuration
summary: |
The duration, in seconds, that the player must hold the button/key down to
@@ -219,6 +225,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.KeyboardKeyCode
summary: |
The key the player should press to trigger the prompt.
@@ -239,6 +246,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.MaxActivationDistance
summary: |
The maximum distance a Player's `Class.Player.Character|character` can be
@@ -261,6 +269,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.MaxIndicatorDistance
summary: ''
description: ''
@@ -278,6 +287,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.ObjectText
summary: |
An optional property that determines the object name text shown to the
@@ -299,6 +309,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.RequiresLineOfSight
summary: |
Whether the prompt is hidden if the path between the player's
@@ -326,6 +337,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.RootLocalizationTable
summary: |
A reference to a `Class.LocalizationTable` to be used to apply automated
@@ -357,6 +369,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.Style
summary: |
The style of the prompt's UI.
@@ -387,6 +400,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
- name: ProximityPrompt.UIOffset
summary: |
The pixel offset applied to the prompt's UI.
@@ -406,6 +420,7 @@ properties:
can_save: true
capabilities:
- UI
+ - Input
methods:
- name: ProximityPrompt:InputHoldBegin
summary: |
@@ -427,6 +442,7 @@ methods:
thread_safety: Unsafe
capabilities:
- UI
+ - Input
- name: ProximityPrompt:InputHoldEnd
summary: |
Fires a signal indicating that the user ended pressing the prompt GUI
@@ -445,6 +461,7 @@ methods:
thread_safety: Unsafe
capabilities:
- UI
+ - Input
events:
- name: ProximityPrompt.IndicatorHidden
summary: ''
@@ -456,6 +473,7 @@ events:
security: None
capabilities:
- UI
+ - Input
- name: ProximityPrompt.IndicatorShown
summary: ''
description: ''
@@ -466,6 +484,7 @@ events:
security: None
capabilities:
- UI
+ - Input
- name: ProximityPrompt.PromptButtonHoldBegan
summary: |
Triggered when a player begins holding down the
@@ -488,6 +507,7 @@ events:
security: None
capabilities:
- UI
+ - Input
- name: ProximityPrompt.PromptButtonHoldEnded
summary: |
Triggers when the player ends holding down the button on a prompt with a
@@ -508,6 +528,7 @@ events:
security: None
capabilities:
- UI
+ - Input
- name: ProximityPrompt.PromptHidden
summary: |
Triggers when the `Class.ProximityPrompt|prompt` becomes hidden.
@@ -521,6 +542,7 @@ events:
security: None
capabilities:
- UI
+ - Input
- name: ProximityPrompt.PromptShown
summary: |
Triggers when the `Class.ProximityPrompt|prompt` becomes visible.
@@ -539,6 +561,7 @@ events:
security: None
capabilities:
- UI
+ - Input
- name: ProximityPrompt.Triggered
summary: |
Triggered when the prompt
@@ -562,6 +585,7 @@ events:
security: None
capabilities:
- UI
+ - Input
- name: ProximityPrompt.TriggerEnded
summary: |
Triggers when `Class.ProximityPrompt.KeyboardKeyCode|key`/button is
@@ -585,4 +609,5 @@ events:
security: None
capabilities:
- UI
+ - Input
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/TeleportService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/TeleportService.yaml
index c011cf73..681ea169 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/TeleportService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/TeleportService.yaml
@@ -7,12 +7,16 @@ type: class
memory_category: Instances
summary: |
Enables transporting `Class.Player|Players` between places and servers.
+
+ For more information on how to teleport players between servers, see
+
+ [Teleport between places](../../../projects/teleport.md).
description: |
**TeleportService** is responsible for transporting `Class.Player|Players`
between different places and servers.
For more information on how to teleport players between servers, see
- [Teleporting Between Places](../../../projects/teleport.md).
+ [Teleport between places](../../../projects/teleport.md).
code_samples: []
inherits:
- Instance
@@ -45,7 +49,8 @@ properties:
serialization:
can_load: true
can_save: false
- capabilities: []
+ capabilities:
+ - Teleport
methods:
- name: TeleportService:GetArrivingTeleportGui
summary: |
@@ -86,7 +91,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Teleport
- name: TeleportService:GetLocalPlayerTeleportData
summary: |
Returns the _teleportData_ the `Class.Players.LocalPlayer` arrived into
@@ -110,7 +117,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Teleport
- name: TeleportService:GetPlayerPlaceInstanceAsync
summary: |
Returns the `Class.DataModel.PlaceId|PlaceId` and
@@ -204,7 +212,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Teleport
- name: TeleportService:GetTeleportSetting
summary: |
Retrieves a teleport setting saved using
@@ -281,7 +290,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Teleport
- name: TeleportService:PromptExperienceDetailsAsync
summary: |
Prompts a `Class.Player` with information about the specified experience.
@@ -332,7 +342,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Teleport
- name: TeleportService:ReserveServerAsync
summary: |
Returns an access code that can be used to teleport players to a reserved
@@ -400,7 +411,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Teleport
- name: TeleportService:ReserveServer
summary: |
Returns an access code that can be used to teleport players to a reserved
@@ -428,7 +440,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Teleport
- name: TeleportService:SetTeleportGui
summary: |
Sets the custom `Class.ScreenGui|teleport GUI` that will be shown to the
@@ -484,7 +497,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Teleport
- name: TeleportService:SetTeleportSetting
summary: |
Stores a value under a given key that persists across all teleportations
@@ -571,7 +586,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Teleport
- name: TeleportService:Teleport
summary: |
Teleports a `Class.Player` to the place associated with the given
@@ -616,7 +632,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Teleport
- name: TeleportService:TeleportAsync
summary: |
The all-encompassing method to teleport a player or group of players from
@@ -683,7 +701,7 @@ methods:
For more information on how to teleport players between servers and
receive user data from a teleport, see
- [Teleporting Between Places](../../../projects/teleport.md#sending-user-data-along-with-teleports).
+ [Teleport between places](../../../projects/teleport.md#sending-user-data-along-with-teleports).
code_samples: []
parameters:
- name: placeId
@@ -714,7 +732,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Teleport
- name: TeleportService:TeleportPartyAsync
summary: |
Teleports a group of `Class.Player|Players` to the same server of the
@@ -762,7 +782,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Teleport
- name: TeleportService:TeleportToPlaceInstance
summary: |
Teleports a `Class.Player` to the server instance associated with the
@@ -816,7 +838,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Teleport
- name: TeleportService:TeleportToPrivateServer
summary: |
Teleport a group of `Class.Player|Players` to a reserved server created
@@ -871,7 +895,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Teleport
- name: TeleportService:TeleportToSpawnByName
summary: |
A variant of `Class.TeleportService:Teleport()` that causes the
@@ -921,7 +947,9 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - UI
+ - Teleport
events:
- name: TeleportService.LocalPlayerArrivedFromTeleport
summary: |
@@ -996,7 +1024,8 @@ events:
tags: []
deprecation_message: ''
security: None
- capabilities: []
+ capabilities:
+ - Teleport
- name: TeleportService.TeleportInitFailed
summary: |
Fires when a teleport fails to start, leaving the player in their current
@@ -1060,7 +1089,7 @@ events:
For more information on how to teleport players between servers, see
- [Teleporting Between Places](../../../projects/teleport.md).
+ [Teleport between places](../../../projects/teleport.md).
code_samples: []
parameters:
- name: player
@@ -1092,5 +1121,6 @@ events:
tags: []
deprecation_message: ''
security: None
- capabilities: []
+ capabilities:
+ - Teleport
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/TestService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/TestService.yaml
index 291ffec9..02946364 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/TestService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/TestService.yaml
@@ -748,7 +748,7 @@ methods:
summary: ''
- name: source
type: Instance
- default:
+ default: nil
summary: ''
returns:
- type: ()
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/VoiceChatService.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/VoiceChatService.yaml
index 657efbda..264e5b21 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/VoiceChatService.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/VoiceChatService.yaml
@@ -46,7 +46,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Audio
+ - Chat
- name: VoiceChatService.EnableDefaultVoice
summary: |
Controls whether each voice-eligible player can be heard as though they
@@ -74,7 +76,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Audio
+ - Chat
- name: VoiceChatService.UseAudioApi
summary: |
Controls whether voice chat is represented and controlled by
@@ -113,7 +117,9 @@ properties:
serialization:
can_load: true
can_save: true
- capabilities: []
+ capabilities:
+ - Audio
+ - Chat
methods:
- name: VoiceChatService:GetChatGroupsAsync
summary: |
@@ -181,6 +187,7 @@ methods:
security: None
thread_safety: Unsafe
capabilities:
+ - Audio
- Chat
- name: VoiceChatService:IsVoiceEnabledForUserIdAsync
summary: |
@@ -221,6 +228,8 @@ methods:
deprecation_message: ''
security: None
thread_safety: Unsafe
- capabilities: []
+ capabilities:
+ - Audio
+ - Chat
events: []
callbacks: []
diff --git a/.cursor/rules/roblox/en-us/reference/engine/classes/Wire.yaml b/.cursor/rules/roblox/en-us/reference/engine/classes/Wire.yaml
index c39b19d5..7f1c41b5 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/classes/Wire.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/classes/Wire.yaml
@@ -57,10 +57,11 @@ properties:
`Class.Wire.SourceInstance|SourceInstance`,
`Class.Wire.TargetInstance|TargetInstance`,
`Class.Wire.SourceName|SourceName`, and `Class.Wire.TargetName|TargetName`
- properties are all assigned, the connection is valid, and the connection
- does not result in a cyclic processing graph. Cyclic processing graphs are
- invalid since they can result in infinite computation; attempting to
- create one will log an error.
+ properties are all assigned, the corresponding
+ `Class.Wire.SourceName|SourceName` and `Class.Wire.TargetName|TargetName`
+ pins exist on `Class.Wire.SourceInstance|SourceInstance` and
+ `Class.Wire.TargetInstance|TargetInstance` respectively, and the
+ connection does not result in a cyclic processing graph.
code_samples: []
type: boolean
tags:
diff --git a/.cursor/rules/roblox/en-us/reference/engine/datatypes/PhysicalProperties.yaml b/.cursor/rules/roblox/en-us/reference/engine/datatypes/PhysicalProperties.yaml
index a2252049..5e75c298 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/datatypes/PhysicalProperties.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/datatypes/PhysicalProperties.yaml
@@ -105,6 +105,41 @@ constructors:
code_samples: []
tags: []
deprecation_message: ''
+ - name: PhysicalProperties.new
+ summary: |-
+ Creates a `Datatype.PhysicalProperties` container with the specified density,
+ friction, elasticity, weight of friction, weight of elasticity, and acoustic absorption.
+ description: |-
+ Creates a `Datatype.PhysicalProperties` container with the specified density,
+ friction, elasticity, weight of friction, weight of elasticity, and acoustic absorption.
+ parameters:
+ - name: density
+ type: number
+ default:
+ summary: ''
+ - name: friction
+ type: number
+ default:
+ summary: ''
+ - name: elasticity
+ type: number
+ default:
+ summary: ''
+ - name: frictionWeight
+ type: number
+ default:
+ summary: ''
+ - name: elasticityWeight
+ type: number
+ default:
+ summary: ''
+ - name: acousticAbsorption
+ type: number
+ default:
+ summary: ''
+ code_samples: []
+ tags: []
+ deprecation_message: ''
constants: []
properties:
- name: PhysicalProperties.AcousticAbsorption
diff --git a/.cursor/rules/roblox/en-us/reference/engine/enums/AlphaMode.yaml b/.cursor/rules/roblox/en-us/reference/engine/enums/AlphaMode.yaml
index 8367be70..4664071e 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/enums/AlphaMode.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/enums/AlphaMode.yaml
@@ -20,8 +20,6 @@ items:
summary: |
Overlays the `Class.SurfaceAppearance.ColorMap|ColorMap` on top of the
underlying part color based on the map's alpha channel.
-
-
value: 0
tags: []
deprecation_message: ''
@@ -29,8 +27,6 @@ items:
summary: |
Uses the `Class.SurfaceAppearance.ColorMap|ColorMap` alpha channel to
control the transparency of the surface.
-
-
value: 1
tags: []
deprecation_message: ''
@@ -41,3 +37,11 @@ items:
value: 2
tags: []
deprecation_message: ''
+ - name: Opaque
+ summary: |
+ Ignores the `Class.SurfaceAppearance.ColorMap|ColorMap` alpha channel and
+ assumes an opacity value of 1 everywhere.
+ value: 3
+ tags:
+ - NotBrowsable
+ deprecation_message: ''
diff --git a/.cursor/rules/roblox/en-us/reference/engine/libraries/math.yaml b/.cursor/rules/roblox/en-us/reference/engine/libraries/math.yaml
index 67a82b56..41912e6a 100644
--- a/.cursor/rules/roblox/en-us/reference/engine/libraries/math.yaml
+++ b/.cursor/rules/roblox/en-us/reference/engine/libraries/math.yaml
@@ -283,6 +283,56 @@ functions:
tags: []
code_samples: []
deprecation_message: ''
+ - name: math.isfinite
+ summary: |
+ Returns true if `x` is a finite number.
+ description: |
+ Returns true if `x` is a finite number, meaning it is neither NaN nor
+ positive or negative infinity (±`Library.math.huge`).
+ parameters:
+ - name: x
+ type: number
+ default:
+ summary: ''
+ returns:
+ - type: boolean
+ summary: ''
+ tags: []
+ code_samples: []
+ deprecation_message: ''
+ - name: math.isinf
+ summary: |
+ Returns true if `x` is positive or negative infinity and false otherwise.
+ description: |
+ Returns true if `x` is positive or negative infinity
+ (±`Library.math.huge`) and false otherwise.
+ parameters:
+ - name: x
+ type: number
+ default:
+ summary: ''
+ returns:
+ - type: boolean
+ summary: ''
+ tags: []
+ code_samples: []
+ deprecation_message: ''
+ - name: math.isnan
+ summary: |
+ Returns true if `x` is not a number (NaN) and false otherwise.
+ description: |
+ Returns true if `x` is not a number (NaN) and false otherwise.
+ parameters:
+ - name: x
+ type: number
+ default:
+ summary: ''
+ returns:
+ - type: boolean
+ summary: ''
+ tags: []
+ code_samples: []
+ deprecation_message: ''
- name: math.ldexp
summary: |
Returns `x`\*`2`^`e` (`e` should be an integer).
diff --git a/.cursor/rules/roblox/en-us/scripting/attributes.md b/.cursor/rules/roblox/en-us/scripting/attributes.md
index 9e43f030..b7b823d3 100644
--- a/.cursor/rules/roblox/en-us/scripting/attributes.md
+++ b/.cursor/rules/roblox/en-us/scripting/attributes.md
@@ -13,7 +13,11 @@ Making experiences interactive often means manipulating object properties and at
Before you begin retrieving and manipulating objects, you must have an understanding of replication order.
-The Roblox Engine doesn't guarantee the order in which objects are replicated from the server to the client, which makes the `Class.Instance:WaitForChild()` method essential for accessing objects in client scripts, particularly objects in the `Class.Workspace`. Still, some aspects of the process are predictable:
+The Roblox Engine doesn't guarantee the order in which objects (and changes to objects) are replicated from the server to the client, which makes the `Class.Instance:WaitForChild()` method essential for accessing objects in client scripts, particularly objects in the `Class.Workspace`.
+
+For example, if a server script changes a property of some instance in the Workspace and then calls `Class.RemoteEvent:FireAllClients()`, the property change might replicate to the client before or after `Class.RemoteEvent.OnClientEvent` fires. Use the available methods and events to [detect changes](#detect-changes) rather than assuming a change has replicated. Changes of the same type, such as two attribute changes, generally **do** arrive in order.
+
+When clients first launch an experience, some aspects of replication and script execution are predictable:
1. The client loads the contents of `Class.ReplicatedFirst`, such as a loading screen, assets, and scripts.
1. `Class.LocalScript|LocalScripts` (and `Class.Script|Scripts` with a `Class.Script.RunContext|RunContext` of `Enum.RunContext.Client|Client`) in `ReplicatedFirst` run. These scripts can safely get objects from `ReplicatedFirst` without using `WaitForChild()`:
diff --git a/.cursor/rules/roblox/en-us/tutorials/use-case-tutorials/audio/speech-to-text.md b/.cursor/rules/roblox/en-us/tutorials/use-case-tutorials/audio/speech-to-text.md
index ae1d954e..770b2e64 100644
--- a/.cursor/rules/roblox/en-us/tutorials/use-case-tutorials/audio/speech-to-text.md
+++ b/.cursor/rules/roblox/en-us/tutorials/use-case-tutorials/audio/speech-to-text.md
@@ -11,6 +11,10 @@ Using the [Gingerbread House - Start](https://www.roblox.com/games/1348125963709
For more general guidance on adding audio to your experience, see the [Add 2D audio](./add-2D-audio.md) and [Add 3D audio](./add-3D-audio.md) tutorials.
+
+For more reliable voice detection, use [push to chat](./add-voice-chat.md#add-push-to-chat) alongside STT. This ensures players' microphones are only active while they press and hold a specific button on their device.
+
+
## Audio objects
To create STT audio, it's important to understand the audio objects that you will be working with throughout this tutorial. There are three types of audio objects for STT: