summer-engine 2.3.0 → 2.6.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/marketplace.json +2 -2
- package/.claude-plugin/plugin.json +24 -8
- package/.codex-plugin/plugin.json +19 -8
- package/.cursor-plugin/plugin.json +18 -7
- package/.factory-plugin/plugin.json +3 -3
- package/.opencode/INSTALL.md +1 -1
- package/AGENTS.md +6 -4
- package/CHANGELOG.md +46 -7
- package/CLAUDE.md +2 -2
- package/GEMINI.md +5 -6
- package/README.md +116 -109
- package/_persona/summer/SKILL.md +5 -6
- package/commands/gameskill.md +103 -0
- package/dist/bin/summer.js +17 -4
- package/dist/commands/cloud.d.ts +2 -0
- package/dist/commands/cloud.js +80 -0
- package/dist/commands/create.js +2 -0
- package/dist/commands/doctor.js +90 -1
- package/dist/commands/install.d.ts +17 -0
- package/dist/commands/install.js +63 -4
- package/dist/commands/login.js +4 -1
- package/dist/commands/logout.js +1 -1
- package/dist/commands/memory.d.ts +14 -0
- package/dist/commands/memory.js +196 -0
- package/dist/commands/open.js +1 -1
- package/dist/commands/plan.d.ts +2 -0
- package/dist/commands/plan.js +60 -0
- package/dist/commands/run.js +132 -35
- package/dist/commands/setup.js +8 -2
- package/dist/commands/skills.js +90 -6
- package/dist/commands/status.js +3 -0
- package/dist/lib/agent-config.d.ts +2 -2
- package/dist/lib/agent-config.js +134 -7
- package/dist/lib/api-client.d.ts +13 -0
- package/dist/lib/api-client.js +63 -26
- package/dist/lib/async-op-lifecycle.d.ts +60 -0
- package/dist/lib/async-op-lifecycle.js +83 -0
- package/dist/lib/auth.d.ts +2 -0
- package/dist/lib/auth.js +13 -0
- package/dist/lib/cloud/api.d.ts +79 -0
- package/dist/lib/cloud/api.js +107 -0
- package/dist/lib/cloud/apply.d.ts +32 -0
- package/dist/lib/cloud/apply.js +294 -0
- package/dist/lib/cloud/checkpoint.d.ts +26 -0
- package/dist/lib/cloud/checkpoint.js +142 -0
- package/dist/lib/cloud/conflicts.d.ts +55 -0
- package/dist/lib/cloud/conflicts.js +131 -0
- package/dist/lib/cloud/containment.d.ts +8 -0
- package/dist/lib/cloud/containment.js +52 -0
- package/dist/lib/cloud/diff.d.ts +39 -0
- package/dist/lib/cloud/diff.js +138 -0
- package/dist/lib/cloud/engine-bridge.d.ts +21 -0
- package/dist/lib/cloud/engine-bridge.js +105 -0
- package/dist/lib/cloud/hash-cache.d.ts +23 -0
- package/dist/lib/cloud/hash-cache.js +44 -0
- package/dist/lib/cloud/hash.d.ts +10 -0
- package/dist/lib/cloud/hash.js +111 -0
- package/dist/lib/cloud/http.d.ts +17 -0
- package/dist/lib/cloud/http.js +47 -0
- package/dist/lib/cloud/lock-path.d.ts +1 -0
- package/dist/lib/cloud/lock-path.js +5 -0
- package/dist/lib/cloud/lock.d.ts +14 -0
- package/dist/lib/cloud/lock.js +143 -0
- package/dist/lib/cloud/manifest.d.ts +6 -0
- package/dist/lib/cloud/manifest.js +41 -0
- package/dist/lib/cloud/paths.d.ts +20 -0
- package/dist/lib/cloud/paths.js +90 -0
- package/dist/lib/cloud/project-godot-merge.d.ts +32 -0
- package/dist/lib/cloud/project-godot-merge.js +185 -0
- package/dist/lib/cloud/rules.d.ts +39 -0
- package/dist/lib/cloud/rules.js +159 -0
- package/dist/lib/cloud/sync.d.ts +21 -0
- package/dist/lib/cloud/sync.js +518 -0
- package/dist/lib/cloud/transfer.d.ts +23 -0
- package/dist/lib/cloud/transfer.js +184 -0
- package/dist/lib/cloud/types.d.ts +62 -0
- package/dist/lib/cloud/validate-path.d.ts +23 -0
- package/dist/lib/cloud/validate-path.js +103 -0
- package/dist/lib/engine.d.ts +6 -0
- package/dist/lib/engine.js +36 -1
- package/dist/lib/game-task-plan.d.ts +42 -0
- package/dist/lib/game-task-plan.js +376 -0
- package/dist/lib/project-memory.d.ts +33 -0
- package/dist/lib/project-memory.js +220 -0
- package/dist/lib/skills-registry.d.ts +134 -61
- package/dist/lib/skills-registry.js +102 -4
- package/dist/lib/version-check.d.ts +106 -0
- package/dist/lib/version-check.js +338 -0
- package/dist/mcp/server.d.ts +2 -0
- package/dist/mcp/server.js +83 -0
- package/dist/mcp/tools/asset-tools.js +265 -45
- package/dist/mcp/tools/cloud-tools.d.ts +2 -0
- package/dist/mcp/tools/cloud-tools.js +42 -0
- package/dist/mcp/tools/debug-tools.js +32 -2
- package/dist/mcp/tools/generate-tools.js +101 -13
- package/dist/mcp/tools/project-tools.js +76 -21
- package/dist/mcp/tools/with-engine.d.ts +14 -0
- package/dist/mcp/tools/with-engine.js +52 -7
- package/gemini-extension.json +3 -3
- package/hooks/pre-commit-doctor.sh +0 -0
- package/hooks/run-hook.cmd +0 -0
- package/hooks/session-start.sh +0 -0
- package/package.json +20 -7
- package/skills/2d-assets/character-portrait/SKILL.md +1 -1
- package/skills/2d-assets/concept-art/SKILL.md +1 -1
- package/skills/2d-assets/create-asset-sheet/SKILL.md +163 -0
- package/skills/2d-assets/instantiate-asset-pack/SKILL.md +245 -0
- package/skills/2d-assets/pixel-art/SKILL.md +1 -1
- package/skills/2d-assets/skybox-panorama/SKILL.md +1 -1
- package/skills/2d-assets/sprite-sheet/SKILL.md +1 -1
- package/skills/2d-assets/tileable-texture/SKILL.md +1 -1
- package/skills/2d-assets/ui-graphics/SKILL.md +1 -1
- package/skills/2d-assets/use-widget-asset/SKILL.md +217 -0
- package/skills/3d-assets/character-model/SKILL.md +28 -6
- package/skills/3d-assets/environment-kit/SKILL.md +7 -2
- package/skills/3d-assets/organic-model/SKILL.md +5 -4
- package/skills/3d-assets/prop-model/SKILL.md +17 -9
- package/skills/3d-assets/vehicle-model/SKILL.md +5 -4
- package/skills/README.md +37 -30
- package/skills/ai-and-npcs/design-npc/SKILL.md +6 -6
- package/skills/animation/animation-tree/SKILL.md +4 -2
- package/skills/animation/facial-and-lipsync/SKILL.md +1 -1
- package/skills/animation/generate-motion/SKILL.md +26 -5
- package/skills/animation/procedural-animation/SKILL.md +2 -2
- package/skills/asset-pipeline/asset-strategy/SKILL.md +3 -2
- package/skills/audio/adaptive-music/SKILL.md +1 -1
- package/skills/audio/audio-direction/SKILL.md +5 -5
- package/skills/audio/sound-effect/SKILL.md +2 -2
- package/skills/audio/voice-line/SKILL.md +25 -3
- package/skills/character-controllers/fps-controller/SKILL.md +5 -5
- package/skills/debugging/debug/SKILL.md +39 -1
- package/skills/deployment/export-and-ship/SKILL.md +4 -4
- package/skills/gameplay-mechanics/auto-fire-targeting/SKILL.md +170 -0
- package/skills/gameplay-mechanics/design-mechanic/SKILL.md +8 -8
- package/skills/level-design/design-level/SKILL.md +5 -5
- package/skills/level-design/scene-to-level/SKILL.md +125 -0
- package/skills/multiplayer-and-networking/host-authoritative-state/SKILL.md +4 -4
- package/skills/multiplayer-and-networking/peer-to-peer-multiplayer/SKILL.md +4 -4
- package/skills/multiplayer-and-networking/setup-multiplayer/SKILL.md +7 -7
- package/skills/performance/tune-performance/SKILL.md +5 -5
- package/skills/rendering-and-lighting/3d-lighting/SKILL.md +1 -1
- package/skills/rendering-and-lighting/art-direction/SKILL.md +5 -5
- package/skills/scene-and-project/brainstorm-game/SKILL.md +4 -4
- package/skills/scene-and-project/play/SKILL.md +1 -1
- package/skills/scene-and-project/scene-composition/SKILL.md +30 -1
- package/skills/scripting-patterns/gdscript-patterns/SKILL.md +53 -0
- package/skills/ui-and-ux/ui-basics/SKILL.md +1 -1
- package/skills/video/animated-loop/SKILL.md +1 -1
- package/skills/video/cinematic-cutscene/SKILL.md +1 -1
- package/skills/video/trailer-shot/SKILL.md +1 -1
- package/skills/visual-effects/game-feel/SKILL.md +6 -6
- package/skills/workflow/brainstorming/SKILL.md +164 -0
- package/skills/workflow/brainstorming/scripts/frame-template.html +214 -0
- package/skills/workflow/brainstorming/scripts/helper.js +88 -0
- package/skills/workflow/brainstorming/scripts/server.cjs +354 -0
- package/skills/workflow/brainstorming/scripts/start-server.sh +148 -0
- package/skills/workflow/brainstorming/scripts/stop-server.sh +56 -0
- package/skills/workflow/brainstorming/spec-document-reviewer-prompt.md +49 -0
- package/skills/workflow/brainstorming/visual-companion.md +287 -0
- package/skills/workflow/debugging-game-feel/SKILL.md +174 -0
- package/skills/workflow/diagnosing-perf-regressions/SKILL.md +190 -0
- package/skills/workflow/dispatching-parallel-agents/SKILL.md +182 -0
- package/skills/workflow/gameskill/SKILL.md +111 -0
- package/skills/workflow/investigating-bugs/CREATION-LOG.md +119 -0
- package/skills/workflow/investigating-bugs/SKILL.md +296 -0
- package/skills/workflow/investigating-bugs/condition-based-waiting-example.ts +158 -0
- package/skills/workflow/investigating-bugs/condition-based-waiting.md +115 -0
- package/skills/workflow/investigating-bugs/defense-in-depth.md +122 -0
- package/skills/workflow/investigating-bugs/find-polluter.sh +63 -0
- package/skills/workflow/investigating-bugs/root-cause-tracing.md +169 -0
- package/skills/workflow/investigating-bugs/test-academic.md +14 -0
- package/skills/workflow/investigating-bugs/test-pressure-1.md +58 -0
- package/skills/workflow/investigating-bugs/test-pressure-2.md +68 -0
- package/skills/workflow/investigating-bugs/test-pressure-3.md +69 -0
- package/skills/workflow/mcpupdate/SKILL.md +134 -0
- package/skills/workflow/playtesting-a-feature/SKILL.md +173 -0
- package/skills/{_meta → workflow}/skill-create/SKILL.md +32 -22
- package/skills/{_meta → workflow}/skill-improve/SKILL.md +9 -10
- package/skills/{_meta → workflow}/skill-test/SKILL.md +12 -12
- package/skills/{_meta → workflow}/using-summer/SKILL.md +5 -2
- package/skills/workflow/verification-before-completion/SKILL.md +139 -0
- package/skills/workflow/writing-plans/SKILL.md +152 -0
- package/skills/workflow/writing-plans/plan-document-reviewer-prompt.md +49 -0
- package/skills/workflow/writing-skills/SKILL.md +655 -0
- package/skills/workflow/writing-skills/anthropic-best-practices.md +1150 -0
- package/skills/workflow/writing-skills/examples/CLAUDE_MD_TESTING.md +189 -0
- package/skills/workflow/writing-skills/graphviz-conventions.dot +172 -0
- package/skills/workflow/writing-skills/persuasion-principles.md +187 -0
- package/skills/workflow/writing-skills/render-graphs.js +168 -0
- package/skills/workflow/writing-skills/testing-skills-with-subagents.md +384 -0
- package/dist/commands/assets.d.ts +0 -2
- package/dist/commands/assets.js +0 -189
- package/dist/commands/debug.d.ts +0 -2
- package/dist/commands/debug.js +0 -127
- package/dist/commands/doctor.test.js +0 -29
- package/dist/commands/project.d.ts +0 -2
- package/dist/commands/project.js +0 -170
- package/dist/commands/scene.d.ts +0 -2
- package/dist/commands/scene.js +0 -290
- package/dist/lib/agent-config.test.d.ts +0 -1
- package/dist/lib/agent-config.test.js +0 -80
- package/dist/lib/format.test.d.ts +0 -1
- package/dist/lib/format.test.js +0 -36
- package/dist/lib/plugin-manifests.test.d.ts +0 -1
- package/dist/lib/plugin-manifests.test.js +0 -134
- package/dist/lib/with-engine.d.ts +0 -14
- package/dist/lib/with-engine.js +0 -109
- package/skills/_shared/collaborative-protocol.md +0 -50
- package/skills/_shared/gd-style.md +0 -121
- package/skills/_shared/godot-version.md +0 -32
- package/skills/_shared/mcp-tools-reference.md +0 -133
- package/skills/_shared/summer-folder.md +0 -44
- package/skills/_shared/template-registry.md +0 -40
- package/skills/_tests/runner.md +0 -90
- package/skills/_tests/specs/3d-lighting.md +0 -19
- package/skills/_tests/specs/art-direction.md +0 -115
- package/skills/_tests/specs/asset-strategy.md +0 -19
- package/skills/_tests/specs/audio-direction.md +0 -123
- package/skills/_tests/specs/brainstorm-game.md +0 -99
- package/skills/_tests/specs/debug.md +0 -94
- package/skills/_tests/specs/design-level.md +0 -113
- package/skills/_tests/specs/design-mechanic.md +0 -112
- package/skills/_tests/specs/design-npc.md +0 -143
- package/skills/_tests/specs/export-and-ship.md +0 -114
- package/skills/_tests/specs/fps-controller.md +0 -113
- package/skills/_tests/specs/gdscript-patterns.md +0 -19
- package/skills/_tests/specs/host-authoritative-state.md +0 -104
- package/skills/_tests/specs/make-game.md +0 -19
- package/skills/_tests/specs/peer-to-peer-multiplayer.md +0 -99
- package/skills/_tests/specs/play.md +0 -88
- package/skills/_tests/specs/scene-composition.md +0 -19
- package/skills/_tests/specs/setup-multiplayer.md +0 -106
- package/skills/_tests/specs/tune-performance.md +0 -104
- package/skills/_tests/specs/ui-basics.md +0 -19
- package/skills/_tests/specs/vfx.md +0 -116
- package/skills/catalog.yaml +0 -991
- /package/dist/{commands/doctor.test.d.ts → lib/cloud/types.js} +0 -0
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: auto-fire-targeting
|
|
3
|
+
description: Use when designing or fixing the targeting system for an auto-fire weapon (survivors-genre, top-down ARPG, tower-defense). Covers the pending-damage pattern that prevents over-commit when bullet flight time is longer than fire rate. Trigger on "auto-fire", "auto-aim", "weapon targeting", "targeting", "wasted bullets", "overkill", "damage prediction", "survivors weapon".
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: gameplay-mechanics
|
|
7
|
+
allowed-tools: Read Edit Grep
|
|
8
|
+
paths: ["**/*.gd"]
|
|
9
|
+
---
|
|
10
|
+
|
|
11
|
+
# Auto-Fire Weapon Targeting — pending-damage pattern
|
|
12
|
+
|
|
13
|
+
A survivors-genre auto-fire weapon picks a target each fire frame. Naive nearest-enemy targeting wastes bullets when fire rate exceeds bullet flight time. This skill encodes the pending-damage pattern that fixes it.
|
|
14
|
+
|
|
15
|
+
## The problem
|
|
16
|
+
|
|
17
|
+
Auto-fire weapon. Bullet speed 22 m/s. Target 10m away. Bullet takes ~0.45s to arrive. With high attack speed the player fires several bullets per second. By the time the first bullet arrives and kills the target, several more bullets are already in flight toward where the target was. They miss into empty space. The player sees bullets "fan out in a cone past the dead enemy" while other enemies stand around untouched.
|
|
18
|
+
|
|
19
|
+
This is not a re-targeting bug. The weapon's `_fire()` correctly re-runs `find_nearest_enemy()` each shot. The issue is that the target is alive at fire-time and dead at arrival-time. All shots fired in that window aim at it because none of them know about the kill in flight.
|
|
20
|
+
|
|
21
|
+
## The fix — pending damage commitment
|
|
22
|
+
|
|
23
|
+
Each enemy carries a counter of damage that is in flight toward it. Targeting de-prefers (but does not exclude) enemies whose pending damage already exceeds their current HP.
|
|
24
|
+
|
|
25
|
+
### 1. Add the counter to the enemy base class
|
|
26
|
+
|
|
27
|
+
```gdscript
|
|
28
|
+
# enemy_base_3d.gd
|
|
29
|
+
|
|
30
|
+
var pending_damage: float = 0.0
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
func commit_pending(amount: float) -> void:
|
|
34
|
+
pending_damage += amount
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
func release_pending(amount: float) -> void:
|
|
38
|
+
pending_damage = maxf(0.0, pending_damage - amount)
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
## True if enough damage is already in flight to kill this enemy.
|
|
42
|
+
func is_saturated() -> bool:
|
|
43
|
+
return pending_damage >= health
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### 2. Update the targeting helper
|
|
47
|
+
|
|
48
|
+
The selector keeps the saturated set as a fallback. If every enemy is saturated, the player must still be able to fire on someone — fall through to a normal nearest pick across saturated enemies. Otherwise prefer non-saturated.
|
|
49
|
+
|
|
50
|
+
```gdscript
|
|
51
|
+
# targeting.gd
|
|
52
|
+
|
|
53
|
+
static func pick(origin: Vector3, mode: int, max_range: float, ...) -> Node3D:
|
|
54
|
+
var enemies: Array = GameManager.get_enemies()
|
|
55
|
+
var best: Node3D = null
|
|
56
|
+
var best_score: float = -INF
|
|
57
|
+
var fallback: Node3D = null
|
|
58
|
+
var fallback_score: float = -INF
|
|
59
|
+
for enemy in enemies:
|
|
60
|
+
# ... existing range + LoS filters ...
|
|
61
|
+
var score := _score(enemy, d_sq, mode)
|
|
62
|
+
var saturated: bool = "is_saturated" in enemy and enemy.is_saturated()
|
|
63
|
+
if saturated:
|
|
64
|
+
if score > fallback_score:
|
|
65
|
+
fallback_score = score
|
|
66
|
+
fallback = enemy
|
|
67
|
+
else:
|
|
68
|
+
if score > best_score:
|
|
69
|
+
best_score = score
|
|
70
|
+
best = enemy
|
|
71
|
+
if best != null:
|
|
72
|
+
return best
|
|
73
|
+
return fallback # everyone is saturated; fire on the next-best anyway
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
### 3. Commit at fire time
|
|
77
|
+
|
|
78
|
+
```gdscript
|
|
79
|
+
# projectile_weapon.gd
|
|
80
|
+
|
|
81
|
+
func _spawn_projectile(dir: Vector3, target: Node3D) -> void:
|
|
82
|
+
var dmg: float = base_damage * GameManager.player_damage_mult
|
|
83
|
+
# Commit expected damage. No crit factor — we don't gamble on RNG. If crit
|
|
84
|
+
# over-kills the target, the next-frame release refunds the difference.
|
|
85
|
+
var commit_amount: float = dmg
|
|
86
|
+
if target != null and target.has_method("commit_pending"):
|
|
87
|
+
target.commit_pending(commit_amount)
|
|
88
|
+
var proj: Node3D = _projectile_scene.instantiate()
|
|
89
|
+
# ... add_child, position, etc ...
|
|
90
|
+
proj.setup(dir * PROJECTILE_SPEED, dmg, ..., target, commit_amount)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### 4. Release at bullet death (catch-all)
|
|
94
|
+
|
|
95
|
+
The bullet must release the commitment exactly once when it leaves the tree, regardless of how. Hit, pierce-out, range-expire, or any other free path. Use `tree_exiting` so the release is guaranteed without each free-site having to remember.
|
|
96
|
+
|
|
97
|
+
```gdscript
|
|
98
|
+
# bullet.gd
|
|
99
|
+
|
|
100
|
+
var _committed_target: Node = null
|
|
101
|
+
var _committed_amount: float = 0.0
|
|
102
|
+
var _committed_released: bool = false
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
func setup(..., commit_target: Node = null, commit_amount: float = 0.0) -> void:
|
|
106
|
+
# ... other setup ...
|
|
107
|
+
_committed_target = commit_target
|
|
108
|
+
_committed_amount = commit_amount
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
func _ready() -> void:
|
|
112
|
+
# ... other wiring ...
|
|
113
|
+
tree_exiting.connect(_release_committed)
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## Idempotent so multiple call paths can't double-release.
|
|
117
|
+
func _release_committed() -> void:
|
|
118
|
+
if _committed_released:
|
|
119
|
+
return
|
|
120
|
+
_committed_released = true
|
|
121
|
+
if _committed_amount <= 0.0:
|
|
122
|
+
return
|
|
123
|
+
if _committed_target != null and is_instance_valid(_committed_target) \
|
|
124
|
+
and _committed_target.has_method("release_pending"):
|
|
125
|
+
_committed_target.release_pending(_committed_amount)
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
## Bonus — spread fan across multiple enemies
|
|
129
|
+
|
|
130
|
+
When the weapon fires N projectiles per shot (extra-projectiles upgrade, multishot), pick a fresh target per projectile instead of fanning all N at the primary target. Combined with the saturation filter this drains follow-on shots toward fresh enemies.
|
|
131
|
+
|
|
132
|
+
```gdscript
|
|
133
|
+
# projectile_weapon.gd, multishot path
|
|
134
|
+
|
|
135
|
+
for i in total_projectiles:
|
|
136
|
+
var per_shot_target := Targeting.pick(global_position, mode, range)
|
|
137
|
+
if per_shot_target == null:
|
|
138
|
+
per_shot_target = primary_target # fall back if nothing else in range
|
|
139
|
+
_spawn_projectile(dir.rotated(Vector3.UP, fan_angle), per_shot_target)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
## Bonus — bump projectile speed
|
|
143
|
+
|
|
144
|
+
The over-commit window is `attack_speed * bullet_travel_time`. Faster bullets shrink it for free. 22 m/s up to 35 m/s halves the window without affecting balance much. Cheap fix to bundle with the pattern.
|
|
145
|
+
|
|
146
|
+
## What this does NOT solve
|
|
147
|
+
|
|
148
|
+
- **Pierce > 1 weapons.** The committed amount is reserved on the first target only. Subsequent pierces are bonus damage to whoever happens to be in line. That is fine — pierce already feels random by design.
|
|
149
|
+
- **AOE / nova / orbital weapons.** They hit everyone in radius regardless of "target," so single-target pending-damage doesn't apply. Skip them.
|
|
150
|
+
- **Slow-but-massive weapons.** A single shot that one-shots multiple enemies in sequence (rocket launcher, railgun) doesn't benefit much. The window where the over-commit happens is too short to matter.
|
|
151
|
+
|
|
152
|
+
## Why this beats alternatives
|
|
153
|
+
|
|
154
|
+
| Alternative | Why we didn't pick it |
|
|
155
|
+
|---|---|
|
|
156
|
+
| In-flight bullet retargeting (each bullet seeks the nearest live enemy mid-flight) | Per-bullet logic is expensive and the homing visual reads as a different weapon archetype. Pending-damage is fire-and-forget. |
|
|
157
|
+
| Predict the kill (fire only enough bullets to kill) | Requires knowing exact damage including crit and item modifiers. Edge cases multiply. |
|
|
158
|
+
| Just bump bullet speed | Helps but doesn't eliminate the issue at very high attack-speed builds. |
|
|
159
|
+
| Shoot-through-enemies (everyone gets free pierce) | Changes weapon identity. AOE bleed. |
|
|
160
|
+
|
|
161
|
+
Pending-damage is local to the targeting query, requires no per-bullet ticking, and keeps each weapon archetype's identity intact.
|
|
162
|
+
|
|
163
|
+
## Verification
|
|
164
|
+
|
|
165
|
+
Test scenario: spawn a single weak enemy directly in front of the player at point-blank range. Equip the auto-fire weapon and the highest-attack-speed item. Watch the bullet fan when the enemy dies.
|
|
166
|
+
|
|
167
|
+
Before: 5-15 bullets continue past the corpse over the next ~0.5s.
|
|
168
|
+
After: 1-2 bullets continue (the ones that were already past the half-flight point), the rest of the fire pool redirects to whatever target Targeting picks next, or stops if there's none in range.
|
|
169
|
+
|
|
170
|
+
Use `summer_get_diagnostics` to confirm no new errors. Use `summer_inspect_node` on a sample enemy mid-fight to confirm `pending_damage` is being incremented and decremented as expected.
|
|
@@ -148,7 +148,7 @@ lifetime = 0.4
|
|
|
148
148
|
|
|
149
149
|
### 7. Write the GDScript stub
|
|
150
150
|
|
|
151
|
-
Stub only — implementation is the next session. Use `
|
|
151
|
+
Stub only — implementation is the next session. Use `references/gd-style.md` conventions. For double-jump:
|
|
152
152
|
|
|
153
153
|
```gdscript
|
|
154
154
|
class_name PlayerController
|
|
@@ -236,12 +236,12 @@ Ask:
|
|
|
236
236
|
| Hand-wave depth | "Players will use it strategically" is not depth. Name the choice the player makes. |
|
|
237
237
|
| Tunables hard-coded as `const` | Use `@export` so designers tune in the inspector. |
|
|
238
238
|
| Adding the mechanic without the FX/audio nodes | Without nodes for feedback, the mechanic ships feeling cheap. Scaffold the nodes alongside the script. |
|
|
239
|
-
| Setting `position` for movement instead of `velocity` | Physics objects use `velocity` in `_physics_process`. See `
|
|
240
|
-
| Calling SetResourceProperty on inline sub_resources | Silent fail. See `
|
|
239
|
+
| Setting `position` for movement instead of `velocity` | Physics objects use `velocity` in `_physics_process`. See `references/gd-style.md`. |
|
|
240
|
+
| Calling SetResourceProperty on inline sub_resources | Silent fail. See `references/mcp-tools-reference.md` § Trap. |
|
|
241
241
|
|
|
242
242
|
## Collaborative protocol
|
|
243
243
|
|
|
244
|
-
This skill writes scene nodes and one or more files (`.gd`, `.summer/mechanics/<name>.md`). Group writes into one ask per phase. See `
|
|
244
|
+
This skill writes scene nodes and one or more files (`.gd`, `.summer/mechanics/<name>.md`). Group writes into one ask per phase. See `references/collaborative-protocol.md`.
|
|
245
245
|
|
|
246
246
|
## Want a working starter?
|
|
247
247
|
|
|
@@ -254,10 +254,10 @@ This skill is a workflow that designs and scaffolds — the templates are runnab
|
|
|
254
254
|
|
|
255
255
|
## See also
|
|
256
256
|
|
|
257
|
-
- `
|
|
258
|
-
- `
|
|
259
|
-
- `
|
|
260
|
-
- `
|
|
257
|
+
- `references/collaborative-protocol.md`
|
|
258
|
+
- `references/mcp-tools-reference.md`
|
|
259
|
+
- `references/gd-style.md` — GDScript conventions
|
|
260
|
+
- `references/godot-version.md` — Godot 4.5 API notes
|
|
261
261
|
- `scene-and-project/brainstorm-game/SKILL.md` — produces `.summer/GameSoul.md` this skill reads
|
|
262
262
|
- `level-design/design-level/SKILL.md` — design the levels that exercise the mechanic
|
|
263
263
|
- `character-controllers/fps-controller/SKILL.md` — FPS movement scaffolding
|
|
@@ -239,11 +239,11 @@ End with:
|
|
|
239
239
|
| Reward gating too generous | Free heals before the peak deflate the peak. Gate them after the test. |
|
|
240
240
|
| Blending level types | Stealth + puzzle + boss in one level = three half-baked levels. Pick one. |
|
|
241
241
|
| Building geometry before the skeleton | Skeleton-first lets you iterate on layout cheaply. Geometry comes after the design is locked. |
|
|
242
|
-
| Calling SetResourceProperty on inline sub_resources | Silent fail. See `
|
|
242
|
+
| Calling SetResourceProperty on inline sub_resources | Silent fail. See `references/mcp-tools-reference.md` § Trap. |
|
|
243
243
|
|
|
244
244
|
## Collaborative protocol
|
|
245
245
|
|
|
246
|
-
This skill creates a new scene file (`.tscn`) and a design doc (`.md`). Group writes per phase. Always ask before `summer_create_scene`. See `
|
|
246
|
+
This skill creates a new scene file (`.tscn`) and a design doc (`.md`). Group writes per phase. Always ask before `summer_create_scene`. See `references/collaborative-protocol.md`.
|
|
247
247
|
|
|
248
248
|
## Want a working starter?
|
|
249
249
|
|
|
@@ -256,9 +256,9 @@ The skeleton this skill produces is meant to be filled in via `/summer:design-me
|
|
|
256
256
|
|
|
257
257
|
## See also
|
|
258
258
|
|
|
259
|
-
- `
|
|
260
|
-
- `
|
|
261
|
-
- `
|
|
259
|
+
- `references/collaborative-protocol.md`
|
|
260
|
+
- `references/mcp-tools-reference.md`
|
|
261
|
+
- `references/godot-version.md` — Godot 4.5 API notes
|
|
262
262
|
- `scene-and-project/brainstorm-game/SKILL.md` — produces `.summer/GameSoul.md`
|
|
263
263
|
- `gameplay-mechanics/design-mechanic/SKILL.md` — designs the verbs the level exercises
|
|
264
264
|
- `ai-and-npcs/design-npc/SKILL.md` — designs the enemies the encounters reference
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: scene-to-level
|
|
3
|
+
description: Use when the user wants to go from a single scene reference image (a screenshot or concept art of how the final game should look) all the way to a playable Godot scene populated with the right assets and terrain. Orchestrates concept → asset pack → terrain → composition → scene assembly. Trigger on "build this scene", "make this playable", "I want a level that looks like this", "from a screenshot to a game", "implement this concept".
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: level-design
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_create_scene summer_open_scene summer_add_node summer_set_prop summer_set_resource_property summer_save_scene summer_get_scene_tree summer_inspect_node summer_search_assets summer_import_from_url
|
|
9
|
+
paths: ["**/*.tscn", "**/*.gd", "assets/**", ".summer/**", "levels/**"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# scene-to-level — From a reference image to a playable scene
|
|
13
|
+
|
|
14
|
+
This is the **orchestrator** skill. It doesn't generate art, doesn't slice sheets, doesn't write game code — it routes the user through the chain of skills that do, and stitches their outputs together into a placeable Godot scene.
|
|
15
|
+
|
|
16
|
+
Use it when the user shows you a screenshot or concept image and says "build this." The output is a `.tscn` you can hit play on, populated with assets that match the reference's style.
|
|
17
|
+
|
|
18
|
+
## The pipeline (decision tree)
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
1. Read the reference image (vision).
|
|
22
|
+
└── What kind of scene is it?
|
|
23
|
+
├─ 2D top-down / isometric / side-scroller
|
|
24
|
+
│ └── route to TERRAIN + 2D ASSETS path
|
|
25
|
+
├─ 3D third-person / first-person
|
|
26
|
+
│ └── route to 3D ASSETS path (out of scope for this skill —
|
|
27
|
+
│ use summer:3d-assets/ subskills directly)
|
|
28
|
+
└─ UI-only screen (menu, HUD)
|
|
29
|
+
└── route to UI ASSETS path (just plan-asset-pack)
|
|
30
|
+
|
|
31
|
+
2. For each visible element, route to the right sub-pipeline:
|
|
32
|
+
|
|
33
|
+
TERRAIN → summer:2d-assets/tileable-texture
|
|
34
|
+
(auto-tiling Wang / 47-tile sheet; CURRENTLY a placeholder
|
|
35
|
+
that generates a single tile — full auto-tile work is
|
|
36
|
+
tracked in publicsummerengine/Docs/assetCreation/
|
|
37
|
+
TERRAIN_AUTOTILE_IDEA.md and not yet built)
|
|
38
|
+
|
|
39
|
+
PROPS / DECOR / LIGHTING / NATURE / WATER / BUILDINGS / UI / VFX
|
|
40
|
+
── If user has time for individual generation, prefer:
|
|
41
|
+
│ summer:2d-assets/create-asset-sheet (Plan + Generate Pack
|
|
42
|
+
│ mode at /studio/plan-asset-pack — higher quality, each asset
|
|
43
|
+
│ gets full model attention)
|
|
44
|
+
└── If user wants fast / exploratory:
|
|
45
|
+
summer:2d-assets/create-asset-sheet (Slice from a sheet at
|
|
46
|
+
/studio/create-tileset — one sheet, autoslice, cheaper)
|
|
47
|
+
|
|
48
|
+
CHARACTERS → summer:2d-assets/character-portrait first for the static
|
|
49
|
+
frame, then summer:2d-assets/sprite-sheet for animation
|
|
50
|
+
|
|
51
|
+
3. Once assets exist, USE-WIDGET-ASSET on any UI / panel / bar /
|
|
52
|
+
toggle pack files to wire them as NinePatchRect / TextureProgressBar
|
|
53
|
+
/ etc. (see summer:2d-assets/use-widget-asset)
|
|
54
|
+
|
|
55
|
+
4. Compose the scene:
|
|
56
|
+
- summer_create_scene with a Node2D / Control root depending on the
|
|
57
|
+
scene type
|
|
58
|
+
- Add a TileMap node for terrain; assign the generated tileset
|
|
59
|
+
resource
|
|
60
|
+
- Place props as Sprite2D / TextureRect children, positioned to
|
|
61
|
+
match the reference's composition
|
|
62
|
+
- Wire UI as Control nodes anchored to the viewport
|
|
63
|
+
|
|
64
|
+
5. Validate:
|
|
65
|
+
- summer_get_script_errors
|
|
66
|
+
- summer_play (the user takes over from here)
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
## When to use
|
|
70
|
+
|
|
71
|
+
- "Make this screenshot playable."
|
|
72
|
+
- "I want a level that looks exactly like this concept art."
|
|
73
|
+
- "Build a Japanese village scene like this reference."
|
|
74
|
+
- "I have a UI mockup — implement it."
|
|
75
|
+
|
|
76
|
+
## When NOT to use
|
|
77
|
+
|
|
78
|
+
- The user wants a **single asset** → `summer:2d-assets/pixel-art` or a leaf skill directly.
|
|
79
|
+
- The user wants to **design** a level from scratch (gameplay beats, pacing, encounters) → `summer:level-design/design-level`. This skill is post-design — it implements a known visual target.
|
|
80
|
+
- The user wants a **3D level** → use `summer:3d-assets/` subskills directly; the orchestration for 3D scenes isn't in this skill yet.
|
|
81
|
+
- The user wants a **playable prototype with mechanics already** → mechanics aren't in scope. This skill produces the *visuals*; the mechanic skills (e.g. `summer:gameplay-mechanics/design-mechanic`) handle behavior.
|
|
82
|
+
|
|
83
|
+
## Required up-front
|
|
84
|
+
|
|
85
|
+
Before starting, you need either:
|
|
86
|
+
|
|
87
|
+
1. A reference image (URL or local file) the user provides, OR
|
|
88
|
+
2. A vivid text description of the target scene from the user
|
|
89
|
+
|
|
90
|
+
If neither is offered, stop and ask. Don't guess what a "japanese village scene" looks like — get the reference first.
|
|
91
|
+
|
|
92
|
+
## Honest reliability map
|
|
93
|
+
|
|
94
|
+
| Pipeline node | Reliability | Cost (rough) | What can go wrong |
|
|
95
|
+
|---|---|---|---|
|
|
96
|
+
| Reading the reference (vision call) | High | $0.02 | Model misidentifies the scene type |
|
|
97
|
+
| Plan + Generate Pack (theme → per-asset) | High for props / icons / UI | $0.10–0.50 per pack | Style drift across items if no style ref |
|
|
98
|
+
| Slice from a sheet (single-sheet path) | Medium for dense sheets | $0.08 + upscales | Touching sprites merge into one slice |
|
|
99
|
+
| Tileable terrain (auto-tile) | LOW today — not built. | n/a | Use a single tile placeholder or stitch by hand |
|
|
100
|
+
| Sprite-sheet animation | Medium — see that skill's own honesty section | varies | Frame consistency is the hard part |
|
|
101
|
+
| Scene assembly via `summer_*` tools | High | free | Engine must be running |
|
|
102
|
+
|
|
103
|
+
Surface this map to the user when relevant — don't claim "ready to play in 10 minutes" if terrain auto-tiling is what they actually need.
|
|
104
|
+
|
|
105
|
+
## A worked example
|
|
106
|
+
|
|
107
|
+
User shows you a screenshot of a Japanese village with multiple islands, water between them, buildings, characters, and a bottom palette UI:
|
|
108
|
+
|
|
109
|
+
1. **Vision pass** identifies the scene as 2D isometric with: water terrain (large area), grass terrain (per island), buildings (5+ distinct), characters (2), UI palette + toolbar.
|
|
110
|
+
2. **Plan the props pack** via the create-asset-sheet planner: 12 props at minimum (torii, sakura, lantern, pagoda, bridge, well, sign, banner, bucket, hay, fence, crate). Generated per-asset for quality.
|
|
111
|
+
3. **Plan the buildings pack**: 5 distinct buildings (small house, barn, shop, pagoda, watchtower).
|
|
112
|
+
4. **Generate terrain**: today, single grass tile + single water tile + edge variant placeholders. Full Wang-tile auto-tiling is the TERRAIN_AUTOTILE_IDEA.md unbuilt path.
|
|
113
|
+
5. **Plan the UI pack** via the planner with theme "isometric voxel game UI: bottom palette, toolbar with Place/Erase/Pan/Save/Reset, asset category tabs, instruction panel."
|
|
114
|
+
6. **For each UI slice that's a panel / button**, use `summer:2d-assets/use-widget-asset` to wire as NinePatchRect.
|
|
115
|
+
7. **Compose**: TileMap for terrain; Sprite2D placement matching the reference; Control nodes for the UI.
|
|
116
|
+
8. **Validate + hand off**.
|
|
117
|
+
|
|
118
|
+
Total wall-clock: maybe 30 min for the asset packs (parallel), another 15 for scene composition. NOT a five-minute thing.
|
|
119
|
+
|
|
120
|
+
## What this skill explicitly defers
|
|
121
|
+
|
|
122
|
+
- **3D scene assembly.** Out of scope; use `summer:3d-assets/` directly until a 3D variant of this orchestrator exists.
|
|
123
|
+
- **Auto-tiling terrain.** The pipeline node exists in the decision tree but the leaf skill that implements it is not built — see `publicsummerengine/Docs/assetCreation/TERRAIN_AUTOTILE_IDEA.md`.
|
|
124
|
+
- **Animation orchestration.** Per-character `summer:2d-assets/sprite-sheet` is invoked manually; no auto-pairing of characters with their animation pipelines yet.
|
|
125
|
+
- **Gameplay code.** Player movement, interactions, win conditions — those are level-design + gameplay-mechanics skills, not this one.
|
|
@@ -321,12 +321,12 @@ This skill writes new autoload files (one per Manager). Always ask before each:
|
|
|
321
321
|
|
|
322
322
|
Don't bulk-create five Managers in one shot. Walk one Manager end-to-end (data → mutators → requests → broadcasts → lifecycle) so the user can verify the shape, then repeat for the next domain.
|
|
323
323
|
|
|
324
|
-
After each Manager file lands, call `summer_get_script_errors` to confirm clean compile. See [`
|
|
324
|
+
After each Manager file lands, call `summer_get_script_errors` to confirm clean compile. See [`references/collaborative-protocol.md`](../../references/collaborative-protocol.md).
|
|
325
325
|
|
|
326
326
|
## See also
|
|
327
327
|
|
|
328
328
|
- [`peer-to-peer-multiplayer`](../peer-to-peer-multiplayer/SKILL.md) — the four-layer architecture overview. Read this first if you haven't.
|
|
329
329
|
- [`setup-multiplayer`](../setup-multiplayer/SKILL.md) — lighter intro that just gets a session running. Use that one if the user just wants two players to see each other.
|
|
330
|
-
- [`
|
|
331
|
-
- [`
|
|
332
|
-
- [`
|
|
330
|
+
- [`references/godot-version.md`](../../references/godot-version.md) — Godot 4.5 multiplayer API stability notes.
|
|
331
|
+
- [`references/gd-style.md`](../../references/gd-style.md) — typed-GDScript conventions used in the examples above.
|
|
332
|
+
- [`references/mcp-tools-reference.md`](../../references/mcp-tools-reference.md) — `summer_get_script_errors` for compile verification.
|
|
@@ -361,7 +361,7 @@ This skill writes multiple new files (`autoloads/network_manager.gd`, `autoloads
|
|
|
361
361
|
|
|
362
362
|
Don't apply all four layers in one shot — checkpoint after each layer so the user can verify before adding the next.
|
|
363
363
|
|
|
364
|
-
See [`
|
|
364
|
+
See [`references/collaborative-protocol.md`](../../references/collaborative-protocol.md).
|
|
365
365
|
|
|
366
366
|
## Want a working starter?
|
|
367
367
|
|
|
@@ -371,8 +371,8 @@ When the `template-co-op-3d` template ships in the registry, this skill will ref
|
|
|
371
371
|
|
|
372
372
|
## See also
|
|
373
373
|
|
|
374
|
-
- [`
|
|
375
|
-
- [`
|
|
376
|
-
- [`
|
|
374
|
+
- [`references/godot-version.md`](../../references/godot-version.md) — Godot 4.5 multiplayer API stability notes
|
|
375
|
+
- [`references/mcp-tools-reference.md`](../../references/mcp-tools-reference.md) — `summer_project_setting` for autoload registration
|
|
376
|
+
- [`references/gd-style.md`](../../references/gd-style.md) — typed-GDScript conventions
|
|
377
377
|
- [`host-authoritative-state`](../host-authoritative-state/SKILL.md) — deeper dive on JUST the state ownership decision matrix
|
|
378
378
|
- [`setup-multiplayer`](../setup-multiplayer/SKILL.md) — lighter intro that just gets a session running (use that one if the user just wants 2 players to see each other; use this one if they want to ship a real game)
|
|
@@ -286,7 +286,7 @@ Test checklist:
|
|
|
286
286
|
| Replicate every property | Replicate position, rotation, health, that's it | Bandwidth + bug surface |
|
|
287
287
|
| Run physics on every peer for every player | Physics on owner only, others receive transform | Otherwise jitter and divergence |
|
|
288
288
|
| Trust the client | Validate `get_remote_sender_id()` in every `any_peer` RPC | Cheaters route through the wrong RPC |
|
|
289
|
-
| Inline `SceneReplicationConfig` sub_resource | Save as standalone `.tres` | Silent-fail trap (see `
|
|
289
|
+
| Inline `SceneReplicationConfig` sub_resource | Save as standalone `.tres` | Silent-fail trap (see `references/mcp-tools-reference.md`) |
|
|
290
290
|
| Roll custom transport | ENet (or WebSocket for browser) | You will hit edge cases ENet already solved |
|
|
291
291
|
| Skip authority check in damage RPC | `if not multiplayer.is_server(): return` at the top of damage handlers | Otherwise damage applied N times |
|
|
292
292
|
| Spawn players on every peer | MultiplayerSpawner — host spawns, clients receive | Otherwise N copies of each player |
|
|
@@ -303,22 +303,22 @@ Test checklist:
|
|
|
303
303
|
|
|
304
304
|
## Collaborative protocol
|
|
305
305
|
|
|
306
|
-
This skill rewires the project at the architectural level. Always ask before each block of changes. Group writes — "I'm about to add the autoload + 2 scenes + 3 scripts + InputMap entries. OK?". See `
|
|
306
|
+
This skill rewires the project at the architectural level. Always ask before each block of changes. Group writes — "I'm about to add the autoload + 2 scenes + 3 scripts + InputMap entries. OK?". See `references/collaborative-protocol.md`.
|
|
307
307
|
|
|
308
308
|
## Want a working starter?
|
|
309
309
|
|
|
310
310
|
For a known-good multiplayer scaffold (host + join UI, ENet transport, MultiplayerSpawner, replicated player), point users at:
|
|
311
311
|
|
|
312
|
-
→ **template-id**: TBD (`template-co-op-online` planned, see `
|
|
312
|
+
→ **template-id**: TBD (`template-co-op-online` planned, see `references/template-registry.md`)
|
|
313
313
|
|
|
314
314
|
For now: this skill produces the scaffold inline. When the template lands, link from here.
|
|
315
315
|
|
|
316
316
|
## See also
|
|
317
317
|
|
|
318
|
-
- `
|
|
319
|
-
- `
|
|
320
|
-
- `
|
|
321
|
-
- `
|
|
318
|
+
- `references/mcp-tools-reference.md` — full MCP tool list (project-setting, autoload registration)
|
|
319
|
+
- `references/godot-version.md` — `MultiplayerAPI` is medium-churn; `SceneReplicationConfig` settled in 4.0+
|
|
320
|
+
- `references/collaborative-protocol.md` — "May I write" pattern
|
|
321
|
+
- `references/gd-style.md` — typed GDScript conventions
|
|
322
322
|
- `multiplayer-and-networking/multiplayerapi-basics/SKILL.md` — deeper MultiplayerAPI patterns
|
|
323
323
|
- `multiplayer-and-networking/client-server-pattern/SKILL.md` — dedicated server architecture
|
|
324
324
|
- `multiplayer-and-networking/peer-replication/SKILL.md` — synchronizer config patterns
|
|
@@ -200,7 +200,7 @@ Compare: was the metric movement at least 50% of what was promised? If yes, ship
|
|
|
200
200
|
|
|
201
201
|
## Collaborative protocol
|
|
202
202
|
|
|
203
|
-
This skill makes scene/resource/code changes. Always ask before each fix is applied. See `
|
|
203
|
+
This skill makes scene/resource/code changes. Always ask before each fix is applied. See `references/collaborative-protocol.md`.
|
|
204
204
|
|
|
205
205
|
## Want a working starter?
|
|
206
206
|
|
|
@@ -208,10 +208,10 @@ No template — this is a workflow. Performance tuning is project-specific by de
|
|
|
208
208
|
|
|
209
209
|
## See also
|
|
210
210
|
|
|
211
|
-
- `
|
|
212
|
-
- `
|
|
213
|
-
- `
|
|
214
|
-
- `
|
|
211
|
+
- `references/mcp-tools-reference.md` — full MCP tool list
|
|
212
|
+
- `references/godot-version.md` — Godot 4.5 renderer notes (Compositor, RenderSceneBuffers churn)
|
|
213
|
+
- `references/collaborative-protocol.md` — "May I write" pattern
|
|
214
|
+
- `references/gd-style.md` — GDScript conventions (avoid bare types, use `:=`)
|
|
215
215
|
- `performance/profiling-godot/SKILL.md` — deeper Godot profiler usage
|
|
216
216
|
- `performance/draw-call-batching/SKILL.md` — MultiMeshInstance3D patterns
|
|
217
217
|
- `performance/lod-and-culling/SKILL.md` — LOD setup
|
|
@@ -121,4 +121,4 @@ Then create `Environment` and `Sky` resources via the inspector or load from `.t
|
|
|
121
121
|
|
|
122
122
|
## Collaborative protocol
|
|
123
123
|
|
|
124
|
-
This skill mutates the scene (adds lights + WorldEnvironment + tunes Environment sub-properties). Always ask before applying: "May I add a DirectionalLight3D Sun with shadows + a WorldEnvironment with a procedural sky?". See `../../
|
|
124
|
+
This skill mutates the scene (adds lights + WorldEnvironment + tunes Environment sub-properties). Always ask before applying: "May I add a DirectionalLight3D Sun with shadows + a WorldEnvironment with a procedural sky?". See `../../references/collaborative-protocol.md`.
|
|
@@ -261,11 +261,11 @@ End with:
|
|
|
261
261
|
| Procedural skybox without angle | Mid-day sun + uniform fog reads generic. Always angle the sun. |
|
|
262
262
|
| Skipping the lighting plan | Lighting *is* art direction in 3D. Without a plan, every level looks different. |
|
|
263
263
|
| Adopting "AAA realism" at vertical-slice scope | Asset cost is brutal solo. Stylized always wins. |
|
|
264
|
-
| Calling SetResourceProperty on inline sub_resources | Silent fail. See `
|
|
264
|
+
| Calling SetResourceProperty on inline sub_resources | Silent fail. See `references/mcp-tools-reference.md` § Trap. |
|
|
265
265
|
|
|
266
266
|
## Collaborative protocol
|
|
267
267
|
|
|
268
|
-
This skill writes one design doc (`.summer/art-bible.md`) and may modify `project.godot` settings + the main scene's `WorldEnvironment`. Always ask. See `
|
|
268
|
+
This skill writes one design doc (`.summer/art-bible.md`) and may modify `project.godot` settings + the main scene's `WorldEnvironment`. Always ask. See `references/collaborative-protocol.md`.
|
|
269
269
|
|
|
270
270
|
## Want a working starter?
|
|
271
271
|
|
|
@@ -273,9 +273,9 @@ No template — this is a workflow that produces the bible the rest of the proje
|
|
|
273
273
|
|
|
274
274
|
## See also
|
|
275
275
|
|
|
276
|
-
- `
|
|
277
|
-
- `
|
|
278
|
-
- `
|
|
276
|
+
- `references/collaborative-protocol.md`
|
|
277
|
+
- `references/godot-version.md` — Godot 4.5 rendering API notes (Compositor moved in 4.4 / 4.5)
|
|
278
|
+
- `references/mcp-tools-reference.md`
|
|
279
279
|
- `scene-and-project/brainstorm-game/SKILL.md` — produces the brief that anchors the bible
|
|
280
280
|
- `audio/audio-direction/SKILL.md` — the sonic counterpart
|
|
281
281
|
- `rendering-and-lighting/3d-lighting/SKILL.md` — implements the lighting plan
|
|
@@ -193,16 +193,16 @@ Don't auto-pick. Let them decide.
|
|
|
193
193
|
|
|
194
194
|
## Collaborative protocol
|
|
195
195
|
|
|
196
|
-
This skill writes one file (`.summer/GameSoul.md`). Always ask before writing. Always show the brief inline before saving so the user can react. See `
|
|
196
|
+
This skill writes one file (`.summer/GameSoul.md`). Always ask before writing. Always show the brief inline before saving so the user can react. See `references/collaborative-protocol.md`.
|
|
197
197
|
|
|
198
198
|
## Want a working starter?
|
|
199
199
|
|
|
200
|
-
No template — this is a workflow that produces the brief that drives template selection later. Once `.summer/GameSoul.md` exists, `/summer:make-game` can match it against `
|
|
200
|
+
No template — this is a workflow that produces the brief that drives template selection later. Once `.summer/GameSoul.md` exists, `/summer:make-game` can match it against `references/template-registry.md`.
|
|
201
201
|
|
|
202
202
|
## See also
|
|
203
203
|
|
|
204
|
-
- `
|
|
205
|
-
- `
|
|
204
|
+
- `references/collaborative-protocol.md` — "May I write?" pattern
|
|
205
|
+
- `references/template-registry.md` — templates the brief will be matched against later
|
|
206
206
|
- `gameplay-mechanics/design-mechanic/SKILL.md` — design the core loop in detail
|
|
207
207
|
- `level-design/design-level/SKILL.md` — sketch level 1
|
|
208
208
|
- `rendering-and-lighting/art-direction/SKILL.md` — turn the one-phrase look into a full bible
|
|
@@ -104,5 +104,5 @@ No template — works against any Godot/Summer project that has a main scene set
|
|
|
104
104
|
|
|
105
105
|
## See also
|
|
106
106
|
|
|
107
|
-
- `
|
|
107
|
+
- `references/mcp-tools-reference.md` — full tool list
|
|
108
108
|
- `debugging/debug/SKILL.md` — what to do when /play surfaces an error
|
|
@@ -112,6 +112,35 @@ Use `./` for paths relative to the scene root:
|
|
|
112
112
|
|
|
113
113
|
No fallback for this — Summer MCP required. Handwriting `.tscn` files for hierarchy mutations is error-prone (UID collisions, wrong format version, broken sub_resource refs). If MCP isn't connected, open the scene in the Godot editor and use the SceneTree dock.
|
|
114
114
|
|
|
115
|
+
## Trap — Cross-scene transform leak when copying a scene as a template
|
|
116
|
+
|
|
117
|
+
When you duplicate a scene to spawn a sibling level (for example, `level_1.tscn` → `level_2.tscn`), every child instance carries its transform offset baked at the original level's coordinate system. If the source level places its player at world `(223, 108, -1833)` and instances a kill-volume scene at offset `(512, -3, 512)`, those numbers are anchored to the source level's terrain origin. Drop the same kill-volume instance into a level whose player spawns at world `(0, 1, 0)` and the volume's wall colliders may end up slicing the new arena at world `x = 0`. The user sees a "glitching invisible line through the middle of the map" they can't pass through. The colliders are invisible under the floor, so visual diagnosis is hard. Only collision-walking through them reveals the problem.
|
|
118
|
+
|
|
119
|
+
Rule when copying a scene as a template:
|
|
120
|
+
|
|
121
|
+
1. Audit every child instance for hardcoded `transform = Transform3D(...)` lines.
|
|
122
|
+
2. Decide for each: keep, re-zero (origin = `(0,0,0)`), or drop entirely.
|
|
123
|
+
3. The bigger the original level's world-space coordinates, the more dangerous the copy. Re-zero by default; you can move things back if needed.
|
|
124
|
+
4. Levels that spawn the player at world origin (for example flat arenas centered on `(0,0,0)`) should drop ALL transform overrides from carry-over instances. Only re-add transforms relative to the new origin.
|
|
125
|
+
|
|
126
|
+
## Trap — Third-person camera collision when foliage shouldn't block
|
|
127
|
+
|
|
128
|
+
Godot's `SpringArm3D` shortens the camera boom when it raycasts into geometry on the configured `collision_mask`. If your trees, bushes, or grass have collision so the player physically bumps them, on the same layer the SpringArm queries, the camera shortens for foliage too. Players see the camera awkwardly snap forward whenever they walk near a tree.
|
|
129
|
+
|
|
130
|
+
The pattern that works:
|
|
131
|
+
|
|
132
|
+
1. Foliage gets its own physics layer. Conventionally layer 9 ("Foliage").
|
|
133
|
+
- Foliage `StaticBody3D`: `collision_layer = 256` (which is 2^8, layer 9).
|
|
134
|
+
2. Player still bumps into foliage by including that layer in its `collision_mask`.
|
|
135
|
+
- Player `CharacterBody3D`: `collision_mask = 259` (which is 1 + 2 + 256, Entities + Level + Foliage).
|
|
136
|
+
3. SpringArm uses a mask that catches solid level geometry but excludes foliage.
|
|
137
|
+
- SpringArm: `collision_mask = 3` (which is 1 + 2, Entities + Level only).
|
|
138
|
+
4. For the visual fade the user expects when the camera is "behind" a tree, add the foliage mesh to the `camera_fade` group. An existing camera-occlusion fade system can ghost the mesh by AABB intersection with the camera-to-player segment without touching collision.
|
|
139
|
+
|
|
140
|
+
Why per-layer split: there's no clean way to exclude a single body type from `SpringArm3D`'s collision check via `add_excluded_object` for dynamically-spawned foliage. You'd have to register every tree at spawn time and re-register on level change. Layer-level filtering is set-and-forget.
|
|
141
|
+
|
|
142
|
+
Don't skip the player mask update. If you only move foliage to layer 9 without adding it to the player's mask, the player walks straight through trees.
|
|
143
|
+
|
|
115
144
|
## Collaborative protocol
|
|
116
145
|
|
|
117
|
-
This skill creates and mutates scene files. Always ask before applying: "May I create `res://scenes/player.tscn` and instantiate it under `./World`?". See `../../
|
|
146
|
+
This skill creates and mutates scene files. Always ask before applying: "May I create `res://scenes/player.tscn` and instantiate it under `./World`?". See `../../references/collaborative-protocol.md`.
|
|
@@ -90,6 +90,59 @@ var siblings = get_parent().get_children()
|
|
|
90
90
|
|
|
91
91
|
For health systems, input handling, and state machines, see [reference.md](reference.md).
|
|
92
92
|
|
|
93
|
+
## Anti-patterns — introspection traps
|
|
94
|
+
|
|
95
|
+
Godot's introspection API has Object-instance methods that look like they should work on script-class references. They don't. Calling them on a `const ScriptName = preload(...)` reference is a parse error, not a runtime no-op.
|
|
96
|
+
|
|
97
|
+
| Wrong | Right | Why |
|
|
98
|
+
|---|---|---|
|
|
99
|
+
| `if SomeScript.has_static_method("play"): SomeScript.play(...)` | Just call `SomeScript.play(...)` directly. If the method exists in the script, it parses; if not, the parser catches it. | `has_static_method()` is an `Object` instance method. `SomeScript` here is a `Script` reference. It has no `has_static_method` member, so the parser rejects the call. |
|
|
100
|
+
| `if SomeScript.has_method("foo")` (on a script-class ref) | Same. Call `foo()` directly, or check `is_instance_of()` after instancing. | Same trap. |
|
|
101
|
+
| Defensive guards "in case the script ships in parallel" | Don't ship in parallel agents that depend on each other's APIs without one of them landing first. The compiler will catch missing methods at parse time. | Guards that don't compile aren't guards. |
|
|
102
|
+
|
|
103
|
+
**Rule of thumb:** if you're tempted to write `Klass.has_*("name")` on a `const Klass = preload(...)` reference, you're confusing class-level introspection (compile-time, automatic) with instance-level introspection (`Object` method, runtime). GDScript's parser already does the compile-time check for free.
|
|
104
|
+
|
|
105
|
+
**Side note on `has_method` vs `has_static_method`:** `has_method` works on a node/instance to check if the *instance* has a method. `has_static_method` works on an *Object* instance to check if its *class* has a static method. Neither is callable on a bare `Script` reference (`preload(...)` result). To check static-method presence at runtime, call the method inside a `try`-equivalent. In practice if your code paths are well-typed you don't need to.
|
|
106
|
+
|
|
107
|
+
## Anti-pattern — `@onready var = $Path` on nodes that don't exist on every variant
|
|
108
|
+
|
|
109
|
+
Godot resolves `$Path` (the `get_node` shorthand) at `@implicit_ready` time. If the node is missing from the current scene, you get `Node not found: "X" (relative to "Y")` errors before any of your `_ready()` runtime guards can run.
|
|
110
|
+
|
|
111
|
+
Common case: a script is shared by multiple scene variants where some variants have an optional child. Even if every code path that touches the variable has a `if inventory_ui:` guard, the `@onready` line itself errors at scene load.
|
|
112
|
+
|
|
113
|
+
| Wrong | Right |
|
|
114
|
+
|---|---|
|
|
115
|
+
| `@onready var inventory_ui: CanvasLayer = $InventoryUI` | `@onready var inventory_ui: CanvasLayer = get_node_or_null("InventoryUI")` |
|
|
116
|
+
| `@onready var hp_bar: ProgressBar = $HUD/HPBar` (HUD optional) | `@onready var hp_bar: ProgressBar = get_node_or_null("HUD/HPBar")` |
|
|
117
|
+
|
|
118
|
+
**Rule of thumb:** if the node is required for the script to function at all, use `$Path` and rely on the parse-time error. If the node may be missing in some scene variants the script is reused across, use `get_node_or_null` and guard at every read site.
|
|
119
|
+
|
|
120
|
+
## Anti-pattern — `Label3D.label_settings` (it doesn't exist)
|
|
121
|
+
|
|
122
|
+
`LabelSettings` is a resource type used by `Label` (the 2D Control node) to bundle font + size + outline + colors. `Label3D` does NOT accept it. Assigning `LabelSettings` to `label_settings` on a `Label3D` raises `Invalid assignment of property or key 'label_settings' with value of type 'LabelSettings' on a base object of type 'Label3D'.`
|
|
123
|
+
|
|
124
|
+
`Label3D` exposes the same styling fields as direct properties:
|
|
125
|
+
|
|
126
|
+
```gdscript
|
|
127
|
+
# WRONG - parses but errors at runtime when label is a Label3D.
|
|
128
|
+
var settings := LabelSettings.new()
|
|
129
|
+
settings.font = my_font
|
|
130
|
+
settings.font_size = 24
|
|
131
|
+
settings.outline_size = 2
|
|
132
|
+
settings.outline_color = my_outline
|
|
133
|
+
my_label_3d.label_settings = settings # <-- runtime error
|
|
134
|
+
|
|
135
|
+
# RIGHT - set the styling directly on the Label3D.
|
|
136
|
+
my_label_3d.font = my_font
|
|
137
|
+
my_label_3d.font_size = 24
|
|
138
|
+
my_label_3d.outline_size = 2
|
|
139
|
+
my_label_3d.outline_modulate = my_outline
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Note the field name difference too: `LabelSettings.outline_color` (Label 2D) vs `Label3D.outline_modulate` (Label3D). Easy to miss in copy-paste.
|
|
143
|
+
|
|
144
|
+
**Rule of thumb:** `LabelSettings` is for `Label` only. For `Label3D` use direct properties. For `RichTextLabel`, neither — it has its own theme overrides.
|
|
145
|
+
|
|
93
146
|
## Scene Integration
|
|
94
147
|
|
|
95
148
|
When the AI adds a node with Summer MCP tools and attaches a script, the script path is set via `summer_set_prop(path, "script", "res://path/to/script.gd")`. The script file must exist first. Create or edit `.gd` files with the host agent's normal file-editing tools, then use Summer MCP only to attach the script and connect scene signals.
|