gotchi-generator 1.0.2 → 1.0.4

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A Node.js-based tool for generating individual sprite sheets for Aavegotchi NFTs by compositing multiple trait layers based on their attributes. This project includes both the generation engine and a web-based viewer for browsing the generated sprites.
4
4
 
5
- ![Aavegotchi Sprite Generator Demo](screenshot.gif)
5
+ ![Aavegotchi Sprite Generator Demo](https://unpkg.com/gotchi-generator@latest/screenshot.gif)
6
6
 
7
7
  ## Features
8
8
 
package/dist/index.cjs CHANGED
@@ -21,6 +21,24 @@ function loadGotchis(jsonPath) {
21
21
  const data = fs__default.default.readFileSync(jsonPath, "utf8");
22
22
  return JSON.parse(data);
23
23
  }
24
+ function normalizeAttributes(originalAttributes) {
25
+ const normalized = [];
26
+ let hasPet = originalAttributes.some(
27
+ (attr) => attr.trait_type === "Wearable (Pet)" && attr.value.trim() !== ""
28
+ );
29
+ for (const attr of originalAttributes) {
30
+ if (attr.trait_type === "Wearable (Body)" && attr.value === "Foxy Tail") {
31
+ if (hasPet) {
32
+ continue;
33
+ }
34
+ normalized.push({ trait_type: "Wearable (Pet)", value: attr.value });
35
+ hasPet = true;
36
+ continue;
37
+ }
38
+ normalized.push(attr);
39
+ }
40
+ return normalized;
41
+ }
24
42
  function matchCondition(gotchiAttributes, conditionSet) {
25
43
  const maticMapping = {
26
44
  amUSDT: "aUSDT",
@@ -76,14 +94,15 @@ function getImagePath(basePath, folder, traitValue) {
76
94
  return null;
77
95
  }
78
96
  async function generateSpritesheet(gotchi, config, basePath, outputFolder, verbose = false) {
79
- const matchingConfig = findMatchingConfig(gotchi.attributes, config);
97
+ const attributes = normalizeAttributes(gotchi.attributes);
98
+ const matchingConfig = findMatchingConfig(attributes, config);
80
99
  if (!matchingConfig) {
81
100
  return {
82
101
  success: false,
83
102
  error: "No matching configuration found",
84
103
  details: {
85
104
  // Add a helpful detail for debugging
86
- layersUsed: gotchi.attributes.map((a) => `${a.trait_type}: ${a.value}`)
105
+ layersUsed: attributes.map((a) => `${a.trait_type}: ${a.value}`)
87
106
  }
88
107
  };
89
108
  }
@@ -108,7 +127,7 @@ async function generateSpritesheet(gotchi, config, basePath, outputFolder, verbo
108
127
  const layerBuffers = [];
109
128
  const missingImages = [];
110
129
  const loadErrors = [];
111
- const handWearables = gotchi.attributes.filter(
130
+ const handWearables = attributes.filter(
112
131
  (attr) => attr.trait_type === "Wearable (Hands)"
113
132
  );
114
133
  for (const traitKey of layerOrder) {
@@ -150,7 +169,7 @@ async function generateSpritesheet(gotchi, config, basePath, outputFolder, verbo
150
169
  }
151
170
  } else {
152
171
  if (prop) {
153
- matchingAttributes = gotchi.attributes.filter(
172
+ matchingAttributes = attributes.filter(
154
173
  (attr) => attr.trait_type === traitKey
155
174
  );
156
175
  folder = prop.folder;
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/generate_spritesheets.ts","../src/index.ts"],"names":["fs","path","sharp","fileURLToPath"],"mappings":"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","file":"index.cjs","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport sharp from \"sharp\";\nimport {\n Config,\n ConditionSet,\n Gotchi,\n GotchiAttribute,\n GenerationResult,\n} from \"./types.js\";\n\nfunction loadConfig(configPath: string): Config {\n const data = fs.readFileSync(configPath, \"utf8\");\n return JSON.parse(data) as Config;\n}\n\nfunction loadGotchis(jsonPath: string): Gotchi[] {\n const data = fs.readFileSync(jsonPath, \"utf8\");\n return JSON.parse(data) as Gotchi[];\n}\n\nfunction matchCondition(\n gotchiAttributes: GotchiAttribute[],\n conditionSet: ConditionSet\n): boolean {\n const maticMapping: Record<string, string> = {\n amUSDT: \"aUSDT\",\n amAAVE: \"aAAVE\",\n amDAI: \"aDAI\",\n amUSDC: \"aUSDC\",\n };\n\n for (const condition of conditionSet.keys_and_values || []) {\n const keys = condition.keys || [];\n const values = condition.values || [];\n\n for (const key of keys) {\n if (values.length > 0) {\n const attrValues = gotchiAttributes\n .filter((attr) => attr.trait_type === key)\n .map((attr) => maticMapping[attr.value] || attr.value);\n\n if (!attrValues.some((val) => values.includes(val))) return false;\n } else {\n const hasKey = gotchiAttributes.some((attr) => attr.trait_type === key);\n if (!hasKey) return false;\n }\n }\n }\n return true;\n}\n\nfunction findMatchingConfig(\n gotchiAttributes: GotchiAttribute[],\n config: Config\n): ConditionSet | null {\n for (const conditionSet of config.if_keys_and_values || []) {\n if (matchCondition(gotchiAttributes, conditionSet)) return conditionSet;\n }\n return null;\n}\n\nfunction getImagePath(\n basePath: string,\n folder: string,\n traitValue: string\n): string | null {\n const maticMapping: Record<string, string> = {\n amUSDT: \"aUSDT\",\n amAAVE: \"aAAVE\",\n amDAI: \"aDAI\",\n amUSDC: \"aUSDC\",\n };\n\n const mappedValue = maticMapping[traitValue] || traitValue;\n const traitsBase = path.join(basePath, \"Trait Files\", \"Sprites\");\n const searchPath = path.join(traitsBase, ...folder.split(\"/\"));\n\n const possibleExtensions = [\".png\", \".PNG\", \".jpg\", \".JPG\", \".jpeg\", \".JPEG\"];\n\n for (const ext of possibleExtensions) {\n const imagePath = path.join(searchPath, `${mappedValue}${ext}`);\n if (fs.existsSync(imagePath)) return imagePath;\n }\n\n if (fs.existsSync(searchPath) && fs.statSync(searchPath).isDirectory()) {\n const files = fs.readdirSync(searchPath);\n for (const file of files) {\n const fileName = path.parse(file).name;\n if (fileName.toLowerCase() === mappedValue.toLowerCase()) {\n return path.join(searchPath, file);\n }\n }\n }\n\n return null;\n}\n\nasync function generateSpritesheet(\n gotchi: Gotchi,\n config: Config,\n basePath: string,\n outputFolder: string,\n verbose = false\n): Promise<GenerationResult> {\n const matchingConfig = findMatchingConfig(gotchi.attributes, config);\n\n if (!matchingConfig) {\n return {\n success: false,\n error: \"No matching configuration found\",\n details: {\n // Add a helpful detail for debugging\n layersUsed: gotchi.attributes.map((a) => `${a.trait_type}: ${a.value}`),\n },\n };\n }\n\n const layerOrder = [\n \"Base Body\",\n \"Eye Shape\",\n \"Eye Color\",\n \"Wearable (Body)\",\n \"Wearable (Face)\",\n \"Wearable (Eyes)\",\n \"Wearable (Head)\",\n \"Wearable (Hands) L\",\n \"Wearable (Hands) R\",\n \"Wearable (Pet)\",\n ];\n\n const propertyMap: Record<string, { key: string; folder: string }> = {};\n for (const prop of matchingConfig.properties || []) {\n propertyMap[prop.key] = prop;\n }\n\n let compositeImage: sharp.Sharp | null = null;\n const layersUsed: string[] = [];\n const layerBuffers: { input: Buffer }[] = [];\n const missingImages: string[] = [];\n const loadErrors: string[] = [];\n\n const handWearables = gotchi.attributes.filter(\n (attr) => attr.trait_type === \"Wearable (Hands)\"\n );\n\n for (const traitKey of layerOrder) {\n let prop = propertyMap[traitKey];\n let matchingAttributes: (GotchiAttribute | undefined)[] = [];\n let folder: string | null = null;\n\n if (traitKey === \"Wearable (Hands) L\") {\n prop = propertyMap[\"Wearable (Hands)\"];\n if (prop && handWearables.length > 0) {\n matchingAttributes = [handWearables[0]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) L\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing left hand: ${handWearables[0].value} from ${folder}`\n );\n }\n } else if (traitKey === \"Wearable (Hands) R\") {\n prop = propertyMap[\"Wearable (Hands)\"];\n if (prop && handWearables.length > 1) {\n matchingAttributes = [handWearables[1]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) R\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing right hand: ${handWearables[1].value} from ${folder}`\n );\n } else if (prop && handWearables.length === 1) {\n matchingAttributes = [handWearables[0]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) R\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing single hand item as right: ${handWearables[0].value} from ${folder}`\n );\n }\n } else {\n if (prop) {\n matchingAttributes = gotchi.attributes.filter(\n (attr) => attr.trait_type === traitKey\n );\n folder = prop.folder;\n }\n }\n\n if (!prop || matchingAttributes.length === 0 || !folder) continue;\n\n for (const attr of matchingAttributes) {\n if (!attr) continue;\n const traitValue = attr.value;\n const imagePath = getImagePath(basePath, folder, traitValue);\n\n if (imagePath) {\n try {\n const imageBuffer = await sharp(imagePath).png().toBuffer();\n const metadata = await sharp(imageBuffer).metadata();\n\n if (!compositeImage) {\n compositeImage = sharp({\n create: {\n width: metadata.width as number,\n height: metadata.height as number,\n channels: 4,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n },\n });\n }\n\n layerBuffers.push({ input: imageBuffer });\n const layerLabel =\n traitKey.includes(\"Hands\") && traitKey !== \"Wearable (Hands)\"\n ? `${traitKey}: ${traitValue}`\n : `${attr.trait_type}: ${traitValue}`;\n layersUsed.push(layerLabel);\n if (verbose)\n console.log(` Found and added: ${layerLabel} from ${imagePath}`);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n loadErrors.push(`${traitKey}/${traitValue}: ${message}`);\n if (verbose)\n console.log(\n ` Error loading: ${traitKey}/${traitValue}: ${message}`\n );\n }\n } else if (traitValue) {\n missingImages.push(`${traitKey}/${traitValue} in ${folder}`);\n if (verbose)\n console.log(\n ` Missing image: ${traitKey}/${traitValue} in ${folder}`\n );\n }\n }\n }\n\n if (compositeImage && layerBuffers.length > 0) {\n try {\n const outputPath = path.join(outputFolder, `${gotchi.id}.png`);\n await compositeImage.composite(layerBuffers).png().toFile(outputPath);\n return {\n success: true,\n details: { layersUsed, missingImages, loadErrors },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: `Failed to save spritesheet: ${message}`,\n details: { layersUsed, missingImages, loadErrors },\n };\n }\n } else {\n return {\n success: false,\n error: \"No layers found to composite\",\n details: { layersUsed, missingImages, loadErrors },\n };\n }\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n\n if (args.length < 1) {\n console.log(\n \"Usage: node generate_spritesheets.js <input_json_file> [options]\"\n );\n console.log(\n 'Example: node generate_spritesheets.js \"processedAavegotchis.json\"'\n );\n console.log(\"Options:\");\n console.log(\" --limit <n> Process only first n gotchis\");\n console.log(\n \" --ids <id1,id2> Process only specific IDs (comma-separated)\"\n );\n console.log(\" --start <n> Start processing from gotchi at index n\");\n console.log(\n \" --batch <n> Number of gotchis to process in parallel (default: 10)\"\n );\n console.log(\" --verbose Show detailed layer information\");\n console.log(\"\");\n console.log(\"Example with all gotchis in batches of 20:\");\n console.log(\n ' node generate_spritesheets.js \"processedAavegotchis.json\" --batch 20'\n );\n process.exit(1);\n }\n\n const inputJson = args[0];\n const configFile = \"config.json\";\n const outputFolder = \"website/spritesheets\";\n const basePath = \".\";\n\n let limit: number | null = null;\n let specificIds: number[] | null = null;\n let startIndex = 0;\n let verbose = false;\n\n for (let i = 1; i < args.length; i++) {\n if (args[i] === \"--limit\" && args[i + 1]) {\n limit = parseInt(args[i + 1]);\n i++;\n } else if (args[i] === \"--ids\" && args[i + 1]) {\n specificIds = args[i + 1]\n .split(\",\")\n .map((id) => parseInt(id))\n .filter((n) => !Number.isNaN(n));\n i++;\n } else if (args[i] === \"--start\" && args[i + 1]) {\n startIndex = parseInt(args[i + 1]);\n i++;\n } else if (args[i] === \"--verbose\") {\n verbose = true;\n }\n }\n\n if (!fs.existsSync(inputJson)) {\n console.log(`Error: Input file '${inputJson}' not found`);\n process.exit(1);\n }\n\n if (!fs.existsSync(configFile)) {\n console.log(`Error: Config file '${configFile}' not found`);\n process.exit(1);\n }\n\n if (!fs.existsSync(outputFolder)) {\n fs.mkdirSync(outputFolder, { recursive: true });\n }\n\n console.log(`Loading configuration from ${configFile}...`);\n const config = loadConfig(configFile);\n\n console.log(`Loading gotchis from ${inputJson}...`);\n let gotchis = loadGotchis(inputJson);\n\n if (specificIds) {\n gotchis = gotchis.filter((g) => specificIds!.includes(g.id));\n console.log(`Filtering to ${gotchis.length} specific gotchis`);\n }\n\n if (startIndex > 0) {\n gotchis = gotchis.slice(startIndex);\n console.log(`Starting from index ${startIndex}`);\n }\n\n if (limit) {\n gotchis = gotchis.slice(0, limit);\n console.log(`Limiting to ${gotchis.length} gotchis`);\n }\n\n const batchSize = args.includes(\"--batch\")\n ? parseInt(args[args.indexOf(\"--batch\") + 1]) || 10\n : 10;\n\n console.log(\n `Processing ${gotchis.length} gotchis in batches of ${batchSize}...`\n );\n console.log(\"-\".repeat(50));\n\n let successCount = 0;\n let failCount = 0;\n const failedGotchis: Array<{\n id: number;\n attributes: GotchiAttribute[];\n error: string;\n details?: unknown;\n }> = [];\n const allMissingLayers: Array<{\n gotchiId: number;\n missingLayer: string;\n attributes: GotchiAttribute[];\n }> = [];\n\n for (let i = 0; i < gotchis.length; i += batchSize) {\n const batch = gotchis.slice(i, Math.min(i + batchSize, gotchis.length));\n const batchNum = Math.floor(i / batchSize) + 1;\n const totalBatches = Math.ceil(gotchis.length / batchSize);\n\n console.log(\n `\\nProcessing batch ${batchNum}/${totalBatches} (${batch.length} gotchis)...`\n );\n\n const batchResults = await Promise.all(\n batch.map(async (gotchi, index) => {\n try {\n const result = await generateSpritesheet(\n gotchi,\n config,\n basePath,\n outputFolder,\n verbose\n );\n\n if (\n result.details?.missingImages &&\n result.details.missingImages.length > 0\n ) {\n result.details.missingImages.forEach((missing) => {\n allMissingLayers.push({\n gotchiId: gotchi.id,\n missingLayer: missing,\n attributes: gotchi.attributes,\n });\n });\n }\n\n if (!result.success) {\n console.log(` ✗ Failed gotchi ${gotchi.id}: ${result.error}`);\n return {\n success: false as const,\n gotchi,\n error: result.error ?? \"Unknown error\",\n details: result.details,\n };\n }\n\n if (verbose && result.details) {\n console.log(\n ` ✓ Completed gotchi ${\n gotchi.id\n } - Layers: ${result.details.layersUsed?.join(\", \")}`\n );\n } else {\n console.log(\n ` ✓ Completed gotchi ${gotchi.id} (${i + index + 1}/${\n gotchis.length\n })`\n );\n }\n return { success: true as const, gotchi, details: result.details };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n console.log(` ✗ Error processing gotchi ${gotchi.id}: ${message}`);\n return {\n success: false as const,\n gotchi,\n error: `Unexpected error: ${message}`,\n };\n }\n })\n );\n\n batchResults.forEach((result) => {\n if (result.success) {\n successCount++;\n } else {\n failCount++;\n failedGotchis.push({\n id: result.gotchi.id,\n attributes: result.gotchi.attributes,\n error: result.error,\n details: result.details || {},\n });\n }\n });\n\n console.log(\n `Batch ${batchNum} complete: ${\n batchResults.filter((r) => r.success).length\n } succeeded, ${batchResults.filter((r) => !r.success).length} failed`\n );\n }\n\n console.log(\"\\n\" + \"=\".repeat(50));\n console.log(\"Processing complete!\");\n console.log(`Successfully generated: ${successCount} spritesheets`);\n console.log(`Failed: ${failCount}`);\n console.log(`Output saved to: ${outputFolder}/`);\n\n if (failedGotchis.length > 0) {\n const failedLogPath = \"failed_gotchis.json\";\n fs.writeFileSync(failedLogPath, JSON.stringify(failedGotchis, null, 2));\n console.log(`\\nFailed gotchis logged to: ${failedLogPath}`);\n console.log(\"Failed IDs:\", failedGotchis.map((g) => g.id).join(\", \"));\n }\n\n if (allMissingLayers.length > 0) {\n const missingByItem: Record<\n string,\n { layer: string; count: number; gotchiIds: number[] }\n > = {};\n allMissingLayers.forEach((item) => {\n if (!missingByItem[item.missingLayer]) {\n missingByItem[item.missingLayer] = {\n layer: item.missingLayer,\n count: 0,\n gotchiIds: [],\n };\n }\n missingByItem[item.missingLayer].count++;\n missingByItem[item.missingLayer].gotchiIds.push(item.gotchiId);\n });\n\n const missingLayersSummary = Object.values(missingByItem).sort(\n (a, b) => b.count - a.count\n );\n\n const missingLayersLog = {\n totalMissing: allMissingLayers.length,\n uniqueMissingLayers: missingLayersSummary.length,\n summary: missingLayersSummary,\n detailed: allMissingLayers,\n };\n\n const missingLogPath = \"missing_layers.json\";\n fs.writeFileSync(missingLogPath, JSON.stringify(missingLayersLog, null, 2));\n console.log(`\\nMissing layers logged to: ${missingLogPath}`);\n console.log(`Total missing layer instances: ${allMissingLayers.length}`);\n console.log(`Unique missing layers: ${missingLayersSummary.length}`);\n\n console.log(\"\\nTop missing layers:\");\n missingLayersSummary.slice(0, 5).forEach((item) => {\n console.log(` - ${item.layer} (${item.count} gotchis)`);\n });\n }\n\n try {\n const outputFiles = fs.readdirSync(outputFolder);\n const spriteList = outputFiles\n .filter((fileName) => fileName.toLowerCase().endsWith(\".png\"))\n .map((fileName) => path.parse(fileName).name)\n .filter((baseName) => /^\\d+$/.test(baseName))\n .map((baseName) => ({\n id: parseInt(baseName, 10),\n path: `spritesheets/${baseName}.png`,\n }))\n .sort((a, b) => a.id - b.id);\n\n const listPath = path.join(outputFolder, \"list.json\");\n fs.writeFileSync(listPath, JSON.stringify(spriteList, null, 2));\n console.log(`\\nSprite list written to: ${listPath}`);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(`\\nWarning: Failed to write sprite list: ${message}`);\n }\n}\n\n// Execute only when run directly via tsx/node\nif (import.meta.url === `file://${process.argv[1]}`) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n main().catch((error) => {\n console.error(\"Error:\", error);\n process.exit(1);\n });\n}\n\nexport { generateSpritesheet };\n","import path from \"path\";\nimport { fileURLToPath } from \"url\";\nexport { generateSpritesheet } from \"./generate_spritesheets.js\";\nexport type {\n Gotchi,\n GotchiAttribute,\n Config,\n ConfigProperty,\n ConditionKV,\n ConditionSet,\n GenerationResult,\n GenerationDetails,\n} from \"./types.js\";\nexport function getPackageBasePath(): string {\n const distDirectoryPath = path.dirname(fileURLToPath(import.meta.url));\n return path.resolve(distDirectoryPath, \"..\");\n}\n"]}
1
+ {"version":3,"sources":["../src/generate_spritesheets.ts","../src/index.ts"],"names":["fs","path","sharp","fileURLToPath"],"mappings":"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","file":"index.cjs","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport sharp from \"sharp\";\nimport {\n Config,\n ConditionSet,\n Gotchi,\n GotchiAttribute,\n GenerationResult,\n} from \"./types.js\";\n\nfunction loadConfig(configPath: string): Config {\n const data = fs.readFileSync(configPath, \"utf8\");\n return JSON.parse(data) as Config;\n}\n\nfunction loadGotchis(jsonPath: string): Gotchi[] {\n const data = fs.readFileSync(jsonPath, \"utf8\");\n return JSON.parse(data) as Gotchi[];\n}\n\nfunction normalizeAttributes(\n originalAttributes: GotchiAttribute[]\n): GotchiAttribute[] {\n const normalized: GotchiAttribute[] = [];\n let hasPet = originalAttributes.some(\n (attr) => attr.trait_type === \"Wearable (Pet)\" && attr.value.trim() !== \"\"\n );\n\n for (const attr of originalAttributes) {\n if (attr.trait_type === \"Wearable (Body)\" && attr.value === \"Foxy Tail\") {\n if (hasPet) {\n // Skip mis-slotted Foxy Tail if a proper pet is already present\n continue;\n }\n normalized.push({ trait_type: \"Wearable (Pet)\", value: attr.value });\n hasPet = true;\n continue;\n }\n normalized.push(attr);\n }\n\n return normalized;\n}\n\nfunction matchCondition(\n gotchiAttributes: GotchiAttribute[],\n conditionSet: ConditionSet\n): boolean {\n const maticMapping: Record<string, string> = {\n amUSDT: \"aUSDT\",\n amAAVE: \"aAAVE\",\n amDAI: \"aDAI\",\n amUSDC: \"aUSDC\",\n };\n\n for (const condition of conditionSet.keys_and_values || []) {\n const keys = condition.keys || [];\n const values = condition.values || [];\n\n for (const key of keys) {\n if (values.length > 0) {\n const attrValues = gotchiAttributes\n .filter((attr) => attr.trait_type === key)\n .map((attr) => maticMapping[attr.value] || attr.value);\n\n if (!attrValues.some((val) => values.includes(val))) return false;\n } else {\n const hasKey = gotchiAttributes.some((attr) => attr.trait_type === key);\n if (!hasKey) return false;\n }\n }\n }\n return true;\n}\n\nfunction findMatchingConfig(\n gotchiAttributes: GotchiAttribute[],\n config: Config\n): ConditionSet | null {\n for (const conditionSet of config.if_keys_and_values || []) {\n if (matchCondition(gotchiAttributes, conditionSet)) return conditionSet;\n }\n return null;\n}\n\nfunction getImagePath(\n basePath: string,\n folder: string,\n traitValue: string\n): string | null {\n const maticMapping: Record<string, string> = {\n amUSDT: \"aUSDT\",\n amAAVE: \"aAAVE\",\n amDAI: \"aDAI\",\n amUSDC: \"aUSDC\",\n };\n\n const mappedValue = maticMapping[traitValue] || traitValue;\n const traitsBase = path.join(basePath, \"Trait Files\", \"Sprites\");\n const searchPath = path.join(traitsBase, ...folder.split(\"/\"));\n\n const possibleExtensions = [\".png\", \".PNG\", \".jpg\", \".JPG\", \".jpeg\", \".JPEG\"];\n\n for (const ext of possibleExtensions) {\n const imagePath = path.join(searchPath, `${mappedValue}${ext}`);\n if (fs.existsSync(imagePath)) return imagePath;\n }\n\n if (fs.existsSync(searchPath) && fs.statSync(searchPath).isDirectory()) {\n const files = fs.readdirSync(searchPath);\n for (const file of files) {\n const fileName = path.parse(file).name;\n if (fileName.toLowerCase() === mappedValue.toLowerCase()) {\n return path.join(searchPath, file);\n }\n }\n }\n\n return null;\n}\n\nasync function generateSpritesheet(\n gotchi: Gotchi,\n config: Config,\n basePath: string,\n outputFolder: string,\n verbose = false\n): Promise<GenerationResult> {\n const attributes = normalizeAttributes(gotchi.attributes);\n const matchingConfig = findMatchingConfig(attributes, config);\n\n if (!matchingConfig) {\n return {\n success: false,\n error: \"No matching configuration found\",\n details: {\n // Add a helpful detail for debugging\n layersUsed: attributes.map((a) => `${a.trait_type}: ${a.value}`),\n },\n };\n }\n\n const layerOrder = [\n \"Base Body\",\n \"Eye Shape\",\n \"Eye Color\",\n \"Wearable (Body)\",\n \"Wearable (Face)\",\n \"Wearable (Eyes)\",\n \"Wearable (Head)\",\n \"Wearable (Hands) L\",\n \"Wearable (Hands) R\",\n \"Wearable (Pet)\",\n ];\n\n const propertyMap: Record<string, { key: string; folder: string }> = {};\n for (const prop of matchingConfig.properties || []) {\n propertyMap[prop.key] = prop;\n }\n\n let compositeImage: sharp.Sharp | null = null;\n const layersUsed: string[] = [];\n const layerBuffers: { input: Buffer }[] = [];\n const missingImages: string[] = [];\n const loadErrors: string[] = [];\n\n const handWearables = attributes.filter(\n (attr) => attr.trait_type === \"Wearable (Hands)\"\n );\n\n for (const traitKey of layerOrder) {\n let prop = propertyMap[traitKey];\n let matchingAttributes: (GotchiAttribute | undefined)[] = [];\n let folder: string | null = null;\n\n if (traitKey === \"Wearable (Hands) L\") {\n prop = propertyMap[\"Wearable (Hands)\"];\n if (prop && handWearables.length > 0) {\n matchingAttributes = [handWearables[0]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) L\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing left hand: ${handWearables[0].value} from ${folder}`\n );\n }\n } else if (traitKey === \"Wearable (Hands) R\") {\n prop = propertyMap[\"Wearable (Hands)\"];\n if (prop && handWearables.length > 1) {\n matchingAttributes = [handWearables[1]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) R\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing right hand: ${handWearables[1].value} from ${folder}`\n );\n } else if (prop && handWearables.length === 1) {\n matchingAttributes = [handWearables[0]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) R\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing single hand item as right: ${handWearables[0].value} from ${folder}`\n );\n }\n } else {\n if (prop) {\n matchingAttributes = attributes.filter(\n (attr) => attr.trait_type === traitKey\n );\n folder = prop.folder;\n }\n }\n\n if (!prop || matchingAttributes.length === 0 || !folder) continue;\n\n for (const attr of matchingAttributes) {\n if (!attr) continue;\n const traitValue = attr.value;\n const imagePath = getImagePath(basePath, folder, traitValue);\n\n if (imagePath) {\n try {\n const imageBuffer = await sharp(imagePath).png().toBuffer();\n const metadata = await sharp(imageBuffer).metadata();\n\n if (!compositeImage) {\n compositeImage = sharp({\n create: {\n width: metadata.width as number,\n height: metadata.height as number,\n channels: 4,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n },\n });\n }\n\n layerBuffers.push({ input: imageBuffer });\n const layerLabel =\n traitKey.includes(\"Hands\") && traitKey !== \"Wearable (Hands)\"\n ? `${traitKey}: ${traitValue}`\n : `${attr.trait_type}: ${traitValue}`;\n layersUsed.push(layerLabel);\n if (verbose)\n console.log(` Found and added: ${layerLabel} from ${imagePath}`);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n loadErrors.push(`${traitKey}/${traitValue}: ${message}`);\n if (verbose)\n console.log(\n ` Error loading: ${traitKey}/${traitValue}: ${message}`\n );\n }\n } else if (traitValue) {\n missingImages.push(`${traitKey}/${traitValue} in ${folder}`);\n if (verbose)\n console.log(\n ` Missing image: ${traitKey}/${traitValue} in ${folder}`\n );\n }\n }\n }\n\n if (compositeImage && layerBuffers.length > 0) {\n try {\n const outputPath = path.join(outputFolder, `${gotchi.id}.png`);\n await compositeImage.composite(layerBuffers).png().toFile(outputPath);\n return {\n success: true,\n details: { layersUsed, missingImages, loadErrors },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: `Failed to save spritesheet: ${message}`,\n details: { layersUsed, missingImages, loadErrors },\n };\n }\n } else {\n return {\n success: false,\n error: \"No layers found to composite\",\n details: { layersUsed, missingImages, loadErrors },\n };\n }\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n\n if (args.length < 1) {\n console.log(\n \"Usage: node generate_spritesheets.js <input_json_file> [options]\"\n );\n console.log(\n 'Example: node generate_spritesheets.js \"processedAavegotchis.json\"'\n );\n console.log(\"Options:\");\n console.log(\" --limit <n> Process only first n gotchis\");\n console.log(\n \" --ids <id1,id2> Process only specific IDs (comma-separated)\"\n );\n console.log(\" --start <n> Start processing from gotchi at index n\");\n console.log(\n \" --batch <n> Number of gotchis to process in parallel (default: 10)\"\n );\n console.log(\" --verbose Show detailed layer information\");\n console.log(\"\");\n console.log(\"Example with all gotchis in batches of 20:\");\n console.log(\n ' node generate_spritesheets.js \"processedAavegotchis.json\" --batch 20'\n );\n process.exit(1);\n }\n\n const inputJson = args[0];\n const configFile = \"config.json\";\n const outputFolder = \"website/spritesheets\";\n const basePath = \".\";\n\n let limit: number | null = null;\n let specificIds: number[] | null = null;\n let startIndex = 0;\n let verbose = false;\n\n for (let i = 1; i < args.length; i++) {\n if (args[i] === \"--limit\" && args[i + 1]) {\n limit = parseInt(args[i + 1]);\n i++;\n } else if (args[i] === \"--ids\" && args[i + 1]) {\n specificIds = args[i + 1]\n .split(\",\")\n .map((id) => parseInt(id))\n .filter((n) => !Number.isNaN(n));\n i++;\n } else if (args[i] === \"--start\" && args[i + 1]) {\n startIndex = parseInt(args[i + 1]);\n i++;\n } else if (args[i] === \"--verbose\") {\n verbose = true;\n }\n }\n\n if (!fs.existsSync(inputJson)) {\n console.log(`Error: Input file '${inputJson}' not found`);\n process.exit(1);\n }\n\n if (!fs.existsSync(configFile)) {\n console.log(`Error: Config file '${configFile}' not found`);\n process.exit(1);\n }\n\n if (!fs.existsSync(outputFolder)) {\n fs.mkdirSync(outputFolder, { recursive: true });\n }\n\n console.log(`Loading configuration from ${configFile}...`);\n const config = loadConfig(configFile);\n\n console.log(`Loading gotchis from ${inputJson}...`);\n let gotchis = loadGotchis(inputJson);\n\n if (specificIds) {\n gotchis = gotchis.filter((g) => specificIds!.includes(g.id));\n console.log(`Filtering to ${gotchis.length} specific gotchis`);\n }\n\n if (startIndex > 0) {\n gotchis = gotchis.slice(startIndex);\n console.log(`Starting from index ${startIndex}`);\n }\n\n if (limit) {\n gotchis = gotchis.slice(0, limit);\n console.log(`Limiting to ${gotchis.length} gotchis`);\n }\n\n const batchSize = args.includes(\"--batch\")\n ? parseInt(args[args.indexOf(\"--batch\") + 1]) || 10\n : 10;\n\n console.log(\n `Processing ${gotchis.length} gotchis in batches of ${batchSize}...`\n );\n console.log(\"-\".repeat(50));\n\n let successCount = 0;\n let failCount = 0;\n const failedGotchis: Array<{\n id: number;\n attributes: GotchiAttribute[];\n error: string;\n details?: unknown;\n }> = [];\n const allMissingLayers: Array<{\n gotchiId: number;\n missingLayer: string;\n attributes: GotchiAttribute[];\n }> = [];\n\n for (let i = 0; i < gotchis.length; i += batchSize) {\n const batch = gotchis.slice(i, Math.min(i + batchSize, gotchis.length));\n const batchNum = Math.floor(i / batchSize) + 1;\n const totalBatches = Math.ceil(gotchis.length / batchSize);\n\n console.log(\n `\\nProcessing batch ${batchNum}/${totalBatches} (${batch.length} gotchis)...`\n );\n\n const batchResults = await Promise.all(\n batch.map(async (gotchi, index) => {\n try {\n const result = await generateSpritesheet(\n gotchi,\n config,\n basePath,\n outputFolder,\n verbose\n );\n\n if (\n result.details?.missingImages &&\n result.details.missingImages.length > 0\n ) {\n result.details.missingImages.forEach((missing) => {\n allMissingLayers.push({\n gotchiId: gotchi.id,\n missingLayer: missing,\n attributes: gotchi.attributes,\n });\n });\n }\n\n if (!result.success) {\n console.log(` ✗ Failed gotchi ${gotchi.id}: ${result.error}`);\n return {\n success: false as const,\n gotchi,\n error: result.error ?? \"Unknown error\",\n details: result.details,\n };\n }\n\n if (verbose && result.details) {\n console.log(\n ` ✓ Completed gotchi ${\n gotchi.id\n } - Layers: ${result.details.layersUsed?.join(\", \")}`\n );\n } else {\n console.log(\n ` ✓ Completed gotchi ${gotchi.id} (${i + index + 1}/${\n gotchis.length\n })`\n );\n }\n return { success: true as const, gotchi, details: result.details };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n console.log(` ✗ Error processing gotchi ${gotchi.id}: ${message}`);\n return {\n success: false as const,\n gotchi,\n error: `Unexpected error: ${message}`,\n };\n }\n })\n );\n\n batchResults.forEach((result) => {\n if (result.success) {\n successCount++;\n } else {\n failCount++;\n failedGotchis.push({\n id: result.gotchi.id,\n attributes: result.gotchi.attributes,\n error: result.error,\n details: result.details || {},\n });\n }\n });\n\n console.log(\n `Batch ${batchNum} complete: ${\n batchResults.filter((r) => r.success).length\n } succeeded, ${batchResults.filter((r) => !r.success).length} failed`\n );\n }\n\n console.log(\"\\n\" + \"=\".repeat(50));\n console.log(\"Processing complete!\");\n console.log(`Successfully generated: ${successCount} spritesheets`);\n console.log(`Failed: ${failCount}`);\n console.log(`Output saved to: ${outputFolder}/`);\n\n if (failedGotchis.length > 0) {\n const failedLogPath = \"failed_gotchis.json\";\n fs.writeFileSync(failedLogPath, JSON.stringify(failedGotchis, null, 2));\n console.log(`\\nFailed gotchis logged to: ${failedLogPath}`);\n console.log(\"Failed IDs:\", failedGotchis.map((g) => g.id).join(\", \"));\n }\n\n if (allMissingLayers.length > 0) {\n const missingByItem: Record<\n string,\n { layer: string; count: number; gotchiIds: number[] }\n > = {};\n allMissingLayers.forEach((item) => {\n if (!missingByItem[item.missingLayer]) {\n missingByItem[item.missingLayer] = {\n layer: item.missingLayer,\n count: 0,\n gotchiIds: [],\n };\n }\n missingByItem[item.missingLayer].count++;\n missingByItem[item.missingLayer].gotchiIds.push(item.gotchiId);\n });\n\n const missingLayersSummary = Object.values(missingByItem).sort(\n (a, b) => b.count - a.count\n );\n\n const missingLayersLog = {\n totalMissing: allMissingLayers.length,\n uniqueMissingLayers: missingLayersSummary.length,\n summary: missingLayersSummary,\n detailed: allMissingLayers,\n };\n\n const missingLogPath = \"missing_layers.json\";\n fs.writeFileSync(missingLogPath, JSON.stringify(missingLayersLog, null, 2));\n console.log(`\\nMissing layers logged to: ${missingLogPath}`);\n console.log(`Total missing layer instances: ${allMissingLayers.length}`);\n console.log(`Unique missing layers: ${missingLayersSummary.length}`);\n\n console.log(\"\\nTop missing layers:\");\n missingLayersSummary.slice(0, 5).forEach((item) => {\n console.log(` - ${item.layer} (${item.count} gotchis)`);\n });\n }\n\n try {\n const outputFiles = fs.readdirSync(outputFolder);\n const spriteList = outputFiles\n .filter((fileName) => fileName.toLowerCase().endsWith(\".png\"))\n .map((fileName) => path.parse(fileName).name)\n .filter((baseName) => /^\\d+$/.test(baseName))\n .map((baseName) => ({\n id: parseInt(baseName, 10),\n path: `spritesheets/${baseName}.png`,\n }))\n .sort((a, b) => a.id - b.id);\n\n const listPath = path.join(outputFolder, \"list.json\");\n fs.writeFileSync(listPath, JSON.stringify(spriteList, null, 2));\n console.log(`\\nSprite list written to: ${listPath}`);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(`\\nWarning: Failed to write sprite list: ${message}`);\n }\n}\n\n// Execute only when run directly via tsx/node\nif (import.meta.url === `file://${process.argv[1]}`) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n main().catch((error) => {\n console.error(\"Error:\", error);\n process.exit(1);\n });\n}\n\nexport { generateSpritesheet };\n","import path from \"path\";\nimport { fileURLToPath } from \"url\";\nexport { generateSpritesheet } from \"./generate_spritesheets.js\";\nexport type {\n Gotchi,\n GotchiAttribute,\n Config,\n ConfigProperty,\n ConditionKV,\n ConditionSet,\n GenerationResult,\n GenerationDetails,\n} from \"./types.js\";\nexport function getPackageBasePath(): string {\n const distDirectoryPath = path.dirname(fileURLToPath(import.meta.url));\n return path.resolve(distDirectoryPath, \"..\");\n}\n"]}
package/dist/index.js CHANGED
@@ -12,6 +12,24 @@ function loadGotchis(jsonPath) {
12
12
  const data = fs.readFileSync(jsonPath, "utf8");
13
13
  return JSON.parse(data);
14
14
  }
15
+ function normalizeAttributes(originalAttributes) {
16
+ const normalized = [];
17
+ let hasPet = originalAttributes.some(
18
+ (attr) => attr.trait_type === "Wearable (Pet)" && attr.value.trim() !== ""
19
+ );
20
+ for (const attr of originalAttributes) {
21
+ if (attr.trait_type === "Wearable (Body)" && attr.value === "Foxy Tail") {
22
+ if (hasPet) {
23
+ continue;
24
+ }
25
+ normalized.push({ trait_type: "Wearable (Pet)", value: attr.value });
26
+ hasPet = true;
27
+ continue;
28
+ }
29
+ normalized.push(attr);
30
+ }
31
+ return normalized;
32
+ }
15
33
  function matchCondition(gotchiAttributes, conditionSet) {
16
34
  const maticMapping = {
17
35
  amUSDT: "aUSDT",
@@ -67,14 +85,15 @@ function getImagePath(basePath, folder, traitValue) {
67
85
  return null;
68
86
  }
69
87
  async function generateSpritesheet(gotchi, config, basePath, outputFolder, verbose = false) {
70
- const matchingConfig = findMatchingConfig(gotchi.attributes, config);
88
+ const attributes = normalizeAttributes(gotchi.attributes);
89
+ const matchingConfig = findMatchingConfig(attributes, config);
71
90
  if (!matchingConfig) {
72
91
  return {
73
92
  success: false,
74
93
  error: "No matching configuration found",
75
94
  details: {
76
95
  // Add a helpful detail for debugging
77
- layersUsed: gotchi.attributes.map((a) => `${a.trait_type}: ${a.value}`)
96
+ layersUsed: attributes.map((a) => `${a.trait_type}: ${a.value}`)
78
97
  }
79
98
  };
80
99
  }
@@ -99,7 +118,7 @@ async function generateSpritesheet(gotchi, config, basePath, outputFolder, verbo
99
118
  const layerBuffers = [];
100
119
  const missingImages = [];
101
120
  const loadErrors = [];
102
- const handWearables = gotchi.attributes.filter(
121
+ const handWearables = attributes.filter(
103
122
  (attr) => attr.trait_type === "Wearable (Hands)"
104
123
  );
105
124
  for (const traitKey of layerOrder) {
@@ -141,7 +160,7 @@ async function generateSpritesheet(gotchi, config, basePath, outputFolder, verbo
141
160
  }
142
161
  } else {
143
162
  if (prop) {
144
- matchingAttributes = gotchi.attributes.filter(
163
+ matchingAttributes = attributes.filter(
145
164
  (attr) => attr.trait_type === traitKey
146
165
  );
147
166
  folder = prop.folder;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/generate_spritesheets.ts","../src/index.ts"],"names":["path"],"mappings":"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","file":"index.js","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport sharp from \"sharp\";\nimport {\n Config,\n ConditionSet,\n Gotchi,\n GotchiAttribute,\n GenerationResult,\n} from \"./types.js\";\n\nfunction loadConfig(configPath: string): Config {\n const data = fs.readFileSync(configPath, \"utf8\");\n return JSON.parse(data) as Config;\n}\n\nfunction loadGotchis(jsonPath: string): Gotchi[] {\n const data = fs.readFileSync(jsonPath, \"utf8\");\n return JSON.parse(data) as Gotchi[];\n}\n\nfunction matchCondition(\n gotchiAttributes: GotchiAttribute[],\n conditionSet: ConditionSet\n): boolean {\n const maticMapping: Record<string, string> = {\n amUSDT: \"aUSDT\",\n amAAVE: \"aAAVE\",\n amDAI: \"aDAI\",\n amUSDC: \"aUSDC\",\n };\n\n for (const condition of conditionSet.keys_and_values || []) {\n const keys = condition.keys || [];\n const values = condition.values || [];\n\n for (const key of keys) {\n if (values.length > 0) {\n const attrValues = gotchiAttributes\n .filter((attr) => attr.trait_type === key)\n .map((attr) => maticMapping[attr.value] || attr.value);\n\n if (!attrValues.some((val) => values.includes(val))) return false;\n } else {\n const hasKey = gotchiAttributes.some((attr) => attr.trait_type === key);\n if (!hasKey) return false;\n }\n }\n }\n return true;\n}\n\nfunction findMatchingConfig(\n gotchiAttributes: GotchiAttribute[],\n config: Config\n): ConditionSet | null {\n for (const conditionSet of config.if_keys_and_values || []) {\n if (matchCondition(gotchiAttributes, conditionSet)) return conditionSet;\n }\n return null;\n}\n\nfunction getImagePath(\n basePath: string,\n folder: string,\n traitValue: string\n): string | null {\n const maticMapping: Record<string, string> = {\n amUSDT: \"aUSDT\",\n amAAVE: \"aAAVE\",\n amDAI: \"aDAI\",\n amUSDC: \"aUSDC\",\n };\n\n const mappedValue = maticMapping[traitValue] || traitValue;\n const traitsBase = path.join(basePath, \"Trait Files\", \"Sprites\");\n const searchPath = path.join(traitsBase, ...folder.split(\"/\"));\n\n const possibleExtensions = [\".png\", \".PNG\", \".jpg\", \".JPG\", \".jpeg\", \".JPEG\"];\n\n for (const ext of possibleExtensions) {\n const imagePath = path.join(searchPath, `${mappedValue}${ext}`);\n if (fs.existsSync(imagePath)) return imagePath;\n }\n\n if (fs.existsSync(searchPath) && fs.statSync(searchPath).isDirectory()) {\n const files = fs.readdirSync(searchPath);\n for (const file of files) {\n const fileName = path.parse(file).name;\n if (fileName.toLowerCase() === mappedValue.toLowerCase()) {\n return path.join(searchPath, file);\n }\n }\n }\n\n return null;\n}\n\nasync function generateSpritesheet(\n gotchi: Gotchi,\n config: Config,\n basePath: string,\n outputFolder: string,\n verbose = false\n): Promise<GenerationResult> {\n const matchingConfig = findMatchingConfig(gotchi.attributes, config);\n\n if (!matchingConfig) {\n return {\n success: false,\n error: \"No matching configuration found\",\n details: {\n // Add a helpful detail for debugging\n layersUsed: gotchi.attributes.map((a) => `${a.trait_type}: ${a.value}`),\n },\n };\n }\n\n const layerOrder = [\n \"Base Body\",\n \"Eye Shape\",\n \"Eye Color\",\n \"Wearable (Body)\",\n \"Wearable (Face)\",\n \"Wearable (Eyes)\",\n \"Wearable (Head)\",\n \"Wearable (Hands) L\",\n \"Wearable (Hands) R\",\n \"Wearable (Pet)\",\n ];\n\n const propertyMap: Record<string, { key: string; folder: string }> = {};\n for (const prop of matchingConfig.properties || []) {\n propertyMap[prop.key] = prop;\n }\n\n let compositeImage: sharp.Sharp | null = null;\n const layersUsed: string[] = [];\n const layerBuffers: { input: Buffer }[] = [];\n const missingImages: string[] = [];\n const loadErrors: string[] = [];\n\n const handWearables = gotchi.attributes.filter(\n (attr) => attr.trait_type === \"Wearable (Hands)\"\n );\n\n for (const traitKey of layerOrder) {\n let prop = propertyMap[traitKey];\n let matchingAttributes: (GotchiAttribute | undefined)[] = [];\n let folder: string | null = null;\n\n if (traitKey === \"Wearable (Hands) L\") {\n prop = propertyMap[\"Wearable (Hands)\"];\n if (prop && handWearables.length > 0) {\n matchingAttributes = [handWearables[0]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) L\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing left hand: ${handWearables[0].value} from ${folder}`\n );\n }\n } else if (traitKey === \"Wearable (Hands) R\") {\n prop = propertyMap[\"Wearable (Hands)\"];\n if (prop && handWearables.length > 1) {\n matchingAttributes = [handWearables[1]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) R\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing right hand: ${handWearables[1].value} from ${folder}`\n );\n } else if (prop && handWearables.length === 1) {\n matchingAttributes = [handWearables[0]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) R\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing single hand item as right: ${handWearables[0].value} from ${folder}`\n );\n }\n } else {\n if (prop) {\n matchingAttributes = gotchi.attributes.filter(\n (attr) => attr.trait_type === traitKey\n );\n folder = prop.folder;\n }\n }\n\n if (!prop || matchingAttributes.length === 0 || !folder) continue;\n\n for (const attr of matchingAttributes) {\n if (!attr) continue;\n const traitValue = attr.value;\n const imagePath = getImagePath(basePath, folder, traitValue);\n\n if (imagePath) {\n try {\n const imageBuffer = await sharp(imagePath).png().toBuffer();\n const metadata = await sharp(imageBuffer).metadata();\n\n if (!compositeImage) {\n compositeImage = sharp({\n create: {\n width: metadata.width as number,\n height: metadata.height as number,\n channels: 4,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n },\n });\n }\n\n layerBuffers.push({ input: imageBuffer });\n const layerLabel =\n traitKey.includes(\"Hands\") && traitKey !== \"Wearable (Hands)\"\n ? `${traitKey}: ${traitValue}`\n : `${attr.trait_type}: ${traitValue}`;\n layersUsed.push(layerLabel);\n if (verbose)\n console.log(` Found and added: ${layerLabel} from ${imagePath}`);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n loadErrors.push(`${traitKey}/${traitValue}: ${message}`);\n if (verbose)\n console.log(\n ` Error loading: ${traitKey}/${traitValue}: ${message}`\n );\n }\n } else if (traitValue) {\n missingImages.push(`${traitKey}/${traitValue} in ${folder}`);\n if (verbose)\n console.log(\n ` Missing image: ${traitKey}/${traitValue} in ${folder}`\n );\n }\n }\n }\n\n if (compositeImage && layerBuffers.length > 0) {\n try {\n const outputPath = path.join(outputFolder, `${gotchi.id}.png`);\n await compositeImage.composite(layerBuffers).png().toFile(outputPath);\n return {\n success: true,\n details: { layersUsed, missingImages, loadErrors },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: `Failed to save spritesheet: ${message}`,\n details: { layersUsed, missingImages, loadErrors },\n };\n }\n } else {\n return {\n success: false,\n error: \"No layers found to composite\",\n details: { layersUsed, missingImages, loadErrors },\n };\n }\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n\n if (args.length < 1) {\n console.log(\n \"Usage: node generate_spritesheets.js <input_json_file> [options]\"\n );\n console.log(\n 'Example: node generate_spritesheets.js \"processedAavegotchis.json\"'\n );\n console.log(\"Options:\");\n console.log(\" --limit <n> Process only first n gotchis\");\n console.log(\n \" --ids <id1,id2> Process only specific IDs (comma-separated)\"\n );\n console.log(\" --start <n> Start processing from gotchi at index n\");\n console.log(\n \" --batch <n> Number of gotchis to process in parallel (default: 10)\"\n );\n console.log(\" --verbose Show detailed layer information\");\n console.log(\"\");\n console.log(\"Example with all gotchis in batches of 20:\");\n console.log(\n ' node generate_spritesheets.js \"processedAavegotchis.json\" --batch 20'\n );\n process.exit(1);\n }\n\n const inputJson = args[0];\n const configFile = \"config.json\";\n const outputFolder = \"website/spritesheets\";\n const basePath = \".\";\n\n let limit: number | null = null;\n let specificIds: number[] | null = null;\n let startIndex = 0;\n let verbose = false;\n\n for (let i = 1; i < args.length; i++) {\n if (args[i] === \"--limit\" && args[i + 1]) {\n limit = parseInt(args[i + 1]);\n i++;\n } else if (args[i] === \"--ids\" && args[i + 1]) {\n specificIds = args[i + 1]\n .split(\",\")\n .map((id) => parseInt(id))\n .filter((n) => !Number.isNaN(n));\n i++;\n } else if (args[i] === \"--start\" && args[i + 1]) {\n startIndex = parseInt(args[i + 1]);\n i++;\n } else if (args[i] === \"--verbose\") {\n verbose = true;\n }\n }\n\n if (!fs.existsSync(inputJson)) {\n console.log(`Error: Input file '${inputJson}' not found`);\n process.exit(1);\n }\n\n if (!fs.existsSync(configFile)) {\n console.log(`Error: Config file '${configFile}' not found`);\n process.exit(1);\n }\n\n if (!fs.existsSync(outputFolder)) {\n fs.mkdirSync(outputFolder, { recursive: true });\n }\n\n console.log(`Loading configuration from ${configFile}...`);\n const config = loadConfig(configFile);\n\n console.log(`Loading gotchis from ${inputJson}...`);\n let gotchis = loadGotchis(inputJson);\n\n if (specificIds) {\n gotchis = gotchis.filter((g) => specificIds!.includes(g.id));\n console.log(`Filtering to ${gotchis.length} specific gotchis`);\n }\n\n if (startIndex > 0) {\n gotchis = gotchis.slice(startIndex);\n console.log(`Starting from index ${startIndex}`);\n }\n\n if (limit) {\n gotchis = gotchis.slice(0, limit);\n console.log(`Limiting to ${gotchis.length} gotchis`);\n }\n\n const batchSize = args.includes(\"--batch\")\n ? parseInt(args[args.indexOf(\"--batch\") + 1]) || 10\n : 10;\n\n console.log(\n `Processing ${gotchis.length} gotchis in batches of ${batchSize}...`\n );\n console.log(\"-\".repeat(50));\n\n let successCount = 0;\n let failCount = 0;\n const failedGotchis: Array<{\n id: number;\n attributes: GotchiAttribute[];\n error: string;\n details?: unknown;\n }> = [];\n const allMissingLayers: Array<{\n gotchiId: number;\n missingLayer: string;\n attributes: GotchiAttribute[];\n }> = [];\n\n for (let i = 0; i < gotchis.length; i += batchSize) {\n const batch = gotchis.slice(i, Math.min(i + batchSize, gotchis.length));\n const batchNum = Math.floor(i / batchSize) + 1;\n const totalBatches = Math.ceil(gotchis.length / batchSize);\n\n console.log(\n `\\nProcessing batch ${batchNum}/${totalBatches} (${batch.length} gotchis)...`\n );\n\n const batchResults = await Promise.all(\n batch.map(async (gotchi, index) => {\n try {\n const result = await generateSpritesheet(\n gotchi,\n config,\n basePath,\n outputFolder,\n verbose\n );\n\n if (\n result.details?.missingImages &&\n result.details.missingImages.length > 0\n ) {\n result.details.missingImages.forEach((missing) => {\n allMissingLayers.push({\n gotchiId: gotchi.id,\n missingLayer: missing,\n attributes: gotchi.attributes,\n });\n });\n }\n\n if (!result.success) {\n console.log(` ✗ Failed gotchi ${gotchi.id}: ${result.error}`);\n return {\n success: false as const,\n gotchi,\n error: result.error ?? \"Unknown error\",\n details: result.details,\n };\n }\n\n if (verbose && result.details) {\n console.log(\n ` ✓ Completed gotchi ${\n gotchi.id\n } - Layers: ${result.details.layersUsed?.join(\", \")}`\n );\n } else {\n console.log(\n ` ✓ Completed gotchi ${gotchi.id} (${i + index + 1}/${\n gotchis.length\n })`\n );\n }\n return { success: true as const, gotchi, details: result.details };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n console.log(` ✗ Error processing gotchi ${gotchi.id}: ${message}`);\n return {\n success: false as const,\n gotchi,\n error: `Unexpected error: ${message}`,\n };\n }\n })\n );\n\n batchResults.forEach((result) => {\n if (result.success) {\n successCount++;\n } else {\n failCount++;\n failedGotchis.push({\n id: result.gotchi.id,\n attributes: result.gotchi.attributes,\n error: result.error,\n details: result.details || {},\n });\n }\n });\n\n console.log(\n `Batch ${batchNum} complete: ${\n batchResults.filter((r) => r.success).length\n } succeeded, ${batchResults.filter((r) => !r.success).length} failed`\n );\n }\n\n console.log(\"\\n\" + \"=\".repeat(50));\n console.log(\"Processing complete!\");\n console.log(`Successfully generated: ${successCount} spritesheets`);\n console.log(`Failed: ${failCount}`);\n console.log(`Output saved to: ${outputFolder}/`);\n\n if (failedGotchis.length > 0) {\n const failedLogPath = \"failed_gotchis.json\";\n fs.writeFileSync(failedLogPath, JSON.stringify(failedGotchis, null, 2));\n console.log(`\\nFailed gotchis logged to: ${failedLogPath}`);\n console.log(\"Failed IDs:\", failedGotchis.map((g) => g.id).join(\", \"));\n }\n\n if (allMissingLayers.length > 0) {\n const missingByItem: Record<\n string,\n { layer: string; count: number; gotchiIds: number[] }\n > = {};\n allMissingLayers.forEach((item) => {\n if (!missingByItem[item.missingLayer]) {\n missingByItem[item.missingLayer] = {\n layer: item.missingLayer,\n count: 0,\n gotchiIds: [],\n };\n }\n missingByItem[item.missingLayer].count++;\n missingByItem[item.missingLayer].gotchiIds.push(item.gotchiId);\n });\n\n const missingLayersSummary = Object.values(missingByItem).sort(\n (a, b) => b.count - a.count\n );\n\n const missingLayersLog = {\n totalMissing: allMissingLayers.length,\n uniqueMissingLayers: missingLayersSummary.length,\n summary: missingLayersSummary,\n detailed: allMissingLayers,\n };\n\n const missingLogPath = \"missing_layers.json\";\n fs.writeFileSync(missingLogPath, JSON.stringify(missingLayersLog, null, 2));\n console.log(`\\nMissing layers logged to: ${missingLogPath}`);\n console.log(`Total missing layer instances: ${allMissingLayers.length}`);\n console.log(`Unique missing layers: ${missingLayersSummary.length}`);\n\n console.log(\"\\nTop missing layers:\");\n missingLayersSummary.slice(0, 5).forEach((item) => {\n console.log(` - ${item.layer} (${item.count} gotchis)`);\n });\n }\n\n try {\n const outputFiles = fs.readdirSync(outputFolder);\n const spriteList = outputFiles\n .filter((fileName) => fileName.toLowerCase().endsWith(\".png\"))\n .map((fileName) => path.parse(fileName).name)\n .filter((baseName) => /^\\d+$/.test(baseName))\n .map((baseName) => ({\n id: parseInt(baseName, 10),\n path: `spritesheets/${baseName}.png`,\n }))\n .sort((a, b) => a.id - b.id);\n\n const listPath = path.join(outputFolder, \"list.json\");\n fs.writeFileSync(listPath, JSON.stringify(spriteList, null, 2));\n console.log(`\\nSprite list written to: ${listPath}`);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(`\\nWarning: Failed to write sprite list: ${message}`);\n }\n}\n\n// Execute only when run directly via tsx/node\nif (import.meta.url === `file://${process.argv[1]}`) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n main().catch((error) => {\n console.error(\"Error:\", error);\n process.exit(1);\n });\n}\n\nexport { generateSpritesheet };\n","import path from \"path\";\nimport { fileURLToPath } from \"url\";\nexport { generateSpritesheet } from \"./generate_spritesheets.js\";\nexport type {\n Gotchi,\n GotchiAttribute,\n Config,\n ConfigProperty,\n ConditionKV,\n ConditionSet,\n GenerationResult,\n GenerationDetails,\n} from \"./types.js\";\nexport function getPackageBasePath(): string {\n const distDirectoryPath = path.dirname(fileURLToPath(import.meta.url));\n return path.resolve(distDirectoryPath, \"..\");\n}\n"]}
1
+ {"version":3,"sources":["../src/generate_spritesheets.ts","../src/index.ts"],"names":["path"],"mappings":"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","file":"index.js","sourcesContent":["import fs from \"fs\";\nimport path from \"path\";\nimport sharp from \"sharp\";\nimport {\n Config,\n ConditionSet,\n Gotchi,\n GotchiAttribute,\n GenerationResult,\n} from \"./types.js\";\n\nfunction loadConfig(configPath: string): Config {\n const data = fs.readFileSync(configPath, \"utf8\");\n return JSON.parse(data) as Config;\n}\n\nfunction loadGotchis(jsonPath: string): Gotchi[] {\n const data = fs.readFileSync(jsonPath, \"utf8\");\n return JSON.parse(data) as Gotchi[];\n}\n\nfunction normalizeAttributes(\n originalAttributes: GotchiAttribute[]\n): GotchiAttribute[] {\n const normalized: GotchiAttribute[] = [];\n let hasPet = originalAttributes.some(\n (attr) => attr.trait_type === \"Wearable (Pet)\" && attr.value.trim() !== \"\"\n );\n\n for (const attr of originalAttributes) {\n if (attr.trait_type === \"Wearable (Body)\" && attr.value === \"Foxy Tail\") {\n if (hasPet) {\n // Skip mis-slotted Foxy Tail if a proper pet is already present\n continue;\n }\n normalized.push({ trait_type: \"Wearable (Pet)\", value: attr.value });\n hasPet = true;\n continue;\n }\n normalized.push(attr);\n }\n\n return normalized;\n}\n\nfunction matchCondition(\n gotchiAttributes: GotchiAttribute[],\n conditionSet: ConditionSet\n): boolean {\n const maticMapping: Record<string, string> = {\n amUSDT: \"aUSDT\",\n amAAVE: \"aAAVE\",\n amDAI: \"aDAI\",\n amUSDC: \"aUSDC\",\n };\n\n for (const condition of conditionSet.keys_and_values || []) {\n const keys = condition.keys || [];\n const values = condition.values || [];\n\n for (const key of keys) {\n if (values.length > 0) {\n const attrValues = gotchiAttributes\n .filter((attr) => attr.trait_type === key)\n .map((attr) => maticMapping[attr.value] || attr.value);\n\n if (!attrValues.some((val) => values.includes(val))) return false;\n } else {\n const hasKey = gotchiAttributes.some((attr) => attr.trait_type === key);\n if (!hasKey) return false;\n }\n }\n }\n return true;\n}\n\nfunction findMatchingConfig(\n gotchiAttributes: GotchiAttribute[],\n config: Config\n): ConditionSet | null {\n for (const conditionSet of config.if_keys_and_values || []) {\n if (matchCondition(gotchiAttributes, conditionSet)) return conditionSet;\n }\n return null;\n}\n\nfunction getImagePath(\n basePath: string,\n folder: string,\n traitValue: string\n): string | null {\n const maticMapping: Record<string, string> = {\n amUSDT: \"aUSDT\",\n amAAVE: \"aAAVE\",\n amDAI: \"aDAI\",\n amUSDC: \"aUSDC\",\n };\n\n const mappedValue = maticMapping[traitValue] || traitValue;\n const traitsBase = path.join(basePath, \"Trait Files\", \"Sprites\");\n const searchPath = path.join(traitsBase, ...folder.split(\"/\"));\n\n const possibleExtensions = [\".png\", \".PNG\", \".jpg\", \".JPG\", \".jpeg\", \".JPEG\"];\n\n for (const ext of possibleExtensions) {\n const imagePath = path.join(searchPath, `${mappedValue}${ext}`);\n if (fs.existsSync(imagePath)) return imagePath;\n }\n\n if (fs.existsSync(searchPath) && fs.statSync(searchPath).isDirectory()) {\n const files = fs.readdirSync(searchPath);\n for (const file of files) {\n const fileName = path.parse(file).name;\n if (fileName.toLowerCase() === mappedValue.toLowerCase()) {\n return path.join(searchPath, file);\n }\n }\n }\n\n return null;\n}\n\nasync function generateSpritesheet(\n gotchi: Gotchi,\n config: Config,\n basePath: string,\n outputFolder: string,\n verbose = false\n): Promise<GenerationResult> {\n const attributes = normalizeAttributes(gotchi.attributes);\n const matchingConfig = findMatchingConfig(attributes, config);\n\n if (!matchingConfig) {\n return {\n success: false,\n error: \"No matching configuration found\",\n details: {\n // Add a helpful detail for debugging\n layersUsed: attributes.map((a) => `${a.trait_type}: ${a.value}`),\n },\n };\n }\n\n const layerOrder = [\n \"Base Body\",\n \"Eye Shape\",\n \"Eye Color\",\n \"Wearable (Body)\",\n \"Wearable (Face)\",\n \"Wearable (Eyes)\",\n \"Wearable (Head)\",\n \"Wearable (Hands) L\",\n \"Wearable (Hands) R\",\n \"Wearable (Pet)\",\n ];\n\n const propertyMap: Record<string, { key: string; folder: string }> = {};\n for (const prop of matchingConfig.properties || []) {\n propertyMap[prop.key] = prop;\n }\n\n let compositeImage: sharp.Sharp | null = null;\n const layersUsed: string[] = [];\n const layerBuffers: { input: Buffer }[] = [];\n const missingImages: string[] = [];\n const loadErrors: string[] = [];\n\n const handWearables = attributes.filter(\n (attr) => attr.trait_type === \"Wearable (Hands)\"\n );\n\n for (const traitKey of layerOrder) {\n let prop = propertyMap[traitKey];\n let matchingAttributes: (GotchiAttribute | undefined)[] = [];\n let folder: string | null = null;\n\n if (traitKey === \"Wearable (Hands) L\") {\n prop = propertyMap[\"Wearable (Hands)\"];\n if (prop && handWearables.length > 0) {\n matchingAttributes = [handWearables[0]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) L\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing left hand: ${handWearables[0].value} from ${folder}`\n );\n }\n } else if (traitKey === \"Wearable (Hands) R\") {\n prop = propertyMap[\"Wearable (Hands)\"];\n if (prop && handWearables.length > 1) {\n matchingAttributes = [handWearables[1]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) R\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing right hand: ${handWearables[1].value} from ${folder}`\n );\n } else if (prop && handWearables.length === 1) {\n matchingAttributes = [handWearables[0]];\n const baseFolderParts = prop.folder.split(\"/\");\n baseFolderParts[baseFolderParts.length - 1] = \"Wearable (Hands) R\";\n folder = baseFolderParts.join(\"/\");\n if (verbose)\n console.log(\n ` Processing single hand item as right: ${handWearables[0].value} from ${folder}`\n );\n }\n } else {\n if (prop) {\n matchingAttributes = attributes.filter(\n (attr) => attr.trait_type === traitKey\n );\n folder = prop.folder;\n }\n }\n\n if (!prop || matchingAttributes.length === 0 || !folder) continue;\n\n for (const attr of matchingAttributes) {\n if (!attr) continue;\n const traitValue = attr.value;\n const imagePath = getImagePath(basePath, folder, traitValue);\n\n if (imagePath) {\n try {\n const imageBuffer = await sharp(imagePath).png().toBuffer();\n const metadata = await sharp(imageBuffer).metadata();\n\n if (!compositeImage) {\n compositeImage = sharp({\n create: {\n width: metadata.width as number,\n height: metadata.height as number,\n channels: 4,\n background: { r: 0, g: 0, b: 0, alpha: 0 },\n },\n });\n }\n\n layerBuffers.push({ input: imageBuffer });\n const layerLabel =\n traitKey.includes(\"Hands\") && traitKey !== \"Wearable (Hands)\"\n ? `${traitKey}: ${traitValue}`\n : `${attr.trait_type}: ${traitValue}`;\n layersUsed.push(layerLabel);\n if (verbose)\n console.log(` Found and added: ${layerLabel} from ${imagePath}`);\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n loadErrors.push(`${traitKey}/${traitValue}: ${message}`);\n if (verbose)\n console.log(\n ` Error loading: ${traitKey}/${traitValue}: ${message}`\n );\n }\n } else if (traitValue) {\n missingImages.push(`${traitKey}/${traitValue} in ${folder}`);\n if (verbose)\n console.log(\n ` Missing image: ${traitKey}/${traitValue} in ${folder}`\n );\n }\n }\n }\n\n if (compositeImage && layerBuffers.length > 0) {\n try {\n const outputPath = path.join(outputFolder, `${gotchi.id}.png`);\n await compositeImage.composite(layerBuffers).png().toFile(outputPath);\n return {\n success: true,\n details: { layersUsed, missingImages, loadErrors },\n };\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n return {\n success: false,\n error: `Failed to save spritesheet: ${message}`,\n details: { layersUsed, missingImages, loadErrors },\n };\n }\n } else {\n return {\n success: false,\n error: \"No layers found to composite\",\n details: { layersUsed, missingImages, loadErrors },\n };\n }\n}\n\nasync function main(): Promise<void> {\n const args = process.argv.slice(2);\n\n if (args.length < 1) {\n console.log(\n \"Usage: node generate_spritesheets.js <input_json_file> [options]\"\n );\n console.log(\n 'Example: node generate_spritesheets.js \"processedAavegotchis.json\"'\n );\n console.log(\"Options:\");\n console.log(\" --limit <n> Process only first n gotchis\");\n console.log(\n \" --ids <id1,id2> Process only specific IDs (comma-separated)\"\n );\n console.log(\" --start <n> Start processing from gotchi at index n\");\n console.log(\n \" --batch <n> Number of gotchis to process in parallel (default: 10)\"\n );\n console.log(\" --verbose Show detailed layer information\");\n console.log(\"\");\n console.log(\"Example with all gotchis in batches of 20:\");\n console.log(\n ' node generate_spritesheets.js \"processedAavegotchis.json\" --batch 20'\n );\n process.exit(1);\n }\n\n const inputJson = args[0];\n const configFile = \"config.json\";\n const outputFolder = \"website/spritesheets\";\n const basePath = \".\";\n\n let limit: number | null = null;\n let specificIds: number[] | null = null;\n let startIndex = 0;\n let verbose = false;\n\n for (let i = 1; i < args.length; i++) {\n if (args[i] === \"--limit\" && args[i + 1]) {\n limit = parseInt(args[i + 1]);\n i++;\n } else if (args[i] === \"--ids\" && args[i + 1]) {\n specificIds = args[i + 1]\n .split(\",\")\n .map((id) => parseInt(id))\n .filter((n) => !Number.isNaN(n));\n i++;\n } else if (args[i] === \"--start\" && args[i + 1]) {\n startIndex = parseInt(args[i + 1]);\n i++;\n } else if (args[i] === \"--verbose\") {\n verbose = true;\n }\n }\n\n if (!fs.existsSync(inputJson)) {\n console.log(`Error: Input file '${inputJson}' not found`);\n process.exit(1);\n }\n\n if (!fs.existsSync(configFile)) {\n console.log(`Error: Config file '${configFile}' not found`);\n process.exit(1);\n }\n\n if (!fs.existsSync(outputFolder)) {\n fs.mkdirSync(outputFolder, { recursive: true });\n }\n\n console.log(`Loading configuration from ${configFile}...`);\n const config = loadConfig(configFile);\n\n console.log(`Loading gotchis from ${inputJson}...`);\n let gotchis = loadGotchis(inputJson);\n\n if (specificIds) {\n gotchis = gotchis.filter((g) => specificIds!.includes(g.id));\n console.log(`Filtering to ${gotchis.length} specific gotchis`);\n }\n\n if (startIndex > 0) {\n gotchis = gotchis.slice(startIndex);\n console.log(`Starting from index ${startIndex}`);\n }\n\n if (limit) {\n gotchis = gotchis.slice(0, limit);\n console.log(`Limiting to ${gotchis.length} gotchis`);\n }\n\n const batchSize = args.includes(\"--batch\")\n ? parseInt(args[args.indexOf(\"--batch\") + 1]) || 10\n : 10;\n\n console.log(\n `Processing ${gotchis.length} gotchis in batches of ${batchSize}...`\n );\n console.log(\"-\".repeat(50));\n\n let successCount = 0;\n let failCount = 0;\n const failedGotchis: Array<{\n id: number;\n attributes: GotchiAttribute[];\n error: string;\n details?: unknown;\n }> = [];\n const allMissingLayers: Array<{\n gotchiId: number;\n missingLayer: string;\n attributes: GotchiAttribute[];\n }> = [];\n\n for (let i = 0; i < gotchis.length; i += batchSize) {\n const batch = gotchis.slice(i, Math.min(i + batchSize, gotchis.length));\n const batchNum = Math.floor(i / batchSize) + 1;\n const totalBatches = Math.ceil(gotchis.length / batchSize);\n\n console.log(\n `\\nProcessing batch ${batchNum}/${totalBatches} (${batch.length} gotchis)...`\n );\n\n const batchResults = await Promise.all(\n batch.map(async (gotchi, index) => {\n try {\n const result = await generateSpritesheet(\n gotchi,\n config,\n basePath,\n outputFolder,\n verbose\n );\n\n if (\n result.details?.missingImages &&\n result.details.missingImages.length > 0\n ) {\n result.details.missingImages.forEach((missing) => {\n allMissingLayers.push({\n gotchiId: gotchi.id,\n missingLayer: missing,\n attributes: gotchi.attributes,\n });\n });\n }\n\n if (!result.success) {\n console.log(` ✗ Failed gotchi ${gotchi.id}: ${result.error}`);\n return {\n success: false as const,\n gotchi,\n error: result.error ?? \"Unknown error\",\n details: result.details,\n };\n }\n\n if (verbose && result.details) {\n console.log(\n ` ✓ Completed gotchi ${\n gotchi.id\n } - Layers: ${result.details.layersUsed?.join(\", \")}`\n );\n } else {\n console.log(\n ` ✓ Completed gotchi ${gotchi.id} (${i + index + 1}/${\n gotchis.length\n })`\n );\n }\n return { success: true as const, gotchi, details: result.details };\n } catch (error) {\n const message =\n error instanceof Error ? error.message : String(error);\n console.log(` ✗ Error processing gotchi ${gotchi.id}: ${message}`);\n return {\n success: false as const,\n gotchi,\n error: `Unexpected error: ${message}`,\n };\n }\n })\n );\n\n batchResults.forEach((result) => {\n if (result.success) {\n successCount++;\n } else {\n failCount++;\n failedGotchis.push({\n id: result.gotchi.id,\n attributes: result.gotchi.attributes,\n error: result.error,\n details: result.details || {},\n });\n }\n });\n\n console.log(\n `Batch ${batchNum} complete: ${\n batchResults.filter((r) => r.success).length\n } succeeded, ${batchResults.filter((r) => !r.success).length} failed`\n );\n }\n\n console.log(\"\\n\" + \"=\".repeat(50));\n console.log(\"Processing complete!\");\n console.log(`Successfully generated: ${successCount} spritesheets`);\n console.log(`Failed: ${failCount}`);\n console.log(`Output saved to: ${outputFolder}/`);\n\n if (failedGotchis.length > 0) {\n const failedLogPath = \"failed_gotchis.json\";\n fs.writeFileSync(failedLogPath, JSON.stringify(failedGotchis, null, 2));\n console.log(`\\nFailed gotchis logged to: ${failedLogPath}`);\n console.log(\"Failed IDs:\", failedGotchis.map((g) => g.id).join(\", \"));\n }\n\n if (allMissingLayers.length > 0) {\n const missingByItem: Record<\n string,\n { layer: string; count: number; gotchiIds: number[] }\n > = {};\n allMissingLayers.forEach((item) => {\n if (!missingByItem[item.missingLayer]) {\n missingByItem[item.missingLayer] = {\n layer: item.missingLayer,\n count: 0,\n gotchiIds: [],\n };\n }\n missingByItem[item.missingLayer].count++;\n missingByItem[item.missingLayer].gotchiIds.push(item.gotchiId);\n });\n\n const missingLayersSummary = Object.values(missingByItem).sort(\n (a, b) => b.count - a.count\n );\n\n const missingLayersLog = {\n totalMissing: allMissingLayers.length,\n uniqueMissingLayers: missingLayersSummary.length,\n summary: missingLayersSummary,\n detailed: allMissingLayers,\n };\n\n const missingLogPath = \"missing_layers.json\";\n fs.writeFileSync(missingLogPath, JSON.stringify(missingLayersLog, null, 2));\n console.log(`\\nMissing layers logged to: ${missingLogPath}`);\n console.log(`Total missing layer instances: ${allMissingLayers.length}`);\n console.log(`Unique missing layers: ${missingLayersSummary.length}`);\n\n console.log(\"\\nTop missing layers:\");\n missingLayersSummary.slice(0, 5).forEach((item) => {\n console.log(` - ${item.layer} (${item.count} gotchis)`);\n });\n }\n\n try {\n const outputFiles = fs.readdirSync(outputFolder);\n const spriteList = outputFiles\n .filter((fileName) => fileName.toLowerCase().endsWith(\".png\"))\n .map((fileName) => path.parse(fileName).name)\n .filter((baseName) => /^\\d+$/.test(baseName))\n .map((baseName) => ({\n id: parseInt(baseName, 10),\n path: `spritesheets/${baseName}.png`,\n }))\n .sort((a, b) => a.id - b.id);\n\n const listPath = path.join(outputFolder, \"list.json\");\n fs.writeFileSync(listPath, JSON.stringify(spriteList, null, 2));\n console.log(`\\nSprite list written to: ${listPath}`);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n console.log(`\\nWarning: Failed to write sprite list: ${message}`);\n }\n}\n\n// Execute only when run directly via tsx/node\nif (import.meta.url === `file://${process.argv[1]}`) {\n // eslint-disable-next-line @typescript-eslint/no-floating-promises\n main().catch((error) => {\n console.error(\"Error:\", error);\n process.exit(1);\n });\n}\n\nexport { generateSpritesheet };\n","import path from \"path\";\nimport { fileURLToPath } from \"url\";\nexport { generateSpritesheet } from \"./generate_spritesheets.js\";\nexport type {\n Gotchi,\n GotchiAttribute,\n Config,\n ConfigProperty,\n ConditionKV,\n ConditionSet,\n GenerationResult,\n GenerationDetails,\n} from \"./types.js\";\nexport function getPackageBasePath(): string {\n const distDirectoryPath = path.dirname(fileURLToPath(import.meta.url));\n return path.resolve(distDirectoryPath, \"..\");\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gotchi-generator",
3
- "version": "1.0.2",
3
+ "version": "1.0.4",
4
4
  "description": "Generate sprite sheets for Aavegotchis with viewer",
5
5
  "type": "module",
6
6
  "main": "dist/index.cjs",
@@ -17,6 +17,7 @@
17
17
  "files": [
18
18
  "dist",
19
19
  "README.md",
20
+ "screenshot.gif",
20
21
  "LICENSE",
21
22
  "Trait Files",
22
23
  "config.json"
package/screenshot.gif ADDED
Binary file