# openalice-forge

> Asset factory for procedural world generation — NanoBanana texture gen, tree space-colonisation, PBR planner, VRM/GLTF export, SQLite store, cost ledger.

## At a glance
| field | value |
|---|---|
| kind | `service` |
| priority | `—` |
| default branch | `mvp` |
| last activity | 2026-06-17T17:28:58+00:00 |
| features catalogued | **28** |
| runtime deps declared | **3** |

## Manifest
`.atlas-deps.yml` — parsed cleanly: **yes**

### Runtime deps
- **`openalice-axum-common`** · `other` · via `cargo` — Shared axum + tracing + reqwest plumbing pulled in as a Cargo crate at build time.
- `gemini-api` (external) · `http` · via `OPENROUTER_API_KEY` · _optional_ — PBR planner uses Gemini via OpenRouter to draft material parameters before texture generation.
- `nanobanana-api` (external) · `http` · via `NANOBANANA_API_URL` · _optional_ — Calls NanoBanana 2 (OpenRouter — google/gemini-3.1-flash-image-preview) to generate PBR textures and sprites after operator approval.

### Consumed env
- `PORT`
- `FORGE_DATA_DIR`
- `FORGE_SECRET_KEY`
- `FORGE_TEXTURES_DIR`
- `NANOBANANA_API_URL`
- `OPENROUTER_API_KEY`

### Owns tables
- `categories`
- `asset_definitions`
- `asset_files`
- `world_templates`
- `generation_jobs`
- `cost_log`

### Exposes
- `http_endpoint` — https://forge.blal.pro/v1/*
- `docker_image` — openalice-forge-api

## Env drift

**Code reads, manifest omits (1):**
- `DOMAIN`

**Manifest declares, code unused (3):**
- `NANOBANANA_API_URL`
- `OPENROUTER_API_KEY`
- `PORT`

## Live reachability
- last probe: **up** · `https://forge.blal.pro` · HTTP 200 · 35ms
- uptime 24h: **100.0%**

## Features (28)

### forge/api
- **`forge.api.auth`** — @feature forge.api.dashboard — Embedded static HTML dashboard served at / for browsing registry + triggering generations without a CLI. @feature forge.api.file-preview — Sandboxed asset file preview (GET /v1/files/:id/preview) with double path-traversal guard: id alphabet check + canonicalize-within-data-dir assertion. OpenAlice Forge — Asset Factory for procedural world generation. API: GET  /health                          — service health + stats GET  /v1/registry/categories          — list categories GET  /v1/registry/assets?category=... — list assets in category GET  /v1/registry/assets/:id          — get asset definition GET  /v1/registry/search?q=...        — search assets GET  /v1/costs                        — spending summary  
  *src/main.rs:1*

### forge/batch
- **`forge.batch.mock`** · _experimental_ · since 0.1.0 — Run every registered asset through the mock generator pipeline (planning + dry-run).  
  *src/main.rs:412*

### forge/characters
- **`forge.characters.generate-all`** · _stable_ · since 0.1.0 — Procedurally generate all VRM character texture sets (free, no external APIs).  
  *src/main.rs:737*
- **`forge.characters.texture-plan`** — @feature forge.characters.presets — Seeded character presets (Knight, Elf Mage, Villager) used as quick-start palette for VRM avatar customization without manual config. Scaffold module — character texture pipeline lives behind a feature flag. ![allow(dead_code)] Character Factory — VRM-compatible texture generation. Generates face, hair, outfit textures for VRM avatar customization. NOT generating VRM meshes (VRoid Studio limitation) — only textures. VRM UV layout slots: - Face: eyes, mouth, skin tone, markings - Hair: color, highlights, style details - Body/Outfit: armor, robe, casual, accessories Character = combination of face + hair + outfit textures.  
  *src/generators/character.rs:1*

### forge/dashboard
- **`forge.dashboard.mesh-preview`** · _stable_ · since 0.1.0 — Standalone Three.js GLB viewer for inspecting a single forge mesh in the dashboard.  
  *dashboard/src/components/forge/MeshPreview.tsx:40*
- **`forge.dashboard.scene-preview`** · _stable_ · since 0.1.0 — Three.js viewer that instances meshes per InstanceGroup transforms to render a forge scene.  
  *dashboard/src/components/forge/ScenePreview.tsx:137*

### forge/generate
- **`forge.generate.approve`** · _gated_ · since 0.1.0 — Approval endpoint for a planned job — currently GATED. The Forge is dry-run/mock only (no paid API calls without an explicit, not-yet-built approval gate), so this honestly returns 501 instead of leaving the URL the plan/mock messages advertise as a dead 404.  
  *src/main.rs:333*

