mcpField
R
roblox-gamepasses

roblox-gamepasses

github.com/nonlooped开发24318 次安装1 周前更新
代码仓库

关于 roblox-gamepasses

roblox-gamepasses 是面向 Roblox 创作者的变现开发技能,涵盖游戏通行证、开发者产品和订阅的配置与实现。重点说明客户端发起购买、服务器验证并授予权益的安全流程。

主要功能

  1. 01配置游戏通行证与资产 ID
  2. 02实现购买提示和权益发放
  3. 03检查所有权并在服务器验证
  4. 04处理订阅状态与续订
  5. 05应用随机付费物品政策限制
  6. 06查看商品推荐与销售分析

适用场景

  1. 01为 VIP 权限或永久物品设置付费解锁
  2. 02在玩家加入时重新验证通行证权益
  3. 03实现消耗品购买后的服务器端发放
  4. 04为月度权益检查订阅状态

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/nonlooped/roblox-suite --skill roblox-gamepasses

安装后在 Claude Code 中输入/roblox-gamepasses确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
creation-and-setup.md
policyservice.md
purchase-flow-and-granting.md
rules-policies-and-security.md
subscriptions.md
scripts/
PassPurchaseHelper.lua

详细介绍

roblox-gamepasses

主要官方来源: https://create.roblox.com/docs/en-us/production/monetization/passes(另请参阅 developer-products.md 以作对比,以及 MarketplaceService 类参考)。

在服务器上验证购买或所有权后,再发放权益。购买提示和商店展示应放在客户端。

请参阅 roblox-datastores,了解如何存储“玩家拥有此通行证”状态或相关特权;请参阅 roblox-networking,了解购买提示周围的 Remote 验证层。

Game Pass 和 Developer Product

  • Game Pass:一次性购买。为特定体验提供永久特权(VIP 访问权限、永久物品、额外栏位、外观解锁等)。Roblox 会按用户和体验分别跟踪所有权。
  • Developer Product:可重复购买/消耗(货币包、药水、复活、临时增益)。可以多次购买。需要在服务器上通过 ProcessReceipt 回调来发放商品。
  • 截至 2026 年 5 月 30 日,跨体验销售 Game Pass 和 Developer Product 已被禁用。请设计针对特定体验的通行证,或使用 Robux Transfers API 实现捐赠类流程。MarketplaceService:PromptRobuxTransferAsync 必须从服务器调用。只有 Roblox Plus 订阅者才能发起转账,转账金额必须介于 10 到 500 Robux 之间,且发送方不能与接收方相同。接收方获得 90%,体验获得其余 10%;Roblox 不收取转账费用。必须通过 BindReceiptHandler 回调处理转账收据。Roblox 允许体验在收据成功后发放物品或特权;选择不附带奖励属于带有主观判断的防滥用/设计建议,并非平台规则。
  • 你(创作者)要对实际发放权益负全部责任。Roblox 只负责处理交易和 UserOwnsGamePassAsync 查询。
  • 仅当遵守 Paid Random Items 政策时,才能将通行证用于随机虚拟物品。

创建和资产 ID

  1. Creator Dashboard → 你已发布的体验 → Monetization → Passes → Create a Pass。
  2. 上传适合圆形显示的图标(≤512×512,jpg/png/bmp;重要内容必须能在圆形裁剪后保留)。
  3. 名称 + 描述。
  4. 创建后:将鼠标悬停在通行证上 → ⋯ → Copy Asset ID。此数字就是你在所有脚本中使用的 passID。

如需在游戏页面的 Store 选项卡上对外销售:前往通行证 → Sales → 启用 “Item for Sale”,并设置 Robux 价格(1 到 1B)。

提示购买并发放权益

客户端(LocalScript 或 UI 模块;仅用于提示购买和乐观展示):

  • 调用 MarketplaceService:UserOwnsGamePassAsync(使用 pcall)以决定按钮显示“购买”还是“已拥有”。
  • 如果尚未拥有,则调用 MarketplaceService:PromptGamePassPurchase(player, passID)。

服务器端(ServerScriptService 中的 Script;唯一发放权益的位置):

local MarketplaceService = game:GetService("MarketplaceService")
local Players = game:GetService("Players")

local PASS_ID = 1234567890
local granted = {} -- idempotency guard: granted[player][passID]

