Skip to content

Commit

Permalink
update Open Source Docs from Roblox internal teams
Browse files Browse the repository at this point in the history
  • Loading branch information
rbx-open-source-docs[bot] committed Dec 11, 2024
1 parent 8d1e750 commit 2b7e9a6
Show file tree
Hide file tree
Showing 16 changed files with 1,120 additions and 31 deletions.
2 changes: 2 additions & 0 deletions content/common/navigation/engine/design.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ navigation:
path: /production/game-design/monetization-foundations
- title: Season Pass Design
path: /production/game-design/season-pass-design
- title: Starter Pack Design
path: /production/game-design/starter-pack-design
- title: Subscription Design
path: /production/game-design/subscription-design
- title: Contextual Purchases
Expand Down
7 changes: 7 additions & 0 deletions content/common/navigation/engine/resources.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,13 @@ navigation:
- heading: Code Samples
- title: Overview
path: /samples/
- heading: Feature Packages
- title: Overview
path: /resources/feature-packages/
- title: Bundles
path: /resources/feature-packages/bundles
- title: Missions
path: /resources/feature-packages/missions
- heading: Developer Modules
- title: Overview
path: /resources/modules/
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion content/en-us/production/game-design/season-pass-design.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Season Pass Design
description: Season Pass Design
description: Teaches you about best practice guidance on designing season packs.
---

<iframe width="880" height="495" src="https://www.youtube-nocookie.com/embed/k2gbQI-ggB4?controls=0" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" allowfullscreen></iframe>
Expand Down
56 changes: 56 additions & 0 deletions content/en-us/production/game-design/starter-pack-design.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
---
title: Starter Pack Design
description: Teaches you about best practice guidance on designing starter packs.
---

