Upstreet Docs
    Platform

    Deep dive into the AI-powered generative pipeline—characters, scenes, music, 3D models, and more. From prompt to asset in one API call.

    Generations

    Turn imagination into reality—AI-powered content creation that brings your virtual world to life.

    Generations are the heart of Upstreet's creative engine. Describe what you want in text or with a reference image—characters, scenes, music, 3D models, sprites, voices, videos—and our AI pipelines transform your vision into playable assets, ready for worlds, NPCs, and the marketplace.

    Hero: floating holographic character silhouettes emerging from a glowing AI core, cyberpunk digital art

    Generated character preview in a neon-lit showcase, stylized 3D avatar


    What Are Generations?

    Generations are AI-powered content creation tasks. You provide a prompt (and optionally a reference image), choose a type, and the platform runs a specialized pipeline to produce a finished asset stored in the platform.

    Every character you meet, every scene you explore, every item you pick up—many of these started as a generation. The pipeline takes your creative intent and transforms it into binary assets stored in the platform, ready for use in worlds, NPCs, and the marketplace.

    AspectDescription
    InputText prompt, image URL, or reference to another asset
    OutputBinary artifacts (images, models, audio files, splats)
    Types15+ specialized pipelines for different content
    StateTrack progress from pending → processing → complete/error

    Generation Types

    Every generation has a type that determines the pipeline, input format, and output format. Use the right type for the asset you want:

    TypeDescriptionUse Case
    characterAI-generated character from prompt or imageNPCs, companions, avatars
    sceneImage2D scene/background imageStatic environments, level art
    scene360360° panoramic sceneImmersive environments
    sceneSplat3D Gaussian splat from referenceVolumetric 3D scenes
    model3D mesh modelProps, objects, items
    characterRenderRendered character from preview + spritesheetAnimated character rigs
    itemIn-world item assetPickups, inventory, marketplace
    sprite2D sprite assetTop-down and platformer characters
    mobMobile entity (enemy/NPC sprite)Game enemies, critters
    musicAI-generated music trackAmbient soundscapes, themes
    soundEffectShort audio clipUI, actions, ambience
    voiceVoice assets for cloning (see client.voices)NPC speech, narration
    imageGeneric image generationArt, thumbnails, social content
    videoAI-generated video clipCutscenes, previews

    Character, sprite, mob, item, and image produce 2D visuals. Use character for NPCs and companions. Sprites and mobs are optimized for top-down and platformer game modes. Items are in-world collectibles.

    Music and soundEffect generate audio. Music supports prompt and optional musicLengthMs. Sound effects are short clips for actions and ambience. Voice cloning uses client.voices (separate from generations) for NPC speech.

    sceneImage, scene360, and sceneSplat create environment assets. Splats produce Gaussian splat clouds for real-time 3D. characterRender turns a character preview + spritesheet into a renderable 3D representation. model produces 3D meshes for props and objects.


    The Generation Lifecycle

    Generations follow a clear path from creation to completion: prompt/input → create → processing → complete/error.

    flowchart LR
        subgraph input [Input]
            Prompt["Prompt / Image URL"]
            Ref["refType + refId"]
        end
    
        subgraph pipeline [Pipeline]
            Create["1. Create"]
            Process["2. Processing"]
            Complete["3. Complete"]
            Error["3. Error"]
        end
    
        Prompt --> Create
        Ref --> Create
        Create --> Process
        Process --> Complete
        Process --> Error

    1. Prompt / Input

    Provide a text prompt, image URL, or reference to another asset. Many types support smartPrompt for AI-enhanced prompts.

    2. Create

    Call client.generations.create() with type, input, and optional refType/refId. You receive a generation ID immediately.

    3. Processing

    The platform queues your job and runs the appropriate AI pipeline. Generation state moves from pending to processing.

    4. Complete or Error

    When done, the state is complete (API: done) and output contains the asset URLs. On failure, state is error and error holds the message. Use retry() to create a new attempt.


    Generation States

    StateDescription
    pendingJob created, waiting in queue
    processingPipeline is running
    complete / doneComplete—output assets are ready
    errorFailed—check error field; use retry() to retry

    The API uses done for completed generations. The web app and SDK surface this as "complete" in the UI.


    Streaming Generation Progress

    Track progress in real time with events and logs.

    Per-Generation Logs (SSE)

    Listen to a single generation's log stream:

    import { PUClient } from 'pu-client';
    
    const client = new PUClient({ apiKey: process.env.PU_API_KEY! });
    
    const id = await client.generations.create({
      type: 'character',
      input: { prompt: 'A wise owl wizard in robes' },
    });
    
    const { events, unsubscribe } = client.generations.listen(id);
    
    events.addEventListener('change', (e: MessageEvent) => {
      const detail = e.data;
      console.log('Progress:', detail);
    });
    
    events.addEventListener('error', (e: MessageEvent) => {
      console.error('Stream error:', e.data);
    });
    
    // When done, stop listening
    unsubscribe();

    Global Events (Subscribe)

    Subscribe to all generation updates, optionally filtered by refType and refId:

    const channel = client.generations.subscribe({ refType: 'npc', refId: 'my-npc-id' });
    
    channel.addEventListener('update', (e: MessageEvent) => {
      const { generation } = e.data;
      console.log(`${generation.type} ${generation.id}: ${generation.state}`);
    });
    
    // Unsubscribe when done
    channel.unsubscribe();

    Smart Prompts

    Smart prompts use AI to enhance your text before sending it to the generation pipeline. Enable with smartPrompt: true in the input.

    When you pass a short or vague prompt, the platform can expand it into a richer, more detailed description optimized for the chosen generation type. This improves output quality without requiring you to write lengthy prompts.

    const id = await client.generations.create({
      type: 'sceneImage',
      input: {
        prompt: 'cozy cabin in snow',
        smartPrompt: true,
      },
    });

    Reference Types (refType / refId)

    Link generations to other entities using refType and refId. This enables:

    • Filtering — Subscribe to events for a specific NPC, level, or project
    • Attribution — Know which entity a generation belongs to
    • UI grouping — The generations page can show assets by parent
    refTypeTypical refIdUse Case
    npcNPC UUIDCharacter for an NPC
    levelLevel/map/stage IDScene for a world
    projectProject nameWiki, blog, web project
    characterCharacter IDRender or variant of a character
    const id = await client.generations.create({
      type: 'character',
      input: { prompt: 'Merchant with a satchel' },
      refType: 'npc',
      refId: npc.id,
    });

    The Generations Page

    The web app provides a unified interface at /generations:

    FeatureDescription
    ListAll your generations, filterable by type and state
    CreateStart new generations with type, prompt, and options
    ProgressLive progress for pending/processing jobs
    RetryRetry failed generations with one click
    UseCopy asset URLs, link to NPCs, place in worlds

    Placeholder: Generations dashboard showing list of character, scene, and music generations with status badges


    Generation Pipeline Diagram

    flowchart TB
        subgraph client [Client]
            SDK["pu-client SDK"]
            WebApp["Web App /generations"]
        end
    
        subgraph api [API]
            CreateAPI["POST /api/tasks/generationNext/{type}"]
            EventsAPI["GET /api/generations/events"]
            LogsAPI["GET /api/generations/{id}/logs"]
        end
    
        subgraph workers [AI Workers]
            CharWorker["Character Pipeline"]
            SceneWorker["Scene Pipelines"]
            AudioWorker["Audio Pipelines"]
            ImageWorker["Image Pipelines"]
        end
    
        subgraph storage [Storage]
            Assets["Asset Storage"]
        end
    
        SDK --> CreateAPI
        WebApp --> CreateAPI
        SDK --> EventsAPI
        SDK --> LogsAPI
        CreateAPI --> CharWorker
        CreateAPI --> SceneWorker
        CreateAPI --> AudioWorker
        CreateAPI --> ImageWorker
    
        CharWorker --> Assets
        SceneWorker --> Assets
        AudioWorker --> Assets
        ImageWorker --> Assets
    
        CharWorker -.->|"emit"| EventsAPI
        SceneWorker -.->|"emit"| EventsAPI
        AudioWorker -.->|"emit"| EventsAPI
        ImageWorker -.->|"emit"| EventsAPI

    SDK Code Examples

    Create a character

    import { PUClient } from 'pu-client';
    
    const client = new PUClient({ apiKey: process.env.PU_API_KEY! });
    
    const id = await client.generations.create({
      type: 'character',
      input: {
        prompt: 'A steampunk fox inventor with goggles',
        smartPrompt: true,
      },
    });
    
    console.log(`Generation started: ${id}`);

    Create a scene from an image

    const id = await client.generations.create({
      type: 'sceneSplat',
      input: {
        splatUrl: 'https://example.com/reference-room.jpg',
      },
    });

    Create music

    const id = await client.generations.create({
      type: 'music',
      input: {
        prompt: 'Ambient forest with soft piano, 2 minutes',
        musicLengthMs: 120000,
      },
    });

    Create a video

    const id = await client.generations.create({
      type: 'video',
      input: {
        prompt: 'A dragon flying over a mountain at sunset',
      },
    });

    List and retry failed generations

    const generations = await client.generations.list();
    const failed = generations.filter(g => g.state === 'error');
    
    for (const g of failed) {
      const newId = await client.generations.retry(g.id);
      console.log(`Retrying ${g.id} as ${newId}`);
    }

    Next Steps