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.


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.
| Aspect | Description |
|---|---|
| Input | Text prompt, image URL, or reference to another asset |
| Output | Binary artifacts (images, models, audio files, splats) |
| Types | 15+ specialized pipelines for different content |
| State | Track 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:
| Type | Description | Use Case |
|---|---|---|
character | AI-generated character from prompt or image | NPCs, companions, avatars |
sceneImage | 2D scene/background image | Static environments, level art |
scene360 | 360° panoramic scene | Immersive environments |
sceneSplat | 3D Gaussian splat from reference | Volumetric 3D scenes |
model | 3D mesh model | Props, objects, items |
characterRender | Rendered character from preview + spritesheet | Animated character rigs |
item | In-world item asset | Pickups, inventory, marketplace |
sprite | 2D sprite asset | Top-down and platformer characters |
mob | Mobile entity (enemy/NPC sprite) | Game enemies, critters |
music | AI-generated music track | Ambient soundscapes, themes |
soundEffect | Short audio clip | UI, actions, ambience |
voice | Voice assets for cloning (see client.voices) | NPC speech, narration |
image | Generic image generation | Art, thumbnails, social content |
video | AI-generated video clip | Cutscenes, 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 --> Error1. 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
| State | Description |
|---|---|
pending | Job created, waiting in queue |
processing | Pipeline is running |
complete / done | Complete—output assets are ready |
error | Failed—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
| refType | Typical refId | Use Case |
|---|---|---|
npc | NPC UUID | Character for an NPC |
level | Level/map/stage ID | Scene for a world |
project | Project name | Wiki, blog, web project |
character | Character ID | Render 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:
| Feature | Description |
|---|---|
| List | All your generations, filterable by type and state |
| Create | Start new generations with type, prompt, and options |
| Progress | Live progress for pending/processing jobs |
| Retry | Retry failed generations with one click |
| Use | Copy asset URLs, link to NPCs, place in worlds |

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"| EventsAPISDK 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}`);
}