summer-engine 3.1.0 → 3.2.0

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 (366) hide show
  1. package/.claude-plugin/marketplace.json +2 -2
  2. package/.claude-plugin/plugin.json +27 -5
  3. package/.codex-plugin/plugin.json +28 -6
  4. package/.cursor-plugin/plugin.json +27 -5
  5. package/.factory-plugin/plugin.json +27 -5
  6. package/.opencode/plugins/summer.js +1 -1
  7. package/CHANGELOG.md +102 -0
  8. package/README.md +18 -3
  9. package/assets/audit/scene_audit.gd +4136 -0
  10. package/assets/seeing/seeing_probe.gd +1873 -0
  11. package/dist/cli/commands/skills.js +20 -2
  12. package/dist/core/api-client.d.ts +9 -1
  13. package/dist/core/api-client.js +21 -4
  14. package/dist/core/capabilities/agent-playbook.js +46 -0
  15. package/dist/core/capabilities/audit/accept.d.ts +55 -0
  16. package/dist/core/capabilities/audit/accept.js +147 -0
  17. package/dist/core/capabilities/audit/args.d.ts +95 -0
  18. package/dist/core/capabilities/audit/args.js +89 -0
  19. package/dist/core/capabilities/audit/audit.d.ts +56 -0
  20. package/dist/core/capabilities/audit/audit.js +287 -0
  21. package/dist/core/capabilities/audit/frame.d.ts +14 -0
  22. package/dist/core/capabilities/audit/frame.js +35 -0
  23. package/dist/core/capabilities/audit/gaps.d.ts +96 -0
  24. package/dist/core/capabilities/audit/gaps.js +257 -0
  25. package/dist/core/capabilities/audit/judge.d.ts +162 -0
  26. package/dist/core/capabilities/audit/judge.js +1134 -0
  27. package/dist/core/capabilities/audit/math.d.ts +110 -0
  28. package/dist/core/capabilities/audit/math.js +263 -0
  29. package/dist/core/capabilities/audit/summary.d.ts +74 -0
  30. package/dist/core/capabilities/audit/summary.js +212 -0
  31. package/dist/core/capabilities/board.d.ts +31 -0
  32. package/dist/core/capabilities/board.js +43 -0
  33. package/dist/core/capabilities/camera-view.d.ts +4 -2
  34. package/dist/core/capabilities/camera-view.js +6 -3
  35. package/dist/core/capabilities/connect-signal.d.ts +85 -0
  36. package/dist/core/capabilities/connect-signal.js +285 -0
  37. package/dist/core/capabilities/engine-fallbacks.d.ts +5 -0
  38. package/dist/core/capabilities/engine-fallbacks.js +5 -0
  39. package/dist/core/capabilities/engine-ops.d.ts +5 -1
  40. package/dist/core/capabilities/engine-ops.js +0 -3
  41. package/dist/core/capabilities/engine-receipt.d.ts +12 -0
  42. package/dist/core/capabilities/engine-receipt.js +26 -0
  43. package/dist/core/capabilities/file-read.d.ts +64 -0
  44. package/dist/core/capabilities/file-read.js +325 -0
  45. package/dist/core/capabilities/game-task-plan.js +4 -2
  46. package/dist/core/capabilities/grep.d.ts +60 -0
  47. package/dist/core/capabilities/grep.js +190 -0
  48. package/dist/core/capabilities/inspect-node.d.ts +56 -0
  49. package/dist/core/capabilities/inspect-node.js +225 -0
  50. package/dist/core/capabilities/inspect-resource.d.ts +61 -0
  51. package/dist/core/capabilities/inspect-resource.js +376 -0
  52. package/dist/core/capabilities/math3d.d.ts +28 -0
  53. package/dist/core/capabilities/math3d.js +88 -0
  54. package/dist/core/capabilities/motion-generation.d.ts +62 -0
  55. package/dist/core/capabilities/motion-generation.js +138 -0
  56. package/dist/core/capabilities/placement-batch.d.ts +102 -0
  57. package/dist/core/capabilities/placement-batch.js +483 -0
  58. package/dist/core/capabilities/placement-math.d.ts +70 -0
  59. package/dist/core/capabilities/placement-math.js +209 -0
  60. package/dist/core/capabilities/placement-script.d.ts +42 -0
  61. package/dist/core/capabilities/placement-script.js +1096 -0
  62. package/dist/core/capabilities/placement.d.ts +485 -0
  63. package/dist/core/capabilities/placement.js +1731 -0
  64. package/dist/core/capabilities/project-context.d.ts +33 -2
  65. package/dist/core/capabilities/project-context.js +87 -4
  66. package/dist/core/capabilities/replace-node.d.ts +91 -0
  67. package/dist/core/capabilities/replace-node.js +423 -0
  68. package/dist/core/capabilities/runtime-control.d.ts +18 -2
  69. package/dist/core/capabilities/runtime-control.js +67 -2
  70. package/dist/core/capabilities/scene-batch.d.ts +63 -0
  71. package/dist/core/capabilities/scene-batch.js +394 -0
  72. package/dist/core/capabilities/scene-readback.d.ts +36 -0
  73. package/dist/core/capabilities/scene-readback.js +54 -0
  74. package/dist/core/capabilities/seeing/args.d.ts +348 -0
  75. package/dist/core/capabilities/seeing/args.js +178 -0
  76. package/dist/core/capabilities/seeing/candidates.d.ts +127 -0
  77. package/dist/core/capabilities/seeing/candidates.js +282 -0
  78. package/dist/core/capabilities/seeing/math.d.ts +134 -0
  79. package/dist/core/capabilities/seeing/math.js +269 -0
  80. package/dist/core/capabilities/seeing/probe.d.ts +62 -0
  81. package/dist/core/capabilities/seeing/probe.js +188 -0
  82. package/dist/core/capabilities/seeing/scoring.d.ts +235 -0
  83. package/dist/core/capabilities/seeing/scoring.js +639 -0
  84. package/dist/core/capabilities/seeing/seeing.d.ts +233 -0
  85. package/dist/core/capabilities/seeing/seeing.js +1341 -0
  86. package/dist/core/capabilities/seeing/shot-store.d.ts +52 -0
  87. package/dist/core/capabilities/seeing/shot-store.js +204 -0
  88. package/dist/core/capabilities/surface-snap-mesh.d.ts +88 -0
  89. package/dist/core/capabilities/surface-snap-mesh.js +425 -0
  90. package/dist/core/capabilities/surface-snap.d.ts +77 -0
  91. package/dist/core/capabilities/surface-snap.js +461 -0
  92. package/dist/core/capabilities/tool-dispatch.js +231 -72
  93. package/dist/core/capabilities/tscn.d.ts +85 -0
  94. package/dist/core/capabilities/tscn.js +391 -0
  95. package/dist/core/capabilities/world-snapshot.d.ts +58 -0
  96. package/dist/core/capabilities/world-snapshot.js +150 -0
  97. package/dist/core/capability-skew.d.ts +5 -5
  98. package/dist/core/capability-skew.js +14 -6
  99. package/dist/core/headless/worker-engine-client.d.ts +1 -1
  100. package/dist/core/headless/worker-engine-client.js +2 -2
  101. package/dist/core/library-read.d.ts +37 -5
  102. package/dist/core/library-read.js +264 -33
  103. package/dist/core/library-search.d.ts +2 -2
  104. package/dist/installer/agent-config.js +5 -3
  105. package/dist/installer/agent-table.d.ts +16 -0
  106. package/dist/installer/agent-table.js +52 -17
  107. package/dist/mcp/server.js +9 -3
  108. package/dist/mcp/tools/asset-tools.js +21 -3
  109. package/dist/mcp/tools/audit-tools.d.ts +23 -0
  110. package/dist/mcp/tools/audit-tools.js +60 -0
  111. package/dist/mcp/tools/debug-tools.js +3 -1
  112. package/dist/mcp/tools/file-tools.js +17 -4
  113. package/dist/mcp/tools/generate-tools.js +74 -66
  114. package/dist/mcp/tools/library-tools.js +2 -0
  115. package/dist/mcp/tools/perception-tools.js +6 -19
  116. package/dist/mcp/tools/placement-tools.d.ts +24 -0
  117. package/dist/mcp/tools/placement-tools.js +91 -0
  118. package/dist/mcp/tools/project-tools.js +18 -15
  119. package/dist/mcp/tools/scene-tools.js +71 -83
  120. package/dist/mcp/tools/seeing-tools.d.ts +24 -0
  121. package/dist/mcp/tools/seeing-tools.js +64 -0
  122. package/dist/mcp/tools/spatial-tools.js +17 -9
  123. package/dist/mcp/tools/visual-tools.js +59 -7
  124. package/gemini-extension.json +26 -4
  125. package/integrations/amp/README.md +1 -1
  126. package/integrations/crush/README.md +1 -1
  127. package/integrations/grok-build/README.md +1 -1
  128. package/integrations/hermes/README.md +1 -1
  129. package/integrations/kimi-code/README.md +1 -1
  130. package/integrations/mistral-vibe/README.md +1 -1
  131. package/integrations/opencode/README.md +1 -1
  132. package/integrations/rovo-dev/README.md +1 -1
  133. package/integrations/vscode-copilot/README.md +1 -1
  134. package/integrations/warp/README.md +1 -1
  135. package/integrations/windsurf/README.md +1 -1
  136. package/library/references/mcp-tools-reference/mcp-tools-reference.md +59 -15
  137. package/library/references/mcp-tools-reference/resource.yaml +1 -1
  138. package/library/references/summer-folder/resource.yaml +1 -1
  139. package/library/references/summer-folder/summer-folder.md +1 -1
  140. package/library/skills/3d-lighting/SKILL.md +1 -1
  141. package/library/skills/README.md +36 -14
  142. package/library/skills/adaptive-music/SKILL.md +1 -1
  143. package/library/skills/agent-playtesting/SKILL.md +1 -1
  144. package/library/skills/ai-characters-in-games/SKILL.md +220 -0
  145. package/library/skills/ai-characters-in-games/resource.yaml +30 -0
  146. package/library/skills/ambient-bed/SKILL.md +1 -1
  147. package/library/skills/animated-loop/SKILL.md +1 -1
  148. package/library/skills/animation-tree/SKILL.md +1 -1
  149. package/library/skills/art-direction/SKILL.md +1 -1
  150. package/library/skills/asset-strategy/SKILL.md +2 -1
  151. package/library/skills/asset-strategy/resource.yaml +2 -1
  152. package/library/skills/audio-direction/SKILL.md +1 -1
  153. package/library/skills/auto-fire-targeting/SKILL.md +1 -1
  154. package/library/skills/brainstorm-game/SKILL.md +1 -1
  155. package/library/skills/brainstorming/SKILL.md +1 -1
  156. package/library/skills/browse-templates/SKILL.md +3 -3
  157. package/library/skills/browse-templates/resource.yaml +1 -1
  158. package/library/skills/camera-rigs/SKILL.md +128 -0
  159. package/library/skills/camera-rigs/resource.yaml +29 -0
  160. package/library/skills/celeste-momentum-platforming/SKILL.md +1 -1
  161. package/library/skills/character-animation-wiring/SKILL.md +1 -1
  162. package/library/skills/character-model/SKILL.md +1 -1
  163. package/library/skills/character-movement/SKILL.md +326 -0
  164. package/library/skills/character-movement/references/default-third-person-controller.gd +201 -0
  165. package/library/skills/character-movement/references/default-third-person-verification-probe.gd +154 -0
  166. package/library/skills/character-movement/references/movement-3d.md +136 -0
  167. package/library/skills/character-movement/references/platformer-feel.md +83 -0
  168. package/library/skills/character-movement/resource.yaml +40 -0
  169. package/library/skills/character-portrait/SKILL.md +1 -1
  170. package/library/skills/cinematic-cutscene/SKILL.md +1 -1
  171. package/library/skills/combat-basics/SKILL.md +159 -0
  172. package/library/skills/combat-basics/references/projectiles-and-aoe.md +100 -0
  173. package/library/skills/combat-basics/resource.yaml +34 -0
  174. package/library/skills/concept-art/SKILL.md +1 -1
  175. package/library/skills/create-asset-sheet/SKILL.md +1 -1
  176. package/library/skills/debug/SKILL.md +1 -1
  177. package/library/skills/debugging-game-feel/SKILL.md +1 -1
  178. package/library/skills/design-level/SKILL.md +1 -1
  179. package/library/skills/design-mechanic/SKILL.md +1 -1
  180. package/library/skills/design-npc/SKILL.md +1 -1
  181. package/library/skills/diagnosing-perf-regressions/SKILL.md +1 -1
  182. package/library/skills/dispatching-parallel-agents/SKILL.md +1 -1
  183. package/library/skills/driving-the-editor-ui/SKILL.md +1 -1
  184. package/library/skills/environment-kit/SKILL.md +1 -1
  185. package/library/skills/export-and-ship/SKILL.md +1 -1
  186. package/library/skills/fabricating-assets/SKILL.md +1 -1
  187. package/library/skills/facial-and-lipsync/SKILL.md +1 -1
  188. package/library/skills/fps-controller/SKILL.md +9 -7
  189. package/library/skills/fps-controller/resource.yaml +4 -1
  190. package/library/skills/game-feel/SKILL.md +1 -1
  191. package/library/skills/gameskill/SKILL.md +1 -1
  192. package/library/skills/gdscript-patterns/SKILL.md +1 -1
  193. package/library/skills/generate-motion/SKILL.md +9 -9
  194. package/library/skills/generate-motion/resource.yaml +2 -1
  195. package/library/skills/godogen-visual-proof-game-generation/SKILL.md +1 -1
  196. package/library/skills/headless-scripting/SKILL.md +1 -1
  197. package/library/skills/in-game-purchases/SKILL.md +254 -0
  198. package/library/skills/in-game-purchases/resource.yaml +29 -0
  199. package/library/skills/instantiate-asset-pack/SKILL.md +1 -1
  200. package/library/skills/investigating-bugs/SKILL.md +1 -1
  201. package/library/skills/lumera-single-image-scene-reconstruction/SKILL.md +1 -1
  202. package/library/skills/make-game/SKILL.md +25 -3
  203. package/library/skills/make-game/references/2d-platformer-polish.md +93 -0
  204. package/library/skills/make-game/references/2d-platformer.md +117 -0
  205. package/library/skills/make-game/references/2d-rpg-content.md +234 -0
  206. package/library/skills/make-game/references/2d-rpg.md +241 -0
  207. package/library/skills/make-game/references/2d-survivors-progression.md +201 -0
  208. package/library/skills/make-game/references/2d-survivors.md +237 -0
  209. package/library/skills/make-game/references/3d-fps-systems.md +216 -0
  210. package/library/skills/make-game/references/3d-fps.md +177 -0
  211. package/library/skills/make-game/references/3d-horror-systems.md +186 -0
  212. package/library/skills/make-game/references/3d-horror.md +201 -0
  213. package/library/skills/make-game/references/3d-third-person-systems.md +220 -0
  214. package/library/skills/make-game/references/3d-third-person.md +215 -0
  215. package/library/skills/make-game/resource.yaml +6 -1
  216. package/library/skills/multiplayer/SKILL.md +150 -0
  217. package/library/skills/multiplayer/resource.yaml +33 -0
  218. package/library/skills/multiplayer-movement/SKILL.md +510 -0
  219. package/library/skills/multiplayer-movement/files.md +501 -0
  220. package/library/skills/multiplayer-movement/resource.yaml +30 -0
  221. package/library/skills/multiplayer-project/SKILL.md +521 -0
  222. package/library/skills/multiplayer-project/files.md +448 -0
  223. package/library/skills/multiplayer-project/resource.yaml +36 -0
  224. package/library/skills/multiplayer-publish/SKILL.md +229 -0
  225. package/library/skills/multiplayer-publish/export-errors.md +89 -0
  226. package/library/skills/multiplayer-publish/resource.yaml +28 -0
  227. package/library/skills/multiplayer-state/SKILL.md +438 -0
  228. package/library/skills/multiplayer-state/files.md +592 -0
  229. package/library/skills/multiplayer-state/resource.yaml +35 -0
  230. package/library/skills/multiplayer-testing/SKILL.md +236 -0
  231. package/library/skills/multiplayer-testing/resource.yaml +39 -0
  232. package/library/skills/music-track/SKILL.md +1 -1
  233. package/library/skills/navigate-summer/SKILL.md +1 -1
  234. package/library/skills/new-project/SKILL.md +1 -1
  235. package/library/skills/organic-model/SKILL.md +1 -1
  236. package/library/skills/pixel-art/SKILL.md +1 -1
  237. package/library/skills/play/SKILL.md +1 -1
  238. package/library/skills/playtesting-a-feature/SKILL.md +1 -1
  239. package/library/skills/procedural-animation/SKILL.md +2 -2
  240. package/library/skills/procedural-animation/resource.yaml +1 -1
  241. package/library/skills/prop-model/SKILL.md +1 -1
  242. package/library/skills/psx-retro-rendering/SKILL.md +1 -1
  243. package/library/skills/realtime-wet-surfaces/SKILL.md +2 -2
  244. package/library/skills/remote-deploy/SKILL.md +1 -1
  245. package/library/skills/retarget/SKILL.md +1 -1
  246. package/library/skills/running-in-the-cloud/SKILL.md +1 -1
  247. package/library/skills/save-load/SKILL.md +156 -0
  248. package/library/skills/save-load/resource.yaml +27 -0
  249. package/library/skills/scene-composition/SKILL.md +1 -1
  250. package/library/skills/scene-hierarchy-design/SKILL.md +1 -1
  251. package/library/skills/scene-scripting/SKILL.md +1 -1
  252. package/library/skills/scene-to-level/SKILL.md +1 -1
  253. package/library/skills/skill-create/SKILL.md +1 -1
  254. package/library/skills/skill-improve/SKILL.md +1 -1
  255. package/library/skills/skill-test/SKILL.md +1 -1
  256. package/library/skills/skintokens-auto-rigging/SKILL.md +1 -1
  257. package/library/skills/skybox-panorama/SKILL.md +1 -1
  258. package/library/skills/sound-effect/SKILL.md +1 -1
  259. package/library/skills/spatial-placement/SKILL.md +134 -3
  260. package/library/skills/spatial-placement/references/kit-placement-tools.md +364 -0
  261. package/library/skills/spatial-placement/resource.yaml +16 -2
  262. package/library/skills/sprite-sheet/SKILL.md +1 -1
  263. package/library/skills/summer-analytics/SKILL.md +147 -0
  264. package/library/skills/summer-analytics/resource.yaml +28 -0
  265. package/library/skills/summer-friends/SKILL.md +226 -0
  266. package/library/skills/summer-friends/resource.yaml +28 -0
  267. package/library/skills/summer-leaderboards/SKILL.md +231 -0
  268. package/library/skills/summer-leaderboards/resource.yaml +30 -0
  269. package/library/skills/summer-match-results/SKILL.md +286 -0
  270. package/library/skills/summer-match-results/resource.yaml +32 -0
  271. package/library/skills/summer-matchmaking/SKILL.md +301 -0
  272. package/library/skills/summer-matchmaking/resource.yaml +32 -0
  273. package/library/skills/summer-parties/SKILL.md +253 -0
  274. package/library/skills/summer-parties/resource.yaml +30 -0
  275. package/library/skills/summer-player-data/SKILL.md +322 -0
  276. package/library/skills/summer-player-data/resource.yaml +30 -0
  277. package/library/skills/summer-store/SKILL.md +271 -0
  278. package/library/skills/summer-store/resource.yaml +29 -0
  279. package/library/skills/summer-world-chat/SKILL.md +195 -0
  280. package/library/skills/summer-world-chat/resource.yaml +30 -0
  281. package/library/skills/summer-world-saves/SKILL.md +284 -0
  282. package/library/skills/summer-world-saves/resource.yaml +29 -0
  283. package/library/skills/text-to-motion/SKILL.md +99 -0
  284. package/library/skills/text-to-motion/prompts-and-controls.md +34 -0
  285. package/library/skills/text-to-motion/resource.yaml +41 -0
  286. package/library/skills/text-to-motion/rigging-for-text-motion.md +54 -0
  287. package/library/skills/tileable-texture/SKILL.md +1 -1
  288. package/library/skills/trailer-shot/SKILL.md +1 -1
  289. package/library/skills/tune-performance/SKILL.md +1 -1
  290. package/library/skills/ui-basics/SKILL.md +10 -1
  291. package/library/skills/ui-graphics/SKILL.md +1 -1
  292. package/library/skills/use-widget-asset/SKILL.md +1 -1
  293. package/library/skills/using-summer/SKILL.md +2 -2
  294. package/library/skills/using-summer/resource.yaml +2 -2
  295. package/library/skills/vehicle-model/SKILL.md +1 -1
  296. package/library/skills/verification-before-completion/SKILL.md +1 -1
  297. package/library/skills/verifying-scenes/SKILL.md +76 -2
  298. package/library/skills/verifying-scenes/resource.yaml +13 -2
  299. package/library/skills/vfx-dissolve/SKILL.md +1 -1
  300. package/library/skills/vfx-fire/SKILL.md +1 -1
  301. package/library/skills/vfx-hit-spark/SKILL.md +1 -1
  302. package/library/skills/vfx-lightning/SKILL.md +1 -1
  303. package/library/skills/vfx-magic-glow/SKILL.md +1 -1
  304. package/library/skills/vfx-muzzle-flash/SKILL.md +1 -1
  305. package/library/skills/vfx-smoke/SKILL.md +1 -1
  306. package/library/skills/vfx-water-ripple/SKILL.md +1 -1
  307. package/library/skills/voice-line/SKILL.md +1 -1
  308. package/library/skills/web-and-touch-input/SKILL.md +38 -0
  309. package/library/skills/web-and-touch-input/resource.yaml +28 -0
  310. package/library/skills/web-compatibility-look/SKILL.md +62 -0
  311. package/library/skills/web-compatibility-look/resource.yaml +30 -0
  312. package/library/skills/world-building-3d/SKILL.md +8 -1
  313. package/library/skills/world-building-3d/references/spatial-tools.md +1 -1
  314. package/library/skills/world-building-3d/resource.yaml +2 -1
  315. package/library/skills/writing-plans/SKILL.md +1 -1
  316. package/library/skills/writing-skills/SKILL.md +1 -1
  317. package/library/templates/3d-lan-multiplayer-starter/resource.yaml +2 -2
  318. package/library/tools/attach-to-surface/resource.yaml +142 -0
  319. package/library/tools/batch/resource.yaml +9 -3
  320. package/library/tools/connect-ports/resource.yaml +120 -0
  321. package/library/tools/connect-signal/resource.yaml +3 -2
  322. package/library/tools/debug-views/resource.yaml +94 -0
  323. package/library/tools/frame-nodes/resource.yaml +104 -0
  324. package/library/tools/frame-shot/resource.yaml +134 -0
  325. package/library/tools/generate-motion/resource.yaml +44 -9
  326. package/library/tools/get-board/resource.yaml +50 -0
  327. package/library/tools/get-project-context/resource.yaml +13 -2
  328. package/library/tools/grep/resource.yaml +77 -0
  329. package/library/tools/inspect-asset/resource.yaml +71 -0
  330. package/library/tools/inspect-node/resource.yaml +9 -2
  331. package/library/tools/inspect-resource/resource.yaml +16 -5
  332. package/library/tools/instantiate-scene/resource.yaml +27 -2
  333. package/library/tools/measure/resource.yaml +96 -0
  334. package/library/tools/place-adjacent/resource.yaml +113 -0
  335. package/library/tools/play/resource.yaml +15 -2
  336. package/library/tools/raycast/resource.yaml +101 -0
  337. package/library/tools/read-file/resource.yaml +36 -2
  338. package/library/tools/read-library/resource.yaml +2 -2
  339. package/library/tools/repeat-along/resource.yaml +129 -0
  340. package/library/tools/replace-node/resource.yaml +11 -5
  341. package/library/tools/scene-audit/resource.yaml +144 -0
  342. package/library/tools/screenshot/resource.yaml +13 -2
  343. package/library/tools/search-assets/resource.yaml +18 -0
  344. package/library/tools/shot-sheet/resource.yaml +110 -0
  345. package/library/tools/snap-to-surface/resource.yaml +4 -1
  346. package/library/tools/world-snapshot/resource.yaml +24 -3
  347. package/library/tools/zoom/resource.yaml +105 -0
  348. package/package.json +1 -1
  349. package/registry/generated/aliases.json +17 -3
  350. package/registry/generated/counts.json +3 -3
  351. package/registry/generated/gemini-extension.json +26 -4
  352. package/registry/generated/index.json +2154 -469
  353. package/registry/generated/marketplace.claude.json +2 -2
  354. package/registry/generated/plugin.claude.json +27 -5
  355. package/registry/generated/plugin.codex.json +28 -6
  356. package/registry/generated/plugin.cursor.json +27 -5
  357. package/registry/generated/plugin.factory.json +27 -5
  358. package/registry/generated/skills-index.md +36 -14
  359. package/registry/generated/skills-registry.json +421 -124
  360. package/registry/generated/templates-registry.json +2 -2
  361. package/library/skills/host-authoritative-state/SKILL.md +0 -332
  362. package/library/skills/host-authoritative-state/resource.yaml +0 -28
  363. package/library/skills/peer-to-peer-multiplayer/SKILL.md +0 -373
  364. package/library/skills/peer-to-peer-multiplayer/resource.yaml +0 -28
  365. package/library/skills/setup-multiplayer/SKILL.md +0 -336
  366. package/library/skills/setup-multiplayer/resource.yaml +0 -28