local function grantPassBenefits(player: Player, passID: number)
    if not player or not player:IsDescendantOf(Players) then
        return
    end
    local playerGranted = granted[player]
    if not playerGranted then
        playerGranted = {}
        granted[player] = playerGranted
    end
    if playerGranted[passID] then
        return
    end
    playerGranted[passID] = true

    -- Apply the actual privilege (attributes, table entry, DataStore flag, Remote to client for visuals, etc.)
    -- This is the source of truth.
end

MarketplaceService.PromptGamePassPurchaseFinished:Connect(function(player: Player, purchasedPassID: number, wasPurchased: boolean)
    -- This event also fires on the client; never grant benefits from the client copy.
    if not player or typeof(purchasedPassID) ~= "number" then
        return
    end
    if wasPurchased and purchasedPassID == PASS_ID then
        local ok, err = pcall(function()
            grantPassBenefits(player, PASS_ID)
        end)
        if not ok then
            warn("Failed to grant pass benefits:", err)
        end
    end
end)

Players.PlayerAdded:Connect(function(player: Player)
    local success, owns = pcall(function()
        return MarketplaceService:UserOwnsGamePassAsync(player.UserId, PASS_ID)
    end)
    if success and owns then
        local ok, err = pcall(function()
            grantPassBenefits(player, PASS_ID)
        end)
        if not ok then
            warn("Failed to apply owned pass benefits:", err)
        end
    elseif not success then
        warn("UserOwnsGamePassAsync failed for", player.Name)
    end
end)

Players.PlayerRemoving:Connect(function(player: Player)
    granted[player] = nil
end)

用于动态 UI 的 GetProductInfoAsync(价格、名称、描述、IsForSale): 使用 MarketplaceService:GetProductInfoAsync(id, Enum.InfoType.GamePass)。在客户端调用以供展示,但绝不要据此发放权益。非异步版本 GetProductInfo 仍然存在,但优先使用 GetProductInfoAsync。

功能要求

Game Pass 和 Developer Product 需要已发布的体验。仅当专用测试体验使用的特定 API 要求启用 Studio Access to API Services 时,才启用此选项;不要将该 Studio 设置视为所有 MarketplaceService 购买 API 的一概前提。请在 Engine Reference 对应条目中核实每个 API 的当前要求。

产品推荐

  • MarketplaceService:RankProductsAsync(arrayOfIdentifiers):传入一个包含最多 50 个 {InfoType = Enum.InfoType.GamePass, Id = ...} 的表。返回针对当前用户的个性化排名,格式为 {ProductIdentifier, ProductInfo} 条目。请谨慎使用;在用户加入时调用一次即可。
  • MarketplaceService:RecommendTopProductsAsync({Enum.InfoType.GamePass, Enum.InfoType.Product}):返回最多 50 个用户可能感兴趣的推荐产品。结果通常不包含用户已拥有的物品,但请在 UI 中验证。请谨慎使用;在用户加入时调用一次即可。

在商店的“为你推荐”版块中使用这些结果。衡量它们是否能提高你的体验中的转化率。

促销(购买 Robux 页面奖励池)

你可以将通行证加入促销池,这样购买 Robux 套餐的用户可能会免费获得该通行证(具体取决于其历史记录)。

要求(摘自通行证文档):

  • 建议使用独特的通行证。
  • 如果正在销售,价格必须在 50 至 800 Robux 之间。
  • 必须有缩略图。
  • 必须符合社区标准。
  • 不能是付费随机物品。

通过控制面板中该通行证的“促销”标签页选择加入。

分析与迭代

在 Creator Dashboard → 体验 → 变现 → 通行证 → 分析标签页中,你可以查看:

  • 按销量和净 Robux 排名的热门通行证。
  • 时间序列图表。
  • 通过“购买 Robux”促销获得通行证以及后续加入体验的归因数据。

使用这些数据来确定定价、哪些特权更有吸引力,以及何时开展促销。

