portals-mcp 1.3.5 → 1.3.7

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.
Files changed (82) hide show
  1. package/README.md +86 -11
  2. package/dist/resources/ai/bootstrap.json +57 -57
  3. package/dist/resources/ai/contracts/tool-output-envelope.json +35 -35
  4. package/dist/resources/guide/rules-and-conventions.md +13 -13
  5. package/dist/resources/logic/expression-guide.md +224 -224
  6. package/dist/resources/python/lib/board_helpers.py +486 -486
  7. package/dist/resources/python/lib/modular_helpers.py +281 -281
  8. package/dist/resources/python/lib/portals_components.py +135 -135
  9. package/dist/resources/python/requirements.txt +4 -4
  10. package/dist/resources/python/tools/blender_to_portals.py +363 -363
  11. package/dist/resources/python/tools/build_recipe_manifest.py +255 -255
  12. package/dist/resources/python/tools/check_room_storage.py +251 -251
  13. package/dist/resources/python/tools/classify_modular_edges.py +881 -881
  14. package/dist/resources/python/tools/extract_glb_metadata.py +402 -402
  15. package/dist/resources/python/tools/generate_minimap.py +284 -284
  16. package/dist/resources/python/tools/index_room.py +904 -904
  17. package/dist/resources/python/tools/list_components.py +75 -75
  18. package/dist/resources/python/tools/manifest_to_room_data.py +224 -224
  19. package/dist/resources/python/tools/merge_modular_proposal.py +78 -78
  20. package/dist/resources/python/tools/merge_room.py +709 -709
  21. package/dist/resources/python/tools/parse_cdn_upload.py +106 -106
  22. package/dist/resources/python/tools/query_room.py +484 -484
  23. package/dist/resources/python/tools/repack_glb_textures.py +169 -169
  24. package/dist/resources/python/tools/search_recipes.py +317 -317
  25. package/dist/resources/python/tools/sync_room.py +687 -687
  26. package/dist/resources/recipes/board-game-pawn/implementation.md +314 -314
  27. package/dist/resources/recipes/cutscene-camera/implementation.md +258 -258
  28. package/dist/resources/recipes/dice-roll/implementation.md +131 -131
  29. package/dist/resources/recipes/keypad/implementation.md +753 -753
  30. package/dist/resources/recipes/leaderboard-scoring/implementation.md +250 -250
  31. package/dist/resources/recipes/logic-board/implementation.md +246 -246
  32. package/dist/resources/recipes/position-heartbeat/implementation.md +255 -255
  33. package/dist/resources/recipes/side-scroller/implementation.md +461 -461
  34. package/dist/resources/ref/components/catalog.json +29 -29
  35. package/dist/resources/ref/interactions/basic.json +56 -56
  36. package/dist/resources/ref/interactions/patterns.json +75 -75
  37. package/dist/resources/ref/interactions/quest-driven.json +190 -190
  38. package/dist/resources/ref/items/billboard.json +61 -61
  39. package/dist/resources/ref/items/blink-light.json +55 -55
  40. package/dist/resources/ref/items/chart.json +53 -53
  41. package/dist/resources/ref/items/collectible.json +67 -67
  42. package/dist/resources/ref/items/combat-npc.json +150 -150
  43. package/dist/resources/ref/items/destructible.json +83 -83
  44. package/dist/resources/ref/items/elemental.json +67 -67
  45. package/dist/resources/ref/items/gun.json +123 -123
  46. package/dist/resources/ref/items/image.json +61 -61
  47. package/dist/resources/ref/items/jump-pad.json +46 -46
  48. package/dist/resources/ref/items/leaderboard.json +63 -63
  49. package/dist/resources/ref/items/light.json +53 -53
  50. package/dist/resources/ref/items/npc.json +82 -82
  51. package/dist/resources/ref/items/portal.json +55 -55
  52. package/dist/resources/ref/items/screenshare.json +43 -43
  53. package/dist/resources/ref/items/shotgun.json +49 -49
  54. package/dist/resources/ref/items/vehicle.json +83 -83
  55. package/dist/resources/ref/items/video.json +57 -57
  56. package/dist/resources/ref/systems/function-effector.json +119 -119
  57. package/dist/resources/ref/systems/iframes.json +88 -88
  58. package/dist/resources/ref/systems/movement.json +97 -97
  59. package/dist/resources/ref/systems/quests.json +91 -91
  60. package/dist/resources/ref/systems/variables.json +114 -114
  61. package/dist/resources/reference/glb-asset-catalog.md +923 -923
  62. package/dist/resources/reference/iframes.md +345 -345
  63. package/dist/resources/reference/items/display.md +126 -126
  64. package/dist/resources/reference/items/interactive.md +228 -228
  65. package/dist/resources/reference/movement-reference.md +199 -199
  66. package/dist/resources/reference/parent-child.md +135 -135
  67. package/dist/resources/reference/quests.md +382 -382
  68. package/dist/resources/reference/room-index.md +134 -134
  69. package/dist/resources/usage-rules.md +110 -110
  70. package/dist/resources/workflows/blender-to-portals.md +179 -179
  71. package/dist/resources/workflows/builder-workflow.md +72 -72
  72. package/dist/resources/workflows/function-effects-reference.md +224 -224
  73. package/dist/resources/workflows/modular-build-workflow.md +149 -149
  74. package/dist/resources/workflows/quality-review.md +266 -266
  75. package/dist/resources/workflows/scene-design.md +513 -513
  76. package/package.json +22 -6
  77. package/dist/context-handshake.js +0 -427
  78. package/dist/resources/python/lib/__pycache__/portals_components.cpython-314.pyc +0 -0
  79. package/dist/resources/python/lib/__pycache__/portals_core.cpython-314.pyc +0 -0
  80. package/dist/resources/python/lib/__pycache__/portals_effects.cpython-314.pyc +0 -0
  81. package/dist/resources/python/lib/__pycache__/portals_ops.cpython-314.pyc +0 -0
  82. package/dist/resources/python/lib/__pycache__/portals_utils.cpython-314.pyc +0 -0
