summer-engine 2.7.0 → 2.8.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.
- package/.claude-plugin/plugin.json +2 -1
- package/.codex-plugin/plugin.json +3 -2
- package/.cursor-plugin/plugin.json +2 -1
- package/.opencode/INSTALL.md +1 -1
- package/.opencode/plugins/summer.js +1 -1
- package/AGENTS.md +4 -4
- package/CHANGELOG.md +10 -0
- package/GEMINI.md +5 -4
- package/README.md +58 -19
- package/assets/autopilot/README.md +51 -0
- package/assets/autopilot/autopilot.gd +222 -0
- package/assets/autopilot/probe_base.gd +262 -0
- package/assets/autopilot/run.sh +78 -0
- package/commands/gameskill.md +11 -2
- package/dist/bin/summer.js +8 -0
- package/dist/commands/config.d.ts +2 -0
- package/dist/commands/config.js +53 -0
- package/dist/commands/create.d.ts +1 -0
- package/dist/commands/create.js +38 -6
- package/dist/commands/list.js +1 -1
- package/dist/commands/login.d.ts +19 -0
- package/dist/commands/login.js +123 -36
- package/dist/commands/logout.js +3 -16
- package/dist/commands/logs.d.ts +2 -0
- package/dist/commands/logs.js +19 -0
- package/dist/commands/mcp.js +7 -2
- package/dist/commands/open.js +1 -1
- package/dist/commands/publish.d.ts +2 -0
- package/dist/commands/publish.js +20 -0
- package/dist/commands/releases.d.ts +2 -0
- package/dist/commands/releases.js +20 -0
- package/dist/commands/run.js +1 -1
- package/dist/lib/api-client.d.ts +4 -2
- package/dist/lib/api-client.js +28 -4
- package/dist/lib/auth.d.ts +40 -12
- package/dist/lib/auth.js +173 -37
- package/dist/lib/cloud/engine-bridge.d.ts +17 -4
- package/dist/lib/cloud/engine-bridge.js +32 -6
- package/dist/lib/config.d.ts +20 -0
- package/dist/lib/config.js +142 -0
- package/dist/lib/creator.d.ts +93 -0
- package/dist/lib/creator.js +393 -0
- package/dist/lib/engine.d.ts +35 -2
- package/dist/lib/engine.js +240 -6
- package/dist/lib/public-surface-paths.d.ts +13 -0
- package/dist/lib/public-surface-paths.js +42 -0
- package/dist/lib/skills-registry.d.ts +8 -0
- package/dist/lib/skills-registry.js +9 -0
- package/dist/lib/store.d.ts +14 -0
- package/dist/lib/store.js +145 -0
- package/dist/lib/summer-compatibility.d.ts +6 -0
- package/dist/lib/summer-compatibility.js +22 -0
- package/dist/mcp/server.d.ts +8 -1
- package/dist/mcp/server.js +25 -4
- package/dist/mcp/tools/creator-tools.d.ts +2 -0
- package/dist/mcp/tools/creator-tools.js +105 -0
- package/dist/mcp/tools/generate-tools.js +16 -6
- package/dist/mcp/tools/project-tools.js +12 -7
- package/dist/mcp/tools/scene-tools.js +6 -6
- package/dist/mcp/tools/visual-tools.js +4 -3
- package/hooks/pre-commit-doctor.sh +0 -0
- package/hooks/run-hook.cmd +0 -0
- package/hooks/session-start.sh +5 -5
- package/package.json +3 -1
- package/references/collaborative-protocol.md +50 -0
- package/references/gd-style.md +121 -0
- package/references/godot-version.md +51 -0
- package/references/mcp-tools-reference.md +199 -0
- package/references/public-surface-language.md +30 -0
- package/references/summer-folder.md +90 -0
- package/references/template-registry.md +73 -0
- package/skills/2d-assets/character-portrait/SKILL.md +17 -12
- package/skills/2d-assets/concept-art/SKILL.md +10 -9
- package/skills/2d-assets/pixel-art/SKILL.md +36 -20
- package/skills/2d-assets/skybox-panorama/SKILL.md +32 -37
- package/skills/2d-assets/sprite-sheet/SKILL.md +40 -35
- package/skills/2d-assets/tileable-texture/SKILL.md +28 -22
- package/skills/2d-assets/ui-graphics/SKILL.md +46 -32
- package/skills/2d-assets/use-widget-asset/SKILL.md +8 -6
- package/skills/3d-assets/character-model/SKILL.md +34 -19
- package/skills/3d-assets/environment-kit/SKILL.md +11 -5
- package/skills/3d-assets/organic-model/SKILL.md +8 -5
- package/skills/3d-assets/prop-model/SKILL.md +9 -3
- package/skills/3d-assets/vehicle-model/SKILL.md +32 -19
- package/skills/README.md +1 -1
- package/skills/ai-and-npcs/design-npc/SKILL.md +31 -13
- package/skills/animation/animation-tree/SKILL.md +39 -15
- package/skills/animation/facial-and-lipsync/SKILL.md +25 -8
- package/skills/animation/generate-motion/SKILL.md +47 -15
- package/skills/animation/procedural-animation/SKILL.md +31 -13
- package/skills/animation/retarget/SKILL.md +127 -79
- package/skills/audio/adaptive-music/SKILL.md +24 -20
- package/skills/audio/ambient-bed/SKILL.md +22 -16
- package/skills/audio/audio-direction/SKILL.md +15 -10
- package/skills/audio/music-track/SKILL.md +18 -12
- package/skills/audio/sound-effect/SKILL.md +17 -12
- package/skills/audio/voice-line/SKILL.md +42 -42
- package/skills/character-controllers/fps-controller/SKILL.md +26 -16
- package/skills/debugging/debug/SKILL.md +52 -20
- package/skills/deployment/export-and-ship/SKILL.md +105 -38
- package/skills/deployment/remote-deploy/SKILL.md +56 -23
- package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +26 -1
- package/skills/gameplay-mechanics/design-mechanic/SKILL.md +23 -15
- package/skills/level-design/design-level/SKILL.md +22 -8
- package/skills/level-design/scene-to-level/SKILL.md +13 -7
- package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +8 -8
- package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +2 -7
- package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +26 -18
- package/skills/performance/tune-performance/SKILL.md +51 -32
- package/skills/rendering-and-lighting/3d-lighting/SKILL.md +34 -5
- package/skills/rendering-and-lighting/art-direction/SKILL.md +6 -8
- package/skills/scene-and-project/brainstorm-game/SKILL.md +3 -5
- package/skills/scene-and-project/make-game/SKILL.md +2 -1
- package/skills/scene-and-project/play/SKILL.md +10 -4
- package/skills/scene-and-project/scene-composition/SKILL.md +21 -8
- package/skills/scene-and-project/summer-cloud/SKILL.md +1 -1
- package/skills/ui-and-ux/ui-basics/SKILL.md +16 -7
- package/skills/video/animated-loop/SKILL.md +63 -39
- package/skills/video/cinematic-cutscene/SKILL.md +66 -30
- package/skills/video/trailer-shot/SKILL.md +30 -21
- package/skills/visual-effects/_building-blocks/additive-billboard-particles.md +25 -16
- package/skills/visual-effects/_building-blocks/trauma-shake-snippet.md +5 -3
- package/skills/visual-effects/game-feel/SKILL.md +51 -33
- package/skills/visual-effects/recipes/dissolve/SKILL.md +51 -9
- package/skills/visual-effects/recipes/fire/SKILL.md +136 -49
- package/skills/visual-effects/recipes/hit-spark/SKILL.md +45 -8
- package/skills/visual-effects/recipes/lightning/SKILL.md +59 -27
- package/skills/visual-effects/recipes/magic-glow/SKILL.md +59 -26
- package/skills/visual-effects/recipes/muzzle-flash/SKILL.md +68 -25
- package/skills/visual-effects/recipes/smoke/SKILL.md +89 -28
- package/skills/visual-effects/recipes/water-ripple/SKILL.md +83 -23
- package/skills/workflow/brainstorming/SKILL.md +1 -1
- package/skills/workflow/brainstorming/scripts/start-server.sh +0 -0
- package/skills/workflow/brainstorming/scripts/stop-server.sh +0 -0
- package/skills/workflow/debugging-game-feel/SKILL.md +29 -9
- package/skills/workflow/diagnosing-perf-regressions/SKILL.md +46 -21
- package/skills/workflow/gameskill/SKILL.md +11 -2
- package/skills/workflow/headless-scripting/SKILL.md +407 -0
- package/skills/workflow/investigating-bugs/SKILL.md +4 -2
- package/skills/workflow/investigating-bugs/find-polluter.sh +0 -0
- package/skills/workflow/mcpupdate/SKILL.md +3 -3
- package/skills/workflow/playtesting-a-feature/SKILL.md +94 -21
- package/skills/workflow/skill-create/SKILL.md +7 -7
- package/skills/workflow/skill-test/SKILL.md +3 -3
- package/skills/workflow/using-summer/SKILL.md +12 -2
- package/skills/workflow/verification-before-completion/SKILL.md +2 -0
- package/skills/workflow/writing-plans/SKILL.md +7 -7
- package/skills/workflow/writing-skills/SKILL.md +7 -5
- package/skills/workflow/writing-skills/render-graphs.js +0 -0
- package/skills/workflow/writing-skills/testing-skills-with-subagents.md +1 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"$schema": "https://json.schemastore.org/claude-code-plugin-manifest.json",
|
|
3
3
|
"name": "summer",
|
|
4
4
|
"version": "2.5.1",
|
|
5
|
-
"description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a
|
|
5
|
+
"description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 58-tool MCP bridge to the local desktop app.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Summer Engine",
|
|
8
8
|
"email": "founders@summerengine.com",
|
|
@@ -39,6 +39,7 @@
|
|
|
39
39
|
"./skills/workflow/dispatching-parallel-agents/",
|
|
40
40
|
"./skills/workflow/writing-skills/",
|
|
41
41
|
"./skills/workflow/playtesting-a-feature/",
|
|
42
|
+
"./skills/workflow/headless-scripting/",
|
|
42
43
|
"./skills/workflow/debugging-game-feel/",
|
|
43
44
|
"./skills/workflow/diagnosing-perf-regressions/",
|
|
44
45
|
"./skills/scene-and-project/brainstorm-game/",
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "summer",
|
|
3
3
|
"version": "2.5.1",
|
|
4
|
-
"description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a
|
|
4
|
+
"description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 62-tool MCP bridge. Build games by talking.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Summer Engine",
|
|
7
7
|
"email": "founders@summerengine.com",
|
|
@@ -28,6 +28,7 @@
|
|
|
28
28
|
"./skills/workflow/dispatching-parallel-agents/",
|
|
29
29
|
"./skills/workflow/writing-skills/",
|
|
30
30
|
"./skills/workflow/playtesting-a-feature/",
|
|
31
|
+
"./skills/workflow/headless-scripting/",
|
|
31
32
|
"./skills/workflow/debugging-game-feel/",
|
|
32
33
|
"./skills/workflow/diagnosing-perf-regressions/",
|
|
33
34
|
"./skills/scene-and-project/brainstorm-game/",
|
|
@@ -95,7 +96,7 @@
|
|
|
95
96
|
"interface": {
|
|
96
97
|
"displayName": "Summer",
|
|
97
98
|
"shortDescription": "Superpowers for AI game dev. Build games by talking.",
|
|
98
|
-
"longDescription": "Summer turns Codex into a game-dev studio for Summer Engine
|
|
99
|
+
"longDescription": "Summer turns Codex into a game-dev studio for Summer Engine. Users make Summer games with the Summer SDK and GDScript. The plugin adds game-dev skills, lifecycle hooks, and a 62-tool MCP bridge for guarded project files, scene editing, asset import, play mode, diagnostics, generation, and creator workflows. Git, shell, and grep stay with the host agent. Summer follows its upstream technical base continuously; version-sensitive work uses the bundled compatibility reference instead of a fixed onboarding version. Session-start orients the session. Pre-commit doctor (opt-in) blocks bad commits.",
|
|
99
100
|
"developerName": "Summer Engine",
|
|
100
101
|
"category": "Coding",
|
|
101
102
|
"capabilities": ["Interactive", "Read", "Write"],
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"name": "summer",
|
|
4
4
|
"displayName": "Summer",
|
|
5
5
|
"version": "2.5.1",
|
|
6
|
-
"description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a
|
|
6
|
+
"description": "Agent tooling for Summer Engine: game-dev skills, lifecycle hooks, and a 58-tool MCP bridge to the local desktop app.",
|
|
7
7
|
"author": { "name": "Summer Engine", "email": "founders@summerengine.com" },
|
|
8
8
|
"publisher": "summer-engine",
|
|
9
9
|
"homepage": "https://summerengine.com",
|
|
@@ -30,6 +30,7 @@
|
|
|
30
30
|
"./skills/workflow/dispatching-parallel-agents/",
|
|
31
31
|
"./skills/workflow/writing-skills/",
|
|
32
32
|
"./skills/workflow/playtesting-a-feature/",
|
|
33
|
+
"./skills/workflow/headless-scripting/",
|
|
33
34
|
"./skills/workflow/debugging-game-feel/",
|
|
34
35
|
"./skills/workflow/diagnosing-perf-regressions/",
|
|
35
36
|
"./skills/scene-and-project/brainstorm-game/",
|
package/.opencode/INSTALL.md
CHANGED
|
@@ -30,7 +30,7 @@ Restart OpenCode. The orientation banner ("Summer Engine is loaded. N skills ava
|
|
|
30
30
|
|
|
31
31
|
## What this gives you
|
|
32
32
|
|
|
33
|
-
- **
|
|
33
|
+
- **Summer skills** under the `summer:` namespace, including `using-summer`, `brainstorm-game`, `debug`, `play`, `fps-controller`, `gdscript-patterns`, `scene-composition`, `art-direction`, and more.
|
|
34
34
|
- **A `summer-engine` MCP server** — start it with `npx summer-engine mcp` and OpenCode will route scene/diagnostics/asset tools to your local Summer Engine running on `localhost:6550`.
|
|
35
35
|
- **Session-start orientation** — first user message of every session is prefixed with the using-summer primer so the model invokes skills before responding.
|
|
36
36
|
|
|
@@ -12,7 +12,7 @@ const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
|
12
12
|
const skillsDir = path.resolve(__dirname, '../../skills');
|
|
13
13
|
|
|
14
14
|
const ORIENTATION = `<EXTREMELY_IMPORTANT>
|
|
15
|
-
Summer is loaded.
|
|
15
|
+
Summer is loaded. Summer skills are available under the summer: namespace.
|
|
16
16
|
|
|
17
17
|
Activate summer:using-summer FIRST in any Summer Engine session — it sets workflow priority and the red-flag list.
|
|
18
18
|
|
package/AGENTS.md
CHANGED
|
@@ -4,7 +4,7 @@ This file is for any AI agent that loads context from `AGENTS.md` (Codex CLI, Fa
|
|
|
4
4
|
|
|
5
5
|
## What you're working with
|
|
6
6
|
|
|
7
|
-
**Summer Engine** is the AI-native game engine the user is building in.
|
|
7
|
+
**Summer Engine** is the AI-native game engine the user is building in. The user is making a **Summer game** with the **Summer SDK**, normally in GDScript. The editor, scene graph, asset pipeline, and runtime are instrumented for programmatic control through the `summer-engine` MCP server. Summer currently uses the 4.6.1 upstream technical base, plans to adopt 4.7.1 next, and follows upstream continuously. Those numbers are compatibility facts, not the product identity. Projects use GDScript (`.gd`), C# (`.cs`), scenes (`.tscn`/`.scn`), resources (`.tres`/`.res`), and the technical `project.godot` filename.
|
|
8
8
|
|
|
9
9
|
## Critical rules
|
|
10
10
|
|
|
@@ -23,9 +23,9 @@ This file is for any AI agent that loads context from `AGENTS.md` (Codex CLI, Fa
|
|
|
23
23
|
- **Discipline** (`gdscript-patterns`, `scene-composition`, `art-direction`) → how to shape it.
|
|
24
24
|
- **Build** (`fps-controller`, `design-mechanic`, `design-level`, `setup-multiplayer`, `vfx`, `tune-performance`, `export-and-ship`) → produce the artifact.
|
|
25
25
|
|
|
26
|
-
## MCP tool palette (
|
|
26
|
+
## MCP tool palette (project-matched local editor)
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
The current MCP registry is grouped into these categories:
|
|
29
29
|
|
|
30
30
|
- Scene: `summer_get_scene_tree`, `summer_open_scene`, `summer_create_scene`, `summer_add_node`, `summer_set_prop`, `summer_set_resource_property`, `summer_remove_node`, `summer_save_scene`, `summer_instantiate_scene`, `summer_replace_node`, `summer_select_node`, `summer_inspect_node`, `summer_inspect_resource`, `summer_connect_signal`, `summer_batch`.
|
|
31
31
|
- Diagnostics: `summer_create_debug_report`, `summer_get_script_errors`, `summer_get_diagnostics`, `summer_get_console`, `summer_clear_console`, `summer_get_debugger_errors`, `summer_get_debugger_warnings`.
|
|
@@ -41,7 +41,7 @@ Git, shell, and grep are not exposed. Project file reads and writes are exposed
|
|
|
41
41
|
|
|
42
42
|
## Type-system gotchas
|
|
43
43
|
|
|
44
|
-
`SetProp` values are
|
|
44
|
+
`SetProp` values are Summer Engine variant strings, not JSON objects:
|
|
45
45
|
- `"Vector3(0, 10, 0)"`
|
|
46
46
|
- `"Color(1, 0.5, 0, 1)"` (RGBA, 4 components)
|
|
47
47
|
- `"Transform3D(1,0,0, 0,1,0, 0,0,1, 0,5,0)"`
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to summer-engine will be documented here. Following [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and [Semantic Versioning](https://semver.org/).
|
|
4
4
|
|
|
5
|
+
## [Unreleased]
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
- MCP discovers every live Summer editor through `~/.summer/instances/` and automatically binds local tools to the editor whose project contains the agent's current working directory.
|
|
9
|
+
- `summer mcp --project <path>` and `summer mcp --instance <id>` provide explicit selection for hosts that do not start the MCP server from a project directory.
|
|
10
|
+
|
|
11
|
+
### Changed
|
|
12
|
+
- Multiple live editors are now a fail-closed state when no project can be inferred. MCP lists the non-secret project/instance choices instead of following the machine-global last-opened editor pointer.
|
|
13
|
+
- Selected MCP sessions keep following the same project across editor restarts and validate registry identity against `/api/health` before connecting.
|
|
14
|
+
|
|
5
15
|
## [2.7.0] — 2026-07-24 — "Reliable project mutations"
|
|
6
16
|
|
|
7
17
|
### Added
|
package/GEMINI.md
CHANGED
|
@@ -4,7 +4,7 @@ Summer is the AI game-dev studio for **Summer Engine** — the AI-native game en
|
|
|
4
4
|
|
|
5
5
|
## What Summer Engine is
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Summer Engine is designed for AI-assisted creation. The user is making a **Summer game** with the **Summer SDK**, normally in GDScript. The editor, scene graph, asset pipeline, and runtime are instrumented for programmatic control via MCP. Summer currently uses the 4.6.1 upstream technical base, plans to adopt 4.7.1 next, and follows upstream continuously. Those numbers are compatibility facts, not the product identity. Projects use GDScript (`.gd`), C# (`.cs`), scenes (`.tscn`/`.scn`), resources (`.tres`/`.res`), and the technical `project.godot` filename.
|
|
8
8
|
|
|
9
9
|
## How to behave
|
|
10
10
|
|
|
@@ -18,9 +18,9 @@ The single most important skill to know is `summer:using-summer` — it explains
|
|
|
18
18
|
2. **Discipline skills second**: `gdscript-patterns`, `scene-composition`, `art-direction`, `audio-direction`. These shape content.
|
|
19
19
|
3. **Build skills third**: `fps-controller`, `design-mechanic`, `design-level`, `setup-multiplayer`, `vfx`, `tune-performance`, `export-and-ship`.
|
|
20
20
|
|
|
21
|
-
## MCP tools (when the
|
|
21
|
+
## MCP tools (when the project-matched local editor is running)
|
|
22
22
|
|
|
23
|
-
The `summer-engine` MCP server exposes
|
|
23
|
+
The `summer-engine` MCP server exposes a focused tool registry. The most important:
|
|
24
24
|
|
|
25
25
|
- **Scene mutation**: `summer_add_node`, `summer_set_prop`, `summer_set_resource_property`, `summer_remove_node`, `summer_save_scene`, `summer_replace_node`, `summer_batch`. Every scene mutation requires the exact `res://...tscn` `scenePath`; opening a scene is a user-visible UI action, not a mutation prerequisite. Mutation tools append one final `SaveScene`; raw engine batches must do the same.
|
|
26
26
|
- **Scene inspection**: `summer_get_scene_tree`, `summer_inspect_node`, `summer_inspect_resource`.
|
|
@@ -35,7 +35,8 @@ Git, shell, and grep remain host-native. Use the Summer file tools for project r
|
|
|
35
35
|
|
|
36
36
|
## Type-system traps
|
|
37
37
|
|
|
38
|
-
`SetProp` values are engine-formatted **strings**
|
|
38
|
+
`SetProp` values are engine-formatted **strings** compatible with the current
|
|
39
|
+
Summer Engine type system:
|
|
39
40
|
|
|
40
41
|
- `"Vector3(0, 10, 0)"` — NOT `{x: 0, y: 10, z: 0}`.
|
|
41
42
|
- `"Color(1, 0.5, 0, 1)"` — RGBA, 4 components.
|
package/README.md
CHANGED
|
@@ -2,7 +2,12 @@
|
|
|
2
2
|
|
|
3
3
|
> **Engine mirror only.** This directory is intentionally marked `private` and must never be published to npm. Review and reconcile changes into [SummerEngine/summer-engine-agent](https://github.com/SummerEngine/summer-engine-agent), which is the only npm release source.
|
|
4
4
|
|
|
5
|
-
Build real 2D and 3D games
|
|
5
|
+
Build real 2D and 3D Summer games with Summer Engine, the Summer SDK, and
|
|
6
|
+
GDScript. The agent layer can help author code and scenes, but creators remain
|
|
7
|
+
in control of changes and release decisions. Local export support depends on
|
|
8
|
+
the templates present in the installed engine. The package does not silently
|
|
9
|
+
build, host, or submit games to stores; its explicit, confirmed creator command
|
|
10
|
+
can publish an already-exported Summer `.pck` to Summercraft for review.
|
|
6
11
|
|
|
7
12
|
**Summer** is the MIT open-source agent layer that connects your AI coding agent to Summer Engine. It is the **Summer CLI**, the **Summer MCP** server, and the **Summer agent** skills, hooks, and plugin manifests, all in one package. First-class setup works in Claude Code, Cursor, Codex, Devin Desktop (formerly Windsurf), Cline, Roo Code, Gemini CLI, GitHub Copilot CLI, GitHub Copilot in VS Code, and OpenCode. Factory Droid uses the plugin marketplace path.
|
|
8
13
|
|
|
@@ -11,7 +16,9 @@ Build real 2D and 3D games through conversation. No coding required. Export to S
|
|
|
11
16
|
- **MCP setup:** [www.summerengine.com/mcp](https://www.summerengine.com/mcp)
|
|
12
17
|
- **Docs:** [docs.summerengine.com](https://docs.summerengine.com)
|
|
13
18
|
|
|
14
|
-
|
|
19
|
+
Once setup checks pass, open your agent and say *"let's make an FPS in Summer
|
|
20
|
+
Engine."* The agent can then use the Summer SDK and local editor tools to build
|
|
21
|
+
and verify the project.
|
|
15
22
|
|
|
16
23
|
---
|
|
17
24
|
|
|
@@ -20,10 +27,11 @@ It just works. Open your agent, say *"let's make an FPS in Summer Engine,"* and
|
|
|
20
27
|
Three names, one npm package (`summer-engine`):
|
|
21
28
|
|
|
22
29
|
- **Summer CLI** (`npx -y summer-engine@latest`): installs the engine, signs you in, scaffolds and runs projects, and writes your agent's config. See [www.summerengine.com/cli](https://www.summerengine.com/cli).
|
|
23
|
-
- **Summer MCP**: the local MCP server that gives your agent
|
|
30
|
+
- **Summer MCP**: the local MCP server that gives your agent 58 engine tools to build, run, and debug a real game. See [www.summerengine.com/mcp](https://www.summerengine.com/mcp).
|
|
24
31
|
- **Summer agent layer**: the game-dev skills, hooks, and plugin manifests that give your AI agent judgment, not just a chat box.
|
|
25
32
|
|
|
26
|
-
|
|
33
|
+
The CLI, MCP bridge, and agent layer are MIT licensed. The Summer Engine app has
|
|
34
|
+
its own license. One setup flow wires the pieces together.
|
|
27
35
|
|
|
28
36
|
## Get started: one prompt
|
|
29
37
|
|
|
@@ -110,7 +118,7 @@ npx -y summer-engine@latest install
|
|
|
110
118
|
npx -y summer-engine@latest login
|
|
111
119
|
```
|
|
112
120
|
|
|
113
|
-
This opens the user's default browser. **Tell the user**: "Your browser is opening now. Click sign-in once and come back to this terminal." The CLI waits up to 120 seconds for the auth callback,
|
|
121
|
+
This opens the user's default browser. **Tell the user**: "Your browser is opening now. Click sign-in once and come back to this terminal." The CLI waits up to 120 seconds for the auth callback, validates that the returned identity matches the CLI token, writes the core-compatible session to the secured `~/.summer/` store, and returns. **If the user takes longer than 120 seconds, re-run `npx -y summer-engine@latest login` and tell them to come back to the terminal quickly.** Don't loop indefinitely. The same `auth-token` and `user.json` filenames remain shared with the engine; they sign in once, both surfaces accept it.
|
|
114
122
|
|
|
115
123
|
### Step 4: Re-run doctor to confirm
|
|
116
124
|
|
|
@@ -218,8 +226,9 @@ We tell you before we touch your disk.
|
|
|
218
226
|
| `summer-engine` npm package (CLI + plugin source) | ~3 MB | first `npx -y summer-engine@latest ...` call | [npmjs.com/package/summer-engine](https://www.npmjs.com/package/summer-engine) |
|
|
219
227
|
| Summer Engine app | ~1 GB (engine + bundled Git/runtime tools) | `npx -y summer-engine@latest install` | Summer's signed releases |
|
|
220
228
|
| Auth token | ~1 KB | `npx -y summer-engine@latest login` | Browser to `~/.summer/auth-token` |
|
|
229
|
+
| Creator token | ~50 bytes | only when you run `summer login --creator` and mint one | One-time browser value to `~/.summer/creator-token`; never replaces the auth token |
|
|
221
230
|
| Skill files | < 50 KB | bundled in the npm package | no extra network call |
|
|
222
|
-
| Generated assets (3D / image / audio / video) | varies | only on explicit `summer_generate_*` calls | Summer Engine Studio |
|
|
231
|
+
| Generated assets (3D / image / audio / video) | varies | only on explicit `summer_generate_*` calls when that provider route is enabled for the account | Summer Engine Studio |
|
|
223
232
|
| URL imports | varies | only on explicit `summer_import_from_url` calls | the URL you provide |
|
|
224
233
|
|
|
225
234
|
Not downloaded:
|
|
@@ -235,9 +244,14 @@ Not downloaded:
|
|
|
235
244
|
|---|---|---|
|
|
236
245
|
| **Summer** (this repo: CLI, MCP server, skills, hooks, plugin manifests) | **MIT** | [SummerEngine/summer-engine-agent](https://github.com/SummerEngine/summer-engine-agent) |
|
|
237
246
|
| **Summer Engine app** (the desktop editor and runtime) | free to download, closed source for now | [summerengine.com/download](https://summerengine.com/download) |
|
|
238
|
-
| **Hosted Summer
|
|
247
|
+
| **Hosted Summer integrations** | availability and terms vary by rollout; preview features are labeled in the CLI | [summerengine.com/pricing](https://summerengine.com/pricing) |
|
|
239
248
|
|
|
240
|
-
The desktop app is free to download. The AI-agent layer, meaning the CLI, MCP
|
|
249
|
+
The desktop app is free to download. The AI-agent layer, meaning the CLI, MCP
|
|
250
|
+
server, skills, and plugin manifests, is MIT open source. A command, tool
|
|
251
|
+
contract, or roadmap entry does not by itself mean a hosted service is
|
|
252
|
+
production-ready. Summer Cloud is explicitly a research preview, and managed
|
|
253
|
+
publishing, hosting, store submission, and matchmaking are not promised by this
|
|
254
|
+
package.
|
|
241
255
|
|
|
242
256
|
---
|
|
243
257
|
|
|
@@ -255,7 +269,7 @@ Two pieces, plus the glue.
|
|
|
255
269
|
|
|
256
270
|
Skills don't list steps. They encode the **order of operations**: diagnose before editing, scope before building, ask before guessing. [Agent Skills](https://agentskills.io) format, so any conformant tool picks them up.
|
|
257
271
|
|
|
258
|
-
**MCP bridge.** The `summer-engine` MCP server gives the agent
|
|
272
|
+
**MCP bridge.** The `summer-engine` MCP server gives the agent 62 tools. Local project tools connect to the matching live editor on its loopback port; cloud and creator tools use their documented remote or local configuration contracts without requiring the editor:
|
|
259
273
|
|
|
260
274
|
| | |
|
|
261
275
|
|---|---|
|
|
@@ -263,13 +277,21 @@ Skills don't list steps. They encode the **order of operations**: diagnose befor
|
|
|
263
277
|
| Diagnostics | `summer_create_debug_report`, `summer_get_script_errors`, `summer_get_diagnostics`, `summer_get_console`, `summer_clear_console`, `summer_get_debugger_errors`, `summer_get_debugger_warnings` |
|
|
264
278
|
| Runtime | `summer_play`, `summer_stop`, `summer_is_running` |
|
|
265
279
|
| Visual | `summer_screenshot` (see the editor viewport, an offscreen scene render, or the running game) |
|
|
266
|
-
| Interactive | `
|
|
280
|
+
| Interactive | `RunVerification` raw op via `summer_batch` — a hidden GDScript probe that presses real inputs, saves rendered frames, and asserts. `SimulateInput` is editor-bridge only and not reachable from MCP. |
|
|
267
281
|
| Project | `summer_get_project_context`, `summer_open_main_scene`, `summer_project_setting`, `summer_input_map_bind` |
|
|
268
282
|
| Files | `summer_read_file`, `summer_write_file`, `summer_replace_text` — identity-bound, create-only or sha256-guarded mutations |
|
|
269
283
|
| Assets | `summer_search_assets`, `summer_import_asset`, `summer_import_from_url`, `summer_generate_image`, `summer_generate_3d`, `summer_generate_audio`, `summer_generate_video` |
|
|
284
|
+
| Creator | `summer_creator_publish`, `summer_creator_releases`, `summer_creator_logs`, `summer_creator_config` — confirmed immutable publish and real release history through `summer.creator.v1`, explicit unsupported logs, and shared non-secret configuration. |
|
|
270
285
|
|
|
271
286
|
Git, shell, and grep remain host-native. Project file reads and writes use Summer's identity-bound tools so compatible engine builds can reject wrong-project and stale-content mutations. A host agent can still bypass these safeguards with its own file tools; the package cannot technically intercept that external process.
|
|
272
287
|
|
|
288
|
+
When several Summer editors are open, MCP automatically selects the one whose
|
|
289
|
+
project contains the agent's current working directory. Normal agent configs do
|
|
290
|
+
not need a path or one MCP entry per editor. Hosts that launch MCP outside a
|
|
291
|
+
project can use `summer mcp --project <path>`; `--instance <id>` is available
|
|
292
|
+
when two editors intentionally show the same project. An ambiguous unscoped
|
|
293
|
+
connection is rejected rather than routed to the last editor that opened.
|
|
294
|
+
|
|
273
295
|
**Lifecycle hooks.** A `session-start` hook detects whether you're in a Summer Engine project and feeds the agent a one-line orientation. An opt-in `pre-commit doctor` runs `summer doctor` before `git commit` and blocks when the setup needs attention.
|
|
274
296
|
|
|
275
297
|
For the full architecture, see [docs/OVERVIEW.md](docs/OVERVIEW.md).
|
|
@@ -292,13 +314,21 @@ summer_clear_console # clean slate
|
|
|
292
314
|
summer_play # boot the game (or a specific scene)
|
|
293
315
|
summer_get_debugger_errors # runtime errors: null refs, missing nodes, physics
|
|
294
316
|
summer_screenshot target:game # optional: look at the live frame
|
|
295
|
-
summer_stop #
|
|
317
|
+
summer_stop # stop when runtime checks are done
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
**4. Does the interaction work?** To prove input-driven behavior (jump/move/shoot), use `RunVerification` — a raw op through `summer_batch`. It spawns a hidden, disposable game instance that runs your GDScript probe, presses real inputs, reads state back across frames, saves rendered frames, and dies without ever touching the editor:
|
|
321
|
+
|
|
296
322
|
```
|
|
323
|
+
summer_batch ops:[{op:"RunVerification", probe_source:"…", max_seconds:20}]
|
|
324
|
+
→ {ok, results, frames, out_dir}
|
|
325
|
+
```
|
|
326
|
+
|
|
327
|
+
Unlike `--headless`, that instance has a real renderer, so `save_frame()` writes an actual image. Probe API: `report()` / `save_frame()` / `dump_tree()` / `press()` / `key()` / `finish()`. **`press()` and `key()` are coroutines — `await` them.** Every project scaffolded by `summer create` ships a working example at `tests/autopilot/`.
|
|
328
|
+
|
|
329
|
+
`SimulateInput` is **not** reachable from MCP or the CLI, on any build. It needs the in-editor chat bridge's async reply channel; every queued caller is answered `{ok:false, failure_reason:"unsupported_transport"}`. Use the probe.
|
|
297
330
|
|
|
298
|
-
|
|
299
|
-
- `SimulateInput` — inject into the **running** game: `summer_batch ops:[{op:"SimulateInput", type:"action", action:"jump", pressed:true}]`, then re-check screenshot/debugger.
|
|
300
|
-
- `RunVerification` — spawn a hidden, disposable game instance that runs a GDScript probe (press inputs, read state, save frames) and dies, never touching the editor: `summer_batch ops:[{op:"RunVerification", probe_source:"…", max_seconds:20}]` → `{ok, results, frames, out_dir}`.
|
|
301
|
-
- If neither is available on this build, **ask the user to try it** and report what they see — don't fake it.
|
|
331
|
+
Ask the user to play only for what a probe cannot hold an opinion about: whether it *feels* right, whether it *looks* good, whether it is fun. "I can't simulate input" is not on that list.
|
|
302
332
|
|
|
303
333
|
**Honesty.** Never describe an image you didn't receive; a failed capture is a *result* — report it and climb down (`scene`→`viewport`) or ask the user. Pass structured failures (`failure_reason`, `terminalState`, `identity_mismatch`) through verbatim. `summer_get_project_context` binds the session to the open project; a `projectMismatch` warning on a screenshot means the engine switched projects and the frame may be from the wrong one — rebind before trusting it.
|
|
304
334
|
|
|
@@ -315,7 +345,9 @@ summer_stop # ALWAYS stop — scene edits are refused while
|
|
|
315
345
|
5. **gdscript-patterns** guides every `.gd` write.
|
|
316
346
|
6. **play** runs the game and reports clean or broken.
|
|
317
347
|
7. **debug** runs the cheapest diagnostic, forms one specific hypothesis, asks before editing, re-verifies after the fix.
|
|
318
|
-
8. **export-and-ship** runs
|
|
348
|
+
8. **export-and-ship** inventories installed export templates, runs pre-flight,
|
|
349
|
+
and produces only supported local builds after approval. It does not upload,
|
|
350
|
+
host, publish, or submit them.
|
|
319
351
|
|
|
320
352
|
The skill bundle replaces "agent flailing through tutorials" with measurable craft.
|
|
321
353
|
|
|
@@ -339,7 +371,9 @@ The skill bundle replaces "agent flailing through tutorials" with measurable cra
|
|
|
339
371
|
|
|
340
372
|
**Skill authoring**: `skill-create`, `skill-improve`, `skill-test`
|
|
341
373
|
|
|
342
|
-
C# is supported by the engine. A `summer:csharp-patterns` skill is on the
|
|
374
|
+
C# is supported by the engine. A `summer:csharp-patterns` skill is on the
|
|
375
|
+
roadmap; for now use the upstream C# API reference matching the current Summer
|
|
376
|
+
technical base.
|
|
343
377
|
|
|
344
378
|
Full list of shipping skills: the `skills:` array in [`.claude-plugin/plugin.json`](./.claude-plugin/plugin.json).
|
|
345
379
|
|
|
@@ -477,8 +511,13 @@ npx -y summer-engine@latest doctor
|
|
|
477
511
|
| Command | What it does |
|
|
478
512
|
|---|---|
|
|
479
513
|
| `summer install` | Download Summer Engine. Prints URL and size first. |
|
|
480
|
-
| `summer login` | Browser-based sign-in. |
|
|
514
|
+
| `summer login` | Browser-based core Summer sign-in. |
|
|
515
|
+
| `summer login --creator` | Open Summercraft token settings and securely connect a separate publish-scoped creator token. |
|
|
481
516
|
| `summer logout` | Clear auth tokens. |
|
|
517
|
+
| `summer config [get\|set\|unset]` | Read or update the shared non-secret `~/.summer/config.json`. |
|
|
518
|
+
| `summer publish [project] --artifact <game.pck> --version <value> [--confirm]` | Compute and show the exact immutable target; after approval, stream it through prepare → write-once PUT → finalize. |
|
|
519
|
+
| `summer releases [--cursor <value>]` | List real creator-owned release history. |
|
|
520
|
+
| `summer logs` | Read creator runtime logs. Fails closed while no durable runtime-log source exists. |
|
|
482
521
|
| `summer status` | Engine state, port, auth. |
|
|
483
522
|
| `summer doctor` | Diagnose Node, login, engine, project memory, MCP. |
|
|
484
523
|
| `summer plan <goal>` | Route a game-building goal into skills, MCP tools, gates, and verification. |
|
|
@@ -491,7 +530,7 @@ npx -y summer-engine@latest doctor
|
|
|
491
530
|
| `summer skills list` | Show all skills. |
|
|
492
531
|
| `summer skills install <name>` | Install one. |
|
|
493
532
|
| `summer skills install --recommended --agent <agent>` | Install the recommended set. |
|
|
494
|
-
| `summer mcp` | Start the
|
|
533
|
+
| `summer mcp [--project <path> \| --instance <id>]` | Start MCP; normally auto-binds from the agent's project directory. |
|
|
495
534
|
| `summer mcp setup <agent>` | Write MCP config for an agent. |
|
|
496
535
|
| `summer setup <agent> [--yes]` | One shot: MCP config + recommended skills + doctor. |
|
|
497
536
|
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# tests/autopilot
|
|
2
|
+
|
|
3
|
+
A starting point for proving your game actually works — not that it compiles, that it *works*.
|
|
4
|
+
|
|
5
|
+
`autopilot.gd` boots your game in an invisible instance, presses your real input actions to walk the player through a list of waypoints, saves a rendered frame at each one, records what it found, and exits. It is ordinary GDScript against your real running game. There is no test framework here to learn.
|
|
6
|
+
|
|
7
|
+
## Run it
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
bash tests/autopilot/run.sh
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
No editor needed. Exit code is 0 when the probe finished cleanly and the engine logged no errors.
|
|
14
|
+
|
|
15
|
+
Results land in `tests/autopilot/out/`:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
results.json reports, frame list, errors_seen, duration_ms, finished
|
|
19
|
+
00_start.jpg a real rendered frame, one per waypoint
|
|
20
|
+
engine.log full engine output if something went wrong
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
An agent can also run the same probe through MCP without touching your editor:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
summer_batch ops:[{"op": "RunVerification",
|
|
27
|
+
"probe_source": "<contents of autopilot.gd>",
|
|
28
|
+
"max_seconds": 40}]
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Make it yours
|
|
32
|
+
|
|
33
|
+
Open `autopilot.gd` and edit the `CONFIG` block at the top: the player's node path, your Input Map action names, and the waypoints to walk. Then put your real assertions in `_check_at_waypoint()` and `_check_at_end()` — the shipped version walks and looks, but asserts nothing about *your* game, and a test that asserts nothing always passes.
|
|
34
|
+
|
|
35
|
+
Leave `ACT_UP` / `ACT_DOWN` empty for a side-on platformer. The autopilot then measures arrival on X alone, because in a side-scroller Y is gravity, not a destination.
|
|
36
|
+
|
|
37
|
+
## Rules that will bite you otherwise
|
|
38
|
+
|
|
39
|
+
**Assert inequalities, not exact numbers.** `position.x > start.x + 50` is a real assertion. `position.x == 250.0` is a flaky test you wrote yourself — hold durations resolve on the wall clock, so the same walk lands a few pixels apart between runs.
|
|
40
|
+
|
|
41
|
+
**Wait on `physics_frame`, not timers.** `await get_tree().physics_frame` is reproducible; `await get_tree().create_timer(1.0).timeout` is not.
|
|
42
|
+
|
|
43
|
+
**The global RNG is not seeded.** Anything downstream of `randf()` differs every run. Assert ranges, or seed it yourself at the top of the probe.
|
|
44
|
+
|
|
45
|
+
**`finished: false` is a failure.** It means the probe hit `--summer-verify-max` before calling `finish()`. `run.sh` exits non-zero on it; do not read the partial reports as a pass.
|
|
46
|
+
|
|
47
|
+
**Never add `--headless` to this.** Headless has no renderer: `save_frame()` gets a null image, and `draw_calls` reads 0.0 forever. The verify instance is windowed but positioned off-screen, which is why it can produce real frames and stay invisible.
|
|
48
|
+
|
|
49
|
+
## Frames are the point
|
|
50
|
+
|
|
51
|
+
A saved frame sequence is a flipbook of your feature happening. It is the difference between "the code path executed" and "the thing the player was promised appeared on screen". Save one wherever you would otherwise have asked a human to look.
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
# Autopilot — drives the player through a list of waypoints, saves a frame at each,
|
|
2
|
+
# asserts what it saw, and exits.
|
|
3
|
+
#
|
|
4
|
+
# This is a starting point, not a finished test. Edit CONFIG below to match your game,
|
|
5
|
+
# then add your own assertions in _check_at_waypoint(). Everything here is ordinary
|
|
6
|
+
# GDScript against your real running game — there is no test framework to learn.
|
|
7
|
+
#
|
|
8
|
+
# Run it:
|
|
9
|
+
# bash tests/autopilot/run.sh
|
|
10
|
+
# or from an agent, as a RunVerification probe (see tests/autopilot/README.md).
|
|
11
|
+
|
|
12
|
+
extends "res://tests/autopilot/probe_base.gd"
|
|
13
|
+
|
|
14
|
+
# ── CONFIG — edit this ────────────────────────────────────────────────────────────
|
|
15
|
+
|
|
16
|
+
# Node path to the player, from the current scene root.
|
|
17
|
+
const PLAYER_PATH := "Player"
|
|
18
|
+
|
|
19
|
+
# Input action names from your project's Input Map. Leave an entry empty to skip it.
|
|
20
|
+
const ACT_LEFT := "move_left"
|
|
21
|
+
const ACT_RIGHT := "move_right"
|
|
22
|
+
const ACT_UP := "" # "move_forward" in 3D, "move_up" in top-down 2D
|
|
23
|
+
const ACT_DOWN := ""
|
|
24
|
+
const ACT_JUMP := "jump"
|
|
25
|
+
|
|
26
|
+
# Where to walk. 2D games use x/y in pixels; 3D games use x/z in metres (y ignored).
|
|
27
|
+
# Positions are WORLD positions, not offsets.
|
|
28
|
+
const WAYPOINTS := [
|
|
29
|
+
Vector3(300, 0, 0),
|
|
30
|
+
Vector3(600, 0, 0),
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
# How close counts as arrived, and how long to allow per leg before giving up.
|
|
34
|
+
const ARRIVE_EPSILON := 40.0
|
|
35
|
+
const LEG_TIMEOUT_FRAMES := 240
|
|
36
|
+
|
|
37
|
+
# ── END CONFIG ────────────────────────────────────────────────────────────────────
|
|
38
|
+
|
|
39
|
+
var _player: Node = null
|
|
40
|
+
var _is_3d := false
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
func _ready() -> void:
|
|
44
|
+
await super._ready()
|
|
45
|
+
|
|
46
|
+
# Let the scene settle. Physics frames, not timers — timers are wall-clock and
|
|
47
|
+
# make results differ between runs and between machines.
|
|
48
|
+
for _i in 30:
|
|
49
|
+
await get_tree().physics_frame
|
|
50
|
+
|
|
51
|
+
if not _bind_player():
|
|
52
|
+
finish()
|
|
53
|
+
return
|
|
54
|
+
|
|
55
|
+
report("player_path", PLAYER_PATH)
|
|
56
|
+
report("player_class", _player.get_class())
|
|
57
|
+
report("mode", "3D" if _is_3d else "2D")
|
|
58
|
+
report("start_pos", str(_pos()))
|
|
59
|
+
dump_tree()
|
|
60
|
+
save_frame("00_start")
|
|
61
|
+
|
|
62
|
+
for i in WAYPOINTS.size():
|
|
63
|
+
var target: Vector3 = WAYPOINTS[i]
|
|
64
|
+
var arrived := await _walk_to(target)
|
|
65
|
+
report("waypoint_%d_reached" % i, arrived)
|
|
66
|
+
report("waypoint_%d_pos" % i, str(_pos()))
|
|
67
|
+
save_frame("%02d_waypoint_%d" % [i + 1, i])
|
|
68
|
+
_check_at_waypoint(i)
|
|
69
|
+
if not arrived:
|
|
70
|
+
report("failed_at_waypoint", i)
|
|
71
|
+
break
|
|
72
|
+
|
|
73
|
+
_check_at_end()
|
|
74
|
+
finish()
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
# ── Your assertions go here ───────────────────────────────────────────────────────
|
|
78
|
+
|
|
79
|
+
# Called after arriving at (or failing to reach) each waypoint.
|
|
80
|
+
func _check_at_waypoint(index: int) -> void:
|
|
81
|
+
# Assert things that are TRUE OR FALSE, not things that are approximately a number.
|
|
82
|
+
# Hold durations are wall-clock, so exact distances drift between runs.
|
|
83
|
+
#
|
|
84
|
+
# var hud := get_tree().current_scene.get_node_or_null("UI/HUD")
|
|
85
|
+
# report("hud_visible_at_%d" % index, hud != null and hud.visible)
|
|
86
|
+
# report("enemies_alive_at_%d" % index, get_tree().get_nodes_in_group("enemy").size())
|
|
87
|
+
pass
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
# Called once after the last waypoint.
|
|
91
|
+
func _check_at_end() -> void:
|
|
92
|
+
# report("player_alive", _player.has_method("is_alive") and _player.is_alive())
|
|
93
|
+
pass
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# ── Machinery — you should not need to edit below this line ───────────────────────
|
|
97
|
+
|
|
98
|
+
func _bind_player() -> bool:
|
|
99
|
+
var scene := get_tree().current_scene
|
|
100
|
+
if scene == null:
|
|
101
|
+
report("error", "no current scene — is run/main_scene set in project.godot?")
|
|
102
|
+
return false
|
|
103
|
+
_player = scene.get_node_or_null(PLAYER_PATH)
|
|
104
|
+
if _player == null:
|
|
105
|
+
report("error", "player not found at '%s'" % PLAYER_PATH)
|
|
106
|
+
report("scene_children", _child_names(scene))
|
|
107
|
+
dump_tree()
|
|
108
|
+
return false
|
|
109
|
+
_is_3d = _player is Node3D
|
|
110
|
+
if not (_is_3d or _player is Node2D):
|
|
111
|
+
report("error", "player at '%s' is neither Node2D nor Node3D" % PLAYER_PATH)
|
|
112
|
+
return false
|
|
113
|
+
return true
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
func _child_names(n: Node) -> Array:
|
|
117
|
+
var names := []
|
|
118
|
+
for c in n.get_children():
|
|
119
|
+
names.append(c.name)
|
|
120
|
+
return names
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
# Player position normalised to a Vector3 so one code path handles 2D and 3D.
|
|
124
|
+
# In 2D, x/y are screen pixels and z is unused.
|
|
125
|
+
func _pos() -> Vector3:
|
|
126
|
+
if _is_3d:
|
|
127
|
+
var p: Vector3 = _player.global_position
|
|
128
|
+
return p
|
|
129
|
+
var p2: Vector2 = _player.global_position
|
|
130
|
+
return Vector3(p2.x, p2.y, 0.0)
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
# Distance that matters for "did we arrive", measured ONLY on axes the game can
|
|
134
|
+
# actually steer. A side-on platformer has no up/down actions, so its Y is gravity,
|
|
135
|
+
# not a destination — including it would mean the player never "arrives" while
|
|
136
|
+
# standing on the ground 368 pixels below Y=0. That is a real failure this scaffold
|
|
137
|
+
# hit on its first run.
|
|
138
|
+
func _planar_distance(a: Vector3, b: Vector3) -> float:
|
|
139
|
+
var d := 0.0
|
|
140
|
+
if _has_horizontal_actions():
|
|
141
|
+
d += pow(b.x - a.x, 2.0)
|
|
142
|
+
if _has_secondary_actions():
|
|
143
|
+
var d2 := (b.z - a.z) if _is_3d else (b.y - a.y)
|
|
144
|
+
d += pow(d2, 2.0)
|
|
145
|
+
return sqrt(d)
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
func _has_horizontal_actions() -> bool:
|
|
149
|
+
return _action_live(ACT_LEFT) or _action_live(ACT_RIGHT)
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
func _has_secondary_actions() -> bool:
|
|
153
|
+
return _action_live(ACT_UP) or _action_live(ACT_DOWN)
|
|
154
|
+
|
|
155
|
+
|
|
156
|
+
func _action_live(action: String) -> bool:
|
|
157
|
+
return action != "" and InputMap.has_action(action)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
func _walk_to(target: Vector3) -> bool:
|
|
161
|
+
var frames := 0
|
|
162
|
+
var held: Array[String] = []
|
|
163
|
+
|
|
164
|
+
while frames < LEG_TIMEOUT_FRAMES:
|
|
165
|
+
var here := _pos()
|
|
166
|
+
if _planar_distance(here, target) <= ARRIVE_EPSILON:
|
|
167
|
+
_release(held)
|
|
168
|
+
return true
|
|
169
|
+
|
|
170
|
+
var want := _actions_toward(here, target)
|
|
171
|
+
# Only touch actions that changed, so a held key stays held across frames
|
|
172
|
+
# instead of being released and re-pressed every frame.
|
|
173
|
+
for a in held:
|
|
174
|
+
if not want.has(a):
|
|
175
|
+
_set_action(a, false)
|
|
176
|
+
for a in want:
|
|
177
|
+
if not held.has(a):
|
|
178
|
+
_set_action(a, true)
|
|
179
|
+
held = want
|
|
180
|
+
|
|
181
|
+
await get_tree().physics_frame
|
|
182
|
+
frames += 1
|
|
183
|
+
|
|
184
|
+
_release(held)
|
|
185
|
+
return false
|
|
186
|
+
|
|
187
|
+
|
|
188
|
+
func _actions_toward(here: Vector3, target: Vector3) -> Array[String]:
|
|
189
|
+
var out: Array[String] = []
|
|
190
|
+
var dx := target.x - here.x
|
|
191
|
+
if absf(dx) > ARRIVE_EPSILON * 0.5:
|
|
192
|
+
var a := ACT_RIGHT if dx > 0.0 else ACT_LEFT
|
|
193
|
+
if _action_live(a):
|
|
194
|
+
out.append(a)
|
|
195
|
+
|
|
196
|
+
# Second axis: z in 3D, y in 2D. Skipped when the game has no such actions
|
|
197
|
+
# (a side-on platformer, for example).
|
|
198
|
+
if _has_secondary_actions():
|
|
199
|
+
var d2 := (target.z - here.z) if _is_3d else (target.y - here.y)
|
|
200
|
+
if absf(d2) > ARRIVE_EPSILON * 0.5:
|
|
201
|
+
var b := ACT_DOWN if d2 > 0.0 else ACT_UP
|
|
202
|
+
if _action_live(b):
|
|
203
|
+
out.append(b)
|
|
204
|
+
|
|
205
|
+
return out
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
# Press and release directly rather than via press(), which awaits its own hold
|
|
209
|
+
# duration on the wall clock. Holding across physics frames is what makes an
|
|
210
|
+
# autopilot run reproducible.
|
|
211
|
+
func _set_action(action: String, pressed: bool) -> void:
|
|
212
|
+
if action == "" or not InputMap.has_action(action):
|
|
213
|
+
return
|
|
214
|
+
var ev := InputEventAction.new()
|
|
215
|
+
ev.action = action
|
|
216
|
+
ev.pressed = pressed
|
|
217
|
+
Input.parse_input_event(ev)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
func _release(held: Array) -> void:
|
|
221
|
+
for a in held:
|
|
222
|
+
_set_action(a, false)
|