「ゲームの中でコインを売りたい」「何回でも買える商品はどうやって作るの?」
ロブロックス(Roblox)の開発者製品の作り方を、実際の画像付きで誰でも簡単に分かるように解説します。この記事では、ボタンを押して買うとコインが100枚ずつ増える商品を例にします。Creator Hubで開発者製品を作り、Studioで買った人にコインを渡すスクリプトを置いて、お金のかからないテスト購入で確かめるところまで進めます。
中級ステップ5/28 前の記事:ロブロックス(Roblox)のゲームパスの作り方 全体の順番を見る
使うもの:Roblox Studioが起動するパソコン、ブラウザ(Chromeなど)、Studioの「ファイル」→「Robloxに公開」でRobloxに送ったゲーム。公式の説明では、開発者製品を作る前にゲームを公開してRobloxで開ける状態にしておきます。ゲームをRobloxに保存する方法はゲームを公開する方法で画像付きで解説しています。スクリプトの入れ方はスクリプトの作り方、ボタンの作り方はボタンの作り方で画像付きで解説しています。
今回の完成状態:下の画像のように、ボタンを押して2回買うと、右上のCoinsが200になれば成功です。

開発者製品とは?ゲームパスとの違い
開発者製品は、同じ人が何回でも買える商品です。公式の説明でも、ゲーム内のお金、弾、回復薬のように、2回以上買うものに使うと書かれています。
| 開発者製品(この記事) | ゲームパス | |
|---|---|---|
| 買える回数 | 何回でも | 1人1回 |
| 向いているもの | コイン、回復アイテムなど使ったらなくなるもの | 頭の上の表示、専用エリアなどずっと使えるもの |
| スクリプトで確かめること | 買われるたびに、商品を1回ずつ渡す | パスを持っているかどうか |
一度買えばずっと使える特典は、ゲームパスの作り方で解説しています。
開発者製品で大事なのは、1回の購入につき、商品をちょうど1回だけ渡すことです。渡し忘れると買った人が損をし、2回渡すとゲームのお金の計算が合わなくなります。
1. Creator Hubで開発者製品を作る
ブラウザでcreate.roblox.com/dashboard/creationsを開くと、作ったゲームが「バーチャル空間」に並んでいます。商品を売りたいゲームのカードを押してください(赤い枠)。赤い枠や番号は、その手順で押す場所です。ボタンの名前や置き場所は、Roblox側の更新で変わることがあります。

ゲームの画面が開きます。左のメニューの「収益化」を押すと、右の「▼」が「▲」に変わり、中の項目が開きます(赤い枠)。

収益化の中の「開発者製品」を押します(赤い枠)。

開発者製品の画面が開いたら、右上の「開発者製品を制作」を押してください(赤い枠)。

作成の画面で、名前(画像の1)と詳細を入れます。「販売中のアイテム」(画像の2)がオンになっていることを確かめ、価格(画像の3)を入れます。「変更内容を保存」(画像の4)は、このあと「管理された価格設定」のスイッチをオフにしてから押します(画像はオフにしたあとの画面です)。

| 項目 | 入れた内容 |
|---|---|
| 名前 | コイン100枚 |
| 詳細 | ゲーム内のコインが100枚増えます。何回でも買えます。 |
| 価格 | 25 Robux |
| 管理された価格設定 | オフ |
2026年10月29日に更新された公式の説明では、名前と詳細のあとに、製品のカテゴリ(ゲーム内のショップで商品を分ける分類)を選ぶ手順が入っています。
「管理された価格設定」は、国や地域に合わせた価格などをRobloxが受け持つ設定です。作成の画面では最初からオンになっていました(赤い枠)。

オンのまま保存すると、利用規約への同意を求める画面が出ます。今回はスイッチを押してオフにしてから保存しました(赤い枠)。オフにしても、スイッチの右の文字は「有効化済み」のままなので、スイッチの色と丸の位置で見分けます。オフにしたら、上の画像の4の「変更内容を保存」を押します。

公式の説明では、管理された価格設定は、国や地域ごとの価格(決めた価格の30%〜100%)と、価格を試すテスト(価格最適化)をRobloxがまとめて受け持つ仕組みです。オンにすると購入画面の金額が人によって変わることがあるので、自分で作るボタンには金額を書かないようにします。
2. 製品IDを控える
保存すると一覧に戻ります。「製品ID」の列の数字(赤い枠)が、スクリプトで使う商品の番号です。メモ帳などに書き写して控えておきましょう。

