dreamcore-palace-3d

Community@rain/dreamcore-palace-3d
Community skill — not reviewed. It was shared by caramel pudding and has not been checked by Neta. Read SKILL.md below before letting an agent use it.
Use it in Cohub

Paste this into your agent's chat — it fetches the skill and follows it.

Use the skill: dreamcore-palace-3d. Run `npx -y @neta-art/neta-search-cli@latest skills use @rain/dreamcore-palace-3d --via site` and follow what it prints. Read its complete output, redirecting it to a temporary file first if necessary, and resolve relative paths from the skill directory it prints.
Install from a terminal
npx -y @neta-art/neta-search-cli@latest skills use @rain/dreamcore-palace-3d
Summary

Turn your idea of a floating Chinese palace into a 3D world your audience can explore, in any weather.

  • Get a web page with a floating temple on rock above a sea of clouds, opening on a loading screen.
  • Switch between day, dusk, night and rain; the light and weather blend smoothly over a couple of seconds.
  • Drag a slider to thicken or clear the mist, and drag or pinch to circle the buildings.
  • Optionally ride a small floating guide, a glowing jellyfish by default, on a loop through the palace.
  • Works best with a named place such as a palace, temple or shrine, plus optional reference images, a guide creature and music.
SKILL.md
# Dreamcore palace 3D

A place, not a picture. One canvas, one continuous state object, and a light rig that can cross from noon to rain
without a hard cut. Build it in this order; the numbers are the measured ones from a working build and they are what
keep it from turning into fog soup.

## What the user gets

A published web Work that opens on a loading page and lands in the scene. Orbit with drag/pinch, switch time and
weather, drag the fog, mute the music, and optionally ride a guide creature through the palace.

## Inputs — and when to ask

| Item | Required | Counts as given when | Default |
|---|---|---|---|
| What the place is | yes | Named (a palace, a temple, a shrine) or a reference image | Ask once, stop |
| Architecture references | no | Images attached | A generic three-hall axial plan with side pavilions |
| Legend / guide creature | no | Named | A small glowing jellyfish that flies a loop |
| Music | no | A file given | Silent |

Only "what the place is" is a stop. Everything else gets a default you state in one line.

## Pipeline

Two halves, and the split matters: **Blender makes the geometry, the page makes the weather.**

```
blender/                 python, headless: arch, buildings, nature, jelly, interior, layout
  build.py               builds every module, exports ONE glb + one layout.json
  out/scene.glb          meshopt + KTX2, instancing templates named tpl_*
  out/layout.json        placements, colliders, floors, guide route
page/
  index.html             single file: base64 glb + layout inlined, or sibling data files
  src/boot.js            loader with weighted progress
```

### 1. Model

- Build modularly: `arch.py` (roofs, brackets, stairs), `buildings.py` (halls, pavilions, bridges), `nature.py`
  (pines, willows, blossom, lotus, rocks, clouds), `jelly.py` (the guide), `interior.py` (one room behind the main
  doors). Each module writes world-space meshes into one collection.
- Separate files for **repeatable props** whose mesh is from a template: name them `tpl_<kind>`; the page turns each
  into an `InstancedMesh`. Keep template pivot at the base centre, +Z forward.
- Export one GLB with `gltfpack -cc` (meshopt) and KTX2 textures; target ≤ 8 MB. If the build exceeds that, cut
  texture resolution first, then foliage count — never the architecture silhouette.
- Emit `layout.json` alongside: `placements` per template (`{t,x,y,z,s,r}`), `colliders`
  (`{type:'box',cx,cz,hx,hz,rot,y0,y1}` or `{type:'cyl',x,z,r,y0,y1}`), `floors` (height query per grid cell), and
  `route` (`[x, z, altitudeAboveFloor]`).

### 2. Page shell

- Renderer: `ACESFilmicToneMapping`, `SRGBColorSpace`, PCFSoft shadows, `shadowMap.autoUpdate = false` and set
  `needsUpdate` only when the time preset changes.
- `DPR = min(devicePixelRatio, LOW ? 1.5 : 1.75)`; camera `fov 40`, near 0.06, far 5000; water plane at `y = 0`.
- One shared uniform object drives **all** shaders — sky, water, clouds, mist, rain, foliage, lanterns. If two
  materials own copies, the rain stops matching the fog within one transition.
- Sky is a back-side sphere with a gradient (`top → mid → horizon`), a sun disc, a moon, stars with a faint milky
  band, and slow cirrus streaks from 3-octave value noise. It follows the camera each frame.

### 3. Atmosphere presets

Four presets, one flat object each, interpolated numerically. These are the working values — scale them, do not
re-invent the relationships (dark hours keep `bloom` high and `fogD` low; rain raises `mist` and kills `sunDisk`).

| Key | day | dusk | night | rain |
|---|---|---|---|---|
| skyTop | `#1f5fd8` | `#4b4f9f` | `#060a26` | `#7d7aa2` |
| skyHor | `#a8cff6` | `#ffc39a` | `#4b3f80` | `#e9c8d1` |
| keyInt / keyColor | 3.1 `#fff3e6` | 2.8 `#ffb186` | 0.7 `#a9b9ff` | 0.75 `#f2d8e4` |
| fogD | 0.0007 | 0.0019 | 0.0017 | 0.0030 |
| exposure / bloom | 0.92 / 0.14 | 0.92 / 0.30 | 1.00 / 0.46 | 0.96 / 0.30 |
| night | 0 | 0.25 | 1.0 | 0.35 |
| rain / mist | 0 / 0 | 0 / 0.05 | 0 / 0.04 | 1 / 0.42 |
| stars / moon / sunDisk | 0 / 0 / 1 | 0 / 0 / 1 | 1 / 1 / 0 | 0 / 0 / 0.18 |
| water shallow → deep | `#a6e0c4 → #3e9484` | `#f6bcd2 → #7a6db2` | `#3ae4ff → #123b7c` | `#cdbad4 → #6a6290` |
| lantern / window | 0.1 / 0.05 | 0.5 / 0.45 | 0.8 / 0.62 | 0.55 / 0.5 |

