Fraser commited on
Commit
2531fcd
·
1 Parent(s): b524411

better monster gen

Browse files
src/lib/components/MonsterGenerator/MonsterGenerator.svelte CHANGED
@@ -46,12 +46,11 @@ Format your response as:
46
  # Object Caption
47
  {object description, also assess how rare the object is, the rarer the object the stronger the monster}
48
  # Transformation Brainstorm
49
- {think through how to transform the object into a Pokémon-like creature}
50
- # {monster name}
 
51
  ## Monster Visual Description
52
  {ensure the creature uses all the unique attributes of the object}
53
- ## Monster Lore
54
- ...
55
  \`\`\``;
56
 
57
  const IMAGE_GENERATION_PROMPT = (concept: string) => `Extract ONLY the visual appearance from this monster concept and describe it in one concise sentence:
@@ -202,8 +201,8 @@ Focus on: colors, body shape, eyes, limbs, mouth, and key visual features. Omit
202
  async function generateMonsterImage() {
203
  state.currentStep = 'generating';
204
 
205
- if (!fluxClient || !state.monsterConcept) {
206
- throw new Error('Image generation service not available or no concept');
207
  }
208
 
209
  // Extract the visual description from the joy-caption output
@@ -245,9 +244,18 @@ Focus on: colors, body shape, eyes, limbs, mouth, and key visual features. Omit
245
  throw new Error('Failed to extract visual description');
246
  }
247
 
 
 
 
 
 
 
 
 
 
248
  try {
249
  const output = await fluxClient.predict("/infer", [
250
- `${state.imagePrompt}\nNow generate a Pokémon-Anime-style image of the monster in an idle pose with a white background. The monster should not be attacking or in motion. The full monster must be visible within the frame.`,
251
  0, // seed
252
  true, // randomizeSeed
253
  1024, // width
@@ -309,14 +317,9 @@ Focus on: colors, body shape, eyes, limbs, mouth, and key visual features. Omit
309
  const monsterNameMatch = state.monsterConcept.match(/^# (?!Object Caption|Transformation Brainstorm)(.+)$/m);
310
  const monsterName = monsterNameMatch ? monsterNameMatch[1].trim() : 'Unknown Monster';
311
 
312
- // Extract only the Monster Lore section for description
313
- const loreMatch = state.monsterConcept.match(/## Monster Lore\s*\n([\s\S]*?)(?=##|$)/);
314
- const monsterLore = loreMatch ? loreMatch[1].trim() : '';
315
-
316
  // Debug logging
317
  console.log('Extracted object description:', objectDescription);
318
  console.log('Extracted monster name:', monsterName);
319
- console.log('Extracted monster lore:', monsterLore);
320
 
321
  // Create stats prompt - only ask for battle-related stats
322
  const statsPrompt = `Based on this monster concept, generate a JSON object with battle stats and abilities:
@@ -355,6 +358,7 @@ The output should be formatted as a JSON instance that conforms to the JSON sche
355
  "defence": {"type": "integer", "minimum": 0, "maximum": 100, "description": "Defensive/armor stat (0=paper thin, 100=impenetrable fortress)"},
356
  "attack": {"type": "integer", "minimum": 0, "maximum": 100, "description": "Physical attack power (0=harmless, 100=devastating force)"},
357
  "speed": {"type": "integer", "minimum": 0, "maximum": 100, "description": "Movement and reaction speed (0=immobile, 100=lightning fast)"},
 
358
  "specialPassiveTraitDescription": {"type": "string", "description": "Describe a passive ability that gives this monster a unique advantage in battle"},
359
  "attackActionName": {"type": "string", "description": "Name of the monster's primary damage-dealing attack (e.g., 'Flame Burst', 'Toxic Bite')"},
360
  "attackActionDescription": {"type": "string", "description": "Describe how this attack damages the opponent and any special effects"},
@@ -365,7 +369,7 @@ The output should be formatted as a JSON instance that conforms to the JSON sche
365
  "specialActionName": {"type": "string", "description": "Name of the monster's ultimate move (one use per battle)"},
366
  "specialActionDescription": {"type": "string", "description": "Describe this powerful finishing move and its dramatic effects in battle"}
367
  },
368
- "required": ["rarity", "picletType", "height", "weight", "HP", "defence", "attack", "speed", "specialPassiveTraitDescription", "attackActionName", "attackActionDescription", "buffActionName", "buffActionDescription", "debuffActionName", "debuffActionDescription", "specialActionName", "specialActionDescription"]
369
  }
370
  \`\`\`
371
 
@@ -419,7 +423,7 @@ Write your response within \`\`\`json\`\`\``;
419
 
420
  // Remove any extra fields not in our schema
421
  const allowedFields = ['rarity', 'picletType', 'height', 'weight', 'HP', 'defence', 'attack', 'speed',
422
- 'specialPassiveTraitDescription', 'attackActionName', 'attackActionDescription',
423
  'buffActionName', 'buffActionDescription', 'debuffActionName', 'debuffActionDescription',
424
  'specialActionName', 'specialActionDescription', 'boostActionName', 'boostActionDescription',
425
  'disparageActionName', 'disparageActionDescription'];
@@ -443,7 +447,7 @@ Write your response within \`\`\`json\`\`\``;
443
 