### forge/material
- **`forge.material.pbr-planner`** — Wired into HTTP via POST /v1/materials/plan (main::plan_material). Not yet wired into the mesh pipeline. PBR Material generator — albedo + normal + roughness maps. A PBR material = 3 textures generated from ONE description: 1. Albedo (color/diffuse) — base color texture 2. Normal map — surface bumps and detail 3. Roughness map — shiny vs matte areas For anime style: normal maps are subtle, roughness is mostly flat. Realistic: full PBR with detailed normals and roughness variation.  
  *src/generators/material.rs:1*
- **`forge.material.plan`** · _stable_ · since 0.1.0 — Dry-run a PBR material set — fan one description into albedo + normal + roughness map prompts with per-map cost accounting (no API call).  
  *src/main.rs:212*

### forge/mesh
- **`forge.mesh.flora-primitives`** — Extra flora primitives — mushrooms, ferns, lily pads, lavender, rose bushes, ivy, cactus, crystal clusters. Each generator emits one or more [`MeshData`] objects sized to ~30 cm – 1 m so they drop into the existing scene scatter at sensible per-instance scale ranges. Wind-aware variants apply the foliage shader pivot/wind attributes the same way trees do.  
  *src/generators/flora.rs:1*
- **`forge.mesh.procedural-glb`** — @feature forge.mesh.wind-attributes — Per-vertex wind weight + phase (TEXCOORD_1) and pivot/pivot2 custom attributes exported into GLB for two-level foliage shader animation. Procedural mesh generator — FREE, no API calls. Generates low-poly 3D meshes for game assets: - Trees (trunk cylinder + leaf sphere/cone) - Rocks (noise-displaced icosahedron) - Bushes (cluster of spheres) - Props (barrel, crate, fence post) Output: raw vertex/index data, exported to GLB via glTF.  
  *src/generators/mesh.rs:1*
- **`forge.mesh.tree-space-colonization`** — Space Colonization tree generator. Algorithm: 1. Scatter attraction points in a crown envelope (sphere/ellipsoid) 2. Find nearest branch node for each attractor 3. Grow branches toward attractors 4. Remove attractors that are too close to branches 5. Repeat until no attractors remain 6. Generate cylinder mesh for each branch segment 7. Add leaf billboard quads at branch tips Based on: "Modeling Trees with a Space Colonization Algorithm" (Runions, Lane, Prusinkiewicz, 2007)  
  *src/generators/tree.rs:1*

### forge/meshes
- **`forge.meshes.generate-all`** · _stable_ · since 0.1.0 — Procedurally generate all GLB meshes (trees, props, terrain) free of external API cost.  
  *src/main.rs:790*

### forge/pipeline
- **`forge.pipeline.mock-execute`** — @feature forge.pipeline.job-tracking — Generation jobs persisted to SQLite with status progression (running → completed_mock / accepted / rejected); jobs queryable via GET /v1/generate/jobs. Generation pipeline — plan → approve → generate → review. Debug mode: logs every step, mock generates placeholder images.  
  *src/pipeline/mod.rs:1*
- **`forge.pipeline.placeholder-gen`** — Scaffold module — placeholder helpers used by the mock generation flow only. ![allow(dead_code, unused_variables)] Placeholder image generator — colored PNGs for mock mode. Creates visually distinct placeholders per category so you can see what WOULD be generated without spending tokens.  
  *src/generators/placeholder.rs:1*

### forge/registry
- **`forge.registry.list-assets`** · _stable_ · since 0.1.0 — List asset definitions for a registry category (terrain, character, prop, scene...).  
  *src/main.rs:128*
- **`forge.registry.palettes`** — World Palettes — biome-to-asset mapping. A palette defines which assets are used in each biome, so openalice-world can fetch the right textures/sprites.  
  *src/registry/palettes.rs:1*
- **`forge.registry.search`** · _stable_ · since 0.1.0 — Free-text search across registered asset definitions.  
  *src/main.rs:161*
- **`forge.registry.taxonomy`** — @feature forge.registry.asset-definitions — ~55 default asset definitions seeded at boot covering terrain/flora/structures/characters/materials with generation prompts + biome mappings. Asset registry — categories + definitions + taxonomy seeding.  
  *src/registry/mod.rs:1*

