world-pv

Community@sunset1896/world-pv
Community skill — not reviewed. It was shared by 落嵛 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: world-pv. Run `npx -y @neta-art/neta-search-cli@latest skills use @sunset1896/world-pv --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 @sunset1896/world-pv
Summary

Turn your world into a wordless short film that alternates places and the characters who belong to them.

  • Name a world and it makes the whole film on its own: shot list, pictures, motion, music and a finished video you can play.
  • Each main character gets an empty-place shot, then their signature moment there; each one stands for one side of your world.
  • Six characters give about 42 seconds. The film ends on a huge wide view of the whole world, pulling back and fading out.
  • Also offers a faster 25-second tour of the world, about 2 seconds a shot, with a world nameplate and optional place-name captions.
  • Works best with 4 to 7 characters who each belong to a distinct place, plus a clear art style for the world.
SKILL.md
# World PV

A short film about **a place** — not a character biography, not a trailer.
The question it answers is "**what kind of world is this**", not "who is this person".

Reply in the user's language. The shot list and prompts may be written in English or in the world's language; the film itself carries no text.

**Default approach (the version the user approved): scene → person, interleaved one-to-one, no text.**

```
S1  Scene (no people, 3.0s)   the place this character belongs to — a real push-in
S2  Person (3.5s)             them there doing the thing they are most known for — they stand for one side of the worldview
S3  Scene → S4 Person → …     one pair per character
N1  World (3.7s)              an extreme wide shot of the whole world, camera pulling back and rising, fading to black
```

Six characters ≈ 42 seconds. Length gives way to completeness — the scene → person rhythm itself keeps viewers watching.

> **Read `reference/problems-and-fixes.md` first.** It holds every problem from four real deliveries that the user rejected or the health check caught, and how each was solved.
> This file covers "how to do it"; that one covers "why it is done this way".

---

## 0. Five hard rules

1. **Interleave scenes and people.** Two person shots must never be adjacent. People alone become a character carousel, and nobody can see the world.
2. **End on the world, not on people.** No group shots from behind, no group photos, no raised hands toward the sunset — they proved awkward in practice. End on an extreme wide shot of the whole world.
3. **No character reference on no-people shots.** `ref: "none"`, text-only generation, and the framing states "no people in frame". Attach a reference and the model stuffs people into the empty view.
4. **No text of any kind in the picture.** `noText: true` by default, nothing burned in post; the prompts also say "no text of any kind in frame, no sign lettering, no watermark". No game UI anywhere in the film (HUD / panels / buttons / borders).
5. **Each shot ≤ 3.7 seconds.** Image-to-video clips are 4.06s; after compose's start margin only about 3.8s remain.

All five are checked automatically by `tools/check-plan.mjs` before shooting; `auto-pv.mjs` runs it as its first step and stops on any ✗.

---

## 0.5 Zero-pause contract (when the user says "fully automatic" or "don't ask me")

Skill installed in the world and the user names the world = **run straight through to the finished film**. **Do not ask and do not wait for confirmation** along the way; stop only in these three cases, and only for that one case each time:

| Stop | Where | Notes |
|---|---|---|
| ✗ in the shot list | step 0 of `auto-pv` | Mechanical errors (adjacent people, reference on an empty view, over-long shot): **fix the shot list yourself** and run again; do not take them to the user |
| One shot keeps failing | video stage | Handle it with the "self-healing" below first; stop only after two rounds of redraws still fail, and name that shot |
| Upstream 503 / credits | any step | Rerunning the same command resumes; shots already saved are not redone |

**Self-healing (built into `auto-pv.mjs`, no one needs to step in)**

- **Copyright block** (`copyright` / `SensitiveContent` / `PolicyViolation`; Quasimodo "riding the bell and being flung off" failed three times in a row like this): judged as "too close to one particular screen adaptation". Retrying the same first frame is useless — it automatically **redraws that shot's still with an original composition** (the prompt adds "do not recreate the iconic shots / character designs of any existing screen adaptation; change the camera position and the moment of action"), then generates the video once more. The still becomes a new image; the text in the shot list does not need to change.
- **No motion detected**: make a last frame and regenerate once with first/last-frame interpolation (existing).
- **Music shorter than the film**: discard and regenerate (existing).

**Deliver once at the end**: when `auto-result.json` is ready, report everything in one go (address, duration, loudness, which side each character speaks for, the one or two places most likely to break), without asking beat by beat. Only touch a shot when the user says something like "redo just S6".

## 1. Fully automatic flow (default)

**The user naming a world = authorization to run fully automatically.** No questions along the way. Confirm beat by beat only if the user explicitly says "show me every step".
16:9 if no frame ratio is given; for portrait add `--ratio 9:16`.

The agent does only **the creative half** (A–D); the rest runs in one command (E).

### A · Read the world

| What to read | Where from |
|---|---|
| Worldview and **visualStyle** (decides the art style of the whole film) | `worldConfig` in `manifest.json` |
| Locations, factions, rule-type lore, world-level events | `materials/location|faction|lore|event/*.json` |
| Main characters' appearance, martial soul / abilities, identity | the appearance, martial soul / ability and identity fields of `materials/character/*.json` |
| The source's original lines on appearance and signature items (materials often say only "beautiful") | `grep` `uploads/*.txt` |
| **Films already made** — finalized person shots can be reused directly | `samples/*/stills/`, `auto-result.json` |

### B · Choose characters: by "side", not by popularity

First list which **sides** this worldview has, find the character who best represents each side, then pair them with **the place they belong to**:

| One side of the worldview | Character | Where they belong |
|---|---|---|
| Where the rules come from (awakening / initiation) | The protagonist | Where they set out from (village, academy, city gate) |
| The peak of power | The strongest one | Their mountain gate / battlefield |
| Beings other than humans | A non-human or another race | Their habitat (forest, deep sea) |
| Sects / clans | A sect disciple | The sect itself |
| Nation / empire | Royalty or a soldier | The imperial city |
| Competition / order | A fighter | The arena |

Douluo Dalu sample: Holy Soul Village → Tang San (martial soul awakening) · Clear Sky Sect mountains → Tang Hao (Titled Douluo) · Star Dou Great Forest → Xiao Wu (hundred-thousand-year soul beast) · Seven Treasure Glazed Tile Sect → Ning Rongrong (sect) · Star Luo imperial city → Dai Mubai (empire and beast martial soul) · Great Soul Arena → Zhu Zhuqing (soul arena) · the continent at dawn.

4–7 characters is ideal. With thin materials and only 2–3 characters it still works; see "3. When the materials are thin".

### C · Reference images

```bash
node .agents/skills/world-pv/tools/fetch-refs.mjs --dir samples/<slug> --names "Tang San,Xiao Wu,Tang Hao" \
  --crop "Tang San=top50,Xiao Wu=0.25:0.06:0.62:0.62"