3. コインを渡すスクリプトを置く
ここからはRoblox Studioで、開発者製品を作ったゲームを開いて作業します。製品IDはゲームごとに決まり、ほかのゲームの製品は公開したゲームでは買えません。公式の説明によると、Studioのテスト購入では製品が今のゲームのものかどうかを確かめません。そのため、ほかのゲームの製品IDでも成功したように見えることがあります。必ず、開発者製品を作ったゲームを開いて作業します。Roblox Studioを起動し、最初の画面の左の「バーチャル空間」を押します(画像の1)。Robloxに保存した作品が並ぶので、1で商品を作ったゲーム(Creator Hubでカードを押したのと同じゲーム。ここでは「Asobishift Practice 3」)のカードを押して開きます(画像の2)。

この記事のゲームは、開いたあとの3D画面の上の作品のタブに「アソビシフト練習3」と出ます。
スクリプトは2つに分けて置きます。
| 置く場所 | 名前 | 種類 | やること |
|---|---|---|---|
| ServerScriptService | CoinShop | Script | 買われたことを受け取り、その人にコインを渡す |
| StarterGui > CoinShopGui > BuyCoinsButton | BuyCoins | LocalScript | ボタンが押されたら購入画面を開く |
サーバーのスクリプト
エクスプローラの「ServerScriptService」にマウスを乗せて、右に出る「+」(赤い枠)を押します。

検索欄に「Script」と入れ、一覧の「Script」(赤い枠)を押して入れます。

入ったScriptをエクスプローラで選んだままF2キーを押し、名前を「CoinShop」に変えます(赤い枠)。

続けてCoinShopを選んだまま、プロパティの検索で「RunContext」と入力し、「▼動作」の欄にあるRunContextの一覧から「Server」(赤い枠)を選びます。RunContextは、スクリプトをサーバーと遊ぶ人のパソコンのどちらで動かすかを決める設定です。

CoinShopのタブ(開いていなければエクスプローラでCoinShopをダブルクリック)で中身を全部消して、次のコードを貼り付けます。コードの4行目、PRODUCT_IDの「3717845406」は、この記事で作った製品の番号です。自分で控えた製品IDに書きかえてください。
local Players = game:GetService("Players")
local MarketplaceService = game:GetService("MarketplaceService")
local PRODUCT_ID = 3717845406 -- 作成した開発者製品のIDに置き換える
local COINS = 100
-- 渡し終えた購入の番号。練習用なのでサーバーが止まると消える
local granted = {}
Players.PlayerAdded:Connect(function(player)
local leaderstats = Instance.new("Folder")
leaderstats.Name = "leaderstats"
leaderstats.Parent = player
local coins = Instance.new("IntValue")
coins.Name = "Coins"
coins.Parent = leaderstats
end)
MarketplaceService.ProcessReceipt = function(receiptInfo)
-- 同じ購入がもう一度届いても、2回渡さない
if granted[receiptInfo.PurchaseId] then
return Enum.ProductPurchaseDecision.PurchaseGranted
end
local player = Players:GetPlayerByUserId(receiptInfo.PlayerId)
if not player or receiptInfo.ProductId ~= PRODUCT_ID then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
local leaderstats = player:FindFirstChild("leaderstats")
local coins = leaderstats and leaderstats:FindFirstChild("Coins")
if not coins then
return Enum.ProductPurchaseDecision.NotProcessedYet
end
coins.Value += COINS
granted[receiptInfo.PurchaseId] = true
print("コインを渡しました", player.Name, receiptInfo.PurchaseId)
return Enum.ProductPurchaseDecision.PurchaseGranted
end

