@remix-gg/mcp 0.4.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +81 -0
- package/dist/client-helpers/index.d.ts +2 -0
- package/dist/client-helpers/index.d.ts.map +1 -0
- package/dist/client-helpers/index.js +2 -0
- package/dist/client-helpers/index.js.map +1 -0
- package/dist/config.d.ts +20 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +58 -0
- package/dist/config.js.map +1 -0
- package/dist/core/api-client.d.ts +4 -0
- package/dist/core/api-client.d.ts.map +1 -0
- package/dist/core/api-client.js +12 -0
- package/dist/core/api-client.js.map +1 -0
- package/dist/core/config.d.ts +6 -0
- package/dist/core/config.d.ts.map +1 -0
- package/dist/core/config.js +19 -0
- package/dist/core/config.js.map +1 -0
- package/dist/core/index.d.ts +5 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +4 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/skills.d.ts +22 -0
- package/dist/core/skills.d.ts.map +1 -0
- package/dist/core/skills.js +49 -0
- package/dist/core/skills.js.map +1 -0
- package/dist/core/tool-defs.d.ts +12 -0
- package/dist/core/tool-defs.d.ts.map +1 -0
- package/dist/core/tool-defs.js +356 -0
- package/dist/core/tool-defs.js.map +1 -0
- package/dist/core/tools/create-game.d.ts +9 -0
- package/dist/core/tools/create-game.d.ts.map +1 -0
- package/dist/core/tools/create-game.js +21 -0
- package/dist/core/tools/create-game.js.map +1 -0
- package/dist/core/tools/create-shop-item.d.ts +14 -0
- package/dist/core/tools/create-shop-item.d.ts.map +1 -0
- package/dist/core/tools/create-shop-item.js +78 -0
- package/dist/core/tools/create-shop-item.js.map +1 -0
- package/dist/core/tools/delete-shop-item.d.ts +9 -0
- package/dist/core/tools/delete-shop-item.d.ts.map +1 -0
- package/dist/core/tools/delete-shop-item.js +19 -0
- package/dist/core/tools/delete-shop-item.js.map +1 -0
- package/dist/core/tools/generate-image.d.ts +8 -0
- package/dist/core/tools/generate-image.d.ts.map +1 -0
- package/dist/core/tools/generate-image.js +32 -0
- package/dist/core/tools/generate-image.js.map +1 -0
- package/dist/core/tools/generate-sprite-sheet.d.ts +14 -0
- package/dist/core/tools/generate-sprite-sheet.d.ts.map +1 -0
- package/dist/core/tools/generate-sprite-sheet.js +29 -0
- package/dist/core/tools/generate-sprite-sheet.js.map +1 -0
- package/dist/core/tools/helpers.d.ts +60 -0
- package/dist/core/tools/helpers.d.ts.map +1 -0
- package/dist/core/tools/helpers.js +68 -0
- package/dist/core/tools/helpers.js.map +1 -0
- package/dist/core/tools/index.d.ts +13 -0
- package/dist/core/tools/index.d.ts.map +1 -0
- package/dist/core/tools/index.js +13 -0
- package/dist/core/tools/index.js.map +1 -0
- package/dist/core/tools/list-shop-items.d.ts +8 -0
- package/dist/core/tools/list-shop-items.d.ts.map +1 -0
- package/dist/core/tools/list-shop-items.js +17 -0
- package/dist/core/tools/list-shop-items.js.map +1 -0
- package/dist/core/tools/update-game.d.ts +11 -0
- package/dist/core/tools/update-game.d.ts.map +1 -0
- package/dist/core/tools/update-game.js +22 -0
- package/dist/core/tools/update-game.js.map +1 -0
- package/dist/core/tools/update-shop-item.d.ts +15 -0
- package/dist/core/tools/update-shop-item.d.ts.map +1 -0
- package/dist/core/tools/update-shop-item.js +24 -0
- package/dist/core/tools/update-shop-item.js.map +1 -0
- package/dist/core/tools/upload-game-asset.d.ts +8 -0
- package/dist/core/tools/upload-game-asset.d.ts.map +1 -0
- package/dist/core/tools/upload-game-asset.js +43 -0
- package/dist/core/tools/upload-game-asset.js.map +1 -0
- package/dist/core/tools/upload-version.d.ts +8 -0
- package/dist/core/tools/upload-version.d.ts.map +1 -0
- package/dist/core/tools/upload-version.js +20 -0
- package/dist/core/tools/upload-version.js.map +1 -0
- package/dist/core/tools/validate-game.d.ts +6 -0
- package/dist/core/tools/validate-game.d.ts.map +1 -0
- package/dist/core/tools/validate-game.js +41 -0
- package/dist/core/tools/validate-game.js.map +1 -0
- package/dist/core/tools.test.d.ts +2 -0
- package/dist/core/tools.test.d.ts.map +1 -0
- package/dist/core/tools.test.js +825 -0
- package/dist/core/tools.test.js.map +1 -0
- package/dist/generated/server-api.d.ts +3673 -0
- package/dist/generated/server-api.d.ts.map +1 -0
- package/dist/generated/server-api.js +2 -0
- package/dist/generated/server-api.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +365 -0
- package/dist/index.js.map +1 -0
- package/dist/server/create-server.d.ts +12 -0
- package/dist/server/create-server.d.ts.map +1 -0
- package/dist/server/create-server.js +29 -0
- package/dist/server/create-server.js.map +1 -0
- package/dist/server/create-server.test.d.ts +2 -0
- package/dist/server/create-server.test.d.ts.map +1 -0
- package/dist/server/create-server.test.js +37 -0
- package/dist/server/create-server.test.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.d.ts.map +1 -0
- package/dist/server/index.js +8 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/lib/config.d.ts +2 -0
- package/dist/server/lib/config.d.ts.map +1 -0
- package/dist/server/lib/config.js +2 -0
- package/dist/server/lib/config.js.map +1 -0
- package/dist/server/resources/skills.d.ts +3 -0
- package/dist/server/resources/skills.d.ts.map +1 -0
- package/dist/server/resources/skills.js +60 -0
- package/dist/server/resources/skills.js.map +1 -0
- package/dist/server/resources/skills.test.d.ts +2 -0
- package/dist/server/resources/skills.test.d.ts.map +1 -0
- package/dist/server/resources/skills.test.js +44 -0
- package/dist/server/resources/skills.test.js.map +1 -0
- package/dist/server/tools/register.d.ts +3 -0
- package/dist/server/tools/register.d.ts.map +1 -0
- package/dist/server/tools/register.js +26 -0
- package/dist/server/tools/register.js.map +1 -0
- package/dist/server/tools/register.test.d.ts +2 -0
- package/dist/server/tools/register.test.d.ts.map +1 -0
- package/dist/server/tools/register.test.js +85 -0
- package/dist/server/tools/register.test.js.map +1 -0
- package/dist/types.d.ts +73 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +31 -0
- package/dist/types.js.map +1 -0
- package/package.json +38 -0
- package/skills/SKILL.md +82 -0
- package/skills/actions/open-game.md +18 -0
- package/skills/workflows/add-image-to-game.md +121 -0
- package/skills/workflows/add-sprite-to-game.md +127 -0
- package/skills/workflows/game-creation.md +124 -0
- package/skills/workflows/implement-multiplayer.md +355 -0
- package/skills/workflows/integrate-save-game.md +135 -0
- package/skills/workflows/manage-shop-items.md +246 -0
- package/skills/workflows/upload-game.md +74 -0
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Manage Shop Items Workflow
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This skill covers the full shop-item lifecycle for a Remix game. Use it
|
|
6
|
+
to list current shop items, create new ones, update existing metadata, delete
|
|
7
|
+
or deactivate items, and integrate item consumption in game code.
|
|
8
|
+
|
|
9
|
+
The safe default is:
|
|
10
|
+
|
|
11
|
+
1. Run `listShopItems` first.
|
|
12
|
+
2. Reuse or update an existing item when the intended slug already exists.
|
|
13
|
+
3. Create only when the intended slug is not already present.
|
|
14
|
+
|
|
15
|
+
## Prerequisites
|
|
16
|
+
|
|
17
|
+
- The game HTML file must already exist.
|
|
18
|
+
- A game must already be created on the Remix platform.
|
|
19
|
+
- If you already have custom icon art, upload or reuse that hosted asset URL.
|
|
20
|
+
- If `iconUrl` is omitted when creating a `CONSUMABLE` or `ONE_TIME` item,
|
|
21
|
+
the tool will auto-generate and upload a shop icon for you.
|
|
22
|
+
- Shop item lifecycle is backend-managed:
|
|
23
|
+
- create always starts as `PENDING`
|
|
24
|
+
- launch or approval moves `PENDING` items to `ACTIVE`
|
|
25
|
+
- delete soft-deletes items to `INACTIVE`
|
|
26
|
+
|
|
27
|
+
## 1. List Or Inspect Items
|
|
28
|
+
|
|
29
|
+
Always list current items before creating, editing, or deleting. This avoids
|
|
30
|
+
duplicate slugs, duplicate names, and accidental edits to the wrong item.
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
listShopItems({
|
|
34
|
+
gameId: "<your-game-id>"
|
|
35
|
+
})
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Use the returned `itemId` for updates and deletes. Use the returned `slug` in
|
|
39
|
+
game code purchase calls and inventory checks.
|
|
40
|
+
|
|
41
|
+
If the intended slug or name already exists, update that item instead of
|
|
42
|
+
creating a duplicate.
|
|
43
|
+
|
|
44
|
+
## 2. Create Item
|
|
45
|
+
|
|
46
|
+
Read `.remix-settings.json` first and use the existing `gameId` when present.
|
|
47
|
+
|
|
48
|
+
Choose the item behavior before calling the tool:
|
|
49
|
+
|
|
50
|
+
- `CONSUMABLE` for items players can buy many times, like extra lives.
|
|
51
|
+
- `ONE_TIME` for permanent one-time unlocks.
|
|
52
|
+
- `TIER_UNLOCK` for progression-style tier unlocks.
|
|
53
|
+
|
|
54
|
+
Create the item:
|
|
55
|
+
|
|
56
|
+
```js
|
|
57
|
+
createShopItem({
|
|
58
|
+
gameId: "<your-game-id>",
|
|
59
|
+
name: "Extra Life",
|
|
60
|
+
slug: "extra-life",
|
|
61
|
+
itemType: "CONSUMABLE",
|
|
62
|
+
bitsCost: 50,
|
|
63
|
+
description: "Spend one to restore a life after game over."
|
|
64
|
+
})
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
New items are created as `PENDING` automatically. Launching a game moves its
|
|
68
|
+
items to `ACTIVE`. Deleting an item soft-deletes it to `INACTIVE`.
|
|
69
|
+
|
|
70
|
+
For tier unlocks, pass `itemType: "TIER_UNLOCK"` and `tier`.
|
|
71
|
+
|
|
72
|
+
Provide `iconUrl` only when you want a specific custom icon. Otherwise, let
|
|
73
|
+
the tool auto-generate the icon for `CONSUMABLE` and `ONE_TIME` items.
|
|
74
|
+
`TIER_UNLOCK` items do not auto-generate icons.
|
|
75
|
+
|
|
76
|
+
After creation, tell the user which outcome happened:
|
|
77
|
+
|
|
78
|
+
- the item was created with their provided icon
|
|
79
|
+
- the item was created and an icon was auto-generated
|
|
80
|
+
- the item was created but icon generation failed, so it has no icon yet
|
|
81
|
+
|
|
82
|
+
## 3. Update Or Delete Items
|
|
83
|
+
|
|
84
|
+
Update only the fields that should change:
|
|
85
|
+
|
|
86
|
+
```js
|
|
87
|
+
updateShopItem({
|
|
88
|
+
gameId: "<your-game-id>",
|
|
89
|
+
itemId: "<item-id>",
|
|
90
|
+
name: "Extra Life Pack",
|
|
91
|
+
bitsCost: 75
|
|
92
|
+
})
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
Delete or deactivate an item:
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
deleteShopItem({
|
|
99
|
+
gameId: "<your-game-id>",
|
|
100
|
+
itemId: "<item-id>"
|
|
101
|
+
})
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Deletion is a soft delete. The backend moves the item to `INACTIVE`; clients do
|
|
105
|
+
not manage item status directly.
|
|
106
|
+
|
|
107
|
+
## 4. Integrate Consumable Usage In Game Code
|
|
108
|
+
|
|
109
|
+
Call `await sdk.ready()` before checking shop item state. Shop items should use
|
|
110
|
+
the Remix SDK purchase flow and inventory data, not custom payment logic.
|
|
111
|
+
|
|
112
|
+
Register `sdk.onPurchaseComplete(...)` during setup. This is required so your
|
|
113
|
+
game applies the purchase result even when the purchase finishes outside the
|
|
114
|
+
immediate in-game `await sdk.purchase(...)` call, such as when a drawer or
|
|
115
|
+
platform UI completes the purchase after the game triggered it or when the
|
|
116
|
+
platform sends the completion event back into the running game session.
|
|
117
|
+
|
|
118
|
+
**Consumable Shop Item pattern (REQUIRED for item usage):**
|
|
119
|
+
```javascript
|
|
120
|
+
const sdk = window.RemixSDK
|
|
121
|
+
await sdk.ready()
|
|
122
|
+
|
|
123
|
+
function applyPurchase(itemSlug) {
|
|
124
|
+
if (itemSlug === 'extra-life') {
|
|
125
|
+
const currentState = sdk.gameState || {}
|
|
126
|
+
const currentSpent = Number(currentState.extraLivesSpent || 0)
|
|
127
|
+
sdk.singlePlayer.actions.saveGameState({
|
|
128
|
+
gameState: {
|
|
129
|
+
...currentState,
|
|
130
|
+
extraLivesSpent: Math.max(0, currentSpent - 1),
|
|
131
|
+
},
|
|
132
|
+
})
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
sdk.onPurchaseComplete((data) => {
|
|
137
|
+
if (!data.success || !data.item) return
|
|
138
|
+
applyPurchase(data.item)
|
|
139
|
+
})
|
|
140
|
+
|
|
141
|
+
function getPurchasedQuantity(itemSlug) {
|
|
142
|
+
return sdk.getItemPurchaseCount(itemSlug)
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
function getConsumableBalance(itemSlug, spentKey) {
|
|
146
|
+
const purchased = getPurchasedQuantity(itemSlug)
|
|
147
|
+
const spent = Number(sdk.gameState?.[spentKey] || 0)
|
|
148
|
+
return Math.max(0, purchased - spent)
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
function consumeConsumable(itemSlug, spentKey, amount) {
|
|
152
|
+
const currentState = sdk.gameState || {}
|
|
153
|
+
const purchased = getPurchasedQuantity(itemSlug)
|
|
154
|
+
const currentSpent = Number(currentState[spentKey] || 0)
|
|
155
|
+
const nextSpent = Math.min(purchased, Math.max(0, currentSpent + amount))
|
|
156
|
+
const gameState = { ...currentState, [spentKey]: nextSpent }
|
|
157
|
+
sdk.singlePlayer.actions.saveGameState({ gameState })
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Example for extra-life
|
|
161
|
+
const freeLives = 2
|
|
162
|
+
const extraLivesBalance = getConsumableBalance('extra-life', 'extraLivesSpent')
|
|
163
|
+
if (playerLives > freeLives) {
|
|
164
|
+
consumeConsumable('extra-life', 'extraLivesSpent', 1)
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Trigger purchases with the slug:
|
|
169
|
+
|
|
170
|
+
```javascript
|
|
171
|
+
const result = await sdk.purchase({ item: 'extra-life' })
|
|
172
|
+
|
|
173
|
+
if (!result.success) {
|
|
174
|
+
showPurchaseError()
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Use `onPurchaseComplete()` as the single source of truth for applying the item
|
|
179
|
+
effect. The awaited purchase result is fine for UI feedback like closing a menu
|
|
180
|
+
or showing an error, but do not apply the game effect in both places.
|
|
181
|
+
|
|
182
|
+
## Wrong Patterns
|
|
183
|
+
|
|
184
|
+
**❌ WRONG - DO NOT DO THIS:**
|
|
185
|
+
```javascript
|
|
186
|
+
// WRONG - This will be rejected!
|
|
187
|
+
localStorage.setItem('gameState', JSON.stringify(this.gameState))
|
|
188
|
+
sessionStorage.setItem('gameState', JSON.stringify(this.gameState))
|
|
189
|
+
|
|
190
|
+
// WRONG - These SDK functions DO NOT EXIST!
|
|
191
|
+
window.RemixSDK.singlePlayer.actions.checkpoint({ gameState: {...} })
|
|
192
|
+
window.RemixSDK.singlePlayer.actions.save({ gameState: {...} })
|
|
193
|
+
|
|
194
|
+
// WRONG - These vibration methods DO NOT WORK!
|
|
195
|
+
navigator.vibrate(200)
|
|
196
|
+
window.RemixSDK.vibrate()
|
|
197
|
+
|
|
198
|
+
// WRONG - Do not build custom bits/payment flow for item purchases
|
|
199
|
+
customBitsCheckout('item-id')
|
|
200
|
+
|
|
201
|
+
// WRONG - Do not probe multiple hypothetical purchase APIs
|
|
202
|
+
const candidates = [
|
|
203
|
+
() => sdk.store?.actions?.purchase?.({ itemId }),
|
|
204
|
+
() => sdk.store?.actions?.purchaseItem?.({ itemId }),
|
|
205
|
+
() => sdk.monetization?.actions?.purchase?.({ itemId }),
|
|
206
|
+
() => sdk.payments?.actions?.purchase?.({ itemId }),
|
|
207
|
+
() => sdk.bits?.actions?.spend?.({ itemId, amount }),
|
|
208
|
+
]
|
|
209
|
+
|
|
210
|
+
// WRONG - Shop items use { item: 'item-slug' }, not { itemId }
|
|
211
|
+
await sdk.purchase({ itemId: 'item-slug' })
|
|
212
|
+
|
|
213
|
+
// WRONG - Do not skip purchase_complete handling
|
|
214
|
+
await sdk.purchase({ item: 'extra-life' })
|
|
215
|
+
|
|
216
|
+
// WRONG - Do not apply the same item effect in both the promise path
|
|
217
|
+
// and onPurchaseComplete()
|
|
218
|
+
const result = await sdk.purchase({ item: 'extra-life' })
|
|
219
|
+
if (result.success) applyPurchase('extra-life')
|
|
220
|
+
|
|
221
|
+
// WRONG - hasItem/getItemPurchaseCount checks before ready-check/game_info
|
|
222
|
+
const ownsItemTooEarly = sdk.hasItem('item-slug')
|
|
223
|
+
const quantityTooEarly = sdk.getItemPurchaseCount('item-slug')
|
|
224
|
+
|
|
225
|
+
// WRONG - Do not hardcode store metadata in game code
|
|
226
|
+
const SHOP_ITEMS = [{ id: 'save-game', name: 'Save Game', bits: 200, icon: '/save.png' }]
|
|
227
|
+
|
|
228
|
+
// WRONG - Do not persist duplicated metadata in gameState
|
|
229
|
+
window.RemixSDK.singlePlayer.actions.saveGameState({
|
|
230
|
+
gameState: {
|
|
231
|
+
unlockedItems: [{ id: 'save-game', name: 'Save Game', bits: 200 }]
|
|
232
|
+
}
|
|
233
|
+
})
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## Tips
|
|
237
|
+
|
|
238
|
+
- Use short, stable slugs like `extra-life`, `double-jump`, or `shield-boost`.
|
|
239
|
+
- For consumables, store only usage counters in `gameState`, not duplicated
|
|
240
|
+
store metadata.
|
|
241
|
+
- If you need a very specific look, use **add-image-to-game** first and pass
|
|
242
|
+
the hosted `iconUrl` into item create or update calls.
|
|
243
|
+
- If no custom art is needed, omit `iconUrl` and let `createShopItem`
|
|
244
|
+
auto-generate icons for `CONSUMABLE` and `ONE_TIME` items.
|
|
245
|
+
- Always run `listShopItems` before create, update, or delete unless you
|
|
246
|
+
already have the exact `itemId` and intended `slug`.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Upload Game Workflow
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
This skill guides you through uploading a completed HTML game to the Remix
|
|
6
|
+
platform. It covers creating the game entry (if needed) and uploading the code.
|
|
7
|
+
|
|
8
|
+
## Prerequisites
|
|
9
|
+
|
|
10
|
+
- The `REMIX_API_KEY` environment variable must be set.
|
|
11
|
+
- A completed HTML game file, ready for upload.
|
|
12
|
+
|
|
13
|
+
**IMPORTANT:** Never read the HTML game file directly. Both `validateGame` and
|
|
14
|
+
`uploadVersion` accept a `filePath` and read the file themselves. Just pass the
|
|
15
|
+
path.
|
|
16
|
+
|
|
17
|
+
## Steps
|
|
18
|
+
|
|
19
|
+
### 1. Locate the Game File
|
|
20
|
+
|
|
21
|
+
Find the path to the HTML file to upload. It should be a single self-contained
|
|
22
|
+
HTML document with inline CSS and JS. You only need the **file path** — do not
|
|
23
|
+
read the file.
|
|
24
|
+
|
|
25
|
+
### 2. Validate
|
|
26
|
+
|
|
27
|
+
Use the `validateGame` tool with the `filePath` to check the HTML for common
|
|
28
|
+
issues:
|
|
29
|
+
- Missing DOCTYPE or viewport meta
|
|
30
|
+
- Inline event handlers (use addEventListener instead)
|
|
31
|
+
- Infinite loops or blocking animations
|
|
32
|
+
- External resource references (should be self-contained)
|
|
33
|
+
|
|
34
|
+
Fix any reported issues before proceeding.
|
|
35
|
+
|
|
36
|
+
### 3. Create the Game (only if no existing IDs)
|
|
37
|
+
|
|
38
|
+
**IMPORTANT:** You MUST check for a `.remix-settings.json` file in the project
|
|
39
|
+
root BEFORE calling `createGame`. If the file exists and contains both `gameId`
|
|
40
|
+
and `versionId`, **do NOT call `createGame`** — skip directly to step 4 and
|
|
41
|
+
use the existing IDs. Calling `createGame` when IDs already exist will create
|
|
42
|
+
a duplicate game entry.
|
|
43
|
+
|
|
44
|
+
Only if no settings file exists (or it is missing `gameId` or `versionId`),
|
|
45
|
+
use the `createGame` tool with a `name` for the game. The tool will:
|
|
46
|
+
- Register the game on the Remix platform
|
|
47
|
+
- Return the **game ID** and **version ID**
|
|
48
|
+
|
|
49
|
+
After `createGame` succeeds, write the returned IDs to `.remix-settings.json`:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{
|
|
53
|
+
"gameId": "<returned game ID>",
|
|
54
|
+
"versionId": "<returned version ID>",
|
|
55
|
+
"name": "<game name>"
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 4. Upload the Code
|
|
60
|
+
|
|
61
|
+
Read `gameId` and `versionId` from `.remix-settings.json` (or use the values
|
|
62
|
+
just obtained from `createGame`).
|
|
63
|
+
|
|
64
|
+
Use the `uploadVersion` tool to upload the HTML to the game version:
|
|
65
|
+
- Pass `gameId` and `versionId`
|
|
66
|
+
- Pass the absolute path to the HTML file as the `filePath` argument (the tool reads the file itself — do NOT read the file contents first)
|
|
67
|
+
|
|
68
|
+
The tool returns a confirmation with the game ID, version ID, and thread ID.
|
|
69
|
+
|
|
70
|
+
## Tips
|
|
71
|
+
|
|
72
|
+
- Always validate before uploading to catch issues early.
|
|
73
|
+
- You can re-upload code to the same version as many times as needed.
|
|
74
|
+
- If you need a fresh version, create a new game entry with `createGame`.
|