How do I make it work? Please tell me. I’m new to this stuff lol
Where do I put my accessory? Please tell me as I’m not good at this kinda thing
Not speaking as a UGC creator, but isn’t this just reinforcing the already insane 40% affiliate fee? If this is widely adopted, the Catalog might be scarcely used since the Catalog is already outdated and cluttered, making things almost impossible to find since there isn’t proper tag metadata support. UGC creators already have to compete with popular games, this will make it even harder now to compete with all of the games that will utilize this since they can just easily paste in the asset link. I understand this can greatly increase net profits since there’ll be a general increase of transactions but the revenue balance between creators and sellers is way too unfavorable to creators.
On top of the current UGC options, UGC creators should have an option to only allow game sales from a specified list as well as an option to disallow sales within the Catalog itself. This could create exclusivity allowing UGC creators to incentivize purchasing assets outside of the catalog or in their own experiences so they may keep the revenue which would otherwise be going to someone who just pasted the asset link into a module and can generally help with engagement and exposure to other associated products. This would give many UGC creators an advantage in the game development space which I would assume many of the leading developers already qualify for UGC creation. This would also incentivize the UGC creators to not only create assets but to create these marketplaces, whether that be game-integrated shops, in-game purchasable rewards, games exclusively dedicated to creating a marketplace/shopping experience, etc. Purchasable rewards are something that I feel has been long overdue. Imagine being able to buy a hat for your avatar that only 10% of the most dedicated players in [insert game here] have. It’d be a monumentally better version of having a rare trophy since you could show off your achievements through your avatar with exclusive and themed accessories.
I really don’t think it’s fair to creators that spend hundreds or even thousands of hours creating assets only to get a huge amount of their revenue cut from front-page games (if they have All Games sales enabled), and now with the promotion of this module, random less popular games on top of the already encroaching cut from Roblox themselves.
Personally I believe for items sold in-game, UGC creators should make 50% and the affiliate should make 20%. (Currently UGC creators make a measly 30%, while affiliates make 40% just for copy+pasting the asset link into their game.)
I realize the enormous affiliate fee is probably the way of reinforcing and incentivizing all leagues of developers to make games that generate extremely favorable amounts of revenue but the way it is currently, it’s basically fighting and splitting that revenue between two very different types of developers (one side of which I personally don’t think deserves such a high cut) all while Roblox makes more money in the bottom line from the increase of transactions across the board.
This module’s tutorial and relevant information can be found here.
https://create.roblox.com/docs/tools/modules/merch-booth
This looks inspired from avatar editor service
This opens the door for many scams.
You can copy the UI, make like a limited hat and sell it for a few thousand sayings its a sale etc. You can hook up with your own gamepass and make thousands off it.
You can do this without the help of this module, I’d even argue that you can find a free model like this in the Roblox toolbox and do whatever malicious thing you’d want to.
This isn’t opening the door at all, it’s already been opened. Also just for reference, limiteds can’t be sold in places. Making a gamepass, making it look like a new limited and having someone gullible enough to buy it is already rare, plus you’ll get terminated for it.
I think maybe that I will just have some idea
This is a great resource to help developers monetize their experiences! I actually added it into one of my experiences already to try it out!
A few thoughts on this module:
Feature Request: Add a function to open the catalog to a subset of items
It would be helpful if the catalog could be opened to a subset of the items available in the catalog. This idea essentially combines the concept of the openItemView
function with the catalog filtering functionality.
Possible use cases:
- When a player interacts with an ATM, open the catalog to the “Cash” developer products rather than to all the developer products / the entire catalog.
- When a player inspects a mannequin’s outfit, open the catalog to only the items displayed on the mannequin.
Two implementation ideas for how the items to display could be specified:
- Pass an
itemId
array to the function. - Allow the developer to tag an
itemId
with a “category”. To open to a subset of items, the developer would call the function with the desired category name. Note: If this option is implemented, it would be beneficial to allow anitemId
to be present in multiple categories at the same time (e.g. the developer may wish to use the same item in multiple outfits).
Bug: The removeItem
function does not remove the specified item
The removeItem
function does not actually remove the specified item from the catalog. After digging into the code a little bit, I found that the client-side implementation was incomplete (the code needed in the setEnabled
module was missing). Here is the setEnabled
module code with the finished implementation:
local LocalizationService = game:GetService("LocalizationService")
local UserInputService = game:GetService("UserInputService")
local MarketplaceService = game:GetService("MarketplaceService")
local RunService = game:GetService("RunService")
local Players = game:GetService("Players")
local MerchBooth = script:FindFirstAncestor("MerchBooth")
local Roact = require(MerchBooth.Packages["Roact_1.4.3"])
local RoactRodux = require(MerchBooth.Packages["RoactRodux_0.5.0"])
local t = require(MerchBooth.Packages["t_3.0.0"])
local App = require(MerchBooth.Components.App)
local getCurrentDevice = require(MerchBooth.Modules.getCurrentDevice)
local uiStatesEvents = require(MerchBooth.Api.uiStatesEvents)
local itemEvents = require(MerchBooth.Api.itemEvents)
local reducer = require(MerchBooth.Reducers.reducer)
local setMerchBoothVisible = require(MerchBooth.Actions.setMerchBoothVisible)
local setItemInfo = require(MerchBooth.Actions.setItemInfo)
local removeItemInfo = require(MerchBooth.Actions.removeItemInfo)
local setMerchBoothEnabled = require(MerchBooth.Actions.setMerchBoothEnabled)
local updateItemInfo = require(MerchBooth.Actions.updateItemInfo)
local addProximityButton = require(MerchBooth.Actions.addProximityButton)
local removeProximityButton = require(MerchBooth.Actions.removeProximityButton)
local setDevice = require(MerchBooth.Actions.setDevice)
local initialLoadData = MerchBooth.Remote.InitialLoadData :: RemoteEvent
return function(store: any)
local LocalPlayer = Players.LocalPlayer
local app = Roact.createElement(RoactRodux.StoreProvider, {
store = store,
}, {
Roact.createElement(App),
})
local mountedTree
local connections = {}
local function onItemInfoReceived(id: string, info: table)
store:dispatch(setItemInfo(id, info))
local isOwned = false
if info.productType == Enum.InfoType.Asset then
isOwned = MarketplaceService:PlayerOwnsAsset(LocalPlayer, id) -- yields
elseif info.productType == Enum.InfoType.GamePass then
isOwned = MarketplaceService:UserOwnsGamePassAsync(LocalPlayer.UserId, id)
end
store:dispatch(updateItemInfo(id, {
isOwned = isOwned,
}))
-- Titles and descriptions are in EN since they come from the server. If locale is non-EN, they need to be
-- fetched again in order to be translated
if LocalizationService.RobloxLocaleId ~= "en-us" then
task.spawn(function()
local updatedInfo = MarketplaceService:GetProductInfo(tonumber(id), Enum.InfoType.Asset) -- yields
store:dispatch(updateItemInfo(id, {
title = updatedInfo.Name,
description = updatedInfo.Description,
}))
end)
end
end
local function setCurrentDevice()
local device = getCurrentDevice(UserInputService:GetLastInputType())
store:dispatch(setDevice(device))
end
--[=[
Sets whether the entire MerchBooth is enabled (catalog view + item details + button + proximity buttons) or not.
```lua
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MerchBooth = require(ReplicatedStorage:WaitForChild("MerchBooth"))
MerchBooth.setEnabled(true)
```
@within MerchBooth
@client
]=]
local function setEnabled(
isEnabled: boolean,
setItemInfoRemote: RemoteEvent?,
removeItemInfoRemote: RemoteEvent?,
addProximityButtonRemote: RemoteEvent?,
removeProximityButtonRemote: RemoteEvent?,
playParticleEmitterRemote: RemoteEvent?
)
assert(RunService:IsClient(), "MerchBooth.setEnabled must be called on the client")
assert(t.boolean(isEnabled), "Bad argument #1 to MerchBooth.setEnabled: expected a boolean")
store:dispatch(setMerchBoothEnabled(isEnabled))
if isEnabled then
connections.uiStateEvents = uiStatesEvents.connect(store)
connections.itemEvents = itemEvents.connect(store, function(state: reducer.State)
return state.server.itemInfo
end)
-- Mount MerchBoothUI to PlayerGui
local playerGui = LocalPlayer:WaitForChild("PlayerGui")
mountedTree = Roact.mount(app, playerGui)
-- Setting up connections
setItemInfoRemote = setItemInfoRemote or MerchBooth.Remote.SetItemInfo
removeItemInfoRemote = removeItemInfoRemote or MerchBooth.Remote.RemoveItemInfo
addProximityButtonRemote = addProximityButtonRemote or MerchBooth.Remote.AddProximityButton
removeProximityButtonRemote = removeProximityButtonRemote or MerchBooth.Remote.RemoveProximityButton
playParticleEmitterRemote = playParticleEmitterRemote or MerchBooth.Remote.PlayParticleEmitter
connections.setItemInfoConnection = setItemInfoRemote.OnClientEvent:Connect(function(action)
onItemInfoReceived(action.itemId, action.info)
end)
connections.removeItemInfoConnection = removeItemInfoRemote.OnClientEvent:Connect(function(action)
store:dispatch(removeItemInfo(action.itemId))
end)
connections.addProximityConnection = addProximityButtonRemote.OnClientEvent:Connect(function(id, adornee)
store:dispatch(addProximityButton(id, adornee))
end)
connections.removeProximityConnection = removeProximityButtonRemote.OnClientEvent:Connect(function(adornee)
store:dispatch(removeProximityButton(adornee))
end)
connections.initialLoadEventConnection = initialLoadData.OnClientEvent:Connect(
function(itemInfo, proximityButtons)
for id, info in pairs(itemInfo) do
onItemInfoReceived(id, info)
end
for _, tuple in ipairs(proximityButtons) do
store:dispatch(addProximityButton(tuple[2], tuple[1]))
end
end
)
connections.characterAddedConnection = LocalPlayer.CharacterAdded:Connect(function()
store:dispatch(setMerchBoothVisible(false))
end)
connections.playParticleEmitterConnection = playParticleEmitterRemote.OnClientEvent:Connect(function()
local state: reducer.State = store:getState()
local emitter = state.config.particleEmitterTemplate:Clone()
emitter.Parent = LocalPlayer.Character.Humanoid.RootPart
emitter:Emit(15)
task.wait()
if emitter.Parent then
emitter.Enabled = false
end
task.wait(4)
if emitter.Parent then
emitter:Destroy()
end
end)
connections.lastInputTypeChangedConnection = UserInputService.LastInputTypeChanged:Connect(setCurrentDevice)
setCurrentDevice()
else
-- Unmount MerchBoothUI from PlayerGui
if mountedTree then
store:dispatch(setMerchBoothVisible(false))
store:flush()
Roact.unmount(mountedTree)
mountedTree = nil
end
-- Disconnecting connections
for _, connection in pairs(connections) do
if typeof(connection) == "table" then
-- The event returned by uiStateEvents uses a lowercase syntax
connection:disconnect()
else
connection:Disconnect()
end
end
end
end
return setEnabled
end
this is ‘official’ though - as it’ll be used in many games people may think it is safe.
I think that maybe more help at the script
I don’t think you understood my reply. Roblox official (official library release, not official substitute for the catalog) or not, anyone can create a scam interface to trick players. This release isn’t opening doors to any new scams.
Any player who wants to scam with a fake catalog can do so and could have been doing it long before this was released. You’re putting blame on the wrong people, this module isn’t causing any more damage.
It’s not an update is a free model Roblox released.
Hi,
This module looks amazing and I have been able to add it to our new project. I would like to ask about the proximity prompt. I’m successfully adding products as in the tutorial, but if I modify the merchbooth.additemasync as indicated in Merch Booth | Roblox Creator Documentation , I get several errors:
An example code looks like this:
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local MerchBooth = require(ReplicatedStorage:WaitForChild("MerchBooth"))
local success, errorMessage = pcall(function()
MerchBooth.addItemAsync(4819740796)
end)
if success then
local item = workspace:FindFirstChild("Robox")
if item then
MerchBooth.addProximityButton(item, 4819740796)
end
end
In fact, These errors correspond to the proximity trying to be added to a regular part, they need to be added to an adornee (Surface GUI element). I managed to add one. thanks
Maybe think not too script error and or I know let’s me get just see how to get much Fix bug
This seems very useful. I really like the UI, It looks very clean.
Is there a way to view the amount of revenue generated from using the merch booth module?
This is a very interesting idea, we can look into this!
Hello developer I need some help I wanna ask you something removed Roblox system from finally gets fixed that server not getting issues I am so happy that you know