コードの10〜17行目では、ゲームに入った人に「leaderstats」という名前のフォルダーと、その中のCoinsを作ります。この名前のフォルダーに入れた数は、テストの画面の右上の一覧に出ます。
コードの中心は「ProcessReceipt(プロセスレシート)」です。開発者製品が買われると、Robloxがこの仕組みに「だれが、どの商品を、どの購入番号で買ったか」を知らせてきます。
| 返す値 | 意味 | このコードで返すとき |
|---|---|---|
| PurchaseGranted | 商品を渡し終えた | COINSで決めた100枚をCoinsに足したあと。前に渡した購入番号がもう一度届いたとき |
| NotProcessedYet | まだ渡せていない | 買った人がゲームにいない、コインの入れ物がまだできていないとき |
「NotProcessedYet」を返した購入は、公式の説明では、その人がまたゲームに入ったときなどにもう一度知らせが届きます。そのため、渡し終えた購入番号(PurchaseId)を覚えておき、同じ番号が届いたらコインを増やさずに「渡し終えた」とだけ返します。
「ProcessReceipt」は、1つのゲームでサーバーのスクリプト1つだけが設定できます。ほかのスクリプトでも設定していると、片方が効かなくなるので注意してください。
本番のゲームで使う前に
このコードは練習用なので、コインの数も渡し終えた購入番号も、サーバーが止まると消えてしまいます。公式の説明でも、開発者製品を買ったことはデータストアに保存するよう案内されています。本番のゲームでは、コインの数と渡し終えた購入番号をデータストアに保存してから「PurchaseGranted」を返す形にしてください。データストアの使い方はDataStoreの使い方で解説しています。
公式の説明では、同じ購入の知らせが2つのサーバーで同時に処理されることもあります。そのため、データストアに保存するだけでは二重に渡すのを防ぎきれない場合があります。公式は対策として、データストアのセッションロックを案内しています。
公式の説明では、Creator Hubの「収益化」→「ショップ」で開発者製品を掲載(Listed)にすると、ゲームの中のショップや、Robloxのホーム画面・検索結果でも売られます。ゲームの外で買われた分も、その人がゲームに入ったときにProcessReceiptで渡します。掲載にするのは、データストアに保存する本番用のProcessReceiptにしてからにしてください。
購入画面を開くボタン
エクスプローラの「StarterGui」にマウスを乗せて、右に出る「+」(赤い枠)を押します。

検索欄に「ScreenGui」と入れ、一覧の「ScreenGui」(赤い枠)を押します。

入ったScreenGuiをエクスプローラで選んでF2キーを押し、名前を「CoinShopGui」に変えます(赤い枠)。

次に、エクスプローラのCoinShopGuiにマウスを乗せて、右に出る「+」を押します(赤い枠)。

検索欄に「TextButton」と入れ、一覧の「TextButton」を押します(赤い枠)。

入ったTextButtonの名前を、エクスプローラでF2キーを押して「BuyCoinsButton」に変えます(赤い枠)。

ボタンのプロパティは、次のようにしました。
| 対象 | プロパティ | 値 |
|---|---|---|
| CoinShopGui | ResetOnSpawn | オフ |
| BuyCoinsButton | Text | コイン100枚を買う |
| BuyCoinsButton | Size | {0, 260},{0, 60} |
| BuyCoinsButton | Position | {0, 20},{1, -80} |
| BuyCoinsButton | TextScaled | オン |
まず、エクスプローラでCoinShopGuiを選んだ状態で、プロパティの検索欄に「ResetOnSpawn」と入力し、ResetOnSpawnのチェックを外します(赤い枠)。ResetOnSpawnは、アバターが倒れて復活するたびに画面の表示を作り直す設定です。外しておくと、復活してもボタンが作り直されません。

次に、エクスプローラでBuyCoinsButtonを選び、次の4つを1つずつ変えます。
- BuyCoinsButtonを選んだ状態で、プロパティの検索欄に「Text」と入力します。似た名前の欄が並ぶので、名前がちょうどTextの欄(最初は「Button」)を「コイン100枚を買う」に変えてEnterキーを押します(下の1枚目)
- 続けてBuyCoinsButtonを選んだまま、プロパティの検索欄に「Size」と入力します。AbsoluteSizeなどが並ぶので、名前がちょうどSizeの欄に「{0, 260},{0, 60}」と入れてEnterキーを押します。ボタンが大きくなります(下の2枚目)
- 続けてBuyCoinsButtonを選んだまま、プロパティの検索欄に「Position」と入力します。AbsolutePositionと並ぶので、名前がちょうどPositionの欄に「{0, 20},{1, -80}」と入れてEnterキーを押します。「{1, -80}」は、画面のいちばん下から80ピクセル上という意味です。ボタンが画面の左下に移ります(下の3枚目)
- 続けてBuyCoinsButtonを選んだまま、プロパティの検索欄に「TextScaled」と入力し、TextScaledにチェックを入れます。文字がボタンいっぱいの大きさになります(下の4枚目)
最後に、エクスプローラのBuyCoinsButtonにマウスを乗せて「+」を押します(赤い枠)。

検索欄に「LocalScript」と入れ、一覧の「LocalScript」を押します(赤い枠)。

入ったLocalScriptの名前を、エクスプローラでF2キーを押して「BuyCoins」に変えます(赤い枠)。

