skills/remix-shop-items/SKILL.md
Create, update, delete, and integrate Remix shop items. Use when a game needs Bits items, consumables, one-time unlocks, tier unlocks, store icons, or purchase handling in @remix-gg/sdk code.
npx skillsauth add farworld-labs/remix-skills remix-shop-itemsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill guides you through creating, managing, and integrating shop items for games on the Remix platform.
gameId from .remix-settings.json or .remix-cli.json when available.Read .remix-settings.json or .remix-cli.json in the current directory. If either exists and contains a gameId, use that value.
Only if neither file exists or neither has a gameId should you
follow the upload-game workflow to create one.
Always list current items first so you reuse the right itemId, avoid duplicate slugs, and see whether an item is already PENDING, ACTIVE, or INACTIVE.
POST https://api.remix.gg/v1/games/{gameId}/items
Authorization: Bearer $REMIX_API_KEY
Content-Type: application/json
{
"name": "Extra Life",
"slug": "extra-life",
"itemType": "CONSUMABLE",
"bitsCost": 50,
"description": "Spend one to restore a life after game over.",
"iconUrl": "https://asset-url.png"
}
itemType is one of CONSUMABLE, ONE_TIME, or TIER_UNLOCKbitsCost is required for CONSUMABLE and ONE_TIMEtier is required for TIER_UNLOCKPENDINGcreateShopItem can auto-generate an icon if iconUrl is omitted for CONSUMABLE or ONE_TIMEPOST https://api.remix.gg/v1/games/{gameId}/items/{itemId}
Authorization: Bearer $REMIX_API_KEY
Content-Type: application/json
{ "bitsCost": 75, "name": "Extra Life Pack" }
Accepts a partial body -- only include fields you want to change.
DELETE https://api.remix.gg/v1/games/{gameId}/items/{itemId}
Authorization: Bearer $REMIX_API_KEY
Add the RemixSDK shop integration to your game:
const sdk = window.RemixSDK
await sdk.ready()
function getConsumableBalance(slug, spentKey) {
const purchased = sdk.getItemPurchaseCount(slug)
const spent = Number(sdk.gameState?.[spentKey] || 0)
return Math.max(0, purchased - spent)
}
async function buyExtraLife() {
const result = await sdk.purchase({ item: 'extra-life' })
if (!result.success) showPurchaseError()
}
sdk.onPurchaseComplete(({ success, item }) => {
if (!success || item !== 'extra-life') return
const currentState = sdk.gameState || {}
const spent = Number(currentState.extraLivesSpent || 0)
sdk.singlePlayer.actions.saveGameState({
gameState: {
...currentState,
extraLivesSpent: Math.max(0, spent - 1),
},
})
})
Do NOT do any of the following:
Granting items without listening to onPurchaseComplete. Always wait for
the callback before giving the player anything. The purchase may fail or be
cancelled.
Using singlePlayer.actions.purchase(...) in new code. Call sdk.purchase({ item: 'slug' }).
Using localStorage to track purchases. The platform handles purchase
state. Use hasItem(), getItemPurchaseCount(), inventory, and shopItems.
Hardcoding prices or item metadata in game state. Read item metadata from
the platform and only persist usage counters in gameState.
CONSUMABLE for repeatable purchases, ONE_TIME for permanent unlocks,
and TIER_UNLOCK for progression-style items.sdk.onPurchaseComplete(...) even if you also await sdk.purchase(...).sdk.getShopItem(slug) or sdk.shopItems when the game needs current
price or icon metadata.content-media
Generate and add images to a Remix game
development
Build lightweight mobile-friendly 3D browser games with Three.js
tools
Upload and validate HTML game code for Remix. Use when creating or updating a draft version through the CLI, MCP tools, or direct REST calls.
data-ai
Upload images, audio, or 3D models as hosted game assets