Fraser commited on
Commit
fd1786e
Β·
1 Parent(s): a46ce65

better gen

Browse files
src/lib/components/MonsterGenerator/MonsterGenerator.svelte CHANGED
@@ -8,6 +8,7 @@
8
  import { saveMonster } from '$lib/db/monsters';
9
  import { extractPicletMetadata } from '$lib/services/picletMetadata';
10
  import { savePicletInstance } from '$lib/db/piclets';
 
11
 
12
  interface Props extends MonsterGeneratorProps {}
13
 
@@ -300,30 +301,54 @@ Focus on: colors, body shape, eyes, limbs, mouth, and key visual features. Omit
300
  // Default tier (will be set from the generated stats)
301
  let tier: 'low' | 'medium' | 'high' | 'legendary' = 'medium';
302
 
303
- // Extract monster name from the concept
304
- const nameMatch = state.monsterConcept.match(/^#\s+(.+)$/m);
305
- const monsterName = nameMatch ? nameMatch[1] : 'Unknown Monster';
 
 
 
 
306
 
307
  // Extract only the Monster Lore section for description
308
  const loreMatch = state.monsterConcept.match(/## Monster Lore\s*\n([\s\S]*?)(?=##|$)/);
309
  const monsterLore = loreMatch ? loreMatch[1].trim() : '';
310
 
 
 
 
 
 
311
  // Create stats prompt - only ask for battle-related stats
312
  const statsPrompt = `Based on this monster concept, generate a JSON object with battle stats and abilities:
313
  "${state.monsterConcept}"
314
 
 
 
315
  First, assess the rarity of the original object based on real-world availability and value:
316
  β€’ COMMON: Everyday items everyone has (stationery, grass, rocks, basic furniture, common tools)
317
  β€’ UNCOMMON: Items that cost money but are widely available (electronics, appliances, vehicles, branded items)
318
  β€’ RARE: Expensive or specialized items (luxury goods, professional equipment, gold jewelry, antiques)
319
  β€’ LEGENDARY: Priceless or one-of-a-kind items (crown jewels, world wonders, famous artifacts, masterpiece art)
320
 
 
 
 
 
 
 
 
 
 
 
 
 
321
  The output should be formatted as a JSON instance that conforms to the JSON schema below.
322
 
323
  \`\`\`json
324
  {
325
  "properties": {
326
  "rarity": {"type": "string", "enum": ["common", "uncommon", "rare", "legendary"], "description": "Rarity of the original object based on real-world availability and value"},
 
327
  "height": {"type": "number", "minimum": 0.1, "maximum": 50.0, "description": "Height of the piclet in meters (e.g., 1.2, 0.5, 10.0)"},
328
  "weight": {"type": "number", "minimum": 0.1, "maximum": 10000.0, "description": "Weight of the piclet in kilograms (e.g., 25.4, 150.0, 0.8)"},
329
  "HP": {"type": "integer", "minimum": 0, "maximum": 100, "description": "Health/vitality stat (0=fragile, 100=incredibly tanky)"},
@@ -340,7 +365,7 @@ The output should be formatted as a JSON instance that conforms to the JSON sche
340
  "specialActionName": {"type": "string", "description": "Name of the monster's ultimate move (one use per battle)"},
341
  "specialActionDescription": {"type": "string", "description": "Describe this powerful finishing move and its dramatic effects in battle"}
342
  },
343
- "required": ["rarity", "height", "weight", "HP", "defence", "attack", "speed", "specialPassiveTraitDescription", "attackActionName", "attackActionDescription", "buffActionName", "buffActionDescription", "debuffActionName", "debuffActionDescription", "specialActionName", "specialActionDescription"]
344
  }
345
  \`\`\`
346
 
@@ -393,7 +418,7 @@ Write your response within \`\`\`json\`\`\``;
393
  const parsedStats = JSON.parse(cleanJson.trim());
394
 
395
  // Remove any extra fields not in our schema
396
- const allowedFields = ['rarity', 'height', 'weight', 'HP', 'defence', 'attack', 'speed',
397
  'specialPassiveTraitDescription', 'attackActionName', 'attackActionDescription',
398
  'buffActionName', 'buffActionDescription', 'debuffActionName', 'debuffActionDescription',
399
  'specialActionName', 'specialActionDescription', 'boostActionName', 'boostActionDescription',
 
8
  import { saveMonster } from '$lib/db/monsters';
9
  import { extractPicletMetadata } from '$lib/services/picletMetadata';
10
  import { savePicletInstance } from '$lib/db/piclets';
11
+ import { PicletType, TYPE_DATA } from '$lib/types/picletTypes';
12
 
13
  interface Props extends MonsterGeneratorProps {}
14
 
 
301
  // Default tier (will be set from the generated stats)
302
  let tier: 'low' | 'medium' | 'high' | 'legendary' = 'medium';
303
 
304
+ // Extract object description from the Object Caption section
305
+ const objectMatch = state.monsterConcept.match(/# Object Caption\s*\n([\s\S]*?)(?=^# )/m);
306
+ const objectDescription = objectMatch ? objectMatch[1].trim() : '';
307
+
308
+ // Extract monster name - now it's the third heading after Object Caption and Transformation Brainstorm
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:
323
  "${state.monsterConcept}"
324
 
325
+ The original object is described as: "${objectDescription}"
326
+
327
  First, assess the rarity of the original object based on real-world availability and value:
328
  β€’ COMMON: Everyday items everyone has (stationery, grass, rocks, basic furniture, common tools)
329
  β€’ UNCOMMON: Items that cost money but are widely available (electronics, appliances, vehicles, branded items)
330
  β€’ RARE: Expensive or specialized items (luxury goods, professional equipment, gold jewelry, antiques)
331
  β€’ LEGENDARY: Priceless or one-of-a-kind items (crown jewels, world wonders, famous artifacts, masterpiece art)
332
 
333
+ Next, determine the monster's type based on its concept and appearance. Choose the most appropriate type from these options:
334
+ β€’ BEAST: Vertebrate wildlife β€” mammals, birds, reptiles. Raw physicality, instincts, region-based variants.
335
+ β€’ BUG: Arthropods β€” butterflies, beetles, mantises. Agile swarms, precision strikes, metamorph evolutions.
336
+ β€’ AQUATIC: Life that swims, dives, sloshes, seeps β€” fish, octopus, sentient puddles. Tides, mist, pressure.
337
+ β€’ FLORA: Plants and fungi β€” blooming or decaying. Growth, spores, vines, seasonal shifts.
338
+ β€’ MINERAL: Stones, crystals, metals β€” earth's depths. Durability, reflective armor, seismic shocks.
339
+ β€’ SPACE: Stars, moon, cosmic objects β€” not of this world. Celestial energy and cosmic forces.
340
+ β€’ MACHINA: Engineered devices β€” gadgets to machinery. Gears, circuits, drones, power surges.
341
+ β€’ STRUCTURE: Buildings, bridges, monuments β€” architectural titans. Fortification, terrain shaping.
342
+ β€’ CULTURE: Art, fashion, toys, symbols β€” creative expressions. Buffs, debuffs, illusion, stories.
343
+ β€’ CUISINE: Dishes, drinks, culinary art β€” flavors and aromas. Temperature, restorative, spicy offense.
344
+
345
  The output should be formatted as a JSON instance that conforms to the JSON schema below.
346
 
347
  \`\`\`json
348
  {
349
  "properties": {
350
  "rarity": {"type": "string", "enum": ["common", "uncommon", "rare", "legendary"], "description": "Rarity of the original object based on real-world availability and value"},
351
+ "picletType": {"type": "string", "enum": ["beast", "bug", "aquatic", "flora", "mineral", "space", "machina", "structure", "culture", "cuisine"], "description": "The type that best matches this monster's concept, appearance, and nature"},
352
  "height": {"type": "number", "minimum": 0.1, "maximum": 50.0, "description": "Height of the piclet in meters (e.g., 1.2, 0.5, 10.0)"},
353
  "weight": {"type": "number", "minimum": 0.1, "maximum": 10000.0, "description": "Weight of the piclet in kilograms (e.g., 25.4, 150.0, 0.8)"},
354
  "HP": {"type": "integer", "minimum": 0, "maximum": 100, "description": "Health/vitality stat (0=fragile, 100=incredibly tanky)"},
 
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
 
 
418
  const parsedStats = JSON.parse(cleanJson.trim());
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',
src/lib/components/MonsterGenerator/MonsterResult.svelte CHANGED
@@ -1,6 +1,8 @@
1
  <script lang="ts">
2
  import type { MonsterWorkflowState } from '$lib/types';
3
  import { saveMonster } from '$lib/db/monsters';
 
 
4
 
5
  interface Props {
6
  workflowState: MonsterWorkflowState;
@@ -118,6 +120,12 @@
118
  <div class="tier-badge {workflowState.monsterStats.tier}">{workflowState.monsterStats.tier.toUpperCase()}</div>
119
  <span class="stat-label">Tier</span>
120
  </div>
 
 
 
 
 
 
121
  <div class="stat-item">
122
  <div class="stat-bar" style="width: {workflowState.monsterStats.HP}%; background-color: {getStatColor(workflowState.monsterStats.HP)}20"></div>
123
  <span class="stat-label">HP</span>
 
1
  <script lang="ts">
2
  import type { MonsterWorkflowState } from '$lib/types';
3
  import { saveMonster } from '$lib/db/monsters';
4
+ import { TYPE_DATA, PicletType } from '$lib/types/picletTypes';
5
+ import TypeBadge from '$lib/components/UI/TypeBadge.svelte';
6
 
7
  interface Props {
8
  workflowState: MonsterWorkflowState;
 
120
  <div class="tier-badge {workflowState.monsterStats.tier}">{workflowState.monsterStats.tier.toUpperCase()}</div>
121
  <span class="stat-label">Tier</span>
122
  </div>
123
+ {#if (workflowState.monsterStats as any).picletType}
124
+ <div class="stat-item">
125
+ <TypeBadge type={(workflowState.monsterStats as any).picletType as PicletType} showLabel={true} size="medium" />
126
+ <span class="stat-label">Type</span>
127
+ </div>
128
+ {/if}
129
  <div class="stat-item">
130
  <div class="stat-bar" style="width: {workflowState.monsterStats.HP}%; background-color: {getStatColor(workflowState.monsterStats.HP)}20"></div>
131
  <span class="stat-label">HP</span>
src/lib/db/piclets.ts CHANGED
@@ -26,8 +26,16 @@ export async function monsterToPicletInstance(monster: Monster, level: number =
26
 
27
  const maxHp = calculateHp(baseHp, level);
28
 
29
- // Determine primary type based on concept and caption
30
- const primaryType = getTypeFromConcept(monster.concept, monster.imageCaption);
 
 
 
 
 
 
 
 
31
 
32
  // Create moves based on monster's abilities
33
  const moves: BattleMove[] = [
 
26
 
27
  const maxHp = calculateHp(baseHp, level);
28
 
29
+ // Determine primary type - use picletType from stats if available, otherwise auto-detect
30
+ let primaryType: PicletType;
31
+ if (monster.stats && (monster.stats as any).picletType) {
32
+ // Use the type determined during stat generation
33
+ const statsType = (monster.stats as any).picletType as string;
34
+ primaryType = statsType as PicletType;
35
+ } else {
36
+ // Fallback to concept-based detection
37
+ primaryType = getTypeFromConcept(monster.concept, monster.imageCaption);
38
+ }
39
 
40
  // Create moves based on monster's abilities
41
  const moves: BattleMove[] = [