安全、数据与政策限制

  • 仅从客户端发起提示。仅在服务器的 PromptGamePassPurchaseFinished 处理程序中或通过 PlayerAdded 重新检查后,才授予并记录通行证。
  • 始终使用 pcall 调用 UserOwnsGamePassAsync 和 Prompt...。
  • 每次相关用户加入或会话开始时,都要重新检查所有权,然后再授予游戏或经济特权。
  • 如果需要保留历史记录或自定义元数据,请在 DataStores 中存储自己的所有权记录及相关状态(Roblox 不会通过 Engine API 提供完整的逐用户通行证购买历史)。
  • 对于 RTBF / 被遗忘权,请在删除规则中包含与通行证相关的键(参见 roblox-datastores 技能)。
  • 切勿在玩家可见的 UI 中硬编码 Robux 价格:使用 GetProductInfoAsync,以确保区域定价和优化生效。
  • 仅在专用测试体验中测试购买。
  • 对于付费随机物品(战利品箱 / 扭蛋通行证),在提供随机付费内容前,先使用 PolicyService:检查 PolicyService:GetPolicyInfoForPlayerAsync(player).ArePaidRandomItemsRestricted 和 IsPaidItemTradingAllowed。
  • 对于开发者产品,MarketplaceService.ProcessReceipt 在全局范围内只能赋值 一次;请在单个服务器脚本中赋值一次。成功履行购买后,回调必须返回 Enum.ProductPurchaseDecision.PurchaseGranted;如果履行失败,则返回 Enum.ProductPurchaseDecision.NotProcessedYet,因为 Roblox 可能会重新发送收据,直到返回 PurchaseGranted。
  • 使用 PromptRobuxTransferAsync 的捐赠 / 打赏游戏滥用风险较高;请实施频率限制、备用账号检测和审核流程,并避免以转账为条件授予体验内优势。

订阅(定期权益)

订阅以月费为用户提供定期权益,可通过 Robux 或本地货币自动续订。与永久有效的通行证不同,订阅权益仅在用户持续付费期间有效。每个体验最多可创建 50 个订阅;订阅为单档制(不能设置互斥的青铜/白银/黄金档);以 Robux 定价的订阅默认启用区域定价。

API 接口(订阅 ID 是类似 "EXP-11111111" 的字符串):

  • MarketplaceService:GetUserSubscriptionStatusAsync(player, subscriptionId):仅限服务端,返回 {IsSubscribed: boolean}。
  • MarketplaceService:PromptSubscriptionPurchase(player, subscriptionId):客户端购买提示。
  • MarketplaceService.PromptSubscriptionPurchaseFinished(player, subscriptionId, didTryPurchasing):请注意,didTryPurchasing 表示的是尝试,并不代表购买成功;请稍后重新检查状态。
  • Players.UserSubscriptionStatusChanged(player, subscriptionId):仅限服务端,购买、续订或取消时触发。
  • MarketplaceService:GetSubscriptionProductInfoAsync(subscriptionId) 和 GetUserSubscriptionPaymentHistoryAsync(player, subscriptionId)。

**安全性(与通行证采用相同的安全措施):**在客户端显示购买提示,仅在服务端检查状态并发放/撤销权益,对所有操作使用 pcall,每次玩家加入时都重新检查(订阅可能失效),根据每位玩家的情况遵循 PolicyService:IsEligibleToPurchaseSubscription 的结果,不要在客户端持久化任何敏感信息。

**收益分成:**以 Robux 定价的订阅每月支付 70%。以本地货币定价的订阅首月支付 70%,之后支付 100%,并设有 30 天保留期。Robux 订阅不可退款;本地货币订阅可在保留期内退款。

完整流程、客户端/服务端代码、从通行证迁移的方法及注意事项,请参见 references/subscriptions.md。

创作者奖励(取代 Premium Payouts)

截至 2025 年 7 月 24 日,基于参与度的付款(原称“Premium Payouts”)和创作者联盟计划已停止并由 Creator Rewards 取代。不再有按 Premium 游玩分钟数计算的付款可供集成。

Creator Rewards 是一项包含两种付款类型的平台计划,无需在体验中进行集成:

  • 每日参与奖励:每位活跃消费用户每天奖励 5 Robux;该用户需在你的体验中停留 10 分钟以上,且该体验须为其当天访问的前三个体验之一。
  • 受众拓展奖励:对于新用户/重新激活用户在前 60 天内符合条件的前 $100 消费,创作者可获得 35% 的收入分成;归因方式包括分享链接、直接体验链接或按体验名称搜索。

官方来源:https://create.roblox.com/docs/en-us/creator-rewards

何时使用游戏通行证或其他变现方式

  • 一次性永久解锁或访问权限 → 游戏通行证。
  • 可重复购买的商品(货币、消耗品、临时能力)→ Developer Product(需正确实现 ProcessReceipt)。
  • 每月定期权益 → Subscription(参见 references/subscriptions.md;MarketplaceService:GetUserSubscriptionStatusAsync 等)。

可重复购买流程请参见 Developer Products 文档。

脚本

  • scripts/PassPurchaseHelper.lua:用于管理游戏通行证按钮状态、价格显示和购买提示的客户端辅助脚本。

参考索引

评论

支持 Markdown