# @playcademy/tile-gen

A command-line tool to generate pixel-art tilesets, asset packs, and character sprites using generative AI.

This tool supports both individual asset generation (using descriptions) and comprehensive pack generation (using themes) for different workflows.

## Prerequisites

You will need API keys for:

- **Retro Diffusion:** Set the `RETRO_DIFFUSION_API_KEY` environment variable or provide it via the `--retroKey` option.
- **Google Gemini:** Set the `GEMINI_API_KEY` environment variable or provide it via the `--geminiKey` option.

## Installation / Usage (via NPX)

This package is intended to be used directly via `npx` or `bunx` without explicit installation:

```bash
# Ensure API keys are set in your environment or use CLI options
npx @playcademy/tile-gen <command> [options]
```

### Commands

- **`generate texture`**: Generate seamless ground textures/tiles (default: 1 tile)
- **`generate item`**: Generate small props with transparent backgrounds (default: 1 item)
- **`generate object`**: Generate large environmental objects (default: 1 object)
- **`generate asset`**: Generate general-purpose game assets (default: 1 asset)
- **`generate character`**: Generate 4-directional walking character spritesheet
- **`generate texture-pack`**: Generate stitched texture collections for tilemap editors
- **`generate world-pack`**: Generate complete themed asset packs using bucket system
- **`plan world-pack`**: Preview asset generation plan without consuming credits

Run `npx @playcademy/tile-gen --help` for detailed options for each command.

### Examples

```bash
# Make sure RETRO_DIFFUSION_API_KEY and GEMINI_API_KEY are set

# === Asset Generation ===

# Generate a single seamless ground texture
npx @playcademy/tile-gen generate texture --description "volcanic ash"

# Generate multiple small props
npx @playcademy/tile-gen generate item --description "wooden crate" --count 5

# Generate a large environmental object
npx @playcademy/tile-gen generate object --description "ancient stone pillar"

# Generate general assets without constraints
npx @playcademy/tile-gen generate asset --description "glowing orb"

# Generate a walking character spritesheet
npx @playcademy/tile-gen generate character --description "brave knight from medieval fantasy"

# === Asset Packs ===

# Generate stitched texture collection for tilemap editors
npx @playcademy/tile-gen generate texture-pack --theme "ancient stone ruins"

# Generate complete world asset pack using bucket system
npx @playcademy/tile-gen generate world-pack --theme "ancient desert oasis"

# Generate world pack with custom bucket configuration
npx @playcademy/tile-gen generate world-pack --theme "steampunk city" --config ./my_buckets.json

# Preview the asset plan before generation
npx @playcademy/tile-gen plan world-pack --theme "cyberpunk metropolis"
```

## Asset vs Pack Generation

### When to Use Asset Commands

Perfect for rapid iteration and specific needs:

```bash
# Quick texture for prototyping
generate texture --description "alien landscape"

# Need some props for scene decoration
generate item --description "wooden crate" --count 3

# One specific large object
generate object --description "crashed spaceship"

# Flexible asset generation
generate asset --description "glowing orb"
```

**Benefits:**

- Fast single-asset generation using specific descriptions
- Default count of 1 for immediate results
- Can scale up with `--count N` for multiple variants
- Individual PNG files for immediate use
- No planning overhead - direct prompt-to-image generation

### When to Use Pack Commands

Perfect for comprehensive collections and tilemap workflows:

```bash
# Stitched texture collection for tilemap editors
generate texture-pack --theme "volcanic landscape"

# Complete asset collection for a game level
generate world-pack --theme "haunted swampland"
```

**Benefits:**

- **Texture-pack**: Stitched spritesheets + TSX files for Tiled/Godot
- **World-pack**: Structured, well-rounded asset coverage with manifest files
- Uses AI planning to expand themes into comprehensive asset lists
- Bucket-based categorization ensures variety
- Optimized for complete world-building workflows

## Custom Buckets (World Pack Generation)

The `generate world-pack` command allows you to define custom asset categories, sizes, and counts using a JSON configuration file passed via the `--config` option. This gives you fine-grained control over the types of assets generated for your world pack.

The JSON file should contain an array of "bucket" objects, where each object adheres to the `AssetBucketSpec` structure. Key fields include:

- `id`: A unique identifier for the bucket (e.g., "terrain", "buildings", "foliage").
- `description`: A brief description of the assets in this bucket.
- `sizes`: An array of `[width, height]` tuples defining the possible dimensions for assets in this bucket.
- `context`: Additional instructions for the AI when generating asset names for this bucket.
- `transparentBackground`: Boolean indicating if assets in this bucket should have a transparent background.
- `count`: The target number of assets to generate for this bucket.

**Example `my_buckets.json`:**