Starter packs are a type of item bundle offered to new players in an experience. By enticing players with useful items at a deeply discounted price, starter packs can increase [conversion](../game-design/analytics-essentials.md#monetization-metrics), a vital monetization metric that tracks the number of players spending money in a game.

According to industry benchmarks, games that implement a starter pack may see an **increase in revenue of 2-10% on average**. However, the revenue impact could be even higher, depending on how well a game monetizes already and the details of its starter pack's implementation.

The tips below are based on industry best practices and the Developer Excellence team's experience. Feel free to follow our suggestions, or design the starter pack that best suits your own game.

<Alert severity="info">
For out-of-the-box functionality to sell collections of items to players at a discount, see the [Bundles Feature Package](../../resources/feature-packages/bundles.md).
</Alert>

## Availability

Because the starter pack is a monetization feature, it's recommended to make the pack available as soon as new players spawn for the first time. Gating access to the pack behind completion of a tutorial or first match, time spent in the game, or other restrictions, unnecessarily reduces the number of players who will see and ultimately purchase it.

Because they are priced at a significant discount, starter packs are single-time purchases; after a player purchases the bundle, it is no longer available to them. Players who spend once are more likely to spend again, though, which is why conversion is so important for a game's monetization.

In addition to being single-time purchases, starter packs are often offered to players for a limited time – from minutes or hours to several days – after which the pack is no longer available. The purpose of the timer is twofold: it creates additional incentive for players to make the purchase, and it ensures that the bundle doesn't outlive its usefulness.

Starter packs are designed to help new players jumpstart their experience, but they do not necessarily remain relevant past a certain point of progression; for example, 500 coins might be a significant amount of currency to a Level 1 player, but a trivial amount to a Level 10 player.

The [Bundles Feature Package](../../resources/feature-packages/bundles.md) allows you to define the timer that's best for your game. In general, it is preferable to give players time to make the decision to purchase rather than aggressively limiting its availability; we recommend between 24 hours and 3 days for most experiences.

## Surfacing

Surfacing refers to the discoverability of features in a game, or how easily players can find and access them. Some common and effective ways to surface a starter pack include:

- A dedicated button on the HUD that also displays the countdown timer, visible throughout the duration of the bundle's availability.
- Prominent featuring of the starter pack in the store, with the timer and discount clearly communicated.
- A popup modal dialog advertising the bundle. Some players feel that popups are aggressive, however, so use sparingly. Potential popup opportunities include when the player spawns into the game the last day the offer is available to them, when they level up, or when they lose a match in which the starter pack's items might have been helpful.

## Content

The content of each starter pack is different, depending on the items available in an experience. In general, they should be items that enhance a new player's experience by giving them a head start in the game. Common items include:

- In-game currency
- Resources
- Experience (XP) or other form of progress boost
- Powerups
- Exclusive cosmetic items like avatar clothing or auras/trails that can only be obtained in the starter pack

Try to choose 2-5 items that help players jump into the fun quickly and allow them to feel smart and special because they made the purchase.

## Pricing

The starter pack should be one of the best offers in the game, with **outsized and obvious value** to catch players' attention. Common price points include 99 R, 199 R, and 299 R – but anything less than 399 R ($5) would be a reasonable price targeting new players. The amount will depend on the contents and quantity of items in your bundle.

Whatever price you choose, **we recommend a discount of around 90%** to make value abundantly clear. For items like XP that aren't directly monetized, consider how much time it takes players to earn them and work backward to assign a value.

Beyond your starter pack, make sure that your game has sufficient **spend depth**, or a variety of purchasable content and price points, to appeal to spenders of all levels. Along with frequent content updates, this will help encourage any new payers converted by the starter pack to continue spending in your game. You can use the [Bundles Package](../../resources/feature-packages/bundles.md) to create item offers for this purpose, from permanent content packs to limited-time event bundles.

For more information on monetizing your experience, check out [Monetization Foundation](monetization-foundations.md).
56 changes: 28 additions & 28 deletions content/en-us/reference/cloud/cloud.docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
}
}
},
"/cloud/v2/creator-store-products/{creator-store-product_id}": {
"/cloud/v2/creator-store-products/{creator_store_product_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -295,7 +295,7 @@
}
}
},
"/cloud/v2/groups/{group_id}/join-requests/{join-request_id}:accept": {
"/cloud/v2/groups/{group_id}/join-requests/{join_request_id}:accept": {
"post": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -354,7 +354,7 @@
}
}
},
"/cloud/v2/groups/{group_id}/join-requests/{join-request_id}:decline": {
"/cloud/v2/groups/{group_id}/join-requests/{join_request_id}:decline": {
"post": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -901,7 +901,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/data-stores/{data-store_id}/entries": {
"/cloud/v2/universes/{universe_id}/data-stores/{data_store_id}/entries": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -1073,7 +1073,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/data-stores/{data-store_id}/entries/{entry_id}": {
"/cloud/v2/universes/{universe_id}/data-stores/{data_store_id}/entries/{entry_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -1274,7 +1274,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/data-stores/{data-store_id}/entries/{entry_id}:increment": {
"/cloud/v2/universes/{universe_id}/data-stores/{data_store_id}/entries/{entry_id}:increment": {
"post": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -1349,7 +1349,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/data-stores/{data-store_id}/entries/{entry_id}:listRevisions": {
"/cloud/v2/universes/{universe_id}/data-stores/{data_store_id}/entries/{entry_id}:listRevisions": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -1444,7 +1444,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/data-stores/{data-store_id}/scopes/{scope_id}/entries": {
"/cloud/v2/universes/{universe_id}/data-stores/{data_store_id}/scopes/{scope_id}/entries": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -1634,7 +1634,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/data-stores/{data-store_id}/scopes/{scope_id}/entries/{entry_id}": {
"/cloud/v2/universes/{universe_id}/data-stores/{data_store_id}/scopes/{scope_id}/entries/{entry_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -1862,7 +1862,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/data-stores/{data-store_id}/scopes/{scope_id}/entries/{entry_id}:increment": {
"/cloud/v2/universes/{universe_id}/data-stores/{data_store_id}/scopes/{scope_id}/entries/{entry_id}:increment": {
"post": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -1946,7 +1946,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/data-stores/{data-store_id}/scopes/{scope_id}/entries/{entry_id}:listRevisions": {
"/cloud/v2/universes/{universe_id}/data-stores/{data_store_id}/scopes/{scope_id}/entries/{entry_id}:listRevisions": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -2313,7 +2313,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/memory-store/sorted-maps/{sorted-map_id}/items": {
"/cloud/v2/universes/{universe_id}/memory-store/sorted-maps/{sorted_map_id}/items": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -2484,7 +2484,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/memory-store/sorted-maps/{sorted-map_id}/items/{item_id}": {
"/cloud/v2/universes/{universe_id}/memory-store/sorted-maps/{sorted_map_id}/items/{item_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -2749,7 +2749,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/ordered-data-stores/{ordered-data-store_id}/scopes/{scope_id}/entries": {
"/cloud/v2/universes/{universe_id}/ordered-data-stores/{ordered_data_store_id}/scopes/{scope_id}/entries": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -2938,7 +2938,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/ordered-data-stores/{ordered-data-store_id}/scopes/{scope_id}/entries/{entry_id}": {
"/cloud/v2/universes/{universe_id}/ordered-data-stores/{ordered_data_store_id}/scopes/{scope_id}/entries/{entry_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -3166,7 +3166,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/ordered-data-stores/{ordered-data-store_id}/scopes/{scope_id}/entries/{entry_id}:increment": {
"/cloud/v2/universes/{universe_id}/ordered-data-stores/{ordered_data_store_id}/scopes/{scope_id}/entries/{entry_id}:increment": {
"post": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -3695,7 +3695,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/places/{place_id}/luau-execution-session-tasks/{luau-execution-session-task_id}/logs": {
"/cloud/v2/universes/{universe_id}/places/{place_id}/luau-execution-session-tasks/{luau_execution_session_task_id}/logs": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -3783,7 +3783,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/places/{place_id}/luau-execution-sessions/{luau-execution-session_id}/tasks/{task_id}": {
"/cloud/v2/universes/{universe_id}/places/{place_id}/luau-execution-sessions/{luau_execution_session_id}/tasks/{task_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -3872,7 +3872,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/places/{place_id}/luau-execution-sessions/{luau-execution-session_id}/tasks/{task_id}/logs": {
"/cloud/v2/universes/{universe_id}/places/{place_id}/luau-execution-sessions/{luau_execution_session_id}/tasks/{task_id}/logs": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -4055,7 +4055,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/places/{place_id}/user-restrictions/{user-restriction_id}": {
"/cloud/v2/universes/{universe_id}/places/{place_id}/user-restrictions/{user_restriction_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -4292,7 +4292,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/places/{place_id}/versions/{version_id}/luau-execution-session-tasks/{luau-execution-session-task_id}/logs": {
"/cloud/v2/universes/{universe_id}/places/{place_id}/versions/{version_id}/luau-execution-session-tasks/{luau_execution_session_task_id}/logs": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -4389,7 +4389,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/places/{place_id}/versions/{version_id}/luau-execution-sessions/{luau-execution-session_id}/tasks/{task_id}": {
"/cloud/v2/universes/{universe_id}/places/{place_id}/versions/{version_id}/luau-execution-sessions/{luau_execution_session_id}/tasks/{task_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -4487,7 +4487,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/places/{place_id}/versions/{version_id}/luau-execution-sessions/{luau-execution-session_id}/tasks/{task_id}/logs": {
"/cloud/v2/universes/{universe_id}/places/{place_id}/versions/{version_id}/luau-execution-sessions/{luau_execution_session_id}/tasks/{task_id}/logs": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -4593,7 +4593,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/subscription-products/{subscription-product_id}/subscriptions/{subscription_id}": {
"/cloud/v2/universes/{universe_id}/subscription-products/{subscription_product_id}/subscriptions/{subscription_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -4750,7 +4750,7 @@
}
}
},
"/cloud/v2/universes/{universe_id}/user-restrictions/{user-restriction_id}": {
"/cloud/v2/universes/{universe_id}/user-restrictions/{user_restriction_id}": {
"get": {
"tags": [
"Cloud"
Expand Down Expand Up @@ -5768,7 +5768,7 @@
"description": "The resource path for the role of the group member."
}
},
"description": "A membership to a group. You can use a user ID instead of a membership ID.",
"description": "A membership to a group. A user ID can be used in place of a membership ID.",
"x-resource": true
},
"GroupRole": {
Expand Down Expand Up @@ -6570,7 +6570,7 @@
"description": "Present when the task execution succeeds. Contains the output of the\n execution."
}
},
"description": "A `LuauExecutionSessionTask` (\"task\" for short) executes a given Luau script\n in the context of a specific version of a place.\n\n In a task, physics simulation does not run. Server and local scripts within\n the place also do not automatically run.\n\n The script may access and update the data model of the place, including\n invoking any module scripts. However, data model changes are local to the\n task and cannot be persisted.\n\n The script can also invoke engine APIs that read and/or modify data stored in\n the cloud, such as those for DataStores. Exercise caution when using these\n APIs.\n\n Scripts can be up to 4 MB in size and run for up to 30 seconds. Scripts that\n run for longer than 30 seconds terminate with an error.\n\n Scripts are executed as-is and do not need to be wrapped in a function.\n\n Scripts can return values (using the Luau `return` keyword). Return values\n are serialized to JSON and can be retrieved with the `Get\n LuauExecutionSessionTask` API after the task completes. The total size of the\n return values after JSON serialization must not exceed 4 MB. If the limit is\n exceeded, the task terminates with an error.\n\n If the script raises an unhandled error, the task terminates. The error\n information can be retrieved with the `GetLuauExecutionSessionTask` API.\n\n Standard output (generated by the Luau `print` function) can be retrieved\n with the `ListLuauExecutionSessionTaskLogs` method after the task completes.\n A maximum of 450 KB of logs are retained. If the amount of logs exceeds the\n limit, older logs are discarded.\n\n Information about a task is retained for 24 hours after task completion.\n\n At most ten incomplete tasks are allowed per place. Attempting to create more\n tasks while the first ten are incomplete results in a HTTP 429 response.",
"description": "A `LuauExecutionSessionTask` (\"task\" for short) executes a given Luau script\n in the context of a specific version of a place.\n\n In a task, physics simulation does not run. Server and local scripts within\n the place also do not automatically run.\n\n The script may access and update the data model of the place, including\n invoking any module scripts. However, data model changes are local to the\n task and cannot be persisted.\n\n The script can also invoke engine APIs that read and/or modify data stored in\n the cloud, such as those for DataStores. Exercise caution when using such\n APIs.\n\n Scripts can be up to 4 MB in size and run for up to 30 seconds. Scripts that\n run for longer than 30 seconds terminate with an error.\n\n Scripts are executed as-is and do not need to be wrapped in a function.\n\n Scripts can return values (using the Luau `return` keyword). Return values\n are serialized to JSON and can be retrieved with the `Get\n LuauExecutionSessionTask` API after the task completes. The total size of the\n return values after JSON serialization must not exceed 4 MB. If the limit is\n exceeded, the task terminates with an error.\n\n If the script raises an unhandled error, the task terminates. The error\n information can be retrieved with the `GetLuauExecutionSessionTask` API.\n\n Standard output (generated by the Luau `print` function) can be retrieved\n with the `ListLuauExecutionSessionTaskLogs` method after the task completes.\n A maximum of 450 KB of logs are retained. If the amount of logs exceeds the\n limit, older logs are discarded.\n\n Information about a task is retained for 24 hours after task completion.\n\n At most ten incomplete tasks are allowed per place. Attempting to create more\n tasks while the first ten are incomplete results in a HTTP 429 response.",
"x-resource": true,
"x-oneOf": {
"result": [
Expand Down Expand Up @@ -7881,4 +7881,4 @@
"Universes and Places",
"Users and Groups"
]
}
}
Loading

0 comments on commit 2b7e9a6

Please sign in to comment.