summer-engine 2.0.0 → 2.3.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/{marketplace.json → .claude-plugin/marketplace.json} +3 -3
- package/.claude-plugin/plugin.json +37 -4
- package/.codex-plugin/plugin.json +38 -5
- package/.cursor-plugin/plugin.json +37 -4
- package/.factory-plugin/plugin.json +20 -0
- package/.opencode/INSTALL.md +9 -3
- package/.opencode/plugins/summer.js +0 -2
- package/AGENTS.md +51 -0
- package/CLAUDE.md +5 -0
- package/GEMINI.md +56 -0
- package/README.md +211 -61
- package/_persona/summer/SKILL.md +113 -0
- package/dist/commands/install.js +2 -2
- package/dist/commands/setup.js +4 -0
- package/dist/commands/skills.js +115 -2
- package/dist/lib/agent-config.d.ts +2 -2
- package/dist/lib/agent-config.js +171 -5
- package/dist/lib/skills-registry.d.ts +290 -26
- package/dist/lib/skills-registry.js +503 -1
- package/dist/mcp/tools/generate-tools.js +101 -0
- package/gemini-extension.json +2 -2
- package/package.json +9 -3
- package/skills/2d-assets/character-portrait/SKILL.md +196 -0
- package/skills/2d-assets/concept-art/SKILL.md +152 -0
- package/skills/2d-assets/pixel-art/SKILL.md +180 -0
- package/skills/2d-assets/skybox-panorama/SKILL.md +207 -0
- package/skills/2d-assets/sprite-sheet/SKILL.md +239 -0
- package/skills/2d-assets/tileable-texture/SKILL.md +205 -0
- package/skills/2d-assets/ui-graphics/SKILL.md +210 -0
- package/skills/3d-assets/character-model/SKILL.md +225 -0
- package/skills/3d-assets/environment-kit/SKILL.md +164 -0
- package/skills/3d-assets/organic-model/SKILL.md +192 -0
- package/skills/3d-assets/prop-model/SKILL.md +133 -0
- package/skills/3d-assets/vehicle-model/SKILL.md +202 -0
- package/skills/ai-and-npcs/design-npc/SKILL.md +3 -1
- package/skills/animation/animation-tree/SKILL.md +260 -0
- package/skills/animation/facial-and-lipsync/SKILL.md +282 -0
- package/skills/animation/generate-motion/SKILL.md +129 -0
- package/skills/animation/procedural-animation/SKILL.md +234 -0
- package/skills/animation/retarget/SKILL.md +172 -0
- package/skills/asset-pipeline/asset-strategy/SKILL.md +102 -212
- package/skills/audio/adaptive-music/SKILL.md +326 -0
- package/skills/audio/ambient-bed/SKILL.md +278 -0
- package/skills/audio/music-track/SKILL.md +268 -0
- package/skills/audio/sound-effect/SKILL.md +237 -0
- package/skills/audio/voice-line/SKILL.md +253 -0
- package/skills/catalog.yaml +249 -3
- package/skills/video/animated-loop/SKILL.md +200 -0
- package/skills/video/cinematic-cutscene/SKILL.md +204 -0
- package/skills/video/trailer-shot/SKILL.md +203 -0
- package/skills/visual-effects/_building-blocks/additive-billboard-particles.md +28 -0
- package/skills/visual-effects/_building-blocks/noise-3d-fbm.gdshaderinc +45 -0
- package/skills/visual-effects/_building-blocks/trauma-shake-snippet.md +51 -0
- package/skills/visual-effects/{vfx → game-feel}/SKILL.md +1 -1
- package/skills/visual-effects/recipes/dissolve/SKILL.md +349 -0
- package/skills/visual-effects/recipes/fire/SKILL.md +387 -0
- package/skills/visual-effects/recipes/hit-spark/SKILL.md +330 -0
- package/skills/visual-effects/recipes/lightning/SKILL.md +372 -0
- package/skills/visual-effects/recipes/magic-glow/SKILL.md +377 -0
- package/skills/visual-effects/recipes/muzzle-flash/SKILL.md +326 -0
- package/skills/visual-effects/recipes/smoke/SKILL.md +381 -0
- package/skills/visual-effects/recipes/water-ripple/SKILL.md +340 -0
|
@@ -0,0 +1,207 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: skybox-panorama
|
|
3
|
+
description: Use when generating a 360° panoramic sky image for use as a Sky resource (PanoramaSkyMaterial) in a 3D scene. Equirectangular projection, 2:1 aspect. Wires into WorldEnvironment.sky. Trigger on "skybox", "sky panorama", "360 background", "environment sky", "HDRI sky", "panoramic background", "panorama sky".
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: 2d-assets
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_generate_image summer_search_assets summer_import_from_url summer_set_resource_property summer_add_node summer_set_prop summer_inspect_node
|
|
9
|
+
paths: ["assets/**", "art/sky/**", "environments/**"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# skybox-panorama — 360° Sky for WorldEnvironment
|
|
13
|
+
|
|
14
|
+
This skill generates a single equirectangular panoramic image (2:1 aspect, e.g. 2048×1024 or 4096×2048) suitable for Godot's `PanoramaSkyMaterial`. Wires it into a `Sky` resource on a `WorldEnvironment` node so the sky is visible from every camera angle in your 3D scene.
|
|
15
|
+
|
|
16
|
+
The single biggest failure mode is **non-equirectangular output**. Diffusion models default to flat 2D scenes; if you don't explicitly demand "equirectangular projection," the result looks fine in a thumbnail but distorts brutally when wrapped onto a sphere — horizon bows, zenith pinches, the sun stretches into a smear. This skill encodes the prompt suffix and the import discipline that produces a usable sky on the first or second try.
|
|
17
|
+
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
- "Generate a fantasy sky for the level."
|
|
21
|
+
- "I need a sci-fi nebula skybox."
|
|
22
|
+
- "Make a sunset panorama for the desert scene."
|
|
23
|
+
- "Stormy night sky for the haunted level."
|
|
24
|
+
- The 3D scene needs a visible sky (not just a flat color background).
|
|
25
|
+
|
|
26
|
+
## When NOT to use
|
|
27
|
+
|
|
28
|
+
- The user wants a 2D parallax background → that's a separate `Sprite2D` job, not a panorama.
|
|
29
|
+
- The user wants a HDRI for environment lighting (not just visual sky) → AI panoramas are LDR by default. For real IBL/HDR, use Polyhaven HDRIs (free CC0). Mention this to the user if lighting realism matters.
|
|
30
|
+
- The user wants a 3D-modeled sky-dome with geometry (clouds-as-meshes) → out of scope; use a `Sphere` mesh + custom shader.
|
|
31
|
+
- The scene is 2D → no sky needed.
|
|
32
|
+
|
|
33
|
+
## Steps
|
|
34
|
+
|
|
35
|
+
### 1. Search for an existing sky
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
summer_search_assets(query="<vibe> sky panorama", filter={ kind: "image" })
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Polyhaven (`polyhaven.com/hdris`) hosts hundreds of free CC0 HDRIs that beat AI generation for realism and provide IBL data. For realistic exterior scenes, prefer Polyhaven; for stylized / fantasy / sci-fi, AI generation wins.
|
|
42
|
+
|
|
43
|
+
### 2. Build the prompt — sky description + equirectangular suffix
|
|
44
|
+
|
|
45
|
+
Pattern:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
<sky description>, 360 degree panoramic equirectangular projection, seamless horizontal wrap, no visible seam at left and right edges, distortion-correct for sphere mapping, no foreground objects, no ground horizon line, sky and clouds and atmosphere only
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Load-bearing phrases:
|
|
52
|
+
|
|
53
|
+
- **`360 degree panoramic equirectangular projection`** — primes the model for the right format.
|
|
54
|
+
- **`seamless horizontal wrap, no visible seam at left and right edges`** — the left and right edges of the image meet when wrapped. If they don't match, you see a vertical seam in the sky.
|
|
55
|
+
- **`no foreground objects, no ground horizon line`** — skies show only sky. If you include a horizon, it warps weirdly when sphere-mapped and kills the illusion that the sky is at infinite distance.
|
|
56
|
+
- **`distortion-correct for sphere mapping`** — reminds the model that the top/bottom of the image map to the zenith/nadir.
|
|
57
|
+
|
|
58
|
+
### 3. Generate at 2:1 aspect
|
|
59
|
+
|
|
60
|
+
```
|
|
61
|
+
summer_generate_image(
|
|
62
|
+
prompt="dramatic fantasy sky, golden hour, large purple-orange clouds, distant mountains silhouetted at very bottom, soft god-rays, 360 degree panoramic equirectangular projection, seamless horizontal wrap, no visible seam, no foreground objects, sky only",
|
|
63
|
+
model="nano-banana-2",
|
|
64
|
+
style="realistic",
|
|
65
|
+
options={
|
|
66
|
+
aspectRatio: "2:1",
|
|
67
|
+
image_size: "landscape_16_9",
|
|
68
|
+
negative_prompt: "vertical seam, ground objects, horizon-level details, distorted, warped, characters, buildings"
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`aspectRatio: "2:1"` is critical. Equirectangular MUST be 2:1 (width = 2× height). If the model returns 16:9 or 4:3, the wrap will be wrong.
|
|
74
|
+
|
|
75
|
+
### 4. Verify the seam and projection
|
|
76
|
+
|
|
77
|
+
Before wiring, inspect:
|
|
78
|
+
|
|
79
|
+
- **Left edge ↔ right edge:** mentally place them side-by-side. They should match continuously. If there's a cloud cut in half on the left and a different cloud on the right, regenerate with stronger emphasis on `seamless horizontal wrap`.
|
|
80
|
+
- **Top stretching:** the top 10% of the image stretches enormously when mapped to the zenith. If there are tight features (a sun, a cloud edge) high up, they'll smear. Generations with diffuse, soft top regions wrap better than crisp ones.
|
|
81
|
+
- **Bottom:** same applies to the nadir. Most skies don't show much bottom anyway since the camera sits below the horizon — but avoid generating tight features at the very bottom.
|
|
82
|
+
|
|
83
|
+
If the image fails seam check, regenerate. Some models support `seed` for variation while keeping prompt — bump the seed.
|
|
84
|
+
|
|
85
|
+
### 5. Import to project
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
summer_import_from_url(url="<fileUrl>", path="res://art/sky/fantasy_sunset.png")
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
In the import dock:
|
|
92
|
+
|
|
93
|
+
- `Repeat: Disabled` (panoramas don't tile — they wrap once via the material).
|
|
94
|
+
- `Filter: Linear with mipmaps` (smoother as the camera turns).
|
|
95
|
+
- `Mipmaps: Enabled`.
|
|
96
|
+
- `Compress: VRAM Compressed` for ship.
|
|
97
|
+
|
|
98
|
+
### 6. Wire into WorldEnvironment (3 lines)
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
summer_add_node(parentPath="/root/Game", type="WorldEnvironment", name="WorldEnvironment")
|
|
102
|
+
|
|
103
|
+
summer_set_resource_property(
|
|
104
|
+
nodePath="/root/Game/WorldEnvironment",
|
|
105
|
+
resourceProperty="environment:background_mode",
|
|
106
|
+
value=2 # BG_SKY
|
|
107
|
+
)
|
|
108
|
+
|
|
109
|
+
summer_set_resource_property(
|
|
110
|
+
nodePath="/root/Game/WorldEnvironment",
|
|
111
|
+
resourceProperty="environment:sky:sky_material",
|
|
112
|
+
value="<new PanoramaSkyMaterial with panorama: res://art/sky/fantasy_sunset.png>"
|
|
113
|
+
)
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Then, if the user wants the sky to also light the scene (image-based lighting):
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
summer_set_resource_property(
|
|
120
|
+
nodePath="/root/Game/WorldEnvironment",
|
|
121
|
+
resourceProperty="environment:ambient_light_source",
|
|
122
|
+
value=3 # AMBIENT_SOURCE_SKY
|
|
123
|
+
)
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Note: AI-generated panoramas are LDR (8-bit per channel). For physically-correct IBL with bright suns, the lighting is muted compared to true HDRI. Mention this to the user if they expect strong IBL.
|
|
127
|
+
|
|
128
|
+
### 7. Verify in scene
|
|
129
|
+
|
|
130
|
+
```
|
|
131
|
+
summer_inspect_node(path="/root/Game/WorldEnvironment")
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Then `summer_play` and look around. Sun in the right place? Seam invisible? Top/bottom okay?
|
|
135
|
+
|
|
136
|
+
## Prompt patterns
|
|
137
|
+
|
|
138
|
+
| Goal | Prompt that works | Why |
|
|
139
|
+
|---|---|---|
|
|
140
|
+
| Fantasy sunset | `dramatic fantasy sky at golden hour, large purple and orange clouds, soft god-rays, distant mountain silhouettes at very bottom only, 360 degree panoramic equirectangular projection, seamless horizontal wrap, no visible seam, no foreground, sky only` | Soft top, distant horizon = clean wrap |
|
|
141
|
+
| Sci-fi space nebula | `vast space nebula, deep blue and magenta gas clouds, scattered bright stars, distant galaxy disc, 360 degree panoramic equirectangular projection, seamless horizontal wrap, no visible seam, no foreground objects, no ground` | Space skies wrap easily; no horizon issues |
|
|
142
|
+
| Stormy night | `dark stormy night sky, heavy rolling clouds, distant lightning flashes, full moon partly obscured, 360 degree panoramic equirectangular, seamless wrap, no foreground` | Diffuse cloud structure tolerates wrapping well |
|
|
143
|
+
| Clear blue day | `bright clear blue sky with scattered cumulus clouds, midday sun upper left, 360 degree panoramic equirectangular projection, seamless horizontal wrap, no visible seam, no ground` | Tight sun feature warps; place sun off-center |
|
|
144
|
+
| Alien planet sky | `alien planet sky, two suns one large red one small white, swirling green-purple atmosphere, distant ringed planet at horizon, 360 panoramic equirectangular, seamless wrap, no foreground` | Multi-sun setups wrap if features stay diffuse |
|
|
145
|
+
| Underwater (caustic dome) | `underwater scene seen from below, sun rays piercing water surface, deep blue gradient downward to black, 360 panoramic equirectangular, seamless wrap` | Treat ocean surface as the "sky"; works for underwater levels |
|
|
146
|
+
| Stylized painterly sky | `Studio Ghibli painterly sky, soft cumulus clouds at sunset, warm pastel palette, 360 panoramic equirectangular, seamless wrap, no foreground` (style: "none") | Style preset would fight painterly |
|
|
147
|
+
|
|
148
|
+
### Bad prompts (and why)
|
|
149
|
+
|
|
150
|
+
| Bad | Failure mode |
|
|
151
|
+
|---|---|
|
|
152
|
+
| `beautiful sky` | No equirectangular suffix. Returns flat 16:9 photograph. Wrap looks broken. |
|
|
153
|
+
| `sky with mountains and trees and a castle` | Foreground objects. Horizon-level details warp catastrophically when sphere-mapped. |
|
|
154
|
+
| `360 sky` (without 2:1 aspect) | Aspect mismatch. Wrap is misaligned. |
|
|
155
|
+
| `panoramic sky in 4k` | "4k" implies 3840×2160 (16:9), not 2:1. Specify aspect. |
|
|
156
|
+
| `sky with the sun in the center top` | Sun at zenith stretches into a smear. Place sun off-axis. |
|
|
157
|
+
|
|
158
|
+
## Anti-patterns
|
|
159
|
+
|
|
160
|
+
- **Including foreground or horizon.** Mountains, trees, buildings at horizon level warp weirdly when sphere-mapped (the "swimming horizon" effect). Skies show ONLY sky. If the level needs distant mountains, model them as low-poly meshes in the scene, not in the sky texture.
|
|
161
|
+
- **Not specifying 2:1 aspect.** A 16:9 panorama wrapped equirectangular has obvious horizontal compression. Always `aspectRatio: "2:1"`.
|
|
162
|
+
- **Tight features at zenith/nadir.** Anything in the top or bottom 10% of the image gets pinched. Bias toward soft, diffuse features there.
|
|
163
|
+
- **Expecting HDR / IBL quality.** AI panoramas are 8-bit. If the user needs realistic environment lighting from the sky, point them at Polyhaven HDRIs (CC0). AI is for visual sky, not for lighting.
|
|
164
|
+
- **Forgetting `Repeat: Disabled` on import.** Panoramas wrap once via the material; if `Repeat` is on, you can get duplicate-tile artifacts at the seam.
|
|
165
|
+
- **Visible vertical seam on the wrap.** If left/right edges don't match, regenerate with seed bump or fix the seam in Photoshop/GIMP via the offset trick (offset by 50% horizontally → heal the new visible seam → offset back).
|
|
166
|
+
|
|
167
|
+
## Edge cases
|
|
168
|
+
|
|
169
|
+
- **Animated sky (clouds drift).** AI gives one frame. Animate via shader (UV scroll on the panorama texture) or layer two panoramas with `ProceduralSkyMaterial` for the base + a transparent cloud layer.
|
|
170
|
+
- **Day/night cycle.** Generate two panoramas (day + night). Cross-fade the `sky_material` via shader blend or by swapping `panorama` over a tween. Two LDR panoramas + a blend = serviceable cycle.
|
|
171
|
+
- **First-person VR.** AI panoramas at 2048×1024 are too low-res for VR (visible pixels). Generate at 4096×2048 if the model supports it; otherwise use Polyhaven HDRIs at 8K.
|
|
172
|
+
- **Indoor scene.** Skyboxes are wasted indoors — use `BG_COLOR` or a flat black background. Don't generate a sky for a windowless dungeon.
|
|
173
|
+
- **Visible vertical seam after generation.** Fix in Photoshop/GIMP: `Filter → Other → Offset` by 50% horizontally → the seam moves to the center → heal with content-aware fill or clone stamp → offset back to 0. Or regenerate with seed bump and `seamless horizontal wrap, no visible seam at left and right edges` repeated twice in the prompt.
|
|
174
|
+
|
|
175
|
+
## Fallback (no MCP)
|
|
176
|
+
|
|
177
|
+
Print the call:
|
|
178
|
+
|
|
179
|
+
```
|
|
180
|
+
summer_generate_image(
|
|
181
|
+
prompt="<sky> 360 degree panoramic equirectangular projection, seamless horizontal wrap, no visible seam, no foreground objects, sky only",
|
|
182
|
+
model="nano-banana-2",
|
|
183
|
+
style="realistic",
|
|
184
|
+
options={ aspectRatio: "2:1", negative_prompt: "vertical seam, foreground, distorted, warped, characters, buildings" }
|
|
185
|
+
)
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
User runs via Summer dashboard, then `summer_import_from_url` to `res://art/sky/<name>.png`, sets `Repeat: Disabled`, and wires the WorldEnvironment manually.
|
|
189
|
+
|
|
190
|
+
If MCP is offline entirely: Polyhaven (`polyhaven.com/hdris`) has hundreds of free CC0 HDRIs ready to drop into `PanoramaSkyMaterial`. Often a better choice than AI for realistic exteriors anyway.
|
|
191
|
+
|
|
192
|
+
## Handoff
|
|
193
|
+
|
|
194
|
+
After the sky is wired:
|
|
195
|
+
|
|
196
|
+
- **Add atmospheric fog matching the sky's mood** → `summer:scene-composition` (fog is on the same Environment resource).
|
|
197
|
+
- **Add a directional `DirectionalLight3D` matching the sun position in the panorama** → `summer:3d-lighting` for sun + shadows.
|
|
198
|
+
- **Day/night cycle** → re-invoke this skill for the night sky, then write a small tween between the two `panorama` properties.
|
|
199
|
+
- **Tileable ground texture for the level floor** → `summer:2d-assets/tileable-texture`.
|
|
200
|
+
|
|
201
|
+
## See also
|
|
202
|
+
|
|
203
|
+
- `summer:3d-lighting` — sun, ambient, fog wired alongside the sky.
|
|
204
|
+
- `summer:2d-assets/tileable-texture` — ground/floor counterpart.
|
|
205
|
+
- `summer:scene-composition` — WorldEnvironment placement and configuration.
|
|
206
|
+
- `summer:asset-pipeline/asset-strategy` — meta-router.
|
|
207
|
+
- `_shared/mcp-tools-reference.md` — `summer_generate_image` schema.
|
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: sprite-sheet
|
|
3
|
+
description: Use when generating animated 2D character sprites laid out as a sprite sheet (grid of frames) — walk cycle, attack frames, idle bob, death sequence. Wires into AnimatedSprite2D / SpriteFrames. Trigger on "sprite sheet", "walk cycle", "attack frames", "animated sprite", "frame-by-frame animation", "2D character animation".
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: 2d-assets
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_generate_image summer_search_assets summer_import_from_url summer_set_resource_property summer_add_node summer_set_prop
|
|
9
|
+
paths: ["assets/**", "sprites/**", "art/sprites/**"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# sprite-sheet — Frame-by-Frame 2D Animation
|
|
13
|
+
|
|
14
|
+
This skill produces a grid of animation frames for a 2D character — walk cycle, idle bob, attack swing, death sequence — and wires the result into an `AnimatedSprite2D` via a `SpriteFrames` resource.
|
|
15
|
+
|
|
16
|
+
**Up-front honesty:** sprite-sheet generation from a single text-to-image call is **unreliable**. Models can render "a sprite sheet of a knight walking" and produce 8 frames, but the inter-frame consistency (same anatomy, same costume, same lighting) is poor. Limbs morph between frames. Pixel sprites get extra fingers in frame 3. The result usually looks worse than the static sprite did.
|
|
17
|
+
|
|
18
|
+
This skill therefore offers **three paths**, ranked by reliability:
|
|
19
|
+
|
|
20
|
+
1. **Per-frame img2img** (most reliable) — generate the base pose, then generate each subsequent frame via `referenceImageUrl` with a small pose delta. Composite the frames into a sheet externally or wire each as a separate `SpriteFrames` entry.
|
|
21
|
+
2. **Single-call sheet generation** (fast, unreliable) — one prompt asks for the grid. Works ~30% of the time. Worth trying once for short cycles (4 frames or fewer) before falling back to (1).
|
|
22
|
+
3. **Manual authoring** (most reliable, slowest) — hand-author in **Aseprite** or **Piskel**. For pixel art at 32×32, this is often faster than fixing AI generations.
|
|
23
|
+
|
|
24
|
+
There is no dedicated sprite-sheet generation tool. Recommended path: per-frame `summer_generate_image` with `referenceImageUrl` (img2img) at consistent angle/lighting, OR external tools (Aseprite/Piskel).
|
|
25
|
+
|
|
26
|
+
## When to use
|
|
27
|
+
|
|
28
|
+
- "Generate a walk cycle for the goblin sprite."
|
|
29
|
+
- "I need 4 attack frames for the player character."
|
|
30
|
+
- "Make a death animation — 6 frames of the enemy collapsing."
|
|
31
|
+
- "Create an idle bob, 2-frame loop."
|
|
32
|
+
- The character exists as a static sprite and needs animation.
|
|
33
|
+
|
|
34
|
+
## When NOT to use
|
|
35
|
+
|
|
36
|
+
- The character is 3D — use `summer:animation/generate-motion` for skeletal animation.
|
|
37
|
+
- The user wants a single static sprite → `summer:2d-assets/pixel-art` or `summer:2d-assets/character-portrait`.
|
|
38
|
+
- The user wants UI animation (loading spinner, button hover) — animate via `AnimationPlayer` rotating/tweening a static texture instead. Don't sprite-sheet UI.
|
|
39
|
+
- The user has 12+ frames per animation and 4+ animations — that's hundreds of generations at $0.02 each. Pause and discuss budget.
|
|
40
|
+
|
|
41
|
+
## Steps
|
|
42
|
+
|
|
43
|
+
### 1. Anchor the base sprite
|
|
44
|
+
|
|
45
|
+
You need a stable reference. Either:
|
|
46
|
+
|
|
47
|
+
- The user has a static sprite already (`res://sprites/goblin.png`) — use it as `referenceImageUrl`.
|
|
48
|
+
- Generate a base sprite via `summer:2d-assets/pixel-art` or `summer:2d-assets/character-portrait` first, then return here.
|
|
49
|
+
|
|
50
|
+
Without a base, every frame drifts.
|
|
51
|
+
|
|
52
|
+
### 2. Pick the path
|
|
53
|
+
|
|
54
|
+
Ask the user (or decide based on context):
|
|
55
|
+
|
|
56
|
+
| Signal | Path |
|
|
57
|
+
|---|---|
|
|
58
|
+
| Short cycle (≤4 frames), willing to accept some drift | Try **single-call sheet** first; fall back if bad |
|
|
59
|
+
| Pixel art at small resolution | **Aseprite manual** is often fastest |
|
|
60
|
+
| Higher-res character (128px+), 6-12 frames | **Per-frame img2img** |
|
|
61
|
+
| User wants exact-pixel consistency | **Aseprite manual** — AI cannot deliver exact pixels |
|
|
62
|
+
|
|
63
|
+
State the path before starting: "I'll do per-frame img2img — 6 generations, ~$0.12. The first frame is the base; each next frame uses the previous as reference. OK?"
|
|
64
|
+
|
|
65
|
+
### 3a. Path 1 — Per-frame img2img
|
|
66
|
+
|
|
67
|
+
Generate frame 1 (or use existing base). For each subsequent frame, prompt the pose delta and pass the previous frame as `referenceImageUrl`:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
summer_generate_image(
|
|
71
|
+
prompt="goblin warrior, walk cycle frame 2 of 6, right leg forward, slight bob upward, identical character, same costume, same palette, transparent background",
|
|
72
|
+
referenceImageUrl="<frame 1 fileUrl>",
|
|
73
|
+
model="nano-banana-2",
|
|
74
|
+
style="<same as base>",
|
|
75
|
+
options={ image_size: "square_hd", negative_prompt: "different character, different costume, scene background" }
|
|
76
|
+
)
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Repeat for each frame. Save each as `goblin_walk_01.png`, `goblin_walk_02.png`, etc.
|
|
80
|
+
|
|
81
|
+
After all frames return, either:
|
|
82
|
+
|
|
83
|
+
- Wire each as a separate frame in a `SpriteFrames` resource (Godot will treat them as a sequence — no need to composite into a single sheet image).
|
|
84
|
+
- Composite into a single sheet image via Aseprite (`File → Import Sprite Sheet`) or ImageMagick (`montage frame_*.png -tile 6x1 -geometry +0+0 sheet.png`).
|
|
85
|
+
|
|
86
|
+
### 3b. Path 2 — Single-call sheet (try once)
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
summer_generate_image(
|
|
90
|
+
prompt="goblin warrior walk cycle, sprite sheet, 6 frames in a horizontal row, identical character across frames, side view, transparent background, frames clearly separated, consistent lighting, consistent palette",
|
|
91
|
+
model="nano-banana-2",
|
|
92
|
+
style="pixel",
|
|
93
|
+
options={ image_size: "landscape_16_9", negative_prompt: "different character per frame, scene background, varying lighting" }
|
|
94
|
+
)
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
Inspect the result. If frames are coherent and the count matches, proceed. If anatomy morphs or count is wrong, fall back to Path 1 or Path 3.
|
|
98
|
+
|
|
99
|
+
### 3c. Path 3 — Aseprite manual fallback
|
|
100
|
+
|
|
101
|
+
Tell the user:
|
|
102
|
+
|
|
103
|
+
> AI sprite-sheet generation is unreliable — best path for clean pixel animation is to hand-author in Aseprite (or Piskel for free in-browser). Onion-skin frame-by-frame; ~10 minutes for a 4-frame walk cycle. Want me to generate a base reference image you can trace?
|
|
104
|
+
|
|
105
|
+
If yes, generate the static base via `summer:2d-assets/pixel-art` and stop here. The user takes it to Aseprite.
|
|
106
|
+
|
|
107
|
+
### 4. Import frames into Godot
|
|
108
|
+
|
|
109
|
+
For per-frame import (Path 1):
|
|
110
|
+
|
|
111
|
+
```
|
|
112
|
+
summer_import_from_url(url="<frame 1>", path="res://sprites/goblin/walk_01.png")
|
|
113
|
+
summer_import_from_url(url="<frame 2>", path="res://sprites/goblin/walk_02.png")
|
|
114
|
+
...
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
For a composited sheet (Path 2 or external composite):
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
summer_import_from_url(url="<sheet>", path="res://sprites/goblin/walk_sheet.png")
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Set `Filter: Nearest` on import for pixel art, `Linear` for high-res.
|
|
124
|
+
|
|
125
|
+
### 5. Wire as AnimatedSprite2D
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
summer_add_node(parentPath="/root/Game/Goblin", type="AnimatedSprite2D", name="Sprite")
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Create a `SpriteFrames` resource and add an animation named `walk`. For per-frame textures:
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
summer_set_resource_property(
|
|
135
|
+
nodePath="/root/Game/Goblin/Sprite",
|
|
136
|
+
resourceProperty="sprite_frames:animations/walk/frames",
|
|
137
|
+
value=["res://sprites/goblin/walk_01.png", "res://sprites/goblin/walk_02.png", ...]
|
|
138
|
+
)
|
|
139
|
+
summer_set_resource_property(
|
|
140
|
+
nodePath="/root/Game/Goblin/Sprite",
|
|
141
|
+
resourceProperty="sprite_frames:animations/walk/speed",
|
|
142
|
+
value=8.0
|
|
143
|
+
)
|
|
144
|
+
summer_set_resource_property(
|
|
145
|
+
nodePath="/root/Game/Goblin/Sprite",
|
|
146
|
+
resourceProperty="sprite_frames:animations/walk/loop",
|
|
147
|
+
value=true
|
|
148
|
+
)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
For sheet-based (Path 2): use `AtlasTexture` with one region per frame, then add each AtlasTexture as a frame.
|
|
152
|
+
|
|
153
|
+
### 6. Trigger from code
|
|
154
|
+
|
|
155
|
+
```gdscript
|
|
156
|
+
@onready var sprite: AnimatedSprite2D = $Sprite
|
|
157
|
+
|
|
158
|
+
func _physics_process(delta):
|
|
159
|
+
if velocity.length() > 0.1:
|
|
160
|
+
sprite.play("walk")
|
|
161
|
+
else:
|
|
162
|
+
sprite.play("idle")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
## Prompt patterns
|
|
166
|
+
|
|
167
|
+
### Per-frame img2img (Path 1)
|
|
168
|
+
|
|
169
|
+
| Goal | Frame 1 (base) | Frame N prompt skeleton (with `referenceImageUrl: <frame N-1>`) |
|
|
170
|
+
|---|---|---|
|
|
171
|
+
| Walk cycle (6 frames, side view) | `<character>, side view, idle stance, transparent bg` | `<character>, walk cycle frame N of 6, <leg position description>, identical character, same costume, transparent bg` |
|
|
172
|
+
| Attack swing (4 frames) | `<character>, side view, weapon raised over head` | `<character>, attack frame N, <weapon position: descending / impact / recovery>, identical character, transparent bg` |
|
|
173
|
+
| Idle bob (2 frames, loop) | `<character>, neutral stance, slightly compressed` | `<character>, idle bob upper position, slightly extended upward, identical character, transparent bg` |
|
|
174
|
+
| Death (6 frames) | `<character>, hit react, leaning back` | `<character>, death frame N, <position: stumbling / kneeling / falling / collapsed>, identical character, transparent bg` |
|
|
175
|
+
| Jump (3 frames) | `<character>, crouched ready to jump` | `<character>, jump frame N, <apex extended / falling tucked / land impact>, identical character, transparent bg` |
|
|
176
|
+
|
|
177
|
+
### Single-call sheet (Path 2)
|
|
178
|
+
|
|
179
|
+
| Goal | Prompt that sometimes works |
|
|
180
|
+
|---|---|
|
|
181
|
+
| 4-frame walk cycle | `<character> walk cycle, sprite sheet, 4 frames in horizontal row, side view, identical character, transparent background, clear frame separation, consistent lighting` |
|
|
182
|
+
| 2-frame idle | `<character> idle bob, sprite sheet, 2 frames horizontal, identical character, slight up-down delta, transparent background` |
|
|
183
|
+
|
|
184
|
+
### Bad prompts (and why)
|
|
185
|
+
|
|
186
|
+
| Bad | Failure mode |
|
|
187
|
+
|---|---|
|
|
188
|
+
| `goblin walking` | Returns one image of a walking goblin. Not a sheet, not multiple frames. |
|
|
189
|
+
| `12-frame walk cycle in one image` | Frame count too high for single-call. Anatomy morphs across the row. |
|
|
190
|
+
| `walk cycle for any character` | No character anchor. Frames have different characters. |
|
|
191
|
+
| Per-frame without `referenceImageUrl` | Each frame is a different goblin. |
|
|
192
|
+
| `sprite sheet, photorealistic` | Photoreal characters in tight frames lose identity coherence fast. Stay stylized. |
|
|
193
|
+
|
|
194
|
+
## Anti-patterns
|
|
195
|
+
|
|
196
|
+
- **Skipping the base anchor.** Without a stable reference (existing sprite or generated base), every frame drifts. Anchor first.
|
|
197
|
+
- **Generating walk cycles at high frame counts (12+) via single call.** Will fail. Use per-frame img2img or split into chunks.
|
|
198
|
+
- **Wiring an inconsistent sheet anyway** because you don't want to regenerate. Ship the inconsistency and the player notices the morphing limbs immediately. Cut the frame count or hand-author instead.
|
|
199
|
+
- **Sprite-sheeting things that don't need to be sprite-sheeted.** UI animation, simple bobs, fades — use `AnimationPlayer` to tween a static texture instead. Sprite sheets are for character animation specifically.
|
|
200
|
+
- **Pretending Aseprite is a failure.** Hand-authoring 4 pixel-art frames takes 10 minutes and looks better than 8 AI generations. Don't oversell AI here.
|
|
201
|
+
|
|
202
|
+
## Edge cases
|
|
203
|
+
|
|
204
|
+
- **Pixel art at low resolution.** AI per-frame img2img at 16×16 or 32×32 is ~impossible — the model can't preserve exact pixel positions. Aseprite or Piskel manual is the only reliable path. Generate a high-res reference and trace it down.
|
|
205
|
+
- **Character with cloth / cape physics.** Cloth animation is hard for any AI. Use a base sprite and add cloth as a separate `AnimationPlayer`-tweened layer (`Sprite2D` for the cape, sin-wave-tweened rotation).
|
|
206
|
+
- **8-direction sprite (top-down RPG with N/NE/E/SE/S/SW/W/NW).** Generate one direction's full cycle, then for each other direction generate the FIRST FRAME via img2img with a "rotated to face X" prompt and use it as the new base for that direction's per-frame work. Multiplies generation count by 8 — pause for budget confirmation.
|
|
207
|
+
- **User wants a turn-around (rotating in place over 8 frames).** Same as 8-direction; generate single-frame per angle as anchor, accept that AI rotation won't be perfectly consistent.
|
|
208
|
+
- **Animation needs to loop seamlessly.** Make frame N+1 explicitly bridge back to frame 1 in your prompt. Or generate one extra "bridge" frame and drop it.
|
|
209
|
+
|
|
210
|
+
## Fallback (no MCP)
|
|
211
|
+
|
|
212
|
+
Print the per-frame call sequence:
|
|
213
|
+
|
|
214
|
+
```
|
|
215
|
+
Frame 1: summer_generate_image(prompt="<base>", model="nano-banana-2", style="pixel", ...)
|
|
216
|
+
Frame 2: summer_generate_image(prompt="<base + delta>", referenceImageUrl="<frame 1>", ...)
|
|
217
|
+
Frame 3: summer_generate_image(prompt="<base + delta>", referenceImageUrl="<frame 2>", ...)
|
|
218
|
+
...
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
Tell the user to run via the Summer dashboard. Or recommend Aseprite (paid, $20) / Piskel (free in-browser) for hand-authoring — for pixel art under 64×64, it is the faster path even with MCP available.
|
|
222
|
+
|
|
223
|
+
## Handoff
|
|
224
|
+
|
|
225
|
+
After the animation is wired:
|
|
226
|
+
|
|
227
|
+
- **More animations on the same character** (idle, attack, death) → re-invoke this skill with the same base anchor, vary the delta.
|
|
228
|
+
- **Sound effects synced to animation frames** → `summer:audio/sound-effect`, then wire via `Call Method Track` in `AnimationPlayer`.
|
|
229
|
+
- **Multi-direction sprites** → re-invoke per direction (budget warning).
|
|
230
|
+
- **Pixel-art static base if not yet generated** → `summer:2d-assets/pixel-art` first.
|
|
231
|
+
- **3D character animation instead** → `summer:animation/generate-motion`.
|
|
232
|
+
|
|
233
|
+
## See also
|
|
234
|
+
|
|
235
|
+
- `summer:2d-assets/pixel-art` — base sprite generation.
|
|
236
|
+
- `summer:2d-assets/character-portrait` — base portrait for higher-res characters.
|
|
237
|
+
- `summer:animation/generate-motion` — 3D-skeletal counterpart.
|
|
238
|
+
- `summer:audio/sound-effect` — frame-synced SFX.
|
|
239
|
+
- `_shared/mcp-tools-reference.md` — `summer_generate_image` schema.
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: tileable-texture
|
|
3
|
+
description: Use when generating a seamless tileable texture for walls, floors, terrain, ceilings — square tile that repeats cleanly on all four edges. Wires onto PlaneMesh / CSGBox3D / MeshInstance3D as a StandardMaterial3D albedo. Trigger on "tileable texture", "seamless texture", "wall texture", "floor texture", "ground texture", "terrain texture", "tiled material".
|
|
4
|
+
license: MIT
|
|
5
|
+
compatibility: [Cursor, Claude Code, Windsurf, Codex]
|
|
6
|
+
category: 2d-assets
|
|
7
|
+
user-invocable: true
|
|
8
|
+
allowed-tools: Read Grep Glob Write Edit summer_generate_image summer_search_assets summer_import_from_url summer_set_resource_property summer_add_node summer_set_prop summer_inspect_node
|
|
9
|
+
paths: ["assets/**", "art/textures/**", "materials/**"]
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
# tileable-texture — Seamless Square That Repeats Cleanly
|
|
13
|
+
|
|
14
|
+
This skill generates a seamless square texture (typically 1024×1024) that tiles cleanly on all four edges with no visible seams. Output goes onto a `PlaneMesh`, `CSGBox3D`, or `MeshInstance3D` as a `StandardMaterial3D` albedo, often with `uv_scale` cranked up so a single tile covers a small area and the surface repeats it across a wall or floor.
|
|
15
|
+
|
|
16
|
+
The hard part is "seamless." Most diffusion models violate edge continuity by default — generate a brick wall and the bricks stop mid-row at the edge. This skill encodes the prompt suffix and the post-import verification that catches seams before they ship.
|
|
17
|
+
|
|
18
|
+
## When to use
|
|
19
|
+
|
|
20
|
+
- "Generate a brick wall texture for this room."
|
|
21
|
+
- "I need a grass ground texture for the level."
|
|
22
|
+
- "Tileable wood-floor texture, 1024×1024."
|
|
23
|
+
- "Stone tile texture for the dungeon."
|
|
24
|
+
- "Sand / dirt / metal-panel — seamless."
|
|
25
|
+
|
|
26
|
+
## When NOT to use
|
|
27
|
+
|
|
28
|
+
- The user wants a 3D-modeled wall with geometric brick relief → `summer:asset-pipeline/asset-strategy` (image-to-3D).
|
|
29
|
+
- The user wants a unique mural / non-tiling artwork → `summer:2d-assets/concept-art` or `summer:2d-assets/character-portrait`.
|
|
30
|
+
- The user wants a skybox / 360° environment → `summer:2d-assets/skybox-panorama`.
|
|
31
|
+
- The user wants a normal map / PBR material set — generation today is albedo-only. Normals must be derived (`MaterialMaker`, `NormalMap-Online`) or hand-authored.
|
|
32
|
+
|
|
33
|
+
## Steps
|
|
34
|
+
|
|
35
|
+
### 1. Search for an existing texture
|
|
36
|
+
|
|
37
|
+
```
|
|
38
|
+
summer_search_assets(query="<material> tileable", filter={ kind: "image" })
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Texture libraries (AmbientCG, Polyhaven) often have free PBR sets that beat AI generation for realism. If the user wants photorealistic tiling, pause and suggest those.
|
|
42
|
+
|
|
43
|
+
### 2. Build the prompt — material + the seamless suffix
|
|
44
|
+
|
|
45
|
+
Pattern:
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
<material description>, seamless tileable texture, top-down view, uniform lighting, no perspective, no shadows, no edges, square format, no specific objects in frame
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
The load-bearing phrases are:
|
|
52
|
+
|
|
53
|
+
- **`seamless tileable texture`** — primes the model.
|
|
54
|
+
- **`top-down view`** — kills perspective convergence (which is the #1 source of visible seams).
|
|
55
|
+
- **`uniform lighting`** — kills directional shadows that bake into the tile and stripe across the surface when it repeats.
|
|
56
|
+
- **`no perspective, no shadows, no edges`** — explicit negation of common failure modes.
|
|
57
|
+
- **`no specific objects in frame`** — kills "interest" features the model adds (a single bright leaf, a chip in one brick) that scream "this is a repeating tile."
|
|
58
|
+
|
|
59
|
+
### 3. Generate
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
summer_generate_image(
|
|
63
|
+
prompt="weathered red brick wall, seamless tileable texture, top-down view, uniform lighting, no perspective, no shadows, no specific objects, square format, photographic detail",
|
|
64
|
+
model="nano-banana-2",
|
|
65
|
+
style="realistic",
|
|
66
|
+
options={
|
|
67
|
+
image_size: "square_hd",
|
|
68
|
+
negative_prompt: "perspective, vanishing point, directional shadow, vignette, single feature, scene context, sky, sun"
|
|
69
|
+
}
|
|
70
|
+
)
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
`style: "realistic"` is the right default for textures (most are aiming for photographic surface). Switch to `"none"` for stylized/painterly.
|
|
74
|
+
|
|
75
|
+
### 4. Import to project
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
summer_import_from_url(url="<fileUrl>", path="res://art/textures/brick_red.png")
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
In the import dock, set:
|
|
82
|
+
|
|
83
|
+
- `Repeat: Enabled` (REQUIRED for tiling).
|
|
84
|
+
- `Filter: Linear with mipmaps` (smoother at distance).
|
|
85
|
+
- `Mipmaps: Enabled` (textures viewed at angle need mipmaps).
|
|
86
|
+
- `Compress: VRAM Compressed` for ship; `Lossless` while iterating.
|
|
87
|
+
|
|
88
|
+
### 5. Verify the seam
|
|
89
|
+
|
|
90
|
+
Before wiring into a scene, view the texture tiled. Quick check: in the editor's filesystem dock, right-click the texture → preview → set repeat 4×4 mentally. Or apply to a `PlaneMesh` with `uv_scale = (4, 4)` and look from above.
|
|
91
|
+
|
|
92
|
+
If you see a grid of identical "interest features" (a chip, a stain, a bright pixel) repeating, the tile has a hotspot — regenerate with stronger negative on "single feature."
|
|
93
|
+
|
|
94
|
+
If you see hard horizontal/vertical seams, the edges don't match — regenerate with extra emphasis on `seamless` or run the texture through a seamless-tile filter (Photoshop "Offset" + heal, GIMP "Make Seamless", or Aseprite's Tiled Mode).
|
|
95
|
+
|
|
96
|
+
### 6. Wire onto geometry
|
|
97
|
+
|
|
98
|
+
**On a PlaneMesh (floor/ceiling):**
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
summer_add_node(parentPath="/root/Level", type="MeshInstance3D", name="Floor")
|
|
102
|
+
summer_set_resource_property(nodePath="/root/Level/Floor", resourceProperty="mesh", value="<new PlaneMesh resource>")
|
|
103
|
+
summer_set_prop(path="/root/Level/Floor", property="mesh:size", value="Vector2(20, 20)")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Then create a `StandardMaterial3D`, set `albedo_texture` to the imported texture, and crank `uv1_scale` so each tile covers ~1m of world space:
|
|
107
|
+
|
|
108
|
+
```
|
|
109
|
+
summer_set_resource_property(
|
|
110
|
+
nodePath="/root/Level/Floor",
|
|
111
|
+
resourceProperty="material_override",
|
|
112
|
+
subProperty="albedo_texture",
|
|
113
|
+
value="res://art/textures/brick_red.png"
|
|
114
|
+
)
|
|
115
|
+
summer_set_resource_property(
|
|
116
|
+
nodePath="/root/Level/Floor",
|
|
117
|
+
resourceProperty="material_override",
|
|
118
|
+
subProperty="uv1_scale",
|
|
119
|
+
value="Vector3(20, 20, 1)"
|
|
120
|
+
)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
`uv1_scale = (20, 20, 1)` on a 20m plane means the texture tiles 20× across — each tile covers 1m².
|
|
124
|
+
|
|
125
|
+
**On a CSGBox3D (walls):**
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
summer_add_node(parentPath="/root/Level", type="CSGBox3D", name="WallNorth")
|
|
129
|
+
summer_set_prop(path="/root/Level/WallNorth", property="size", value="Vector3(10, 3, 0.3)")
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Then attach the same material with `uv1_scale` tuned to wall dimensions.
|
|
133
|
+
|
|
134
|
+
## Prompt patterns
|
|
135
|
+
|
|
136
|
+
| Goal | Prompt that works | Why |
|
|
137
|
+
|---|---|---|
|
|
138
|
+
| Brick wall | `weathered red brick wall, seamless tileable texture, top-down view, uniform lighting, no perspective, no shadows, no specific objects, square, photographic` | Top-down + uniform lighting kill perspective seams |
|
|
139
|
+
| Grass ground | `dense fresh grass, seamless tileable texture, top-down view, uniform lighting, no shadows, no flowers, no patches, square` | "No flowers, no patches" kills hotspot features |
|
|
140
|
+
| Wood floor | `oak wood floor planks, seamless tileable, top-down view, uniform lighting, no perspective, no nails, no knots emphasized, square` | "No knots emphasized" kills the ONE bright knot per tile |
|
|
141
|
+
| Stone tiles | `cobblestone path, seamless tileable, top-down, uniform lighting, no shadows, no moss patches, square, photographic` | "No moss patches" kills hotspot |
|
|
142
|
+
| Metal panel | `industrial metal floor panel, seamless tileable, top-down, uniform lighting, no rust hotspots, no scratches concentrated, square` | Diffuse rust spreads across the tile instead of clumping |
|
|
143
|
+
| Sand / dirt | `dry desert sand, seamless tileable, top-down view, uniform soft lighting, no footprints, no rocks, no shadows, square` | Negative space is ideal for tiling |
|
|
144
|
+
| Stylized painterly grass | `stylized painterly grass, Studio Ghibli, seamless tileable, top-down, uniform lighting, no specific blades emphasized, square` (style: "none") | Style preset would fight the painterly direction |
|
|
145
|
+
| Sci-fi panel | `sci-fi metal floor panel with subtle glowing seams, seamless tileable, top-down, uniform lighting, square, the glowing seams form a regular grid that aligns with tile edges` | Make the seams part of the design |
|
|
146
|
+
|
|
147
|
+
### Bad prompts (and why)
|
|
148
|
+
|
|
149
|
+
| Bad | Failure mode |
|
|
150
|
+
|---|---|
|
|
151
|
+
| `brick wall` | No "seamless," no "top-down." Returns a 3D-photographed wall with perspective and a corner. Useless for tiling. |
|
|
152
|
+
| `seamless brick wall in a dungeon at night` | Scene context bakes shadows and ambience that won't tile. |
|
|
153
|
+
| `tileable grass with flowers and rocks` | Hotspot features. Each tile has the SAME flower. Visible repeat. |
|
|
154
|
+
| `seamless wood floor (not specifying square / top-down)` | Often returns floor-from-eye-level with perspective. |
|
|
155
|
+
| `pbr wood floor texture` | "PBR" implies a material set (albedo + normal + roughness). The model only outputs albedo. Generate albedo, derive maps separately. |
|
|
156
|
+
|
|
157
|
+
## Anti-patterns
|
|
158
|
+
|
|
159
|
+
- **Skipping `Repeat: Enabled` on import.** Default is `Repeat: Disabled`. The texture stretches across the whole surface instead of tiling. Looks blurry at distance.
|
|
160
|
+
- **Not tuning `uv1_scale`.** Default scale of (1, 1, 1) on a 20m floor means the 1m-real texture is stretched to 20m. Always scale to physical sizing.
|
|
161
|
+
- **Hotspot features** that scream "repeated tile." Regenerate with stronger negative on single-feature words.
|
|
162
|
+
- **Generating PBR sets with one image.** Diffusion outputs albedo only. For normals/roughness, use a derivation tool or hand-author. Don't claim it's PBR-ready when it's not.
|
|
163
|
+
- **Forgetting mipmaps.** Tileable textures viewed at distance need mipmaps; without them, you get shimmering moire.
|
|
164
|
+
- **Using textures with directional shadow** baked in. Even subtle shadow stripes when tiled. Always demand "uniform lighting."
|
|
165
|
+
|
|
166
|
+
## Edge cases
|
|
167
|
+
|
|
168
|
+
- **User wants normal map / roughness / AO too.** Generation today produces albedo only. Use `Materialize` (free) or `MaterialMaker` (open source) to derive a normal from the albedo. Hand-paint roughness if the surface is heterogeneous (wood = low roughness on knots, high on grain). Set the user's expectation: AI gives albedo; PBR is a follow-up step.
|
|
169
|
+
- **Texture must tile in only one direction (e.g., a brick wall that runs horizontally but not vertically).** Generate 1024×1024 seamless, then crop to your actual aspect; the horizontal tile remains seamless. Or: prompt `tileable horizontally only, distinct top and bottom edges` for ceiling-to-floor walls.
|
|
170
|
+
- **Texture must read at very low resolution (mobile, distant LOD).** Generate at `square_hd`, downscale on import via `Compress: VRAM Compressed`. Avoid generating at low resolution — model quality drops.
|
|
171
|
+
- **User wants animated water / lava texture.** Generate a still tileable texture and use a `ShaderMaterial` with UV scrolling to animate. Don't try to generate frames.
|
|
172
|
+
- **Visible seam after generation.** Run through GIMP `Filters → Map → Make Seamless` or open in Aseprite, set Tiled mode, paint over the seam manually. AI-generated tileables often need a 5-minute touch-up.
|
|
173
|
+
|
|
174
|
+
## Fallback (no MCP)
|
|
175
|
+
|
|
176
|
+
Print the call:
|
|
177
|
+
|
|
178
|
+
```
|
|
179
|
+
summer_generate_image(
|
|
180
|
+
prompt="<material> seamless tileable texture, top-down view, uniform lighting, no perspective, no shadows, no specific objects, square",
|
|
181
|
+
model="nano-banana-2",
|
|
182
|
+
style="realistic",
|
|
183
|
+
options={ image_size: "square_hd", negative_prompt: "perspective, directional shadow, single feature, scene context" }
|
|
184
|
+
)
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
Tell the user to run via the Summer dashboard, then `summer_import_from_url` to `res://art/textures/<name>.png`, set `Repeat: Enabled`, and tune `uv1_scale` to physical size.
|
|
188
|
+
|
|
189
|
+
If MCP is offline entirely: AmbientCG and Polyhaven offer free CC0 PBR texture sets that often beat AI for realism. For stylized, hand-author in Aseprite/Krita with tile-mode preview.
|
|
190
|
+
|
|
191
|
+
## Handoff
|
|
192
|
+
|
|
193
|
+
After the texture is wired:
|
|
194
|
+
|
|
195
|
+
- **More textures in the same biome** → re-invoke this skill, hold style/lighting consistent.
|
|
196
|
+
- **Apply to a procedurally-built level** → `summer:scene-composition` for CSG and modular wall kits.
|
|
197
|
+
- **PBR set with normals/roughness** → out of MCP scope today; user runs derivation in MaterialMaker.
|
|
198
|
+
- **Skybox for the level's environment** → `summer:2d-assets/skybox-panorama`.
|
|
199
|
+
|
|
200
|
+
## See also
|
|
201
|
+
|
|
202
|
+
- `summer:asset-pipeline/asset-strategy` — meta-router and 3D pipeline.
|
|
203
|
+
- `summer:2d-assets/skybox-panorama` — sky/environment counterpart.
|
|
204
|
+
- `summer:scene-composition` — applying textures to CSG and MeshInstance3D.
|
|
205
|
+
- `_shared/mcp-tools-reference.md` — `summer_generate_image` schema.
|