devlyn-cli 1.9.0 โ 1.9.1
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/bin/devlyn.js
CHANGED
|
@@ -138,6 +138,7 @@ ${g} v${PKG.version} ${COLORS.dim}ยท ${k}๐ฉ by Nocodecat @ Donu
|
|
|
138
138
|
|
|
139
139
|
const OPTIONAL_ADDONS = [
|
|
140
140
|
// Local optional skills (copied to .claude/skills/)
|
|
141
|
+
{ name: 'asset-creator', desc: 'AI pixel art game asset pipeline โ generate, chroma-key, catalog', type: 'local' },
|
|
141
142
|
{ name: 'cloudflare-nextjs-setup', desc: 'Cloudflare Workers + Next.js deployment with OpenNext', type: 'local' },
|
|
142
143
|
{ name: 'generate-skill', desc: 'Create well-structured Claude Code skills following Anthropic best practices', type: 'local' },
|
|
143
144
|
{ name: 'prompt-engineering', desc: 'Claude 4 prompt optimization using Anthropic best practices', type: 'local' },
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Asset Catalog Schema
|
|
2
|
+
|
|
3
|
+
The manifest.json file catalogs all generated assets with metadata that supports both runtime rendering and future marketplace features.
|
|
4
|
+
|
|
5
|
+
## manifest.json structure
|
|
6
|
+
|
|
7
|
+
```json
|
|
8
|
+
{
|
|
9
|
+
"version": "1.0",
|
|
10
|
+
"style": "gather-town",
|
|
11
|
+
"generatedWith": "gemini-3-pro-image-preview",
|
|
12
|
+
"assets": {
|
|
13
|
+
"furniture/desk-basic": {
|
|
14
|
+
"file": "furniture/desk-basic.png",
|
|
15
|
+
"category": "furniture",
|
|
16
|
+
"width": 765,
|
|
17
|
+
"height": 746,
|
|
18
|
+
"anchorX": 0.5,
|
|
19
|
+
"anchorY": 1.0,
|
|
20
|
+
"tags": ["workspace", "desk", "monitor"],
|
|
21
|
+
"theme": "default",
|
|
22
|
+
"tier": "free",
|
|
23
|
+
"price": 0,
|
|
24
|
+
"animation": null
|
|
25
|
+
},
|
|
26
|
+
"characters/char-research-sitting": {
|
|
27
|
+
"file": "characters/char-research-sitting.png",
|
|
28
|
+
"category": "character",
|
|
29
|
+
"width": 342,
|
|
30
|
+
"height": 500,
|
|
31
|
+
"anchorX": 0.5,
|
|
32
|
+
"anchorY": 1.0,
|
|
33
|
+
"tags": ["research", "sitting", "typing"],
|
|
34
|
+
"theme": "default",
|
|
35
|
+
"tier": "free",
|
|
36
|
+
"price": 0,
|
|
37
|
+
"animation": {
|
|
38
|
+
"frameWidth": 342,
|
|
39
|
+
"frameCount": 1,
|
|
40
|
+
"fps": 0
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Field reference
|
|
48
|
+
|
|
49
|
+
| Field | Type | Required | Description |
|
|
50
|
+
|-------|------|----------|-------------|
|
|
51
|
+
| `file` | string | yes | Relative path from asset root |
|
|
52
|
+
| `category` | enum | yes | `tile`, `furniture`, `character`, `pet`, `decoration`, `background` |
|
|
53
|
+
| `width` | number | yes | Pixel width after trim |
|
|
54
|
+
| `height` | number | yes | Pixel height after trim |
|
|
55
|
+
| `anchorX` | number | yes | 0-1, horizontal anchor for positioning (0.5 = center) |
|
|
56
|
+
| `anchorY` | number | yes | 0-1, vertical anchor (1.0 = bottom for isometric depth sort) |
|
|
57
|
+
| `tags` | string[] | yes | Searchable keywords |
|
|
58
|
+
| `theme` | string | yes | Theme pack ID (`"default"`, `"cyberpunk"`, `"nature"`, etc.) |
|
|
59
|
+
| `tier` | enum | yes | `"free"`, `"premium"`, `"exclusive"` |
|
|
60
|
+
| `price` | number | yes | 0 for free, positive integer for paid (currency unit TBD) |
|
|
61
|
+
| `animation` | object\|null | no | Spritesheet info if animated |
|
|
62
|
+
|
|
63
|
+
## Animation field
|
|
64
|
+
|
|
65
|
+
For spritesheet assets (multiple frames in one image):
|
|
66
|
+
|
|
67
|
+
```json
|
|
68
|
+
{
|
|
69
|
+
"frameWidth": 64,
|
|
70
|
+
"frameCount": 4,
|
|
71
|
+
"fps": 8
|
|
72
|
+
}
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
The renderer reads left-to-right, each frame `frameWidth` pixels wide, cycling at `fps` frames per second.
|
|
76
|
+
|
|
77
|
+
## Anchor conventions
|
|
78
|
+
|
|
79
|
+
| Asset type | anchorX | anchorY | Reason |
|
|
80
|
+
|------------|---------|---------|--------|
|
|
81
|
+
| Most assets | 0.5 | 1.0 | Bottom-center โ standard for isometric depth sorting |
|
|
82
|
+
| Ceiling items (lights, plants) | 0.5 | 0.0 | Top-center โ hangs from above |
|
|
83
|
+
| Wall items (clock, frame) | 0.5 | 0.5 | Center โ placed on wall surface |
|
|
84
|
+
| Floor tiles | 0.5 | 0.5 | Center โ aligned to grid |
|
|
85
|
+
|
|
86
|
+
## Theme packs
|
|
87
|
+
|
|
88
|
+
A theme is a set of assets that share a visual style. The `"default"` theme ships free with the product. Premium themes are sold as packs.
|
|
89
|
+
|
|
90
|
+
```
|
|
91
|
+
assets/
|
|
92
|
+
โโโ themes/
|
|
93
|
+
โ โโโ default/ โ symlinks or copies of base assets
|
|
94
|
+
โ โโโ cyberpunk/ โ neon-tinted variants
|
|
95
|
+
โ โโโ nature/ โ wood-and-leaf variants
|
|
96
|
+
โ โโโ cozy-night/ โ warm lamp-lit variants
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
When a user switches themes, the renderer swaps asset paths: `furniture/desk-basic.png` โ `themes/cyberpunk/desk-basic.png`. Assets not overridden by the theme fall back to `default`.
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: asset-creator
|
|
3
|
+
description: >
|
|
4
|
+
Generate consistent pixel art game assets using AI image generation + meta-prompting
|
|
5
|
+
for style lock + HSL chroma-key background removal. Produces transparent PNGs ready
|
|
6
|
+
for PixiJS, Phaser, or any 2D game engine. Use when building pixel art games, creating
|
|
7
|
+
game sprites, generating isometric assets, making character sprites, or when user says
|
|
8
|
+
"create asset", "generate sprite", "make game art", "pixel art asset", or "์์
๋ง๋ค์ด".
|
|
9
|
+
allowed-tools: Read, Grep, Glob, Edit, Write, Bash
|
|
10
|
+
argument-hint: "[category] [name] \"[description]\" or batch [category] or list or init"
|
|
11
|
+
---
|
|
12
|
+
|
|
13
|
+
# Asset Creator โ AI-Powered Game Asset Pipeline
|
|
14
|
+
|
|
15
|
+
Generate production-ready pixel art game assets with consistent style, transparent backgrounds, and catalog metadata.
|
|
16
|
+
|
|
17
|
+
Reference files in this skill directory:
|
|
18
|
+
- `STYLE-GUIDE.md` โ Art direction defaults, per-category templates, predefined asset batches
|
|
19
|
+
- `CATALOG-SCHEMA.md` โ manifest.json structure and marketplace metadata
|
|
20
|
+
|
|
21
|
+
## Pipeline overview
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
0. STYLE LOCK Meta-prompt one reference asset โ extract style DNA (once per project)
|
|
25
|
+
1. GENERATE Swap [SUBJECT] in meta prompt โ Gemini 3.0 Pro Image
|
|
26
|
+
2. BG REMOVE HSL flood fill (Pillow) โ magenta + near-white removal
|
|
27
|
+
3. NORMALIZE Auto-crop + category-based size normalization
|
|
28
|
+
4. CATALOG manifest.json auto-registration with marketplace metadata
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
This pipeline was validated through iterative testing. The meta-prompting approach extracts the "style DNA" from one good asset and replicates it precisely โ more consistent than reference images (which the AI may reinterpret) and more token-efficient (264 chars vs 2MB image per call).
|
|
32
|
+
|
|
33
|
+
## Prerequisites
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
# Python 3 with Pillow โ required for HSL background removal
|
|
37
|
+
python3 -c "from PIL import Image; print('OK')"
|
|
38
|
+
|
|
39
|
+
# API key โ required for AI image generation
|
|
40
|
+
grep GEMINI_API_KEY .env
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
ImageMagick is NOT required โ the pipeline uses pure Python (Pillow) for background removal.
|
|
44
|
+
|
|
45
|
+
## Usage
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
/asset-creator init โ Set up project + extract meta prompt from reference
|
|
49
|
+
/asset-creator [category] [name] "[description]" โ Generate one asset
|
|
50
|
+
/asset-creator batch [category] โ Generate all predefined assets in a category
|
|
51
|
+
/asset-creator list โ Show current asset inventory
|
|
52
|
+
/asset-creator gallery โ Generate visual review HTML
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Workflow
|
|
56
|
+
|
|
57
|
+
### Parse the command
|
|
58
|
+
|
|
59
|
+
Read `$ARGUMENTS` and determine the mode:
|
|
60
|
+
|
|
61
|
+
| Input | Mode | Action |
|
|
62
|
+
|---|---|---|
|
|
63
|
+
| `init` | **Init** | Set up directories + extract meta prompt from reference asset |
|
|
64
|
+
| `[category] [name] "[desc]"` | **Single** | Generate one asset |
|
|
65
|
+
| `batch [category]` | **Batch** | Generate all predefined assets for category |
|
|
66
|
+
| `list` | **List** | Show asset inventory from manifest.json |
|
|
67
|
+
| `gallery` | **Gallery** | Generate review HTML |
|
|
68
|
+
| Empty | **Interactive** | Ask what to create |
|
|
69
|
+
|
|
70
|
+
Valid categories: `tile`, `furniture`, `character`, `pet`, `decoration`, `background`
|
|
71
|
+
|
|
72
|
+
### Step 0: Style Lock (init mode, or first run)
|
|
73
|
+
|
|
74
|
+
This is the foundation of style consistency. Run once per project.
|
|
75
|
+
|
|
76
|
+
**If no meta prompt exists** (`{asset-root}/style-prompt.txt` missing):
|
|
77
|
+
|
|
78
|
+
1. Check if the project has a reference asset. If not, generate one "hero asset" (a character or prominent furniture piece) using the default style from `STYLE-GUIDE.md`.
|
|
79
|
+
|
|
80
|
+
2. Send the reference asset to Gemini for meta-prompt extraction:
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
# Send image + extraction prompt to Gemini (text model, not image gen)
|
|
84
|
+
prompt = """Look at this pixel art game asset. Reverse-engineer the EXACT image
|
|
85
|
+
generation prompt that would recreate this STYLE. Replace the specific subject
|
|
86
|
+
with [SUBJECT]. Capture: pixel density, outline thickness, shading technique,
|
|
87
|
+
color palette warmth, perspective angle, proportions, and the solid magenta
|
|
88
|
+
#FF00FF background. Output ONLY the prompt text, max 3 sentences, be precise."""
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Use `gemini-2.5-flash` (text model) for extraction โ it's fast and cheap. NOT the image model.
|
|
92
|
+
|
|
93
|
+
3. Save the extracted meta prompt to `{asset-root}/style-prompt.txt`.
|
|
94
|
+
|
|
95
|
+
4. **Validate**: Generate a test asset using the meta prompt. Show it to the user alongside the reference. If the style matches, the meta prompt is locked. If not, regenerate with adjusted extraction prompt.
|
|
96
|
+
|
|
97
|
+
**If meta prompt exists**: Read `{asset-root}/style-prompt.txt` and use it for all generation.
|
|
98
|
+
|
|
99
|
+
### Step 1: Locate project asset directory
|
|
100
|
+
|
|
101
|
+
Look for existing asset directories in order:
|
|
102
|
+
1. `dashboard/public/assets/office/` (Pyx Org)
|
|
103
|
+
2. `public/assets/game/` (generic game)
|
|
104
|
+
3. `assets/` (fallback)
|
|
105
|
+
|
|
106
|
+
If none exists, create:
|
|
107
|
+
```
|
|
108
|
+
{asset-root}/
|
|
109
|
+
โโโ tiles/
|
|
110
|
+
โโโ furniture/
|
|
111
|
+
โโโ characters/
|
|
112
|
+
โโโ pets/
|
|
113
|
+
โโโ decorations/
|
|
114
|
+
โโโ backgrounds/
|
|
115
|
+
โโโ raw/ # AI originals (magenta bg, never delete)
|
|
116
|
+
โโโ manifest.json
|
|
117
|
+
โโโ style-prompt.txt # Meta prompt (style DNA)
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### Step 2: Generate the asset
|
|
121
|
+
|
|
122
|
+
Read the meta prompt from `{asset-root}/style-prompt.txt`.
|
|
123
|
+
|
|
124
|
+
Construct the final prompt by replacing `[SUBJECT]`:
|
|
125
|
+
```
|
|
126
|
+
{meta_prompt with [SUBJECT] replaced by user's description}
|
|
127
|
+
|
|
128
|
+
Generate a pixel art IMAGE.
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Call Gemini 3.0 Pro Image API (`gemini-3-pro-image-preview`):
|
|
132
|
+
|
|
133
|
+
```python
|
|
134
|
+
import json, base64, urllib.request
|
|
135
|
+
|
|
136
|
+
api_key = os.environ.get("GEMINI_API_KEY") or read_from_dotenv()
|
|
137
|
+
|
|
138
|
+
payload = {
|
|
139
|
+
"contents": [{"parts": [{"text": full_prompt}]}],
|
|
140
|
+
"generationConfig": {
|
|
141
|
+
"responseModalities": ["IMAGE", "TEXT"],
|
|
142
|
+
"temperature": 0.3
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
url = f"https://generativelanguage.googleapis.com/v1beta/models/gemini-3-pro-image-preview:generateContent?key={api_key}"
|
|
147
|
+
req = urllib.request.Request(url, data=json.dumps(payload).encode(),
|
|
148
|
+
headers={"Content-Type": "application/json"}, method="POST")
|
|
149
|
+
|
|
150
|
+
with urllib.request.urlopen(req, timeout=120) as resp:
|
|
151
|
+
result = json.loads(resp.read().decode())
|
|
152
|
+
|
|
153
|
+
# Extract image from response
|
|
154
|
+
for part in result["candidates"][0]["content"]["parts"]:
|
|
155
|
+
if "inlineData" in part:
|
|
156
|
+
data = base64.b64decode(part["inlineData"]["data"])
|
|
157
|
+
with open(f"{asset_root}/raw/{name}.jpg", "wb") as f:
|
|
158
|
+
f.write(data)
|
|
159
|
+
break
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Step 3: Remove background (HSL flood fill)
|
|
163
|
+
|
|
164
|
+
This is the optimized approach โ uses HSL color space instead of RGB for robust chroma-key removal that handles JPG compression artifacts.
|
|
165
|
+
|
|
166
|
+
```python
|
|
167
|
+
from PIL import Image
|
|
168
|
+
import colorsys
|
|
169
|
+
from collections import deque
|
|
170
|
+
|
|
171
|
+
def remove_background(input_path, output_path):
|
|
172
|
+
img = Image.open(input_path).convert("RGBA")
|
|
173
|
+
pixels = img.load()
|
|
174
|
+
w, h = img.size
|
|
175
|
+
|
|
176
|
+
def should_remove(r, g, b):
|
|
177
|
+
rn, gn, bn = r/255.0, g/255.0, b/255.0
|
|
178
|
+
h_val, l_val, s_val = colorsys.rgb_to_hls(rn, gn, bn)
|
|
179
|
+
hue_deg = h_val * 360
|
|
180
|
+
# Magenta hue range (robust against JPG compression)
|
|
181
|
+
if 250 <= hue_deg <= 340 and s_val > 0.2:
|
|
182
|
+
return True
|
|
183
|
+
# Near-white (catches desaturated magenta from JPG artifacts)
|
|
184
|
+
if r > 230 and g > 230 and b > 230:
|
|
185
|
+
return True
|
|
186
|
+
# Very light + low saturation
|
|
187
|
+
if l_val > 0.9 and s_val < 0.15:
|
|
188
|
+
return True
|
|
189
|
+
return False
|
|
190
|
+
|
|
191
|
+
# Phase 1: Flood fill from all edges (only removes connected background)
|
|
192
|
+
visited = set()
|
|
193
|
+
queue = deque()
|
|
194
|
+
for x in range(w):
|
|
195
|
+
queue.append((x, 0)); queue.append((x, h-1))
|
|
196
|
+
for y in range(h):
|
|
197
|
+
queue.append((0, y)); queue.append((w-1, y))
|
|
198
|
+
|
|
199
|
+
while queue:
|
|
200
|
+
x, y = queue.popleft()
|
|
201
|
+
if (x, y) in visited or x < 0 or x >= w or y < 0 or y >= h:
|
|
202
|
+
continue
|
|
203
|
+
visited.add((x, y))
|
|
204
|
+
r, g, b, a = pixels[x, y]
|
|
205
|
+
if should_remove(r, g, b):
|
|
206
|
+
pixels[x, y] = (0, 0, 0, 0)
|
|
207
|
+
for dx, dy in [(-1,0),(1,0),(0,-1),(0,1),(-1,-1),(1,-1),(-1,1),(1,1)]:
|
|
208
|
+
nx, ny = x+dx, y+dy
|
|
209
|
+
if 0 <= nx < w and 0 <= ny < h and (nx, ny) not in visited:
|
|
210
|
+
queue.append((nx, ny))
|
|
211
|
+
|
|
212
|
+
# Phase 2: Edge cleanup (remove remaining pink fringe)
|
|
213
|
+
for y in range(1, h-1):
|
|
214
|
+
for x in range(1, w-1):
|
|
215
|
+
r, g, b, a = pixels[x, y]
|
|
216
|
+
if a == 0: continue
|
|
217
|
+
rn, gn, bn = r/255.0, g/255.0, b/255.0
|
|
218
|
+
h_val, l_val, s_val = colorsys.rgb_to_hls(rn, gn, bn)
|
|
219
|
+
hue_deg = h_val * 360
|
|
220
|
+
if (250 <= hue_deg <= 340 and s_val > 0.1) or (l_val > 0.85 and s_val < 0.2):
|
|
221
|
+
for dx, dy in [(-1,0),(1,0),(0,-1),(0,1)]:
|
|
222
|
+
if pixels[x+dx, y+dy][3] == 0:
|
|
223
|
+
pixels[x, y] = (0, 0, 0, 0)
|
|
224
|
+
break
|
|
225
|
+
|
|
226
|
+
# Auto-crop to content
|
|
227
|
+
bbox = img.getbbox()
|
|
228
|
+
if bbox:
|
|
229
|
+
img = img.crop(bbox)
|
|
230
|
+
img.save(output_path)
|
|
231
|
+
return img.size
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
Why HSL instead of RGB:
|
|
235
|
+
- JPG compression shifts RGB values but barely affects Hue
|
|
236
|
+
- Magenta has a distinctive hue (~300ยฐ) that's stable across compression levels
|
|
237
|
+
- Saturation check prevents false positives on gray/white pixels
|
|
238
|
+
- Flood fill from edges ensures interior light pixels are preserved
|
|
239
|
+
|
|
240
|
+
### Step 4: Register in manifest
|
|
241
|
+
|
|
242
|
+
Read `{asset-root}/manifest.json`. Get dimensions from the processed PNG. Add entry:
|
|
243
|
+
|
|
244
|
+
```json
|
|
245
|
+
{
|
|
246
|
+
"{category}/{name}": {
|
|
247
|
+
"file": "{category}/{name}.png",
|
|
248
|
+
"category": "{category}",
|
|
249
|
+
"width": W,
|
|
250
|
+
"height": H,
|
|
251
|
+
"anchorX": 0.5,
|
|
252
|
+
"anchorY": 1.0,
|
|
253
|
+
"tags": ["inferred", "from", "description"],
|
|
254
|
+
"theme": "default",
|
|
255
|
+
"tier": "free",
|
|
256
|
+
"price": 0
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
See `CATALOG-SCHEMA.md` for full field reference and anchor conventions.
|
|
262
|
+
|
|
263
|
+
### Step 5: Show result
|
|
264
|
+
|
|
265
|
+
Display the generated PNG using the Read tool. Report:
|
|
266
|
+
- File path and size
|
|
267
|
+
- Dimensions (W ร H)
|
|
268
|
+
- Category, tags, tier
|
|
269
|
+
- Manifest status
|
|
270
|
+
|
|
271
|
+
If unsatisfied, offer to regenerate with an adjusted subject description.
|
|
272
|
+
|
|
273
|
+
## Batch Mode
|
|
274
|
+
|
|
275
|
+
Read predefined asset lists from `STYLE-GUIDE.md`. Generate each sequentially with 1.5s delay (rate limiting). Show progress. Generate gallery at end.
|
|
276
|
+
|
|
277
|
+
## List Mode
|
|
278
|
+
|
|
279
|
+
Read manifest.json, group by category, display inventory table with dimensions, tier, and file size.
|
|
280
|
+
|
|
281
|
+
## Gallery Mode
|
|
282
|
+
|
|
283
|
+
Generate `{asset-root}/gallery.html` showing all assets on checkered transparency background, grouped by category. Suggest `python3 -m http.server 8888` to view.
|
|
284
|
+
|
|
285
|
+
## Adapting to other AI generators
|
|
286
|
+
|
|
287
|
+
The pipeline is model-agnostic. To swap generators:
|
|
288
|
+
1. Replace the API call in Step 2
|
|
289
|
+
2. Keep the meta prompt + magenta background instruction
|
|
290
|
+
3. HSL background removal works identically regardless of source
|
|
291
|
+
4. If your model outputs PNG with native transparency, skip Step 3
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
# Asset Creator โ Style Guide
|
|
2
|
+
|
|
3
|
+
This document defines the art direction defaults and per-category templates. In production, the meta prompt (extracted from a reference asset) overrides the default style prefix.
|
|
4
|
+
|
|
5
|
+
## Style System: Meta Prompting
|
|
6
|
+
|
|
7
|
+
The best way to ensure style consistency is **meta prompting** โ extracting the "style DNA" from one good reference asset, then using that exact prompt for all subsequent generations with only the `[SUBJECT]` swapped.
|
|
8
|
+
|
|
9
|
+
### How it works
|
|
10
|
+
|
|
11
|
+
1. Generate or find one "hero asset" that nails the visual style you want
|
|
12
|
+
2. Send it to Gemini text model to reverse-engineer the prompt
|
|
13
|
+
3. Save the extracted prompt as `style-prompt.txt` in the asset root
|
|
14
|
+
4. Every subsequent generation uses this prompt, replacing `[SUBJECT]` only
|
|
15
|
+
|
|
16
|
+
### Why meta prompting beats alternatives
|
|
17
|
+
|
|
18
|
+
| Approach | Consistency | Token cost | Reliability |
|
|
19
|
+
|---|---|---|---|
|
|
20
|
+
| Fixed text prefix (old approach) | Medium โ AI interprets loosely | Low | Medium |
|
|
21
|
+
| Reference image every call | High โ but AI may reinterpret | Very High (~2MB/call) | Medium |
|
|
22
|
+
| **Meta prompt (current)** | **High โ exact reproduction** | **Low (264 chars)** | **High** |
|
|
23
|
+
| Fine-tuned model (Scenario.gg) | Highest | Setup cost | Highest |
|
|
24
|
+
|
|
25
|
+
### Default style prefix (fallback)
|
|
26
|
+
|
|
27
|
+
If no `style-prompt.txt` exists yet (first run / init), use this as the initial generation prompt:
|
|
28
|
+
|
|
29
|
+
```
|
|
30
|
+
Gather Town / Habbo Hotel style pixel art game asset, isometric 3/4 view, bright cheerful warm colors, clean pixel outlines, highly detailed pixel art
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Then extract the meta prompt from the first successful generation.
|
|
34
|
+
|
|
35
|
+
## Background Instruction (always appended)
|
|
36
|
+
|
|
37
|
+
Regardless of meta prompt, ALWAYS append this to every generation prompt:
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
on a solid bright magenta #FF00FF background. The ENTIRE background must be exactly #FF00FF magenta, with NO gradients or shadows on the background. ONLY the single isolated object, nothing else in the scene.
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
This is required by the HSL chroma-key removal pipeline. Magenta (#FF00FF) is the game industry standard chroma-key color โ it never appears in natural pixel art palettes.
|
|
44
|
+
|
|
45
|
+
## Perspective
|
|
46
|
+
|
|
47
|
+
- **Angle**: Isometric ยพ top-down view (~30ยฐ from horizontal)
|
|
48
|
+
- **Camera**: Looking from bottom-left toward top-right
|
|
49
|
+
- **Shadow direction**: Bottom-right, short and crisp
|
|
50
|
+
- **Light source**: Top-left (consistent with shadow direction)
|
|
51
|
+
|
|
52
|
+
## Proportions (relative to character height)
|
|
53
|
+
|
|
54
|
+
| Element | Relative size | Notes |
|
|
55
|
+
|---|---|---|
|
|
56
|
+
| Character (standing) | 1.0x | Reference unit |
|
|
57
|
+
| Character (sitting) | 0.7x | At desk |
|
|
58
|
+
| Desk | 0.5x height, 1.2x width | With monitor, wider than tall |
|
|
59
|
+
| Chair | 0.4x | Office swivel chair |
|
|
60
|
+
| Bookshelf | 1.2x | Taller than character |
|
|
61
|
+
| Door | 1.5x | Tallest common furniture |
|
|
62
|
+
| Floor plant | 0.8-1.0x | Varies by type |
|
|
63
|
+
| Desk plant | 0.2x | Small succulent/cactus |
|
|
64
|
+
| Wall decoration | 0.3-0.5x | Clock, picture frame |
|
|
65
|
+
| Bean bag | 0.4x height, 0.8x width | Wide and low |
|
|
66
|
+
| Kit (pet) | 0.5x | Smaller than character |
|
|
67
|
+
|
|
68
|
+
## Color palette guidelines
|
|
69
|
+
|
|
70
|
+
- **Warm base**: Browns, beiges, warm grays for furniture and floors
|
|
71
|
+
- **Department accents**: Orange (Research), Green (Engineering), Blue (Growth), Purple (Ops)
|
|
72
|
+
- **Skin tones**: Varied, warm undertones
|
|
73
|
+
- **Outlines**: Dark brown or black, 1-2px, clean and consistent
|
|
74
|
+
- **Highlights**: Top-left facing surfaces lighter
|
|
75
|
+
- **Shadows**: Bottom-right facing surfaces darker, 2-3 tone steps
|
|
76
|
+
|
|
77
|
+
## Per-category prompt templates
|
|
78
|
+
|
|
79
|
+
### tile
|
|
80
|
+
```
|
|
81
|
+
{STYLE_PREFIX}. A single isometric {description} tile, 64x64 pixel grid aligned, seamlessly tileable. {BG_SUFFIX}
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### furniture
|
|
85
|
+
```
|
|
86
|
+
{STYLE_PREFIX}. A single {description}. Isometric perspective, detailed with visible texture and shading. {BG_SUFFIX}
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### character
|
|
90
|
+
```
|
|
91
|
+
{STYLE_PREFIX}. A single cute office worker character, {description}. Gather Town style proportions: blocky square head wider than body, dot eyes with white highlight, small body. {BG_SUFFIX}
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### pet
|
|
95
|
+
```
|
|
96
|
+
{STYLE_PREFIX}. A single small cute {description}. Expressive face, big eyes, stubby limbs. Game mascot style. {BG_SUFFIX}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### decoration
|
|
100
|
+
```
|
|
101
|
+
{STYLE_PREFIX}. A single {description}. Small decorative object, detailed pixel art. {BG_SUFFIX}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### background
|
|
105
|
+
```
|
|
106
|
+
{STYLE_PREFIX}. A wide panoramic {description}. Suitable as a background layer, horizontally tileable or wide format. {BG_SUFFIX}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
## Predefined asset batches
|
|
110
|
+
|
|
111
|
+
### tile
|
|
112
|
+
| name | description |
|
|
113
|
+
|------|-------------|
|
|
114
|
+
| floor-wood | wooden floor tile with warm wood grain texture |
|
|
115
|
+
| floor-carpet-orange | orange carpet tile for Research department |
|
|
116
|
+
| floor-carpet-green | green carpet tile for Engineering department |
|
|
117
|
+
| floor-carpet-blue | blue carpet tile for Growth department |
|
|
118
|
+
| floor-carpet-purple | purple carpet tile for Ops department |
|
|
119
|
+
| wall-back | cream/beige back wall section |
|
|
120
|
+
| wall-side | slightly darker side wall section |
|
|
121
|
+
|
|
122
|
+
### furniture
|
|
123
|
+
| name | description |
|
|
124
|
+
|------|-------------|
|
|
125
|
+
| desk-basic | wooden office desk with computer monitor, keyboard, mouse, and coffee mug |
|
|
126
|
+
| desk-standing | modern standing desk with large monitor and adjustable height |
|
|
127
|
+
| chair-office | dark office swivel chair with armrests |
|
|
128
|
+
| bookshelf | tall wooden bookshelf packed with colorful books, small plant on top |
|
|
129
|
+
| whiteboard | office whiteboard covered in colorful sticky notes, marker tray at bottom |
|
|
130
|
+
| beanbag-green | large green bean bag chair, puffy and round |
|
|
131
|
+
| beanbag-orange | large orange bean bag chair, puffy and round |
|
|
132
|
+
| beanbag-purple | large purple bean bag chair, puffy and round |
|
|
133
|
+
| coffee-station | espresso machine on wooden counter with white mug underneath |
|
|
134
|
+
| water-cooler | water cooler dispenser with blue water jug on top |
|
|
135
|
+
| meeting-table | round meeting table with 4 small chairs |
|
|
136
|
+
| sofa | comfortable modern office couch |
|
|
137
|
+
|
|
138
|
+
### character
|
|
139
|
+
| name | description |
|
|
140
|
+
|------|-------------|
|
|
141
|
+
| char-research-sitting | in orange shirt, brown hair, sitting and typing on laptop |
|
|
142
|
+
| char-research-standing | in orange shirt, brown hair, standing casually |
|
|
143
|
+
| char-engineering-sitting | in green shirt, black hair, sitting and typing on laptop |
|
|
144
|
+
| char-engineering-standing | in green shirt, black hair, standing casually |
|
|
145
|
+
| char-growth-sitting | in blue shirt, blonde hair, sitting and typing on laptop |
|
|
146
|
+
| char-growth-standing | in blue shirt, blonde hair, standing casually |
|
|
147
|
+
| char-ops-sitting | in purple shirt, red ponytail, sitting and typing on laptop |
|
|
148
|
+
| char-ops-standing | in purple shirt, red ponytail, standing casually |
|
|
149
|
+
|
|
150
|
+
### pet
|
|
151
|
+
| name | description |
|
|
152
|
+
|------|-------------|
|
|
153
|
+
| kit-idle | golden yellow cat creature mascot, happy expression, standing still |
|
|
154
|
+
| kit-bounce-1 | golden yellow cat creature mascot, jumping up with arms raised |
|
|
155
|
+
| kit-bounce-2 | golden yellow cat creature mascot, at peak of jump |
|
|
156
|
+
| kit-blink | golden yellow cat creature mascot, eyes closed, smiling |
|
|
157
|
+
|
|
158
|
+
### decoration
|
|
159
|
+
| name | description |
|
|
160
|
+
|------|-------------|
|
|
161
|
+
| plant-hanging | hanging potted plant with green vines draping from terracotta pot on chain |
|
|
162
|
+
| plant-floor-large | tall floor potted plant with large green leaves in brown pot |
|
|
163
|
+
| plant-desk | small succulent in tiny pot for desk |
|
|
164
|
+
| clock-wall | round wall clock with simple markers |
|
|
165
|
+
| picture-frame | framed picture/certificate for wall |
|
|
166
|
+
| pendant-light | hanging ceiling pendant light with warm glow |
|
|
167
|
+
| window-large | large floor-to-ceiling window panel |
|
|
168
|
+
| bulletin-board | cork board with pinned papers and photos |
|
|
169
|
+
|
|
170
|
+
### background
|
|
171
|
+
| name | description |
|
|
172
|
+
|------|-------------|
|
|
173
|
+
| skyline-day | city skyline with buildings, blue sky, white clouds, wide panorama |
|
|
174
|
+
| skyline-night | nighttime city skyline with lit windows, dark blue sky, wide panorama |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "devlyn-cli",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.1",
|
|
4
4
|
"description": "AI development toolkit for Claude Code โ ideate, auto-resolve, and ship with context engineering and agent orchestration",
|
|
5
5
|
"homepage": "https://github.com/fysoul17/devlyn-cli#readme",
|
|
6
6
|
"bin": {
|