package/README.md CHANGED
@@ -1,37 +1,90 @@
1
1
  # portals-mcp
2
2
 
3
- An [MCP](https://modelcontextprotocol.io) server that turns AI assistants into game designers for the [Portals](https://portals.to) 3D platform. Any LLM that speaks MCP can build interactive rooms, wire up game logic, and iterate on designs using natural language.
3
+ **Prompt playable 3D multiplayer game in the browser.**
4
+
5
+ [![npm version](https://img.shields.io/npm/v/portals-mcp)](https://www.npmjs.com/package/portals-mcp)
6
+ [![npm downloads](https://img.shields.io/npm/dw/portals-mcp)](https://www.npmjs.com/package/portals-mcp)
7
+ [![license](https://img.shields.io/npm/l/portals-mcp)](#license)
8
+
9
+ `portals-mcp` is an [MCP](https://modelcontextprotocol.io) server that turns Claude, Cursor, and any MCP-capable AI assistant into a game developer on [Portals](https://theportal.to). Describe the game you want; the assistant builds the scene, wires the game logic, generates 3D models, textures, music, and sound effects, and hands you a link anyone can play instantly — multiplayer, in the browser, no engine or build step.
10
+
11
+ <!-- DEMO GIF: docs/demo.gif — record with the shot list below, keep it <60s, ~800px wide, looping.
12
+ Shot list (prompt → playable game in under 60 seconds):
13
+ 1. 0–5s MCP client (Claude Code or Cursor) with the prompt typed: "Build a neon parkour course with a timer and a win screen" — hit enter.
14
+ 2. 5–25s Tools firing in the chat: create_room, apply_operations, text_to_3d_model — fast cuts, no dead air.
15
+ 3. 25–40s render_scene screenshot appears in chat; assistant iterates ("raising the far platforms").
16
+ 4. 40–55s Cut to the browser: the room URL opens, avatar spawns and plays the course.
17
+ 5. 55–60s Second avatar joins (multiplayer beat), room URL overlaid on screen.
18
+ Uncomment the image line below once docs/demo.gif exists:
19
+ -->
20
+ <!-- ![Demo: prompt to playable 3D game in under 60 seconds](docs/demo.gif) -->
4
21
 
5
22
  ## Quick Start
6
23
 
7
- ### 1. Run
24
+ [![Add portals MCP server to Cursor](https://cursor.com/deeplink/mcp-install-dark.svg)](https://cursor.com/en/install-mcp?name=portals&config=eyJjb21tYW5kIjoibnB4IiwiYXJncyI6WyIteSIsInBvcnRhbHMtbWNwQGxhdGVzdCJdfQ%3D%3D)
25
+
26
+ Run it directly:
27
+
28
+ ```bash
29
+ npx -y portals-mcp@latest
30
+ ```
31
+
32
+ ### Claude Code
8
33
 
9
34
  ```bash
10
- npx portals-mcp@latest
35
+ claude mcp add portals -- npx -y portals-mcp@latest
11
36
  ```
12
37
 
13
- ### 2. Configure your MCP client
38
+ ### Claude Desktop
39
+
40
+ Add to `claude_desktop_config.json` (Settings → Developer → Edit Config):
14
41
 
15
42
  ```json
16
43
  {
17
44
  "mcpServers": {
18
45
  "portals": {
19
46
  "command": "npx",
20
- "args": ["portals-mcp"]
47
+ "args": ["-y", "portals-mcp@latest"]
21
48
  }
22
49
  }
23
50
  }
24
51
  ```
25
52
 
26
- ### 3. Bootstrap a session
53
+ ### Cursor
27
54
 
28
- 1. Call `authenticate`. Alternatively, set `PORTALS_ACCESS_KEY` in a `.env` file next to your project to skip the browser prompt.
29
- 2. Call `get_context` with a task description for targeted specs, gotchas, and recipes.
30
- 3. For gameplay mechanics, call `resolve_gameplay_capability` or `plan_gameplay_mechanic` before making platform claims.
31
- 4. Use `apply_operations` for scoped edits or `set_room_data` for full-snapshot replacement.
55
+ Use the button above, or add to `.cursor/mcp.json` (project) or `~/.cursor/mcp.json` (global):
56
+
57
+ ```json
58
+ {
59
+ "mcpServers": {
60
+ "portals": {
61
+ "command": "npx",
62
+ "args": ["-y", "portals-mcp@latest"]
63
+ }
64
+ }
65
+ }
66
+ ```
67
+
68
+ ### Environment variables
69
+
70
+ All optional — with no configuration the server opens a browser sign-in on first use.
71
+
72
+ | Variable | Required | Description |
73
+ |----------|----------|-------------|
74
+ | `PORTALS_ACCESS_KEY` | No | Portals access key. Set it (e.g. in a `.env` file next to your project) to skip the browser sign-in prompt. |
75
+ | `PORTALS_ROOM_ID` | No | Default room ID used when a tool call doesn't specify one. |
76
+ | `PORTALS_DISABLE_TELEMETRY` | No | Set to `1` to disable anonymous usage telemetry. |
77
+
78
+ ### First session
79
+
80
+ 1. Ask your assistant to build something: *"Create a mini golf course with a scoreboard."* It will call `authenticate` (browser sign-in) the first time.
81
+ 2. Behind the scenes the assistant calls `get_context` for targeted specs, gotchas, and recipes, and `resolve_gameplay_capability` / `plan_gameplay_mechanic` before making platform claims.
82
+ 3. Edits land via `apply_operations` (scoped) or `set_room_data` (full snapshot); `render_scene` screenshots let it check its own work.
32
83
 
33
84
  ## Tools
34
85
 
86
+ 51 tools across authentication, marketplace assets, room building, scene design, live-game control, and AI asset generation.
87
+
35
88
  ### Authentication & Discovery
36
89
 
37
90
  | Tool | Description |
@@ -44,6 +97,20 @@ npx portals-mcp@latest
44
97
  | `plan_gameplay_mechanic` | Return a compact implementation contract with required capabilities, objects, variables, triggers, validation, risks, and sources |
45
98
  | `search_recipes` | Search recipe manifest by keywords, tags, and patterns |
46
99
 
100
+ ### Marketplace & Inventory
101
+
102
+ | Tool | Description |
103
+ |------|-------------|
104
+ | `search_marketplace` | Search the Portals creator marketplace for assets (3D models, sounds, packs) |
105
+ | `get_pack_items` | List the items contained in a marketplace pack |
106
+ | `list_marketplace_facets` | List marketplace catalogue facets (categories, themes, visual styles, biomes, types) |
107
+ | `get_user_inventory` | List assets the signed-in user has claimed or purchased |
108
+ | `claim_marketplace_item` | Claim a free marketplace item into the user's inventory |
109
+ | `place_marketplace_items` | Claim a batch of marketplace items and compose the ops to place them in the room |
110
+ | `get_room_build_items` | List every item available in the room's in-game build palette |
111
+ | `add_to_room_inventory` | Add marketplace items or packs to a room's build inventory |
112
+ | `wire_locked_door` | Compose the ops to wire a locked-door mechanic between a key item and a door item |
113
+
47
114
  ### Room Management
48
115
 
49
116
  | Tool | Description |
@@ -56,6 +123,7 @@ npx portals-mcp@latest
56
123
  | `simulate_trigger_zone_input` | Audit and simulate Trigger `pressBtn` / `keyCode` press-inside-zone behavior |
57
124
  | `query_room` | Query room data for specific items, logic, or structure |
58
125
  | `update_room_settings` | Modify name, description, image, privacy, loading screens |
126
+ | `set_room_settings` | Update only scene settings (lighting, skybox, fog, movement, avatars, voice chat) |
59
127
 
60
128
  ### Building
61
129
 
@@ -90,15 +158,22 @@ npx portals-mcp@latest
90
158
  | `change_task_state` | Activate, complete, or reset tasks in a live game |
91
159
  | `get_runtime_data` | Fetch live runtime variables and JS effector results |
92
160
 
93
- ### Generated Assets
161
+ ### AI-Generated Assets
94
162
 
95
163
  | Tool | Description |
96
164
  |------|-------------|
97
165
  | `text_to_3d_model` | Generate a 3D model from text |
98
166
  | `image_to_3d_model` | Generate a 3D model from an image |
99
167
  | `check_3d_model_task` | Poll 3D model generation status |
168
+ | `list_generated_3d_models` | List generated 3D models for the current user |
169
+ | `generate_ai_image` | Generate an image from a text prompt |
170
+ | `list_generated_images` | List generated images for the current user |
171
+ | `generate_ai_texture` | Generate a seamless PBR texture from a text prompt |
172
+ | `list_generated_textures` | List generated textures for the current user |
100
173
  | `text_to_speech` | Generate speech audio |
174
+ | `list_voices` | List available text-to-speech voices |
101
175
  | `generate_sound_effect` | Generate sound effect audio |
176
+ | `generate_music` | Generate an instrumental or vocal music track from a text prompt |
102
177
  | `list_generated_sounds` | List generated sounds for the current user |
103
178
 
104
179
  ## Resources
@@ -1,57 +1,57 @@
1
- {
2
- "format": "portals-mcp-ai-bootstrap",
3
- "version": "4.0.0",
4
- "mode": "ai-first",
5
- "knowledge_architecture": {
6
- "primary": "Call get_context with a description of your task. It returns inline specs, syntax, gotchas, and recipe matches — everything you need in one call.",
7
- "fast_path": "For simple queries (item fields, trigger types, effect schemas), call lookup(term) — returns the spec directly in ~100 tokens.",
8
- "deep_dive": "docs://ref/*, docs://logic/*, docs://recipes/* — available for detailed reference when the inline context from get_context isn't enough."
9
- },
10
- "build_policy": {
11
- "default_ambition": "impressive",
12
- "principle": "When uncertain about scale, build 5-10x more than the minimum viable version. Players remember abundance, not efficiency.",
13
- "anti_patterns": [
14
- "Building a handful of something when the request implies abundance",
15
- "Creating a 'demo' when a full experience was requested",
16
- "Defaulting to the smallest number that technically works"
17
- ]
18
- },
19
- "policy": {
20
- "optimize_for": [
21
- "accuracy_first",
22
- "minimum_context_tokens",
23
- "predictable_outputs",
24
- "tool_first_execution"
25
- ],
26
- "game_bridge": [
27
- "Call connect_to_game after authentication — no roomId needed, the game client provides it via the WS bridge confirmation",
28
- "Call poll_game_events after builds or when expecting user interaction in-game (Ctrl/Cmd+click for items, Shift+click for locations)",
29
- "Events: item_ctrl_clicked (Ctrl/Cmd+click — roomItemId), location_selected (Shift+click — position data)"
30
- ],
31
- "avoid": [
32
- "Building without calling get_context first — Portals has specific syntax that you cannot guess",
33
- "Loading all resources upfront — use get_context for targeted knowledge, lookup for quick facts",
34
- "Reading large guides when a lookup or get_context answers the question",
35
- "Writing external Python scripts for room generation — use apply_operations for all builds, including complex ones with 200+ items",
36
- "Parsing unstructured log output for control flow — always branch on ok/error.code",
37
- "Skipping post-write verification — always get_room_data after set_room_data",
38
- "Ignoring game events — always poll_game_events after user says they interacted in-game"
39
- ],
40
- "testing_workflow": [
41
- "After building logic, TEST it live using this flow:",
42
- "1. connect_to_game — establish the WS bridge to the live game",
43
- "2. get_runtime_data — check initial variable state, confirm init tasks ran",
44
- "3. change_task_state with effectorId — trigger effectors programmatically to simulate player actions (e.g. button clicks, triggers)",
45
- "4. get_runtime_data — verify variables changed as expected",
46
- "5. render_scene — take a screenshot to visually verify displayHtml overlays and scene state",
47
- "TIP: Create hidden test helper items (add_item_with_logic) with known effector IDs like 'test-ready-up' that call SetVariable to trigger your reactive logic. This lets you test without needing the user to click in-game.",
48
- "TIP: Run get_runtime_data and render_scene in parallel for faster test cycles."
49
- ],
50
- "ai_feedback": [
51
- "REQUIRED: Every call to set_room_data and apply_operations MUST include the feedback parameter. This is not optional — the tool will reject calls without it.",
52
- "The feedback parameter requires: confidence (1-5), and at least one of: what_worked, guesses, doc_gaps, ambiguity_flags, recipe_requests, or suspected_errors.",
53
- "Report honestly — low confidence (1-2) triggers automatic gap detection, suspected_errors flags doc inaccuracies for review, what_worked helps rank useful docs higher.",
54
- "This is AI-submitted feedback, not user-reported. You assess your own confidence and report what you observed. Do NOT ask the user to rate pushes."
55
- ]
56
- }
57
- }
1
+ {
2
+ "format": "portals-mcp-ai-bootstrap",
3
+ "version": "4.0.0",
4
+ "mode": "ai-first",
5
+ "knowledge_architecture": {
6
+ "primary": "Call get_context with a description of your task. It returns inline specs, syntax, gotchas, and recipe matches — everything you need in one call.",
7
+ "fast_path": "For simple queries (item fields, trigger types, effect schemas), call lookup(term) — returns the spec directly in ~100 tokens.",
8
+ "deep_dive": "docs://ref/*, docs://logic/*, docs://recipes/* — available for detailed reference when the inline context from get_context isn't enough."
9
+ },
10
+ "build_policy": {
11
+ "default_ambition": "impressive",
12
+ "principle": "When uncertain about scale, build 5-10x more than the minimum viable version. Players remember abundance, not efficiency.",
13
+ "anti_patterns": [
14
+ "Building a handful of something when the request implies abundance",
15
+ "Creating a 'demo' when a full experience was requested",
16
+ "Defaulting to the smallest number that technically works"
17
+ ]
18
+ },
19
+ "policy": {
20
+ "optimize_for": [
21
+ "accuracy_first",
22
+ "minimum_context_tokens",
23
+ "predictable_outputs",
24
+ "tool_first_execution"
25
+ ],
26
+ "game_bridge": [
27
+ "Call connect_to_game after authentication — no roomId needed, the game client provides it via the WS bridge confirmation",
28
+ "Call poll_game_events after builds or when expecting user interaction in-game (Ctrl/Cmd+click for items, Shift+click for locations)",
29
+ "Events: item_ctrl_clicked (Ctrl/Cmd+click — roomItemId), location_selected (Shift+click — position data)"
30
+ ],
31
+ "avoid": [
32
+ "Building without calling get_context first — Portals has specific syntax that you cannot guess",
33
+ "Loading all resources upfront — use get_context for targeted knowledge, lookup for quick facts",
34
+ "Reading large guides when a lookup or get_context answers the question",
35
+ "Writing external Python scripts for room generation — use apply_operations for all builds, including complex ones with 200+ items",
36
+ "Parsing unstructured log output for control flow — always branch on ok/error.code",
37
+ "Skipping post-write verification — always get_room_data after set_room_data",
38
+ "Ignoring game events — always poll_game_events after user says they interacted in-game"
39
+ ],
40
+ "testing_workflow": [
41
+ "After building logic, TEST it live using this flow:",
42
+ "1. connect_to_game — establish the WS bridge to the live game",
43
+ "2. get_runtime_data — check initial variable state, confirm init tasks ran",
44
+ "3. change_task_state with effectorId — trigger effectors programmatically to simulate player actions (e.g. button clicks, triggers)",
45
+ "4. get_runtime_data — verify variables changed as expected",
46
+ "5. render_scene — take a screenshot to visually verify displayHtml overlays and scene state",
47
+ "TIP: Create hidden test helper items (add_item_with_logic) with known effector IDs like 'test-ready-up' that call SetVariable to trigger your reactive logic. This lets you test without needing the user to click in-game.",
48
+ "TIP: Run get_runtime_data and render_scene in parallel for faster test cycles."
49
+ ],
50
+ "ai_feedback": [
51
+ "REQUIRED: Every call to set_room_data and apply_operations MUST include the feedback parameter. This is not optional — the tool will reject calls without it.",
52
+ "The feedback parameter requires: confidence (1-5), and at least one of: what_worked, guesses, doc_gaps, ambiguity_flags, recipe_requests, or suspected_errors.",
53
+ "Report honestly — low confidence (1-2) triggers automatic gap detection, suspected_errors flags doc inaccuracies for review, what_worked helps rank useful docs higher.",
54
+ "This is AI-submitted feedback, not user-reported. You assess your own confidence and report what you observed. Do NOT ask the user to rate pushes."
55
+ ]
56
+ }
57
+ }
@@ -1,35 +1,35 @@
1
- {
2
- "format": "portals-mcp-tool-output-envelope",
3
- "version": "1.0.0",
4
- "description": "Canonical response envelope used by all MCP tools.",
5
- "schema": {
6
- "success": {
7
- "ok": true,
8
- "action": "string",
9
- "summary": "string",
10
- "data": "object",
11
- "next_steps": [
12
- "string"
13
- ]
14
- },
15
- "error": {
16
- "ok": false,
17
- "action": "string",
18
- "summary": "string",
19
- "error": {
20
- "code": "string",
21
- "message": "string",
22
- "details": "object (optional)"
23
- },
24
- "next_steps": [
25
- "string"
26
- ]
27
- }
28
- },
29
- "required_parsing_rules": [
30
- "Always parse as JSON from content[0].text.",
31
- "Gate behavior on ok=true/false before reading data.",
32
- "Use error.code for remediation routing.",
33
- "Treat next_steps as actionable suggestions, not guaranteed prerequisites."
34
- ]
35
- }
1
+ {
2
+ "format": "portals-mcp-tool-output-envelope",
3
+ "version": "1.0.0",
4
+ "description": "Canonical response envelope used by all MCP tools.",
5
+ "schema": {
6
+ "success": {
7
+ "ok": true,
8
+ "action": "string",
9
+ "summary": "string",
10
+ "data": "object",
11
+ "next_steps": [
12
+ "string"
13
+ ]
14
+ },
15
+ "error": {
16
+ "ok": false,
17
+ "action": "string",
18
+ "summary": "string",
19
+ "error": {
20
+ "code": "string",
21
+ "message": "string",
22
+ "details": "object (optional)"
23
+ },
24
+ "next_steps": [
25
+ "string"
26
+ ]
27
+ }
28
+ },
29
+ "required_parsing_rules": [
30
+ "Always parse as JSON from content[0].text.",
31
+ "Gate behavior on ok=true/false before reading data.",
32
+ "Use error.code for remediation routing.",
33
+ "Treat next_steps as actionable suggestions, not guaranteed prerequisites."
34
+ ]
35
+ }
@@ -1,13 +1,13 @@
1
- # Rules and Conventions
2
-
3
- ## Core Rules
4
-
5
- - **Never read snapshot.json into context.** Use `room_index.md` for overview, query tools for specific items. See `docs://reference/room-index`.
6
- - **Design before building.** Never skip to generating items.
7
- - **Always read before writing.** MCP write tools replace entire objects — call `get_room_data` first.
8
- - **Save everything locally.** Design docs, scripts, snapshots — all in `games/{room-id}/`.
9
- - **Build with apply_operations.** Use bulk operations for complex builds, `add_item_with_logic` for items with interactions, and `add_component` for common patterns.
10
- - **Always use the full asset catalog workflow for GLB placement.** See `docs://reference/glb-asset-catalog`.
11
- - **Always search recipes first.** Use `search_recipes` before designing or building any mechanic.
12
- - **Test your logic live.** After building, use `connect_to_game` → `get_runtime_data` to verify variables, `change_task_state` to trigger effectors, and `render_scene` to screenshot the result. Create test helper items with known effector IDs to simulate player actions programmatically.
13
- - **Sync before overwriting.** If a user made manual changes, run `sync_room` before pushing. See `docs://guide/workflow-steps`.
1
+ # Rules and Conventions
2
+
3
+ ## Core Rules
4
+
5
+ - **Never read snapshot.json into context.** Use `room_index.md` for overview, query tools for specific items. See `docs://reference/room-index`.
6
+ - **Design before building.** Never skip to generating items.
7
+ - **Always read before writing.** MCP write tools replace entire objects — call `get_room_data` first.
8
+ - **Save everything locally.** Design docs, scripts, snapshots — all in `games/{room-id}/`.
9
+ - **Build with apply_operations.** Use bulk operations for complex builds, `add_item_with_logic` for items with interactions, and `add_component` for common patterns.
10
+ - **Always use the full asset catalog workflow for GLB placement.** See `docs://reference/glb-asset-catalog`.
11
+ - **Always search recipes first.** Use `search_recipes` before designing or building any mechanic.
12
+ - **Test your logic live.** After building, use `connect_to_game` → `get_runtime_data` to verify variables, `change_task_state` to trigger effectors, and `render_scene` to screenshot the result. Create test helper items with known effector IDs to simulate player actions programmatically.
13
+ - **Sync before overwriting.** If a user made manual changes, run `sync_room` before pushing. See `docs://guide/workflow-steps`.