```

It takes the covers from the world, crops as needed, and tiles a `refs/contact.jpg`. **You must open it and look**:

- **Crop out any text.** Covers auto-generated by the world often print the name on the chest or paste a source excerpt at the bottom — it gets copied into the stills.
- **One person.** If anyone else is in it, use a different image (a single-person still from another film works too).
- **No cover**: `"ref": "none"`, and `who` spells out **hairstyle / hair color / costume / one signature item**. Do not make a three-view sheet for it.

### D · Write the shot list

Copy `templates/plan.ensemble.blank.json` to `samples/<slug>/beats.plan.json`; edit it against the full sample `templates/sample-douluo/beats.plan.json`.
Slots: copy `templates/sample-douluo/slots.json` and change `STYLE` (copy the world's visualStyle verbatim), `MOOD`, `MUSIC` and `TIME`.

**Scene shots** (`cast: "none"`, `ref: "none"`, `archetype: "landmark"`):

- framing: extreme wide shot + the **scale and landmarks** of this place + "no people in frame".
- motion_env: things moving **broadly** (clouds drifting, mist rolling in, flags billowing in rows, fireflies rising). "The grass moves" is too weak; the health check will judge it motionless.
- camera: a real move — `dolly_in` (push in, the most common, like walking in) / `pan_r` / `crane_up`. Not `static`.
- Give the scenes in one film different **times of day**: dawn, rainy night, moonlit night, dusk, night — a sense of time is the cheapest layer of depth.

**Person shots** (`cast: "person"`, `archetype: "envoy"`, `ref`, `who`):

- framing: they are **in the place from the previous shot**, doing the thing they are most known for (awakening, unleashing a move, transforming, raising the sect's treasure).
- motion_people: **wind-up → burst, the whole person changes into a new pose**.
- **Do not write "afterimage streaking / teleporting"** — the whole middle becomes motion blur and the person disappears. Write "two short quick dodges, the person clearly visible each time they land".
- end_pose: the moment the action is at its fullest and holds (the motion-fix round uses it to make the last frame).

**Ending shot** (`archetype: "nameplate"`, `cast: "none"`): an extreme wide shot of the whole world, looking down from above the clouds, light spreading from the horizon, camera `dolly_out` pulling back and rising, fading out.

Durations: scene 3.0, person 3.5, ending 3.7; `t` accumulates beat by beat, `total` is the sum.

### E · One command for the rest

```bash
nohup node .agents/skills/world-pv/tools/auto-pv.mjs --dir samples/<slug> > /dev/null 2>&1 &
tail -5 samples/<slug>/auto.log
```

In order: **shot list check** (stops on ✗) → storyboard pack → per-shot stills (person shots with their own references, no-people shots text only) → image-to-video + music sized to the film length → compose (no text) → health check → shots that do not move are automatically regenerated with first/last-frame interpolation → second compose → upload and confirm it plays. Every step is saved to disk; if interrupted, rerunning the same command resumes. About 15–20 minutes.

When done, tile a per-shot screenshot sheet to review first (`ffmpeg -i final.mp4 -vf "fps=0.35,scale=400:225,tile=5x3" -frames:v 1 check.jpg`), looking especially at: are there people in the empty views, is there any text, is the person still there in the middle of the high-speed action shot.

### Delivery

Read `auto-result.json` and report, in the user's language: the playable address, duration and loudness; which side of the world each character speaks for; why the ending lands on the world; **the one or two places most likely to break**, with the option to redo just that shot.

---

## 2. Revisions: do not start over

Users often say "same characters, add scenes / change the ending / make it longer". Person shots are the most expensive and hardest to get right, so reuse them directly:

```bash
node .agents/skills/world-pv/tools/reuse-shots.mjs --from samples/<old> --to samples/<new> --map S1:S2,S2:S4,S3:S6
```

It moves the finalized stills and videos over under the new ids, and saves how the old shots were written to `reused-shots.json` for you to merge into the new shot list. auto-pv generates only the new shots; **music shorter than the new length is regenerated automatically**.

To change a single shot: delete `stills/<id>.png`, `pv-pack/clips/<id>.mp4` and that entry in `stills.json` / `videos.json`, edit the shot list, and rerun the same command.

---

## 3. When the materials are thin

A personal creator's worldview often cannot fill six characters and six places. **Do not force it; change the approach**:

| Situation | What to do |
|---|---|
| Only 2–3 characters | One pair each (scene → person), plus an "entrance" scene beat at the start; about 20–25s still works |
| Only 1 location | Shoot the same place at different times: dawn → noon → rainy night → daybreak |
| Characters without covers, materials only one line | `who` spells out hairstyle / hair color / costume / one signature item, generated from text |
| No grand wonder | Shoot **something with age on it** (a broken stele, an old city gate, stone steps blackened by smoke) — one ruin works better than ten splendors |
| No factions, no nation | Skip that side; do not invent it |

Better four full beats than ten empty ones.

---

## 4. Another approach: world montage (about 25s, with text)

Use when the user wants a **short, fast tour of the world with place names**: about 2 seconds per beat, "entrance → rules → person → place → power → faction → edge → traces → night → world name", with no more than 2 of the same kind in a row in the main body (the closing pure scenery may run to 3), the world nameplate over the last shot, and optional bottom place-name subtitles (`--subs`).

```bash
node .agents/skills/world-pv/tools/cast-beats.mjs --slots samples/<slug>/slots.json --out samples/<slug>/beats.plan.json --world .
# Then edit every shot by hand: the framing from casting is generic and must be replaced with this world's places and people
nohup node .agents/skills/world-pv/tools/auto-pv.mjs --dir samples/<slug> --subs > /dev/null 2>&1 &
```

The beat catalog is `templates/beat-library.json`, the default skeleton `templates/skeleton.json`, and the example slots `templates/slots.demo.json`.

---

## 5. Files

| Path | What it is |
|---|---|
| `reference/problems-and-fixes.md` | **Problems and fixes**: every pitfall hit — symptom / cause / fix / what catches it |
| `reference/production-notes.md` | A running record of each production (time, data, leftovers) |
| `templates/plan.ensemble.blank.json` | Blank shot-list template for the default approach |
| `templates/sample-douluo/` | The full sample the user approved (shot list + slots, 13 beats, 42.7s) |
| `templates/beat-library.json`, `skeleton.json`, `slots.*.json` | For world montage mode |
| `tools/check-plan.mjs` | **Pre-shoot check**: interleaving, ending, references on empty views, shot length, afterimage actions, prompt length, UI elements |
| `tools/fetch-refs.mjs` | Fetch covers by character name, crop text, make a contact sheet |
| `tools/reuse-shots.mjs` | Reuse finalized shots from an old version in a revision |
| `tools/auto-pv.mjs` | The fully automatic runner |
| `tools/build-pack.mjs` | Shot list → storyboard pack (storyboard.md / .html, per-shot prompts, timeline) |
| `tools/compose.mjs` | Per-shot clips → film (cuts, music, loudness, optional burned-in text) |
| `tools/pv-check.mjs` | Mechanical health check of the film, 7 items |
| `tools/endpoints.mjs` | Last-frame prompts for first/last-frame interpolation |
| `tools/cast-beats.mjs`, `tools/subtitles.mjs` | World montage mode: automatic casting, place-name subtitle track |

---

## 6. Boundaries

- One person's life story → character-pv
- Chat companion → companion-onboarding
- Branching game → create-avg
- Illustrated map → world-map-experience
- Scroll-driven 3D flight → scroll-world-video
- A web page with no video → create-web-work