@@ -0,0 +1,271 @@
1
+ ---
2
+ name: summer-store
3
+ description: "Sell Summer items for Sparks in a multiplayer game: shop, checkout, owned items, authority entitlement checks."
4
+ license: MIT
5
+ compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
+ category: multiplayer-and-networking
7
+ user-invocable: true
8
+ allowed-tools: Read Grep Edit Write summer_get_script_errors summer_project_setting summer_play summer_stop summer_get_diagnostics
9
+ paths: ["**/*.gd", ".summer/test-users.json"]
10
+ ---
11
+
12
+ # /summer-store — sell items, check what players own
13
+
14
+ ## Overview
15
+
16
+ Players pay with **Sparks**, Summer's currency. Your game never touches money,
17
+ balances or approval:
18
+
19
+ 1. The client lists your published offers with `Summer.client.store.list_items()`.
20
+ 2. The player presses Buy. The client asks for a checkout with offer ids and quantities, never prices.
21
+ 3. The Summer app shows its own purchase sheet. The player approves or declines there.
22
+ 4. Summer charges the Sparks and issues the item into the player's **inventory**.
23
+ 5. The game sees the item in `Summer.client.items` (client) and `Summer.authority.items` (authority).
24
+
25
+ Three ids, kept apart:
26
+
27
+ | Id | Where it comes from | Use it for |
28
+ | --- | --- | --- |
29
+ | Offer id | `item.price.offer_id` in the store listing | `SummerCheckoutLine.create(offer_id, quantity)` |
30
+ | Definition id | Your item definition in the Summer catalog | "Does this player own a hat?" |
31
+ | Owned item id | One owned copy (`item.get_owned_item_id()`) | Pointing at a specific owned copy |
32
+
33
+ The rule that makes it cheat-proof: **the authority decides what a player may
34
+ use by reading that player's inventory itself.** A client saying "I bought it"
35
+ proves nothing.
36
+
37
+ **What runs where:**
38
+
39
+ | Surface | Store and checkout | Inventory |
40
+ | --- | --- | --- |
41
+ | Hosted | Need the Summer app's `player.store.read@1` / `player.store.checkout@1` | Needs `player.items@1` |
42
+ | Local Play | `unavailable` | Works from a fixture: empty unless `.summer/test-users.json` lists item templates (step 5) |
43
+ | Guests, older Summer apps | Readiness reports `unavailable` | Readiness reports `unavailable` |
44
+
45
+ Items and offers are created in your game's Studio pages (`summer_open` target
46
+ `game`). Code never creates items.
47
+
48
+ This skill extends the Courtyard game from `skill/multiplayer-project` and
49
+ `skill/multiplayer-state`.
50
+
51
+ ## Steps
52
+
53
+ ### 1. The client shop
54
+
55
+ `client/shop.gd`, a child `Shop` of `Main`. In `client/main.gd`'s `_ready()`, call
56
+ `$Shop.start()` right after `Summer.initialize` succeeds:
57
+
58
+ ```gdscript
59
+ extends Node
60
+ ## A shop for Summer items, paid in Sparks. Summer shows its own purchase
61
+ ## sheet; the game never sees money and never grants an item itself.
62
+
63
+ signal shelf_changed(rows: Array) # [{name, sparks, offer_id}]
64
+ signal checkouts_changed(busy: bool, rows: Array)
65
+ signal status(text: String)
66
+
67
+ var store: SummerClientStore
68
+ var items: SummerClientItems
69
+
70
+
71
+ ## Main calls this right after Summer.initialize succeeds: a child's _ready
72
+ ## runs before that, while Summer.client is still null.
73
+ func start() -> void:
74
+ store = Summer.client.store
75
+ items = Summer.client.items
76
+ # Connect before reading retained statuses; a normal (not deferred)
77
+ # connection is how the SDK knows a result was delivered.
78
+ store.checkout_status_changed.connect(func(_status: SummerCheckoutStatus) -> void: _render_checkouts())
79
+ items.refreshed.connect(_on_items_changed)
80
+ items.item_replaced.connect(func(_change: SummerInventoryChange) -> void: _on_items_changed())
81
+ items.item_removed.connect(func(_change: SummerInventoryChange) -> void: _on_items_changed())
82
+ _render_checkouts()
83
+
84
+
85
+ ## Opening the shop screen.
86
+ func open() -> void:
87
+ var readiness := store.check_browse_readiness()
88
+ if not readiness.ok:
89
+ status.emit("The shop is not available here.") # hide the shop button
90
+ return
91
+ var page := store.list_items(50)
92
+ var listed: SummerResult = await page.get_result_or_completed_signal()
93
+ if not listed.ok:
94
+ status.emit("The shop could not load.")
95
+ return
96
+ var rows := []
97
+ for item in page.items:
98
+ if item.price != null and item.price.offer_id != "":
99
+ rows.append({"name": item.name, "sparks": item.price.sparks_amount, "offer_id": item.price.offer_id})
100
+ shelf_changed.emit(rows)
101
+ if items.check_refresh_readiness().ok:
102
+ items.refresh()
103
+
104
+
105
+ ## The Buy button. One call is one purchase: never call it again to retry.
106
+ func buy(offer_id: String) -> void:
107
+ if not store.check_checkout_readiness().ok:
108
+ status.emit("Purchases are not available here.")
109
+ return
110
+ if store.has_pending_checkouts():
111
+ return
112
+ var lines: Array[SummerCheckoutLine] = [SummerCheckoutLine.create(offer_id, 1)]
113
+ var operation := store.request_checkout(lines)
114
+ _render_checkouts()
115
+ await operation.get_result_or_completed_signal()
116
+ _render_checkouts(operation)
117
+
118
+
119
+ func _render_checkouts(operation: SummerCheckoutOperation = null) -> void:
120
+ var view := SummerCheckoutObservation.capture(store, operation)
121
+ var rows := []
122
+ for checkout in view.statuses:
123
+ rows.append({"id": checkout.request_id, "state": checkout.state, "error": checkout.error_code})
124
+ checkouts_changed.emit(view.has_pending_checkouts(), rows)
125
+ if view.submission_failure != null:
126
+ status.emit("The purchase did not start: %s" % view.submission_failure.code)
127
+
128
+
129
+ ## Ownership comes only from the inventory, never from a checkout result.
130
+ func owns(definition_id: String) -> bool:
131
+ return items.is_projection_loaded() and items.has_owned_definition(definition_id)
132
+
133
+
134
+ func _on_items_changed() -> void:
135
+ status.emit("Inventory updated.")
136
+ ```
137
+
138
+ Bind `checkouts_changed` to the Buy buttons: disable them while `busy` is
139
+ true. Update rows by `id`; a status can be delivered again after a crash, so
140
+ rendering must be idempotent. Show each checkout state:
141
+
142
+ | `state` | Show |
143
+ | --- | --- |
144
+ | `awaiting_approval`, `pending` | "Waiting for Summer…" |
145
+ | `purchased` | "Bought!" The item arrives through the inventory signals, possibly a moment later |
146
+ | `declined`, `expired` | Nothing, or "Cancelled" |
147
+ | `rejected` with `error_code` `insufficient_funds` | "Not enough Sparks" (players get Sparks in the Summer app) |
148
+ | `rejected`, other codes | "The purchase was not completed" |
149
+ | `manual_review` | "We're confirming this purchase." Not done, not failed |
150
+
151
+ ### 2. Unlock from the inventory only
152
+
153
+ Unlock cosmetics in menus with `owns(definition_id)`, and refresh the menu on
154
+ `refreshed`, `item_replaced` and `item_removed`. Never unlock from a
155
+ `purchased` status: the receipt proves the debit, the inventory proves
156
+ ownership, including after a reinstall or on another device. An empty inventory
157
+ before `is_projection_loaded()` is "still loading", not "owns nothing".
158
+
159
+ ### 3. The authority checks entitlement
160
+
161
+ Anything that changes the match because of an item goes through a Command, and
162
+ the authority reads that Session's inventory. Add `"equip"` to the `match` in
163
+ `authority/main.gd`'s `_on_command`:
164
+
165
+ ```gdscript
166
+ "equip":
167
+ _equip(request, str(command.get("definition", "")))
168
+ ```
169
+
170
+ ```gdscript
171
+ ## A player asks to wear a hat. The authority reads that Session's inventory
172
+ ## itself; a client saying "I own it" proves nothing.
173
+ func _equip(request: SummerNetworkCommandRequest, definition_id: String) -> void:
174
+ var session := request.get_session()
175
+ var read := Summer.authority.items.inventory_for_session(session)
176
+ var result: SummerResult = await read.get_result_or_completed_signal()
177
+ if not result.ok:
178
+ request.refuse(&"inventory_unavailable") # retryable: try again later
179
+ return
180
+ for item in read.items:
181
+ if item.is_owned() and item.get_definition_id() == definition_id:
182
+ var hats: Dictionary = match_doc.get("hats", {})
183
+ hats[session.player.user_id] = definition_id
184
+ match_doc["hats"] = hats
185
+ match_group.reset(Game.pack(match_doc))
186
+ request.accept({}, Game.pack({"equipped": definition_id}))
187
+ return
188
+ request.refuse(&"not_owned")
189
+ ```
190
+
191
+ The client sends `await command({"c": "equip", "definition": definition_id})`
192
+ and every client draws hats from `match_doc.hats`. Other players see the hat
193
+ only because the authority published it.
194
+
195
+ `Summer.authority.items.inventory_changed(session, change)` hints that a
196
+ player's inventory changed during the match. To drop an item that was
197
+ refunded mid-match, re-read with `inventory_for_session` (or
198
+ `refresh_inventory`) on that hint.
199
+
200
+ ### 4. Rules and why
201
+
202
+ - **Offer ids and quantities only.** Never send a price, an amount or a buyer. The platform prices everything, and a client-side price is what a cheater edits.
203
+ - **One `request_checkout` is one purchase.** Each call gets a new identity. Never call it again because a result is slow; `is_outcome_unknown()` means it may already be charged, and the status will still arrive.
204
+ - **Connect `checkout_status_changed` normally, before reading statuses.** A synchronous handler is how the SDK knows the result was delivered; a deferred-only handler leaves it undelivered.
205
+ - **`pending` and `manual_review` are not failures.** Don't show success or failure until a terminal state.
206
+ - **Carts:** 1–16 different offers, at most 64 units, as one atomic purchase.
207
+ - **Hide what's unavailable.** `check_browse_readiness()` and `check_checkout_readiness()` return a `SummerResult`; show the shop only when they're `ok`.
208
+
209
+ ### 5. Test
210
+
211
+ **Local Play.** The store and checkout report `unavailable`, so the hidden-shop
212
+ path is what you test. Inventory and the authority check work from a fixture:
213
+ create `.summer/test-users.json` with item templates.
214
+
215
+ ```json
216
+ {
217
+ "schema": "summer.local-fixture.v1",
218
+ "fixture_id": "courtyard",
219
+ "fixture_version": 1,
220
+ "seed": 1,
221
+ "world_definition": "world.json",
222
+ "service_outcomes": [],
223
+ "catalog_item_templates": ["hat"],
224
+ "personas": [
225
+ {"persona_id": "alice", "display_name": "Alice", "participant_role": "player", "eligible_for_outcome": true, "session_lifetime": "match_bound"},
226
+ {"persona_id": "bob", "display_name": "Bob", "participant_role": "player", "eligible_for_outcome": true, "session_lifetime": "match_bound"}
227
+ ]
228
+ }
229
+ ```
230
+
231
+ What the fixture gives you:
232
+
233
+ - Every persona owns one item per template.
234
+ - Ids are local stand-ins. Bob's hat has owned item id `local-item:bob:0`, definition id `local-definition:courtyard:0`, and `item_template_version_id` `"hat"`.
235
+ - A check against your real catalog definition id is therefore `false` in Local Play. To exercise the authority path locally, equip with the local definition id the client reads from `items.get_owned_items()`.
236
+
237
+ **Staging.** Test real purchases there; Summer staging uses sandbox payments.
238
+ Walk through every outcome:
239
+
240
+ - decline the sheet;
241
+ - buy with too few Sparks;
242
+ - buy, then kill the game while the purchase is pending and relaunch: the result must arrive exactly once.
243
+
244
+ ## Checklist
245
+
246
+ - [ ] Local Play: the shop button is hidden, and there are no script errors.
247
+ - [ ] Local Play with the fixture: `items.refresh()` succeeds, the owned item is listed, `equip` is accepted for it and refused with `not_owned` for anything else.
248
+ - [ ] No code path sends a price or grants an item from a checkout status.
249
+ - [ ] Buy is disabled while `has_pending_checkouts()` is true.
250
+ - [ ] `manual_review` shows "confirming", not success or failure.
251
+ - [ ] Staging: a purchase shows up in the inventory, and the equipped item appears for every player.
252
+
253
+ ## Common mistakes
254
+
255
+ | Don't | Do | Why |
256
+ | --- | --- | --- |
257
+ | Unlock on `purchased` | Unlock from `Summer.client.items` | Ownership lives in the inventory; receipts can replay |
258
+ | Let the client tell the authority what it owns | `Summer.authority.items.inventory_for_session(session)` | Client claims are what cheaters forge |
259
+ | Send prices or amounts | Offer id + quantity only | The platform prices every purchase |
260
+ | Call `request_checkout` again on a slow result | Wait for its status; check `is_outcome_unknown()` | The first request may already be charged |
261
+ | Connect the status signal deferred or after reading statuses | Connect normally, first | Deferred handlers don't count as delivered; statuses can be missed |
262
+ | Treat `manual_review` as failed | Show "confirming" | The platform hasn't decided yet |
263
+ | Invent your own paid currency | Sell Summer items for Sparks | Summer can only protect, refund and pay out Sparks purchases |
264
+ | Assume the shop exists everywhere | Check readiness, hide when unavailable | Local Play, guests and older Summer apps have no store |
265
+
266
+ ## See also
267
+
268
+ - `skill/multiplayer-state`: Commands and the match document used for equipped items
269
+ - `skill/multiplayer-testing`: Local Play fixtures and personas
270
+ - `skill/summer-player-data`: saving a player's loadout between matches
271
+ - `skill/summer-analytics`: measuring the shop
@@ -0,0 +1,29 @@
1
+ id: skill/summer-store
2
+ kind: skill
3
+ version: 1.0.0
4
+ summary: "Sell Summer items for Sparks in a multiplayer game: shop, checkout, owned items, authority entitlement checks."
5
+ use_when:
6
+ - "adding a shop, in-game purchases, cosmetics or skins sold for Sparks to a Summer game"
7
+ - "checking on the authority that a player really owns an item before letting them use or equip it"
8
+ - "checkout shows pending, manual_review, insufficient_funds or unavailable, or bought items don't appear"
9
+ facets:
10
+ lifecycle:
11
+ - build
12
+ domains:
13
+ - multiplayer
14
+ - gameplay
15
+ modalities:
16
+ - scripts
17
+ compatibility:
18
+ engine: ">=4.6"
19
+ related:
20
+ skills:
21
+ - skill/multiplayer
22
+ - skill/multiplayer-state
23
+ - skill/multiplayer-testing
24
+ - skill/summer-player-data
25
+ - skill/summer-analytics
26
+ source: official
27
+ license: MIT
28
+ status: preview
29
+ recommended: false
@@ -0,0 +1,195 @@
1
+ ---
2
+ name: summer-world-chat
3
+ description: "Add match chat to a Summer game: one World channel shared by everyone in the match. Hosted only."
4
+ license: MIT
5
+ compatibility: [Cursor, Claude Code, Windsurf, Codex]
6
+ category: multiplayer-and-networking
7
+ user-invocable: true
8
+ allowed-tools: Read Grep Edit Write summer_get_script_errors summer_project_setting summer_play summer_stop summer_get_diagnostics
9
+ paths: ["**/*.gd", "**/*.tscn"]
10
+ ---
11
+
12
+ # /summer-world-chat — chat with everyone in the match
13
+
14
+ ## Overview
15
+
16
+ A **World channel** is a text channel for the World (match) the player has
17
+ joined. Every player in that World can open the same channel by key, such as
18
+ `"match"`. The platform owns everything that matters about it:
19
+
20
+ - who may read it;
21
+ - the text filter;
22
+ - rate limits;
23
+ - 24-hour retention;
24
+ - blocks between players.
25
+
26
+ Your game owns only the chat UI. Messages never travel through your network
27
+ composition, and the authority neither sees nor writes them.
28
+
29
+ | Fact | Value |
30
+ | --- | --- |
31
+ | Text | Plain Unicode, 1 to 4000 characters. Always render it as plain text, never as markup |
32
+ | Channel keys | 1–64 of `A-Z a-z 0-9 _ . -`, starting with a letter or digit; at most 64 channels per World |
33
+ | History | Best effort, not a full log. A new handle shows the newest 2 messages; `load_older()` grows the window to at most 16 |
34
+ | Lifetime | A handle belongs to one World admission. After leaving or joining another World, open a new one |
35
+ | Not included | Direct messages (`skill/summer-friends`), party chat (the Summer app) and messages written by your server |
36
+
37
+ **Hosted only.** Chat needs a joined hosted World and a Summer app whose Player
38
+ Host offers `player.channels`. A queue reservation is not enough: open the
39
+ channel after `enter()` succeeds. In Local Play and editor runs,
40
+ `check_open_readiness()` and `open_world_channel()` fail with `unavailable`.
41
+ Build the "chat hidden" path first.
42
+
43
+ This skill extends the Courtyard game from `skill/multiplayer-project` and
44
+ `skill/multiplayer-state`.
45
+
46
+ ## Steps
47
+
48
+ ### 1. Publish player names
49
+
50
+ Messages carry the author's Summer user id (`player_id`), not a name. The
51
+ authority already knows every verified name. Publish them in the shared match
52
+ document (`skill/multiplayer-state`): in `authority/main.gd`'s `_join`, before
53
+ accepting, add
54
+
55
+ ```gdscript
56
+ var players: Dictionary = match_doc.get("players", {})
57
+ players[session.player.user_id] = session.player.display_name
58
+ match_doc["players"] = players
59
+ match_group.reset(Game.pack(match_doc))
60
+ ```
61
+
62
+ On the client, copy `match_doc.get("players", {})` into the chat node's
63
+ `names` whenever the match document changes.
64
+
65
+ ### 2. Add the chat node
66
+
67
+ `client/chat.gd`, added as a child `Chat` of `Main` in `client/main.tscn`:
68
+
69
+ ```gdscript
70
+ extends Node
71
+ ## Match chat: one World channel that every player in this match shares.
72
+
73
+ signal lines_changed(lines: PackedStringArray)
74
+ signal status(text: String)
75
+
76
+ var chat: SummerWorldChannel
77
+ var names := {} # player user id -> display name, from your match state
78
+
79
+
80
+ ## Call after the player has entered the match.
81
+ func open() -> void:
82
+ var channels := Summer.client.channels
83
+ var ready := channels.check_open_readiness()
84
+ if not ready.ok:
85
+ status.emit("Chat is not available here.") # hide the chat box
86
+ return
87
+ var opened := channels.open_world_channel("match")
88
+ var result: SummerResult = await opened.get_result_or_completed_signal()
89
+ if not result.ok:
90
+ status.emit("Chat is not available here.")
91
+ return
92
+ chat = opened.get_channel()
93
+ if chat == null:
94
+ return # the player already left this World
95
+ chat.history_changed.connect(_render)
96
+ chat.history_failed.connect(func(_failure: SummerResult) -> void: status.emit("Chat history is unavailable. Tap to retry."))
97
+ chat.closed.connect(func(_reason: String) -> void:
98
+ chat = null
99
+ _render())
100
+ _render() # the first history may already be here
101
+
102
+
103
+ ## The Retry tap after history_failed.
104
+ func retry_history() -> void:
105
+ if chat != null:
106
+ chat.refresh()
107
+
108
+
109
+ func send(text: String) -> void:
110
+ if chat == null or text.strip_edges().is_empty():
111
+ return
112
+ var sent := chat.send_message(text)
113
+ var result: SummerResult = await sent.get_result_or_completed_signal()
114
+ if not result.ok and result.retryable and result.code != &"rate_limited":
115
+ # An ambiguous failure may have been accepted. Retry the same send,
116
+ # never send_message again: that would be a second message.
117
+ sent = sent.retry()
118
+ result = await sent.get_result_or_completed_signal()
119
+ if result.ok:
120
+ return
121
+ match result.code:
122
+ &"text_not_allowed":
123
+ status.emit("That message was not sent.")
124
+ &"rate_limited":
125
+ status.emit("You are sending messages too fast.")
126
+ _:
127
+ status.emit("Message not sent.")
128
+
129
+
130
+ ## The visible window always comes from get_messages(), never from appending.
131
+ func _render() -> void:
132
+ var lines := PackedStringArray()
133
+ if chat != null and chat.is_history_current():
134
+ for message in chat.get_messages():
135
+ var author := "Game" if message.author_kind == &"creator_system" else String(names.get(message.player_id, "Player"))
136
+ lines.append("%s: %s" % [author, message.text])
137
+ lines_changed.emit(lines)
138
+ ```
139
+
140
+ Call `$Chat.open()` after `enter()` returns `true`. Wire it into the UI:
141
+
142
+ - **Messages:** a `Label` or `RichTextLabel` with `bbcode_enabled = false`, refilled from `lines_changed`.
143
+ - **Input:** a `LineEdit` whose `text_submitted` calls `$Chat.send(text)` and clears itself.
144
+ - **Status:** `status` feeds a status line; hide the whole box when chat is unavailable.
145
+
146
+ ### 3. Rules the code above follows
147
+
148
+ - **Render, don't append.** `history_changed` means "replace the view from `get_messages()`". It also fires when a block or expiry removes messages, which must disappear from the screen.
149
+ - **`message_received` is for sounds and badges only.** It fires for newly seen messages, not for the initial or older history. Display still comes from `get_messages()`.
150
+ - **One `send_message` call is one message.** For an ambiguous retryable failure, call `retry()` on the same operation; it reuses the original idempotency key. A second `send_message` would post twice.
151
+ - **`text_not_allowed` stored nothing.** The filter refused it, and resending the same text fails again.
152
+ - **`rate_limited`.** About 120 messages a minute per player; tell them to slow down, don't loop.
153
+ - **Sequence gaps are normal.** Blocks, other recipients and expiry hide messages; never treat a gap as an error.
154
+ - **`creator_system` messages are from the game**, never from a player or from Summer staff.
155
+
156
+ ### 4. Test
157
+
158
+ Locally, check that the hidden path works and nothing errors:
159
+
160
+ ```
161
+ summer_project_setting name="summer/local_play/players" value=2
162
+ summer_play
163
+ summer_get_diagnostics
164
+ summer_stop
165
+ ```
166
+
167
+ Then test real chat on Summer staging with two accounts in one match.
168
+
169
+ ## Checklist
170
+
171
+ - [ ] Local Play: `open()` reports chat unavailable, the chat box is hidden, and there are no script errors.
172
+ - [ ] The channel opens only after the player entered the World.
173
+ - [ ] Hosted: a message from one player appears for the other, with the right name.
174
+ - [ ] A filtered message shows "not sent" and never appears.
175
+ - [ ] After leaving and joining another match, chat reopens on a new handle.
176
+ - [ ] Text is shown as plain text: `[b]hi[/b]` appears literally.
177
+
178
+ ## Common mistakes
179
+
180
+ | Don't | Do | Why |
181
+ | --- | --- | --- |
182
+ | Send chat through your own Commands or State | `Summer.client.channels` | Summer filters, rate-limits, applies blocks and expires text; your State does none of that |
183
+ | Open the channel right after `Summer.initialize` | Open after `enter()` succeeds | Only a joined World admission can open it |
184
+ | Append each message to a log | Re-render from `get_messages()` on `history_changed` | Blocked and expired text must disappear |
185
+ | Call `send_message` again after a timeout | `operation.retry()` | A new call is a second message |
186
+ | Render with BBCode enabled | Plain `Label`, or `bbcode_enabled = false` | Player text is never markup |
187
+ | Keep a handle across matches | Open a new channel per World | Handles never follow the player to another World |
188
+ | Show `player_id` | Map it to a name your authority publishes | Ids are not names |
189
+
190
+ ## See also
191
+
192
+ - `skill/multiplayer-state`: the match document that carries player names
193
+ - `skill/summer-friends`: direct messages with friends
194
+ - `skill/summer-parties`: party chat lives in the Summer app
195
+ - `skill/multiplayer-testing`: what Local Play can and can't test
@@ -0,0 +1,30 @@
1
+ id: skill/summer-world-chat
2
+ kind: skill
3
+ version: 1.0.0
4
+ summary: "Add match chat to a Summer game: one World channel shared by everyone in the match. Hosted only."
5
+ use_when:
6
+ - "adding in-game text chat, match chat or a chat box to a multiplayer Summer game"
7
+ - "chat messages fail with text_not_allowed, rate_limited or unavailable, or chat history looks incomplete"
8
+ - "deciding where player chat should live instead of sending it through Commands or State"
9
+ facets:
10
+ lifecycle:
11
+ - build
12
+ domains:
13
+ - multiplayer
14
+ - ui
15
+ modalities:
16
+ - scripts
17
+ - ui
18
+ compatibility:
19
+ engine: ">=4.6"
20
+ related:
21
+ skills:
22
+ - skill/multiplayer
23
+ - skill/multiplayer-state
24
+ - skill/multiplayer-testing
25
+ - skill/summer-friends
26
+ - skill/summer-parties
27
+ source: official
28
+ license: MIT
29
+ status: preview
30
+ recommended: false