portals-mcp 1.3.1 → 1.3.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 +1 -0
- package/dist/resources/index/intents.json +164 -164
- package/dist/resources/index/items.json +3 -3
- package/dist/resources/index/knowledge-map.json +7 -0
- package/dist/resources/index/triggers.json +2 -2
- package/dist/resources/python/README.md +11 -4
- package/dist/resources/python/lib/portals_core.py +5 -1
- package/dist/resources/python/lib/portals_trigger_zone_input.py +293 -0
- package/dist/resources/python/tools/simulate_trigger_zone_input.py +81 -0
- package/dist/resources/python/tools/validate_room.py +14 -1
- package/dist/resources/ref/items/trigger-zone.json +59 -56
- package/dist/resources/ref/pitfalls.json +5 -0
- package/dist/resources/ref/room-data-skeleton.json +67 -67
- package/dist/resources/ref/template-layouts.json +2594 -0
- package/dist/resources/reference/api-cheatsheet.md +3 -1
- package/dist/resources/reference/gotchas.md +6 -1
- package/dist/resources/reference/interactions.md +2 -0
- package/dist/resources/reference/items/gameplay.md +364 -362
- package/dist/resources/reference/template-layouts.md +167 -0
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +96 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -53,6 +53,7 @@ npx portals-mcp@latest
|
|
|
53
53
|
| `get_room_data` | Download room snapshot to temp JSON |
|
|
54
54
|
| `inspect_room_data` | Summarize room-data counts, item types, variables, triggers/actions, and warnings without dumping full JSON |
|
|
55
55
|
| `simulate_key_input` | Audit and simulate `OnKeyPressedEvent` / `OnKeyReleasedEvent` mappings against a snapshot |
|
|
56
|
+
| `simulate_trigger_zone_input` | Audit and simulate Trigger `pressBtn` / `keyCode` press-inside-zone behavior |
|
|
56
57
|
| `query_room` | Query room data for specific items, logic, or structure |
|
|
57
58
|
| `update_room_settings` | Modify name, description, image, privacy, loading screens |
|
|
58
59
|
|
|
@@ -1,164 +1,164 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": "3.0.0",
|
|
3
|
-
"description": "Data-driven intent profiles for context recommendation. Used by get_context to assemble inline knowledge.",
|
|
4
|
-
"base_resources": [
|
|
5
|
-
{ "uri": "docs://ai/bootstrap", "reason": "Execution policy.", "priority": 1 },
|
|
6
|
-
{ "uri": "docs://ai/contracts/tool-output-envelope", "reason": "Tool response schema.", "priority": 1 },
|
|
7
|
-
{ "uri": "docs://usage-rules", "reason": "Read/write conventions.", "priority": 1 },
|
|
8
|
-
{ "uri": "docs://guide/rules-and-conventions", "reason": "Core execution rules.", "priority": 1 },
|
|
9
|
-
{ "uri": "docs://index/knowledge-map", "reason": "Navigate all available content.", "priority": 2 }
|
|
10
|
-
],
|
|
11
|
-
"stage_hints": {
|
|
12
|
-
"setup": ["setup-auth"],
|
|
13
|
-
"design": ["create-room", "gameplay-build", "scene-design"],
|
|
14
|
-
"build": ["gameplay-build", "function-effects"],
|
|
15
|
-
"logic": ["function-effects", "js-scripting", "logic-board"],
|
|
16
|
-
"validate": ["validation-publish"],
|
|
17
|
-
"publish": ["validation-publish"],
|
|
18
|
-
"assets": ["asset-pipeline"],
|
|
19
|
-
"settings": ["settings-update"],
|
|
20
|
-
"scripting": ["local-scripting", "js-scripting"]
|
|
21
|
-
},
|
|
22
|
-
"intents": [
|
|
23
|
-
{
|
|
24
|
-
"id": "setup-auth",
|
|
25
|
-
"keywords": ["install", "setup", "auth", "authenticate", "connect", "key", "access", "mcp", "server", "config"],
|
|
26
|
-
"resources": {
|
|
27
|
-
"required": [],
|
|
28
|
-
"recommended": []
|
|
29
|
-
},
|
|
30
|
-
"tools": ["authenticate"],
|
|
31
|
-
"checks": ["Ensure authenticate returns ok=true.", "Persist PORTALS_ACCESS_KEY in MCP config."]
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
"id": "create-room",
|
|
35
|
-
"keywords": ["create", "new", "template", "duplicate", "clone", "start"],
|
|
36
|
-
"resources": {
|
|
37
|
-
"required": ["docs://guide/workflow-steps", "docs://workflows/scene-design"],
|
|
38
|
-
"recommended": ["docs://recipes/manifest", "docs://ref/room-data-skeleton"]
|
|
39
|
-
},
|
|
40
|
-
"tools": ["create_room", "duplicate_room", "get_room_data"],
|
|
41
|
-
"checks": ["Choose template and room type before calling create_room.", "Capture returned roomId."]
|
|
42
|
-
},
|
|
43
|
-
{
|
|
44
|
-
"id": "scene-item",
|
|
45
|
-
"keywords": ["cube", "spawn", "portal", "npc", "light", "image", "glb", "item", "place", "add", "text", "video", "gun", "vehicle", "trigger", "jump pad", "leaderboard", "camera", "effect", "vfx", "collectible", "destructible", "billboard", "chart", "elemental"],
|
|
46
|
-
"resources": {
|
|
47
|
-
"required": ["docs://index/items"],
|
|
48
|
-
"recommended": ["docs://ref/pitfalls", "docs://ref/interactions/basic", "docs://reference/gotchas"]
|
|
49
|
-
},
|
|
50
|
-
"tools": ["lookup", "get_room_data", "apply_operations"],
|
|
51
|
-
"checks": ["Use lookup tool for specific item specs.", "Read room data before writing."]
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
"id": "gameplay-build",
|
|
55
|
-
"keywords": ["mechanic", "gameplay", "logic", "interaction", "trigger", "effect", "castle", "keypad", "minimap", "leaderboard", "score", "quest", "puzzle", "game", "board game", "hud", "ui", "display", "health bar", "timer"],
|
|
56
|
-
"resources": {
|
|
57
|
-
"required": ["docs://recipes/manifest", "docs://ref/systems/function-effector"],
|
|
58
|
-
"recommended": ["docs://ref/interactions/patterns", "docs://ref/interactions/quest-driven", "docs://ref/systems/quests", "docs://ref/room-data-skeleton", "docs://reference/gotchas", "docs://ref/systems/display-html"]
|
|
59
|
-
},
|
|
60
|
-
"tools": ["search_recipes", "lookup", "get_room_data", "apply_operations"],
|
|
61
|
-
"checks": ["Reuse recipes before custom implementation.", "Verify item/task counts after apply_operations."]
|
|
62
|
-
},
|
|
63
|
-
{
|
|
64
|
-
"id": "function-effects",
|
|
65
|
-
"keywords": ["functioneffector", "ncalc", "variable", "variables", "settask", "setvariable", "timer", "timers", "multiplayer", "team", "teams", "random", "condition", "conditional", "logic expression"],
|
|
66
|
-
"resources": {
|
|
67
|
-
"required": ["docs://ref/systems/function-effector"],
|
|
68
|
-
"recommended": ["docs://logic/js-function-reference", "docs://logic/js-use-effector", "docs://logic/expression-guide", "docs://logic/multiplayer", "docs://logic/string-variables", "docs://ref/interactions/quest-driven", "docs://ref/systems/quests", "docs://ref/systems/variables", "docs://reference/gotchas"]
|
|
69
|
-
},
|
|
70
|
-
"tools": ["search_recipes", "lookup", "get_room_data", "apply_operations"],
|
|
71
|
-
"checks": ["Decimal literals (0.0, 1.0) in expressions.", "Single quotes for string task states.", "Task names omit numbered prefix in NCalc."]
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
"id": "js-scripting",
|
|
75
|
-
"keywords": ["javascript", "js", "functioneffectorjs", "useeffector", "use effector", "onclick", "on click", "click function", "js function", "script", "hide object", "show object", "move to spot", "play sound", "change movement", "lock movement", "teleport", "change avatar", "change camera", "attach item", "displayhtml", "display html", "html overlay", "custom ui", "hud", "custom hud", "backdrop-filter", "html display", "game ui", "overlay", "html panel"],
|
|
76
|
-
"resources": {
|
|
77
|
-
"required": ["docs://logic/js-function-reference", "docs://logic/js-use-effector"],
|
|
78
|
-
"recommended": ["docs://ref/systems/function-effector", "docs://logic/string-variables", "docs://logic/multiplayer", "docs://reference/gotchas", "docs://logic/js-display-html"]
|
|
79
|
-
},
|
|
80
|
-
"tools": ["lookup", "get_room_data", "apply_operations"],
|
|
81
|
-
"checks": ["S: true REQUIRED with OnPlayerLoggedIn trigger.", "R: true for reactive variable watchers.", "V must be single-line (semicolons, not newlines).", "UseEffector effect names are case-sensitive.", "No PrintString in JS — use browser console.", "Use Number() not parseInt() to avoid octal trap.", "displayHtml: Variable names must be all-lowercase (e.g. 'ballx' not 'bX').", "displayHtml: Code after displayHtml() in same V field executes directly — can manipulate rendered HTML."]
|
|
82
|
-
},
|
|
83
|
-
{
|
|
84
|
-
"id": "logic-board",
|
|
85
|
-
"keywords": ["logic board", "flowchart", "circuit", "node", "nodes", "pulse", "diagram", "visualize", "visualise", "board"],
|
|
86
|
-
"resources": {
|
|
87
|
-
"required": ["docs://recipes/logic-board/implementation"],
|
|
88
|
-
"recommended": ["docs://ref/systems/function-effector", "docs://ref/interactions/quest-driven"]
|
|
89
|
-
},
|
|
90
|
-
"tools": ["get_room_data", "apply_operations"],
|
|
91
|
-
"checks": ["Keep board visuals and logic on same nodes.", "Verify parent-child links after write."]
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
"id": "local-scripting",
|
|
95
|
-
"keywords": ["python", "room-index", "query_room", "merge_room", "sync_room", "validate_room", "tooling", "helpers", "minimap", "check_storage"],
|
|
96
|
-
"resources": {
|
|
97
|
-
"required": ["docs://python/README"],
|
|
98
|
-
"recommended": ["docs://ref/systems/movement", "docs://ref/room-data-skeleton"]
|
|
99
|
-
},
|
|
100
|
-
"tools": ["get_room_data", "apply_operations", "query_room"],
|
|
101
|
-
"checks": ["Use query_room to search items by type, position, triggers, or text."]
|
|
102
|
-
},
|
|
103
|
-
{
|
|
104
|
-
"id": "validation-publish",
|
|
105
|
-
"keywords": ["validate", "test", "qa", "verify", "publish", "ship", "regression"],
|
|
106
|
-
"resources": {
|
|
107
|
-
"required": ["docs://workflows/quality-review"],
|
|
108
|
-
"recommended": ["docs://usage-rules"]
|
|
109
|
-
},
|
|
110
|
-
"tools": ["get_room_data", "apply_operations"],
|
|
111
|
-
"checks": ["Resolve all structural errors before publish.", "Keep last-known-good snapshot for rollback."]
|
|
112
|
-
},
|
|
113
|
-
{
|
|
114
|
-
"id": "asset-pipeline",
|
|
115
|
-
"keywords": ["upload", "asset", "glb", "model", "texture", "image", "png", "jpg", "jpeg", "gif", "cdn", "media"],
|
|
116
|
-
"resources": {
|
|
117
|
-
"required": ["docs://reference/glb-asset-catalog"],
|
|
118
|
-
"recommended": ["docs://ref/items/glb"]
|
|
119
|
-
},
|
|
120
|
-
"tools": ["upload_glb", "upload_image"],
|
|
121
|
-
"checks": ["Capture returned CDN URLs.", "Verify references after mutation."]
|
|
122
|
-
},
|
|
123
|
-
{
|
|
124
|
-
"id": "settings-update",
|
|
125
|
-
"keywords": ["settings", "name", "description", "cover", "loading", "images", "visibility", "hide", "loader"],
|
|
126
|
-
"resources": {
|
|
127
|
-
"required": ["docs://ref/settings"],
|
|
128
|
-
"recommended": ["docs://usage-rules"]
|
|
129
|
-
},
|
|
130
|
-
"tools": ["update_room_settings", "get_room_data"],
|
|
131
|
-
"checks": ["Provide at least one field besides roomId.", "Verify CustomLoader behavior if loading images changed."]
|
|
132
|
-
},
|
|
133
|
-
{
|
|
134
|
-
"id": "game-design-full",
|
|
135
|
-
"keywords": ["full build", "complete game", "design game", "new game", "game from scratch", "full game", "build game", "make game", "surprise me"],
|
|
136
|
-
"resources": {
|
|
137
|
-
"required": ["docs://guide/workflow-steps", "docs://workflows/scene-design"],
|
|
138
|
-
"recommended": ["docs://index/knowledge-map", "docs://recipes/manifest", "docs://ref/room-data-skeleton", "docs://ref/systems/display-html"]
|
|
139
|
-
},
|
|
140
|
-
"tools": ["search_recipes", "create_room", "get_room_data", "apply_operations", "analyze_scene", "render_scene"],
|
|
141
|
-
"checks": ["Design before building — write design.md first.", "Search recipes before inventing mechanics.", "Use modular build for 50+ item games.", "Run quality review before pushing."]
|
|
142
|
-
},
|
|
143
|
-
{
|
|
144
|
-
"id": "scene-design",
|
|
145
|
-
"keywords": ["compose", "composition", "spatial", "layout", "placement", "arrange", "density", "zones", "sightline", "scene design", "furnish", "decorate", "populate", "fill", "detail", "design review", "analyze scene", "scene analysis", "evaluate"],
|
|
146
|
-
"resources": {
|
|
147
|
-
"required": ["docs://workflows/scene-design", "docs://workflows/scene-design"],
|
|
148
|
-
"recommended": ["docs://reference/glb-asset-catalog"]
|
|
149
|
-
},
|
|
150
|
-
"tools": ["analyze_scene", "render_scene", "get_room_data", "apply_operations"],
|
|
151
|
-
"checks": ["Analyze scene before making composition changes.", "Use render_scene for visual verification.", "Compare before/after with compare_scene."]
|
|
152
|
-
},
|
|
153
|
-
{
|
|
154
|
-
"id": "room-targeting",
|
|
155
|
-
"keywords": ["edit", "existing", "current", "room id", "roomid", "room-id", "open"],
|
|
156
|
-
"resources": {
|
|
157
|
-
"required": ["docs://usage-rules"],
|
|
158
|
-
"recommended": []
|
|
159
|
-
},
|
|
160
|
-
"tools": ["get_room_data"],
|
|
161
|
-
"checks": ["Ask user for roomId if unknown.", "Always read room data before proposing writes."]
|
|
162
|
-
}
|
|
163
|
-
]
|
|
164
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"version": "3.0.0",
|
|
3
|
+
"description": "Data-driven intent profiles for context recommendation. Used by get_context to assemble inline knowledge.",
|
|
4
|
+
"base_resources": [
|
|
5
|
+
{ "uri": "docs://ai/bootstrap", "reason": "Execution policy.", "priority": 1 },
|
|
6
|
+
{ "uri": "docs://ai/contracts/tool-output-envelope", "reason": "Tool response schema.", "priority": 1 },
|
|
7
|
+
{ "uri": "docs://usage-rules", "reason": "Read/write conventions.", "priority": 1 },
|
|
8
|
+
{ "uri": "docs://guide/rules-and-conventions", "reason": "Core execution rules.", "priority": 1 },
|
|
9
|
+
{ "uri": "docs://index/knowledge-map", "reason": "Navigate all available content.", "priority": 2 }
|
|
10
|
+
],
|
|
11
|
+
"stage_hints": {
|
|
12
|
+
"setup": ["setup-auth"],
|
|
13
|
+
"design": ["create-room", "gameplay-build", "scene-design"],
|
|
14
|
+
"build": ["gameplay-build", "function-effects"],
|
|
15
|
+
"logic": ["function-effects", "js-scripting", "logic-board"],
|
|
16
|
+
"validate": ["validation-publish"],
|
|
17
|
+
"publish": ["validation-publish"],
|
|
18
|
+
"assets": ["asset-pipeline"],
|
|
19
|
+
"settings": ["settings-update"],
|
|
20
|
+
"scripting": ["local-scripting", "js-scripting"]
|
|
21
|
+
},
|
|
22
|
+
"intents": [
|
|
23
|
+
{
|
|
24
|
+
"id": "setup-auth",
|
|
25
|
+
"keywords": ["install", "setup", "auth", "authenticate", "connect", "key", "access", "mcp", "server", "config"],
|
|
26
|
+
"resources": {
|
|
27
|
+
"required": [],
|
|
28
|
+
"recommended": []
|
|
29
|
+
},
|
|
30
|
+
"tools": ["authenticate"],
|
|
31
|
+
"checks": ["Ensure authenticate returns ok=true.", "Persist PORTALS_ACCESS_KEY in MCP config."]
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"id": "create-room",
|
|
35
|
+
"keywords": ["create", "new", "template", "duplicate", "clone", "start"],
|
|
36
|
+
"resources": {
|
|
37
|
+
"required": ["docs://guide/workflow-steps", "docs://workflows/scene-design"],
|
|
38
|
+
"recommended": ["docs://recipes/manifest", "docs://ref/room-data-skeleton", "docs://reference/template-layouts"]
|
|
39
|
+
},
|
|
40
|
+
"tools": ["create_room", "duplicate_room", "get_room_data"],
|
|
41
|
+
"checks": ["Choose template and room type before calling create_room.", "Capture returned roomId."]
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
"id": "scene-item",
|
|
45
|
+
"keywords": ["cube", "spawn", "portal", "npc", "light", "image", "glb", "item", "place", "add", "text", "video", "gun", "vehicle", "trigger", "jump pad", "leaderboard", "camera", "effect", "vfx", "collectible", "destructible", "billboard", "chart", "elemental"],
|
|
46
|
+
"resources": {
|
|
47
|
+
"required": ["docs://index/items"],
|
|
48
|
+
"recommended": ["docs://ref/pitfalls", "docs://ref/interactions/basic", "docs://reference/gotchas", "docs://reference/template-layouts"]
|
|
49
|
+
},
|
|
50
|
+
"tools": ["lookup", "get_room_data", "apply_operations"],
|
|
51
|
+
"checks": ["Use lookup tool for specific item specs.", "Read room data before writing."]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"id": "gameplay-build",
|
|
55
|
+
"keywords": ["mechanic", "gameplay", "logic", "interaction", "trigger", "effect", "castle", "keypad", "minimap", "leaderboard", "score", "quest", "puzzle", "game", "board game", "hud", "ui", "display", "health bar", "timer"],
|
|
56
|
+
"resources": {
|
|
57
|
+
"required": ["docs://recipes/manifest", "docs://ref/systems/function-effector"],
|
|
58
|
+
"recommended": ["docs://ref/interactions/patterns", "docs://ref/interactions/quest-driven", "docs://ref/systems/quests", "docs://ref/room-data-skeleton", "docs://reference/gotchas", "docs://ref/systems/display-html"]
|
|
59
|
+
},
|
|
60
|
+
"tools": ["search_recipes", "lookup", "get_room_data", "apply_operations"],
|
|
61
|
+
"checks": ["Reuse recipes before custom implementation.", "Verify item/task counts after apply_operations."]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"id": "function-effects",
|
|
65
|
+
"keywords": ["functioneffector", "ncalc", "variable", "variables", "settask", "setvariable", "timer", "timers", "multiplayer", "team", "teams", "random", "condition", "conditional", "logic expression"],
|
|
66
|
+
"resources": {
|
|
67
|
+
"required": ["docs://ref/systems/function-effector"],
|
|
68
|
+
"recommended": ["docs://logic/js-function-reference", "docs://logic/js-use-effector", "docs://logic/expression-guide", "docs://logic/multiplayer", "docs://logic/string-variables", "docs://ref/interactions/quest-driven", "docs://ref/systems/quests", "docs://ref/systems/variables", "docs://reference/gotchas"]
|
|
69
|
+
},
|
|
70
|
+
"tools": ["search_recipes", "lookup", "get_room_data", "apply_operations"],
|
|
71
|
+
"checks": ["Decimal literals (0.0, 1.0) in expressions.", "Single quotes for string task states.", "Task names omit numbered prefix in NCalc."]
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
"id": "js-scripting",
|
|
75
|
+
"keywords": ["javascript", "js", "functioneffectorjs", "useeffector", "use effector", "onclick", "on click", "click function", "js function", "script", "hide object", "show object", "move to spot", "play sound", "change movement", "lock movement", "teleport", "change avatar", "change camera", "attach item", "displayhtml", "display html", "html overlay", "custom ui", "hud", "custom hud", "backdrop-filter", "html display", "game ui", "overlay", "html panel"],
|
|
76
|
+
"resources": {
|
|
77
|
+
"required": ["docs://logic/js-function-reference", "docs://logic/js-use-effector"],
|
|
78
|
+
"recommended": ["docs://ref/systems/function-effector", "docs://logic/string-variables", "docs://logic/multiplayer", "docs://reference/gotchas", "docs://logic/js-display-html"]
|
|
79
|
+
},
|
|
80
|
+
"tools": ["lookup", "get_room_data", "apply_operations"],
|
|
81
|
+
"checks": ["S: true REQUIRED with OnPlayerLoggedIn trigger.", "R: true for reactive variable watchers.", "V must be single-line (semicolons, not newlines).", "UseEffector effect names are case-sensitive.", "No PrintString in JS — use browser console.", "Use Number() not parseInt() to avoid octal trap.", "displayHtml: Variable names must be all-lowercase (e.g. 'ballx' not 'bX').", "displayHtml: Code after displayHtml() in same V field executes directly — can manipulate rendered HTML."]
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
"id": "logic-board",
|
|
85
|
+
"keywords": ["logic board", "flowchart", "circuit", "node", "nodes", "pulse", "diagram", "visualize", "visualise", "board"],
|
|
86
|
+
"resources": {
|
|
87
|
+
"required": ["docs://recipes/logic-board/implementation"],
|
|
88
|
+
"recommended": ["docs://ref/systems/function-effector", "docs://ref/interactions/quest-driven"]
|
|
89
|
+
},
|
|
90
|
+
"tools": ["get_room_data", "apply_operations"],
|
|
91
|
+
"checks": ["Keep board visuals and logic on same nodes.", "Verify parent-child links after write."]
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
"id": "local-scripting",
|
|
95
|
+
"keywords": ["python", "room-index", "query_room", "merge_room", "sync_room", "validate_room", "tooling", "helpers", "minimap", "check_storage"],
|
|
96
|
+
"resources": {
|
|
97
|
+
"required": ["docs://python/README"],
|
|
98
|
+
"recommended": ["docs://ref/systems/movement", "docs://ref/room-data-skeleton"]
|
|
99
|
+
},
|
|
100
|
+
"tools": ["get_room_data", "apply_operations", "query_room"],
|
|
101
|
+
"checks": ["Use query_room to search items by type, position, triggers, or text."]
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
"id": "validation-publish",
|
|
105
|
+
"keywords": ["validate", "test", "qa", "verify", "publish", "ship", "regression"],
|
|
106
|
+
"resources": {
|
|
107
|
+
"required": ["docs://workflows/quality-review"],
|
|
108
|
+
"recommended": ["docs://usage-rules"]
|
|
109
|
+
},
|
|
110
|
+
"tools": ["get_room_data", "apply_operations"],
|
|
111
|
+
"checks": ["Resolve all structural errors before publish.", "Keep last-known-good snapshot for rollback."]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"id": "asset-pipeline",
|
|
115
|
+
"keywords": ["upload", "asset", "glb", "model", "texture", "image", "png", "jpg", "jpeg", "gif", "cdn", "media"],
|
|
116
|
+
"resources": {
|
|
117
|
+
"required": ["docs://reference/glb-asset-catalog"],
|
|
118
|
+
"recommended": ["docs://ref/items/glb"]
|
|
119
|
+
},
|
|
120
|
+
"tools": ["upload_glb", "upload_image"],
|
|
121
|
+
"checks": ["Capture returned CDN URLs.", "Verify references after mutation."]
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"id": "settings-update",
|
|
125
|
+
"keywords": ["settings", "name", "description", "cover", "loading", "images", "visibility", "hide", "loader"],
|
|
126
|
+
"resources": {
|
|
127
|
+
"required": ["docs://ref/settings"],
|
|
128
|
+
"recommended": ["docs://usage-rules"]
|
|
129
|
+
},
|
|
130
|
+
"tools": ["update_room_settings", "get_room_data"],
|
|
131
|
+
"checks": ["Provide at least one field besides roomId.", "Verify CustomLoader behavior if loading images changed."]
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
"id": "game-design-full",
|
|
135
|
+
"keywords": ["full build", "complete game", "design game", "new game", "game from scratch", "full game", "build game", "make game", "surprise me"],
|
|
136
|
+
"resources": {
|
|
137
|
+
"required": ["docs://guide/workflow-steps", "docs://workflows/scene-design"],
|
|
138
|
+
"recommended": ["docs://index/knowledge-map", "docs://recipes/manifest", "docs://ref/room-data-skeleton", "docs://ref/systems/display-html", "docs://reference/template-layouts"]
|
|
139
|
+
},
|
|
140
|
+
"tools": ["search_recipes", "create_room", "get_room_data", "apply_operations", "analyze_scene", "render_scene"],
|
|
141
|
+
"checks": ["Design before building — write design.md first.", "Search recipes before inventing mechanics.", "Use modular build for 50+ item games.", "Run quality review before pushing."]
|
|
142
|
+
},
|
|
143
|
+
{
|
|
144
|
+
"id": "scene-design",
|
|
145
|
+
"keywords": ["compose", "composition", "spatial", "layout", "placement", "arrange", "density", "zones", "sightline", "scene design", "furnish", "decorate", "populate", "fill", "detail", "design review", "analyze scene", "scene analysis", "evaluate"],
|
|
146
|
+
"resources": {
|
|
147
|
+
"required": ["docs://workflows/scene-design", "docs://workflows/scene-design"],
|
|
148
|
+
"recommended": ["docs://reference/glb-asset-catalog", "docs://reference/template-layouts"]
|
|
149
|
+
},
|
|
150
|
+
"tools": ["analyze_scene", "render_scene", "get_room_data", "apply_operations"],
|
|
151
|
+
"checks": ["Analyze scene before making composition changes.", "Use render_scene for visual verification.", "Compare before/after with compare_scene."]
|
|
152
|
+
},
|
|
153
|
+
{
|
|
154
|
+
"id": "room-targeting",
|
|
155
|
+
"keywords": ["edit", "existing", "current", "room id", "roomid", "room-id", "open"],
|
|
156
|
+
"resources": {
|
|
157
|
+
"required": ["docs://usage-rules"],
|
|
158
|
+
"recommended": []
|
|
159
|
+
},
|
|
160
|
+
"tools": ["get_room_data"],
|
|
161
|
+
"checks": ["Ask user for roomId if unknown.", "Always read room data before proposing writes."]
|
|
162
|
+
}
|
|
163
|
+
]
|
|
164
|
+
}
|
|
@@ -113,13 +113,13 @@
|
|
|
113
113
|
"category": "gameplay",
|
|
114
114
|
"key_fields": {
|
|
115
115
|
"events": "array — legacy events (usually [])",
|
|
116
|
-
"pressBtn": "bool — require key press",
|
|
117
|
-
"keyCode": "string — key to press (X, H, E)",
|
|
116
|
+
"pressBtn": "bool — require key press while inside before firing OnEnterEvent tasks",
|
|
117
|
+
"keyCode": "string — InputHandler key to press (X, H, E, Alpha1)",
|
|
118
118
|
"cm": "string — custom press message",
|
|
119
119
|
"opacity": "float — editor opacity"
|
|
120
120
|
},
|
|
121
121
|
"valid_triggers": ["OnEnterEvent", "OnExitEvent", "OnKeyPressedEvent", "OnKeyReleasedEvent", "OnPlayerLoggedIn", "ScoreTrigger", "OnTimerStopped", "OnCountdownTimerFinished", "OnAnimationStoppedEvent", "OnPlayerDied", "OnPlayerRevived", "PlayerLeave"],
|
|
122
|
-
"notes": "Invisible during play. NEVER use OnClickEvent/OnHoverStart/OnHoverEnd on triggers.",
|
|
122
|
+
"notes": "Invisible during play. NEVER use OnClickEvent/OnHoverStart/OnHoverEnd on triggers. pressBtn:true gates OnEnterEvent until keyCode is pressed while inside; it is not global OnKeyPressedEvent.",
|
|
123
123
|
"spec_uri": "docs://ref/items/trigger-zone"
|
|
124
124
|
},
|
|
125
125
|
{
|
|
@@ -84,6 +84,13 @@
|
|
|
84
84
|
"uri": "docs://workflows/scene-design",
|
|
85
85
|
"children": []
|
|
86
86
|
},
|
|
87
|
+
{
|
|
88
|
+
"id": "scene.templates",
|
|
89
|
+
"label": "Template Layouts",
|
|
90
|
+
"description": "Live-verified operational zones, placement caveats, floor/terrain Y ranges, and QA status for built-in room templates",
|
|
91
|
+
"uri": "docs://reference/template-layouts",
|
|
92
|
+
"children": []
|
|
93
|
+
},
|
|
87
94
|
{
|
|
88
95
|
"id": "scene.assets",
|
|
89
96
|
"label": "Assets",
|
|
@@ -10,9 +10,9 @@
|
|
|
10
10
|
},
|
|
11
11
|
{
|
|
12
12
|
"$type": "OnEnterEvent",
|
|
13
|
-
"description": "Player enters trigger zone",
|
|
13
|
+
"description": "Player enters trigger zone. If the Trigger item has pressBtn:true, this fires only after the player enters and presses the Trigger keyCode.",
|
|
14
14
|
"applicable_items": ["Trigger"],
|
|
15
|
-
"gotchas": ["ONLY works on Trigger cubes, not ResizableCubes or GLBs"]
|
|
15
|
+
"gotchas": ["ONLY works on Trigger cubes, not ResizableCubes or GLBs", "pressBtn:true gates this trigger by keyCode while inside the zone; use simulate_trigger_zone_input to audit."]
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"$type": "OnExitEvent",
|
|
@@ -11,6 +11,7 @@ The Python toolkit provides validation, room analysis, and query tools. It is bu
|
|
|
11
11
|
**Via dedicated MCP tools**:
|
|
12
12
|
- `query_room` — search items by type, position, triggers, text, parent, or quest reference
|
|
13
13
|
- `simulate_key_input` — audit and simulate keyboard triggers against a snapshot
|
|
14
|
+
- `simulate_trigger_zone_input` — audit and simulate Trigger `pressBtn` / `keyCode` press-inside-zone behavior
|
|
14
15
|
- `apply_operations` — add, modify, remove items/logic/quests (auto-pulls fresh data, auto-validates)
|
|
15
16
|
- `get_room_data` — download room data with auto-generated index
|
|
16
17
|
|
|
@@ -33,6 +34,11 @@ For bulk builds, pass hundreds of operations in a single `apply_operations` call
|
|
|
33
34
|
|
|
34
35
|
Use the `query_room` MCP tool to search items without loading the full room JSON:
|
|
35
36
|
```
|
|
37
|
+
query_room(roomId: "...", types: ["GLB"], hasTriggers: true)
|
|
38
|
+
query_room(roomId: "...", near: {x:10, y:0, z:15}, radius: 5)
|
|
39
|
+
query_room(roomId: "...", search: "door")
|
|
40
|
+
query_room(roomId: "...", parent: "12")
|
|
41
|
+
```
|
|
36
42
|
|
|
37
43
|
## Auditing Keyboard Triggers
|
|
38
44
|
|
|
@@ -43,10 +49,11 @@ simulate_key_input(filePath: ".../snapshot.json", actions: [{type: "press", key:
|
|
|
43
49
|
```
|
|
44
50
|
|
|
45
51
|
Keyboard trigger keys must use Portals/Unity key-code names such as `Alpha1`, `Space`, `Return`, `LeftShift`, and `LeftArrow`.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
52
|
+
|
|
53
|
+
Use `simulate_trigger_zone_input` for Trigger cube `pressBtn` behavior. This is not a global `OnKeyPressedEvent`; it gates the Trigger's `OnEnterEvent` tasks until the player enters the zone and presses `keyCode`.
|
|
54
|
+
```
|
|
55
|
+
simulate_trigger_zone_input(filePath: ".../snapshot.json", actions: [{type: "enter", itemId: "12"}, {type: "press", key: "X"}])
|
|
56
|
+
simulate_trigger_zone_input(filePath: ".../snapshot.json", actions: [{type: "press", key: "X"}, {type: "enter", itemId: "12"}])
|
|
50
57
|
```
|
|
51
58
|
|
|
52
59
|
## Scripts (manual / Blender)
|
|
@@ -16,6 +16,8 @@ Usage:
|
|
|
16
16
|
|
|
17
17
|
from typing import Dict, Tuple, Optional
|
|
18
18
|
|
|
19
|
+
from portals_key_input import validate_key_code
|
|
20
|
+
|
|
19
21
|
|
|
20
22
|
def create_base_item(
|
|
21
23
|
prefab_name: str,
|
|
@@ -350,12 +352,14 @@ def create_trigger(
|
|
|
350
352
|
Notes:
|
|
351
353
|
- Invisible during play (visible in build mode)
|
|
352
354
|
- Two trigger types: User Enter and User Exit
|
|
355
|
+
- If press_button=True, OnEnterEvent tasks fire after the player enters
|
|
356
|
+
the zone and presses key_code; this is separate from OnKeyPressedEvent.
|
|
353
357
|
- Add effects via Tasks array (see portals_effects.py)
|
|
354
358
|
"""
|
|
355
359
|
logic = {
|
|
356
360
|
"events": [],
|
|
357
361
|
"cm": message,
|
|
358
|
-
"keyCode": key_code,
|
|
362
|
+
"keyCode": validate_key_code(key_code, "key_code"),
|
|
359
363
|
"Tasks": [],
|
|
360
364
|
"ViewNodes": []
|
|
361
365
|
}
|