### forge/scenes
- **`forge.scenes.compose`** — @feature forge.scenes.instance-groups — Batched instance transform format ([x,y,z,rot_y,scale] per entry) cuts scene JSON ~5× vs per-key objects; maps 1:1 to Three.js InstancedMesh for single-draw-call rendering. Scene composition — JSON specs describing a placed-asset world. A `SceneSpec` lists a biome, lighting, fog, ground material, and a flat array of `Placement` records pointing at GLBs from `/v1/meshes/`. The world engine (or the dashboard preview) loads the JSON, fetches each referenced GLB, and instantiates them at the given transforms. Placement uses a simple "best-candidate" Poisson-disk-ish sampler: tries N random points per slot, picks the one furthest from any existing placement and above the type's `min_dist`. Cheap, gives a natural-looking scatter without true Poisson cost.  
  *src/scenes.rs:1*
- **`forge.scenes.generate-all`** · _stable_ · since 0.1.0 — Build six demo scenes — JSON specs composing mesh GLBs into playable showcase environments.  
  *src/main.rs:836*

### forge/sprite
- **`forge.sprite.billboard-gen`** — Wired into HTTP via POST /v1/sprites/plan (main::plan_sprite) as a dry-run planner. The alpha post-process pipeline ships when generation goes live. Sprite generator — billboards with alpha transparency. Sprites are 2D images with transparent background used as billboards in 3D (trees, bushes, particles, UI icons). Post-processing pipeline: 1. Generate via NanoBanana with alpha prompt 2. Extract alpha channel (threshold-based) 3. Trim transparent borders (auto-crop) 4. Validate: min opacity area > 10% (not empty)  
  *src/generators/sprite.rs:1*
- **`forge.sprite.plan`** · _stable_ · since 0.1.0 — Dry-run a sprite/billboard generation — return the alpha-optimized prompt, single-call cost, and the alpha post-process pipeline (no API call).  
  *src/main.rs:237*

### forge/store
- **`forge.store.sqlite`** — @feature forge.store.cost-ledger — Generation cost ledger: every real API call records tokens + USD spend; GET /v1/costs returns rolling summary for budget tracking. Persistent SQLite store for asset registry, files, jobs, and costs.  
  *src/store/mod.rs:1*

### forge/texture
- **`forge.texture.nanobanana-gen`** — @feature forge.texture.prompt-builder — Style-aware prompt construction (anime/lowpoly/realistic) with tileable-seam and alpha-isolation clauses baked in automatically. Scaffold module — wired up later when NanoBanana generation goes live. ![allow(dead_code, unused_variables)] Texture generator via NanoBanana 2 (Gemini Flash Image Preview). Prompting best practices (from Google + community guides): - Be specific: lighting, texture quality, color palette - State resolution explicitly: "1024x1024" - For tileable: "seamless tileable texture, repeating pattern" - For anime: "anime style, cel-shaded, flat colors, clean lines" - For sprites: "alpha transparent background, centered, top-down view" - Stack requirements: model handles nuance well - Reference real styles: "Studio Ghibli style", "Genshin Impact aesthetic"  
  *src/generators/texture.rs:1*
- **`forge.texture.plan`** · _stable_ · since 0.1.0 — Dry-run a texture generation — return prompt, settings, and cost estimate (no API call).  
  *src/main.rs:185*
- **`forge.texture.procedural-flora`** — @feature forge.texture.tree-atlas — 512×512 RGBA atlas packing bark + leaf + needle into one GLB image slot; one material per tree type, shared across all instances. Procedural alpha texture generation for WoW-style flora. Generates PNG textures with alpha channel for: - Leaf cluster cards (canopy of small leaves on a single quad) - Single leaf shapes (oval, diamond, star, blossom, needle, fan) - Grass blade silhouette Output: RGBA8 PNG, sized 256×256 by default. Cached on disk so we generate once and re-use across all GLBs.  
  *src/generators/texture_gen.rs:1*

### forge/vrm
- **`forge.vrm.procedural-textures`** — @feature forge.vrm.preset-library — Five built-in presets (Knight, Elf Mage, Villager, Dark Warrior, Forest Elf) cover armor/robe/casual outfit archetypes for immediate world population. Scaffold module — full VRM pipeline ships with the character system. ![allow(dead_code)] VRM Character Texture Factory — procedural textures for VRM avatars. Generates face, hair, outfit textures as colored PNGs. No API calls — pure procedural image generation via `image` crate. openalice-world has base VRM models (male.vrm, female.vrm). We generate textures to apply on them for character customization.  
  *src/generators/vrm.rs:1*

---

*Generated by [openalice-atlas](https://atlas.blal.pro) — single source of truth for the openalicelabs ecosystem.*
