poqpoq World Integration
Scatter vegetation inside your world. One click to landscape. One click to deploy.
How It Works
Landscaper runs standalone or as an embedded iframe inside poqpoq World. When embedded, it communicates with the parent World app via postMessage — receiving terrain data and sending vegetation manifests back.
The app automatically detects embedding by checking window.self !== window.top. When embedded:
- The splash screen is skipped — Landscaper initializes immediately
- Save to World, Open Terraformer, and Return to World buttons appear
- Terrain data arrives from the parent via postMessage
- Manifests are sent back to the parent for persistence
Integration Tiers
🌐 Tier 2 — Dedicated App
World opens Landscaper in a modal iframe. Full UI. All tools available. User paints trees, scatters forests, fine-tunes with brushes. Save sends the manifest back to World.
Best for: Detailed landscape design with full creative control.
⚡ Tier 1 — Quick Plant
World imports Landscaper as a library and calls ScatterSystem.scatter() directly. No iframe, no separate UI. One-click "plant trees" button in the World build panel.
Best for: Quick vegetation with minimal user interaction.
PostMessage Protocol
Landscaper → World
| Message Type | Payload | When Sent |
|---|---|---|
ready | { version: "0.1.0" } | App initializes in embedded mode |
save-manifest | { manifest: LandscaperManifest } | User clicks Save to World |
request-terraformer | {} | User clicks Open Terraformer |
close | {} | User clicks Return to World |
World → Landscaper
| Message Type | Payload | Purpose |
|---|---|---|
init-context | { instanceId, regionBounds, existingManifest } | Initialize with world context |
terrain-data | { heightmapUrl, resolution, regionSize } | Pass terrain heightmap data |
Message Format
// All messages follow this structure
{
"source": "blackbox-landscaper",
"type": "save-manifest",
"payload": {
"manifest": { ... }
}
}
// Sent via:
window.parent.postMessage(JSON.stringify(message), '*')
World Mode Workflow
- World opens Landscaper — Embedded in an iframe with terrain context passed via postMessage
- Landscape the terrain — Scatter vegetation layers, paint with brushes, apply constraints
- Save to World — Click the button. Landscaper packages the vegetation manifest and sends it to the parent via postMessage
- World receives manifest — The World app processes the manifest and populates the scene with matching vegetation
Standalone vs World Mode
| Feature | Standalone | World Mode |
|---|---|---|
| Access | Direct URL | Launched from World iframe |
| Splash screen | Shown (click to start) | Skipped (auto-initialize) |
| Save to World | Hidden | Visible |
| JSON download | Available | Available |
| All scatter tools | Available | Available |
| All brush modes | Available | Available |
Listen for the ready message to know when Landscaper has initialized. Then send init-context with the world instance ID, region bounds, and any existing manifest to restore. See the source code for the full protocol specification.