BuyCoinsのタブ(開いていなければエクスプローラでBuyCoinsをダブルクリック)で中身を全部消して、次のコードを貼り付けます。コードの4行目のPRODUCT_IDも、サーバーのスクリプトと同じ数字に書きかえます。
local MarketplaceService = game:GetService("MarketplaceService")
local player = game:GetService("Players").LocalPlayer
local PRODUCT_ID = 3717845406 -- サーバー側と同じ製品ID
script.Parent.Activated:Connect(function()
MarketplaceService:PromptProductPurchase(player, PRODUCT_ID)
end)
エクスプローラが次の画像の赤い枠のように並べば、準備は完了です。

ボタンのコードは、購入画面を開くだけです。コインを増やすのはサーバーのCoinShopだけにしています。ボタン側で「買ったからコインを増やして」とサーバーに送る作りにすると、ずるをする人がお金を払わずにコインを増やせてしまうからです。
4. テスト購入で確かめる
3D画面の上の作品のタブ「アソビシフト練習3」を押して3D画面に戻り、F5キーでテストを始めます(タブの名前はパソコンによって違います)。右上にCoinsの一覧が出て、最初は0になっています。

左下の「コイン100枚を買う」を押すと、購入の画面が開きます。下に「これはテスト購入です。お持ちのアカウントには課金されません。」(画像の2)と出ていれば、Robuxは使われません。「購入」(画像の1)を押します。

「購入完了」と出て、右上のCoinsが100(画像の1)になり、出力に「コインを渡しました」(画像の2)と出れば成功です。最後の長い英数字が、この購入の番号(PurchaseId)です。

「了解」(画像の3)を押します。もう一度、左下の「コイン100枚を買う」を押し、開いた購入の画面で「購入」を押します。Coinsが200(画像の1)になり、出力にもう1行「コインを渡しました」(画像の2)が増えます。2行の購入番号は違っていて、別々の購入として1回ずつ渡されたと分かります。

Shift + F5キーでテストを停止します。
Studioのテスト購入では、Robuxは使われません。公開したゲームで本当に買うと、Robuxが支払われます。
コインが増えないときの確かめ方
| 症状 | 確かめるところ |
|---|---|
| 購入画面が開かない・違う商品が出る | 2つのスクリプトのPRODUCT_IDが、一覧の「製品ID」と同じ数字か |
| 「購入完了」と出るのにコインが増えない | CoinShopがServerScriptServiceにあり、RunContextがServerか。出力に「コインを渡しました」が出ているか |
| 右上にCoinsが出ない | CoinShopの「leaderstats」の文字が小文字で合っているか |
| 前は動いたのに急に増えなくなった | ほかのスクリプトでもProcessReceiptを設定していないか。ほかのスクリプトやモデルがBindReceiptHandler(公式が案内している新しい受け取り方で、ProcessReceiptより先に使われる)を使っていないか |
スクリプトが動いているか分からないときは、スクリプトが動かないときの確認手順で出力の見方を確かめてください。
AIに相談するときの伝え方
AIにコードを頼むときは、1回の購入で1回だけ渡すことと、どこに保存するかをはっきり伝えます。
Robloxで、何回でも買える開発者製品「コイン100枚」を作っています。
購入はProcessReceiptでサーバーが受け取り、コインはleaderstatsのCoinsに入れています。
同じ購入がもう一度届いても2回渡さないこと、渡せなかったときはNotProcessedYetを返すことを守ってください。
コインの数と渡し終えた購入番号をDataStoreに保存してからPurchaseGrantedを返す形に書きかえ、どこを変えたか説明してください。
今のコード:(CoinShopのコードを貼る)
よくある質問
Studioのテスト購入でRobuxは減る?
減りません。購入の画面に「これはテスト購入です。お持ちのアカウントには課金されません。」と出ます。この記事のテストでも、2回買ってRobuxの支払いはありませんでした。
ゲームパスと開発者製品、どちらを作ればいい?
一度買えばずっと使えるものはゲームパス、使ったらまた買うものは開発者製品です。両方を1つのゲームで売ることもできます。
次のステップ(中級 6/28)
次は、回る床と、行ったり来たりする床を作ります。
次に知りたいことを選ぶ
- 次のステップ:回る床と、行ったり来たりする床を作ります → ロブロックス(Roblox)で回る床と動く床を作る方法
- 一度買えばずっと使える特典を売りたい → ロブロックス(Roblox)のゲームパスの作り方
- コインの数を保存したい → ロブロックス(Roblox)のDataStoreの使い方
- 売れたRobuxを換金したい → ロバックス(Robux)の換金方法