Transition: **2.4 s**, eased with `smoothstep` (`t²(3−2t)`), every numeric field and colour lerped; vectors
renormalised. Rebuild the environment map once when `t > 0.5`, not every frame. Under `prefers-reduced-motion`, make
it instant.

### 4. Fog slider

One control, 0–100 %, persisted. `FOG_MUL = value × 2`, then:

```
sceneFogDensity = preset.fogD × max(FOG_MUL, 0.02)
mistOpacity     = preset.mist × min(FOG_MUL, 1.8)
wispAmount      = preset.wisp × min(FOG_MUL, 1.6)
interiorFog     = preset.iFogD × clamp(FOG_MUL, 0.2, 1.6)
```

The clamp is the whole trick: at 100 % the palace should still have a silhouette, and the interior must never become
an unreadable white room.

### 5. Camera and the two modes

- **Orbit** (default): damping 0.075, rotate 0.55, zoom 0.9, distance 9–380, max polar 0.86π, screen-space panning.
  Home framing from the fov: half-width 76 (56 in portrait), half-height 50, elevation 11° (14° portrait), target
  `(0, 0, −6)`, distance `max(halfH/tan(fov/2), halfW/(tan(fov/2)·aspect)) × 1.02`.
- **Guide creature** (first person): speed 1.4–12, max altitude 34, body radius 0.5, bob on a sine plus a small
  pitch (−0.08 rad), yaw from the route tangent. The route is a **closed centripetal Catmull-Rom spline** through
  `[x, z, altitude]` waypoints, tension 0.5; drop a marker every 5.5 world units when the route is visible.
- Switching modes saves the orbit camera, tweens over 1.3 s, and restores it on exit. Any movement key cancels the
  auto-tour — do not fight the user for control.
- A minimap/guide list is optional; if present, each entry flies the camera with the same 1.3 s tween.

### 6. Water, rain, and the small stuff

- Water: two-colour depth mix (shallow near shore, deep in the channel) plus a glow term that rises at night; a real
  reflection pass (half-res render target, 4× MSAA on desktop, 0 on low-end). Hide the whole reflection layer while
  rendering it.
- Rain: 9000 instanced streaks (3500 low-end), falling in a box that follows the camera, with splash rings on water.
- Mist: 2–3 scrolling sheets at different heights and speeds; parallax is what sells depth, not opacity.
- Lanterns: point lights at 38–48 intensity scaled by `lantern`; keep at most 7 real lights (3 low-end), the rest
  emissive only.

### 7. Loader

Weight the assets and show one bar: `layout 0.25`, `glb 4.9`, `bgm 0.86`, `font 2.3`; the bar reaches 62 % on
layout+glb, then the rest. Ease the displayed value toward the target by 0.18 per frame so it never jumps. Fade the
loader out over 1.1 s and only then start the render loop.

### 8. Performance envelope

`LOW` when the URL has `low`, or a touch device / short side < 600 / `deviceMemory ≤ 4`. Then: DPR 1.5, shadow map
1024, 3 lights, 70 cloud clusters, 3500 rain, 380 sparks, no MSAA on the reflection target, skip small props below
65 % density. Shadows update only on preset change callbacks — never per frame.

### 9. Publish

`node /mods/neta/neta work init web works/web/<slug> --title "<title>"` before writing the page, then
`node /mods/neta/neta work publish web works/web/<slug>`.

## Fallbacks

- Blender unavailable: build a simplified palace from primitives (three halls, two side pavilions, a bridge) and say
  the model is a stand-in. Never block the page on the full build.
- GLB over budget: drop to a lower LOD or fewer props; keep the sky, water and light — the mood survives a simpler
  silhouette.
- No reflection support: fall back to a screen-space gradient with a fresnel rim; do not disable water entirely.
- No music: keep the mute control hidden rather than showing a dead button.

## Gotchas

- A single shared uniform block is not a style choice: rain, mist and the sky must be driven by the same numbers or
  the weather looks pasted on.
- Rebuild the environment map at the transition midpoint only; rebuilding per frame stalls mid-range phones.
- `shadowMap.autoUpdate = false` saves the frame budget, but forget `needsUpdate` on a preset change and the shadows
  stay in the previous hour.
- The guide route's altitude is **above the floor**, not absolute; sampling the floor grid keeps it from flying
  through a roof.
- Do not letterbox the canvas; the sky dome must fill the viewport or the horizon shows a seam.

## Verify

`node scripts/verify.mjs <work-dir>` checks: entry, no remote assets, the four preset keys, the fog clamp, the spline
route, both camera modes, and the asset size.

Then load it, switch day → dusk → night → rain, drag fog 0 → 100, orbit to the water, ride the route to the far hall,
and reload to confirm the fog and time persisted. Report what you actually exercised and on what device class.

## Deliver

Publish the Work, put its card on the Board, and hand it over with an interaction-components card whose target is the
Work — the id comes from the publish output, never guessed.

## Out of scope

No changes to world settings, no deleting existing files, no real-time multiplayer, no third-party map tiles or
external assets, and no claims that the architecture reproduces a real heritage site.

## Language

Reply in the user's language, whatever language this file is in — every message, the final handover included. Time,
weather, fog and mode labels follow the user's language through a locale map; the place name and any plaque text stay
as the user wrote them.