444
  // Add the name, description, and tier that we extracted/mapped
445
  parsedStats.name = monsterName;
446
- parsedStats.description = monsterLore;
447
  parsedStats.tier = tier;
448
 
449
  // Ensure numeric fields are actually numbers
 
46
  # Object Caption
47
  {object description, also assess how rare the object is, the rarer the object the stronger the monster}
48
  # Transformation Brainstorm
49
+ {brief thought on how to transform the object into a Pokémon-like creature}
50
+ # Monster Name
51
+ {monster name}
52
  ## Monster Visual Description
53
  {ensure the creature uses all the unique attributes of the object}
 
 
54
  \`\`\``;
55
 
56
  const IMAGE_GENERATION_PROMPT = (concept: string) => `Extract ONLY the visual appearance from this monster concept and describe it in one concise sentence:
 
201
  async function generateMonsterImage() {
202
  state.currentStep = 'generating';
203
 
204
+ if (!fluxClient || !state.monsterConcept || !state.monsterStats) {
205
+ throw new Error('Image generation service not available or no concept/stats');
206
  }
207
 
208
  // Extract the visual description from the joy-caption output
 
244
  throw new Error('Failed to extract visual description');
245
  }
246
 
247
+ // Get tier for image quality enhancement
248
+ const tier = state.monsterStats.tier || 'medium';
249
+ const tierDescriptions = {
250
+ low: 'simple and basic design',
251
+ medium: 'detailed and well-crafted design',
252
+ high: 'highly detailed and impressive design with special effects',
253
+ legendary: 'extremely detailed and majestic design with dramatic lighting and aura effects'
254
+ };
255
+
256
  try {
257
  const output = await fluxClient.predict("/infer", [
258
+ `${state.imagePrompt}\nNow generate a Pokémon-Anime-style image of the monster in an idle pose with a white background. This is a ${tier} tier monster with ${tierDescriptions[tier as keyof typeof tierDescriptions]}. The monster should not be attacking or in motion. The full monster must be visible within the frame.`,
259
  0, // seed
260
  true, // randomizeSeed
261
  1024, // width
 
317
  const monsterNameMatch = state.monsterConcept.match(/^# (?!Object Caption|Transformation Brainstorm)(.+)$/m);
318
  const monsterName = monsterNameMatch ? monsterNameMatch[1].trim() : 'Unknown Monster';
319
 
 
 
 
 
320
  // Debug logging
321
  console.log('Extracted object description:', objectDescription);
322
  console.log('Extracted monster name:', monsterName);
 
323
 
324
  // Create stats prompt - only ask for battle-related stats
325
  const statsPrompt = `Based on this monster concept, generate a JSON object with battle stats and abilities:
 
358
  "defence": {"type": "integer", "minimum": 0, "maximum": 100, "description": "Defensive/armor stat (0=paper thin, 100=impenetrable fortress)"},
359
  "attack": {"type": "integer", "minimum": 0, "maximum": 100, "description": "Physical attack power (0=harmless, 100=devastating force)"},
360
  "speed": {"type": "integer", "minimum": 0, "maximum": 100, "description": "Movement and reaction speed (0=immobile, 100=lightning fast)"},
361
+ "monsterLore": {"type": "string", "description": "Write a detailed background story for this monster including its personality, habitat, behavior, and lore (2-3 sentences)"},
362
  "specialPassiveTraitDescription": {"type": "string", "description": "Describe a passive ability that gives this monster a unique advantage in battle"},
363
  "attackActionName": {"type": "string", "description": "Name of the monster's primary damage-dealing attack (e.g., 'Flame Burst', 'Toxic Bite')"},
364
  "attackActionDescription": {"type": "string", "description": "Describe how this attack damages the opponent and any special effects"},
 
369
  "specialActionName": {"type": "string", "description": "Name of the monster's ultimate move (one use per battle)"},
370
  "specialActionDescription": {"type": "string", "description": "Describe this powerful finishing move and its dramatic effects in battle"}
371
  },
372
+ "required": ["rarity", "picletType", "height", "weight", "HP", "defence", "attack", "speed", "monsterLore", "specialPassiveTraitDescription", "attackActionName", "attackActionDescription", "buffActionName", "buffActionDescription", "debuffActionName", "debuffActionDescription", "specialActionName", "specialActionDescription"]
373
  }
374
  \`\`\`
375
 
 
423
 
424
  // Remove any extra fields not in our schema
425
  const allowedFields = ['rarity', 'picletType', 'height', 'weight', 'HP', 'defence', 'attack', 'speed',
426
+ 'monsterLore', 'specialPassiveTraitDescription', 'attackActionName', 'attackActionDescription',
427
  'buffActionName', 'buffActionDescription', 'debuffActionName', 'debuffActionDescription',
428
  'specialActionName', 'specialActionDescription', 'boostActionName', 'boostActionDescription',
429
  'disparageActionName', 'disparageActionDescription'];
 
447
 
448
  // Add the name, description, and tier that we extracted/mapped
449
  parsedStats.name = monsterName;
450
+ parsedStats.description = parsedStats.monsterLore || 'A mysterious creature with unknown origins.';
451
  parsedStats.tier = tier;
452
 
453
  // Ensure numeric fields are actually numbers