```json
[
    {
        "id": "terrain_base",
        "description": "Repeating base ground textures",
        "sizes": [[64, 64]],
        "transparentBackground": false,
        "context": "Must be seamless, repeatable ground textures like grass, dirt, sand, stone.",
        "count": 4
    },
    {
        "id": "foliage_details",
        "description": "Small plants and details",
        "sizes": [
            [64, 64],
            [128, 128]
        ],
        "transparentBackground": true,
        "context": "Small standalone plants, flowers, or moss patches.",
        "count": 12
    },
    {
        "id": "ancient_ruins",
        "description": "Broken walls, pillars, statues",
        "sizes": [
            [64, 128],
            [128, 128]
        ],
        "transparentBackground": true,
        "context": "Fragments of ancient stone structures suitable for an oasis ruin theme.",
        "count": 8
    }
]
```

Refer to the `DEFAULT_BUCKETS` definition in [`src/config/buckets.ts`](src/config/buckets.ts) for the default structure used when no `--config` is provided.

## Development

1.  Clone the repository.
2.  Install dependencies:
    ```bash
    bun install
    ```
3.  Navigate to `packages/tile-gen`.
4.  Set up environment variables (copy `.env.example` to `.env` and fill in your API keys).
5.  Build the package:
    ```bash
    bun run build
    ```
6.  Test the local CLI build:
    ```bash
    # From within packages/tile-gen directory
    npx . --theme "test-theme"
    ```

## Programmatic Usage

The core logic is available for programmatic use with two usage patterns:

### Core Functions (Return Base64 Data)

Pure generation functions that return base64 data without filesystem operations or logging:

```typescript
import {
    generateAsset,
    generateCharacter,
    generateItem,
    generateObject,
    generateTexture,
} from '@playcademy/tile-gen'

// Generate a single texture - returns base64 data
const textureResults = await generateTexture({
    theme: 'volcanic ash',
    count: 1,
    size: 64,
    // No outDir - returns data instead of saving
})
// textureResults = [{ base64: 'iVBORw0KGgoAAAANSUhEUgAA...', filename: 'volcanic_ash.png' }]

// Generate multiple items
const itemResults = await generateItem({
    theme: 'wooden crate',
    count: 3,
    size: 64,
})
// itemResults = [
//   { base64: 'iVBORw0KGgoAAAANSUhEUgAA...', filename: 'wooden_crate_001.png' },
//   { base64: 'iVBORw0KGgoAAAANSUhEUgAA...', filename: 'wooden_crate_002.png' },
//   { base64: 'iVBORw0KGgoAAAANSUhEUgAA...', filename: 'wooden_crate_003.png' }
// ]

// Generate object with custom size
const objectResults = await generateObject({
    theme: 'ancient stone pillar',
    size: 128, // Larger size for objects
})

// Generate asset with seamless option
const assetResults = await generateAsset({
    theme: 'glowing orb',
    seamless: true,
    count: 2,
})

// Generate character spritesheet
const characterResults = await generateCharacter({
    description: 'brave knight from medieval fantasy',
})
// characterResults = [{ base64: 'iVBORw0KGgoAAAANSUhEUgAA...', filename: 'brave_knight_from_medieval_fantasy_sprite_sheet.png' }]
```

### CLI Wrapper Functions (Include Logging & File Saving)

Full CLI experience with progress logging and automatic file saving:

```typescript
import {
    generateAssetCLI,
    generateCharacterCLI,
    generateItemCLI,
    generateObjectCLI,
    generateTextureCLI,
    generateTexturePack,
    generateWorldPack,
} from '@playcademy/tile-gen'

// === Asset Generation (with CLI features) ===

// Generate texture with progress logging and file saving
await generateTextureCLI({
    theme: 'volcanic ash',
    count: 1,
    size: 64,
    outDir: './output', // Will save to filesystem
})

// Generate items with logging
await generateItemCLI({
    theme: 'wooden crate',
    count: 3,
    outDir: './assets',
})

// Generate object with logging
await generateObjectCLI({
    theme: 'ancient stone pillar',
    outDir: './objects',
})

// Generate assets with seamless option
await generateAssetCLI({
    theme: 'glowing orb',
    seamless: true,
    outDir: './assets',
})

// Generate character spritesheet
await generateCharacterCLI({
    description: 'brave knight',
    outDir: './characters',
})

// === Pack Generation ===

// Generate texture pack with logging
await generateTexturePack({
    theme: 'mystical forest',
    tileSize: 32,
    outDir: './output',
})

// Generate world asset pack with logging
await generateWorldPack({
    theme: 'cyberpunk city',
    outDir: './assets',
})
```

### When to Use Each Approach

**Use Core Functions When:**

- Building web applications that display images directly
- Processing images in memory without saving
- Building pipelines that transform images before saving
- You want minimal dependencies and no console output

**Use CLI Wrapper Functions When:**

- Building desktop applications or CLI tools
- You want progress indicators and user feedback
- You need automatic file organization and saving
- Prototyping or direct file-based workflows

See [`src/index.ts`](src/index.ts) for the complete list of available exports.

## Dependencies

This package now uses the official [`@superbuilders/retrodiffusion`](https://www.npmjs.com/package/@superbuilders/retrodiffusion) TypeScript SDK for reliable and efficient communication with the Retro Diffusion API.
