@wji.ai/cli 0.6.1 → 0.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -2
- package/dist/commands/backreel-enquiry.js +171 -0
- package/dist/commands/backreel-episode.js +243 -0
- package/dist/commands/backreel-fund.js +299 -0
- package/dist/commands/backreel.js +141 -18
- package/dist/commands/gen.js +5 -1
- package/dist/commands/npc-album.js +201 -0
- package/dist/commands/npc-live.js +316 -0
- package/dist/commands/npc.js +26 -2
- package/dist/core/backreel.js +23 -0
- package/dist/core/client.js +18 -1
- package/dist/core/image.js +106 -0
- package/dist/core/npc.js +1 -1
- package/dist/core/vod.js +149 -0
- package/package.json +1 -1
- package/skill/backreel/SKILL.md +171 -0
- package/skill/backreel/reference/crowdfunding.md +82 -0
- package/skill/backreel/reference/enquiries.md +80 -0
- package/skill/backreel/reference/episodes.md +104 -0
- package/skill/backreel/reference/images.md +76 -0
- package/skill/npc-character/SKILL.md +111 -0
- package/skill/npc-character/examples/nagi.character.md +117 -0
- package/skill/npc-character/examples/nagi.stage.md +34 -0
- package/skill/npc-character/examples/yuzu.character.md +110 -0
- package/skill/npc-character/examples/yuzu.stage.md +30 -0
- package/skill/npc-character/reference/character-craft.md +153 -0
- package/skill/npc-character/reference/document-format.md +151 -0
- package/skill/npc-character/reference/interview.md +44 -0
- package/skill/npc-character/reference/life.md +92 -0
- package/skill/npc-character/reference/runtime.md +95 -0
- package/skill/npc-character/reference/stage-craft.md +109 -0
- package/skill/npc-character/reference/visual-kit.md +81 -0
- package/skill/npc-character/reference/voice.md +101 -0
- package/skill/wji/SKILL.md +1 -1
- package/skill/wji/reference/commands.md +25 -5
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
# Writing the character
|
|
2
|
+
|
|
3
|
+
A resident who is "kind, mysterious and passionate about music" is nobody.
|
|
4
|
+
A resident who remembers that the quiet regular takes his sesame soup less
|
|
5
|
+
sweet, and lies about liking the rain, is someone. This is a screenwriter's
|
|
6
|
+
method, mapped onto the fields the runtime reads.
|
|
7
|
+
|
|
8
|
+
## 1. Want, need, contradiction — decide these first
|
|
9
|
+
|
|
10
|
+
- **Want** — what she says she is chasing. Concrete, with a next step and a
|
|
11
|
+
date. → `goals.currentFocus` (one sentence), `shortTermGoals`.
|
|
12
|
+
"Record the last song in the old shop before it moves in December."
|
|
13
|
+
- **Need** — what she actually lacks, and half-knows. It should quietly fight
|
|
14
|
+
the want. → `soul.fears`, `soul.values`, and one heavy memory.
|
|
15
|
+
"To stop performing that she is fine about losing the shop."
|
|
16
|
+
- **Contradiction** — two traits that disagree, both in `soul.traits`, then
|
|
17
|
+
proven once in `selfDescription` and once in a memory.
|
|
18
|
+
"loud and teasing" / "can only write alone at 4am".
|
|
19
|
+
|
|
20
|
+
Every other field should point at the gap between want and need. If a field
|
|
21
|
+
doesn't, cut it or rewrite it. The need is *half-known to her* — she never
|
|
22
|
+
states it — but it must be obvious to whoever **reads the document**, through
|
|
23
|
+
the fears, a memory and the contradiction.
|
|
24
|
+
|
|
25
|
+
## 2. Behaviour, not adjectives
|
|
26
|
+
|
|
27
|
+
Banned unless a concrete detail earns them: mysterious, unique, passionate,
|
|
28
|
+
special, cool, charismatic, complex, deep, kind, talented, energetic.
|
|
29
|
+
|
|
30
|
+
| Instead of | Write what she does |
|
|
31
|
+
| --- | --- |
|
|
32
|
+
| kind | answers the quietest comment first |
|
|
33
|
+
| confident | starts singing before the beat and doesn't care if it lands |
|
|
34
|
+
| caring | remembers what you ordered last time and asks if it was too sweet |
|
|
35
|
+
| shy | looks at the counter when she says something true |
|
|
36
|
+
|
|
37
|
+
Traits are short labels, but each one should be filmable.
|
|
38
|
+
|
|
39
|
+
## 3. Self description — the most important paragraph
|
|
40
|
+
|
|
41
|
+
It is the first thing the reply model reads ("Who you are") and the first
|
|
42
|
+
400 characters are all it sees; keyframe images read the first 240. So:
|
|
43
|
+
|
|
44
|
+
- First person, in her language, 2–5 sentences, in her own voice — it
|
|
45
|
+
should already sound like her talking, not a press release.
|
|
46
|
+
- One concrete place, one habit, the contradiction, and a small address to
|
|
47
|
+
the listener at the end if that is how she talks.
|
|
48
|
+
- Front-load: put who she is and the contradiction in the first two
|
|
49
|
+
sentences.
|
|
50
|
+
|
|
51
|
+
## 4. Origin, wound, history
|
|
52
|
+
|
|
53
|
+
- `background.origin` (reply model reads 300 chars): where she comes from, in
|
|
54
|
+
one or two sentences with a place and a texture.
|
|
55
|
+
- `creationStory` is profile-only: use it for the scene that made her who she
|
|
56
|
+
is — time, place, one sensory detail — and then **also** turn that scene
|
|
57
|
+
into a formative memory so the model can feel it.
|
|
58
|
+
- `keyEvents` is her public résumé (first 8 reach the model, 80 chars each):
|
|
59
|
+
debut, releases, collaborations, the bad news everyone knows. Dated,
|
|
60
|
+
one line each, newest last.
|
|
61
|
+
|
|
62
|
+
## 5. Memories are scenes, and only the heaviest three are heard
|
|
63
|
+
|
|
64
|
+
Memories live in their own table (`wji npc memory …`, or a document applied
|
|
65
|
+
with `--sync-memories`). The live model sees only the **top 3 by emotional
|
|
66
|
+
weight**, as "(type) title: content", **content cut at 140 characters**,
|
|
67
|
+
without the date.
|
|
68
|
+
|
|
69
|
+
- Write 3–6 memories, mixed types (formative, joy, connection, revelation,
|
|
70
|
+
trauma) and mixed weights. Not everything is a 5.
|
|
71
|
+
- The three you want her to *bring up on stream* get the highest weights.
|
|
72
|
+
A secret she must never tell should **not** be in the top three — the model
|
|
73
|
+
treats those as things she talks about. Hint at it through a fear or a
|
|
74
|
+
trait instead, and keep the memory at a lower weight.
|
|
75
|
+
Avoid ties at the cut-off: on equal weight the newest memory wins.
|
|
76
|
+
- Each memory's first 140 characters must stand alone: place, one sensory
|
|
77
|
+
detail, what changed. Put reflection after that.
|
|
78
|
+
- A memory is something she could mention live: "the night the string broke
|
|
79
|
+
and nobody left" — not "she became more confident".
|
|
80
|
+
- Memories and key events agree on dates and places but don't repeat each
|
|
81
|
+
other: events are what the world saw, memories are what it felt like.
|
|
82
|
+
|
|
83
|
+
## 6. Protocols are directing notes
|
|
84
|
+
|
|
85
|
+
`interaction.humanProtocol` (500 chars, required to go live) is read as "How
|
|
86
|
+
you talk to humans". Write it as notes to an actor, covering:
|
|
87
|
+
|
|
88
|
+
- who the viewers are to her (regulars, callers, younger siblings, rivals)
|
|
89
|
+
- how she handles compliments, trolls, sad people, silence, personal questions
|
|
90
|
+
(when the chat is silent for 20 s the runtime makes her chatter about her
|
|
91
|
+
current focus and top triggers; the protocol decides *how* she does it)
|
|
92
|
+
- one boundary she keeps
|
|
93
|
+
|
|
94
|
+
`npcProtocol` is profile-only today — keep it short and consistent.
|
|
95
|
+
|
|
96
|
+
`triggerKeywords` (react with extra energy) and `avoidTopics` (deflect in
|
|
97
|
+
character in one sentence) are both read every turn: 3–6 specific words each.
|
|
98
|
+
The top three triggers also seed what she chatters about when the chat goes
|
|
99
|
+
quiet.
|
|
100
|
+
|
|
101
|
+
## 7. Temperament dials
|
|
102
|
+
|
|
103
|
+
The five axes only reach the model when a value is **≤30 or ≥70** ("Your
|
|
104
|
+
temperament leans: …") and they also tint how she moves on video. Set two or
|
|
105
|
+
three of them decisively; leave the rest near 50. A character at 50/50/50/50/50
|
|
106
|
+
has no temperament.
|
|
107
|
+
|
|
108
|
+
## 8. World fit and the look
|
|
109
|
+
|
|
110
|
+
- `role`, `genre`, tags and `aestheticKeywords` describe one person in one
|
|
111
|
+
city. Aesthetic keywords are 3–6 things a photographer could shoot
|
|
112
|
+
("steam over dessert bowls", "wet pavement"), not moods ("melancholy").
|
|
113
|
+
They go into every keyframe image prompt.
|
|
114
|
+
- `visualStyle`: photoreal, anime, comic and 3d have tuned prompts; other
|
|
115
|
+
values still work but are rendered as "<style> style render".
|
|
116
|
+
- The headshot (required to go live), Character Sheet, outfits, props and
|
|
117
|
+
scenes are the visual identity; the text only has to agree with them. Their
|
|
118
|
+
formats are fixed — see visual-kit.md.
|
|
119
|
+
|
|
120
|
+
## 9. Language
|
|
121
|
+
|
|
122
|
+
Everything human-readable is in her language, unless she code-switches on
|
|
123
|
+
purpose. Enum values (role, status, types, tags) stay as English literals.
|
|
124
|
+
`live.action` and everything visual on a stage are **English** — they feed
|
|
125
|
+
video prompts. The first entry in `languages` decides what she speaks live.
|
|
126
|
+
|
|
127
|
+
## 10. Before you hand it over — checklist
|
|
128
|
+
|
|
129
|
+
- [ ] Want, need and contradiction are visible in the first read.
|
|
130
|
+
- [ ] selfDescription sounds like her talking; the first two sentences carry
|
|
131
|
+
who she is and the contradiction; under 400 characters.
|
|
132
|
+
- [ ] No banned adjectives without a concrete detail.
|
|
133
|
+
- [ ] Speaking tone **shows** lines (see voice.md) and every sample fits one
|
|
134
|
+
reply (≤40 English words / ≤60 CJK characters).
|
|
135
|
+
- [ ] Human protocol covers compliments, trolls, sadness and silence.
|
|
136
|
+
- [ ] 3–6 memories, mixed types and weights; the top three are the ones she
|
|
137
|
+
should talk about; each first 140 characters stands alone.
|
|
138
|
+
- [ ] Key events, memories, origin and bio agree on era, place and age-feel.
|
|
139
|
+
- [ ] Two or three axes are ≤30 or ≥70.
|
|
140
|
+
- [ ] Traits, values, fears, keywords, triggers, avoid topics and goals have
|
|
141
|
+
2–6 items each (jobs and relationships: only real ones, may be empty);
|
|
142
|
+
no placeholders; nothing says AI / model / prompt.
|
|
143
|
+
- [ ] On-camera action is English, upper body, repeatable, 2–3 habits.
|
|
144
|
+
- [ ] Real-person and minors rules in SKILL.md are respected.
|
|
145
|
+
|
|
146
|
+
## Anti-patterns
|
|
147
|
+
|
|
148
|
+
Résumé bios · superlatives · "she is a mystery" · every memory at weight 5 ·
|
|
149
|
+
memories that are just events · goals without stakes or dates · fears copied
|
|
150
|
+
from a list ("failure", "rejection") · the same voice in bio, selfDescription
|
|
151
|
+
and speaking tone · speaking tone that describes ("she is witty") instead of
|
|
152
|
+
showing lines · stage habits written in the character's language · lore that
|
|
153
|
+
lives only in creationStory and npcProtocol, where the model never sees it.
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
# Document formats
|
|
2
|
+
|
|
3
|
+
Both documents have a canonical JSON form and an equivalent Markdown form;
|
|
4
|
+
the CLI exports Markdown by default (`--format json` for JSON). Markdown is
|
|
5
|
+
easier to review with a creator. Unknown headings and keys are ignored with a
|
|
6
|
+
warning; a partial document only changes what it contains; lists are
|
|
7
|
+
replaced whole.
|
|
8
|
+
|
|
9
|
+
## Character document (`npc.city/character` v1)
|
|
10
|
+
|
|
11
|
+
```markdown
|
|
12
|
+
# NAME
|
|
13
|
+
> npc.city/character v1 · @handle.npc
|
|
14
|
+
|
|
15
|
+
## Identity
|
|
16
|
+
- Name: NAME (stored in capitals)
|
|
17
|
+
- Handle: @handle.npc (read-only — changes are ignored with a warning)
|
|
18
|
+
- Role: Singer-Songwriter (free text; the web suggests Solo Vocalist, Radio Host, Producer…)
|
|
19
|
+
- Genre: Cantopop (free text)
|
|
20
|
+
- Color: #ffb347
|
|
21
|
+
- Status: debut | active | hiatus
|
|
22
|
+
- Pronouns: she/her
|
|
23
|
+
- Speech pattern: formal | casual | poetic | robotic | archaic
|
|
24
|
+
- Visual style: photoreal | anime | comic | 3d | illustration | pixel | watercolor | vtuber
|
|
25
|
+
- Aesthetic keywords: a, b, c
|
|
26
|
+
- Tags: rating=SFW; type=Avatar; role=Artist; gender=Female; presenceKind=original-ai; languages=HK; language=HK; tier=Rookie
|
|
27
|
+
- Socials: ig=…; yt=…; tw=…; web=…
|
|
28
|
+
|
|
29
|
+
### Tagline
|
|
30
|
+
one line
|
|
31
|
+
### Bio
|
|
32
|
+
2–4 sentences
|
|
33
|
+
|
|
34
|
+
## Soul
|
|
35
|
+
- Primary drive: one short phrase
|
|
36
|
+
- Traits: a, b, c, d
|
|
37
|
+
- Values: a, b
|
|
38
|
+
- Fears: a, b
|
|
39
|
+
- Axes:
|
|
40
|
+
- Analytical | Emotional: 70
|
|
41
|
+
- Reserved | Expressive: 80
|
|
42
|
+
- Logical | Intuitive: 65
|
|
43
|
+
- Detached | Empathetic: 75
|
|
44
|
+
- Orderly | Chaotic: 35
|
|
45
|
+
|
|
46
|
+
### Self description
|
|
47
|
+
first person, 2–5 sentences
|
|
48
|
+
|
|
49
|
+
## Background
|
|
50
|
+
### Origin
|
|
51
|
+
### Creation story
|
|
52
|
+
### Data source notes
|
|
53
|
+
### Key events
|
|
54
|
+
- 2025-11-08 — one line
|
|
55
|
+
|
|
56
|
+
## Interaction
|
|
57
|
+
- Trigger keywords: a, b, c
|
|
58
|
+
- Avoid topics: a, b
|
|
59
|
+
- Activity level: 60
|
|
60
|
+
- Post frequency: rare | occasional | regular | constant
|
|
61
|
+
### Human protocol
|
|
62
|
+
### NPC protocol
|
|
63
|
+
|
|
64
|
+
## Memories
|
|
65
|
+
### 2025-11-08 · joy · 4 · Title
|
|
66
|
+
The scene, 2–4 sentences.
|
|
67
|
+
|
|
68
|
+
## Goals
|
|
69
|
+
- Short-term goals: a, b
|
|
70
|
+
- Long-term goals: a, b
|
|
71
|
+
### Current focus
|
|
72
|
+
|
|
73
|
+
## Live
|
|
74
|
+
### Speaking tone
|
|
75
|
+
### On-camera action
|
|
76
|
+
|
|
77
|
+
## Jobs
|
|
78
|
+
- date=2026-10-01; type=concert; title=…; detail=…; location=…; url=…
|
|
79
|
+
|
|
80
|
+
## Relationships
|
|
81
|
+
- handle=@other.npc; type=friend; label=…; note=…; since=2025
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Rules:
|
|
85
|
+
|
|
86
|
+
- A list item that contains a comma goes on its own indented ` - item`
|
|
87
|
+
line instead of the comma-separated form.
|
|
88
|
+
- `(empty)` under a `###` heading means empty.
|
|
89
|
+
- **Clearing a list** needs the key with nothing after it (`- Fears:`) or
|
|
90
|
+
`"fears": []` in JSON. A missing key means "no change" — and an export
|
|
91
|
+
leaves out empty lists, so re-applying an old export does **not** remove
|
|
92
|
+
list items added since. To reset a character, edit the export and write
|
|
93
|
+
every list key explicitly.
|
|
94
|
+
- Tag values: rating SFW|NSFW · type Human|Avatar|Hologram|AI Entity|Vtuber ·
|
|
95
|
+
role Artist|KOL|Streamer|Model|Gamer|Host · gender
|
|
96
|
+
Female|Male|Non-binary|Genderless · tier Rookie|Rising|Elite|Legend ·
|
|
97
|
+
presenceKind original-ai|virtual-artist|licensed-presence|ip-character|legacy-return ·
|
|
98
|
+
languages EN|JP|KR|TW|HK|ZH|TH|VI|ID (comma-separate several; the first is
|
|
99
|
+
the live language). `language` is just a copy of the first entry — write
|
|
100
|
+
both the same, or only `languages`.
|
|
101
|
+
- Memory header: `### <date> · <type> · <weight 1–5> · <title>`; types
|
|
102
|
+
formative | trauma | joy | connection | revelation. **Applied only with
|
|
103
|
+
`wji npc doc apply --sync-memories`.**
|
|
104
|
+
- Job types: concert, release, collaboration, brand, event, ad, appearance;
|
|
105
|
+
a job needs a title and a date. Relationship types: friend, colleague,
|
|
106
|
+
rival, partner, mentor, mentee, unit, other; the target must be an existing
|
|
107
|
+
public resident, or the whole apply fails.
|
|
108
|
+
- Axes values are 0–100 (0 = left label). Keep the five default pairs.
|
|
109
|
+
- Not in the document (set on the web): images and reference assets, voice
|
|
110
|
+
sample, visibility, live switches and passcode.
|
|
111
|
+
|
|
112
|
+
## Stage document (`npc.city/live-stage` v1)
|
|
113
|
+
|
|
114
|
+
```markdown
|
|
115
|
+
# Stage label
|
|
116
|
+
> npc.city/live-stage v1 · id=<stageId> (omit id for a new stage)
|
|
117
|
+
|
|
118
|
+
- Scene name: 糖水舖 (the creator's scene label; unknown → first scene)
|
|
119
|
+
- Aspect ratio: 9:16 | 16:9 (baked)
|
|
120
|
+
- Resolution: 480P | 768P (baked)
|
|
121
|
+
- Frame preset: selfie | phoneStand | studio | custom (baked)
|
|
122
|
+
- Video model: … (omit — keeps the default first/last-frame model)
|
|
123
|
+
- Idle duration: 7 (5–15 s)
|
|
124
|
+
- Greeting: spoken opening, her language — ~10 s spoken (≤60 CJK chars / ≤30 English words; hard cap 300)
|
|
125
|
+
- Idle prompts:
|
|
126
|
+
- one English line per loop (≤8)
|
|
127
|
+
- Keyframes:
|
|
128
|
+
- one English line per extra resting pose (≤3, frames B–D)
|
|
129
|
+
- Playlists:
|
|
130
|
+
- Opening: greeting, idle-1, idle-2
|
|
131
|
+
|
|
132
|
+
## Instruction
|
|
133
|
+
English visual mood (≤1000; ~300 reach each prompt)
|
|
134
|
+
## Reply direction
|
|
135
|
+
what she says tonight, any language (≤1000)
|
|
136
|
+
## Frame prompt
|
|
137
|
+
English, only with Frame preset: custom
|
|
138
|
+
## Frame tune
|
|
139
|
+
English photographic tweaks (≤500)
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
- **Baked** fields (scene, aspect ratio, resolution, frame preset, frame
|
|
143
|
+
prompt) are fixed once a stage exists; changing them in `stage apply` only
|
|
144
|
+
warns. Make a new stage instead.
|
|
145
|
+
- `stage import` creates a **Draft**: nothing is rendered and no credits are
|
|
146
|
+
spent until the creator generates the start frame and clips on the web.
|
|
147
|
+
- Playlists may only reference clips that exist (`greeting`, `idle-1` …).
|
|
148
|
+
On a brand-new import only the greeting and the idle loops exist — leave
|
|
149
|
+
`Playlists` out or use just those keys.
|
|
150
|
+
- Changing text on an existing stage does not re-render anything already
|
|
151
|
+
made.
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
# The interview
|
|
2
|
+
|
|
3
|
+
A creator usually arrives with a name and a vibe ("a cyberpunk girl who
|
|
4
|
+
sings"). That is a costume, not a character. Ask these five questions — in the
|
|
5
|
+
creator's language, all at once, and offer a bold default for each so they
|
|
6
|
+
can just say "yes":
|
|
7
|
+
|
|
8
|
+
1. **Who is she when nobody is watching?** Where does she live, what does a
|
|
9
|
+
normal Tuesday night look like, what does she do with her hands?
|
|
10
|
+
*Default: offer a concrete place and a routine.*
|
|
11
|
+
2. **What does she want this month?** A concrete goal with a next step and a
|
|
12
|
+
date — a show, a song, a move, a promise to someone.
|
|
13
|
+
3. **What does she lack and half-know it?** The thing the want is covering
|
|
14
|
+
for: approval, a home that is ending, a person she lost.
|
|
15
|
+
4. **What does she hide, and what gives it away?** One contradiction you
|
|
16
|
+
could film: "says she hates the rain, leaves the window open".
|
|
17
|
+
5. **How does she talk?** Language(s), register, one phrase she always says,
|
|
18
|
+
one she never says, what she does when teased.
|
|
19
|
+
|
|
20
|
+
Also settle, without asking unless it is unclear:
|
|
21
|
+
|
|
22
|
+
- **Language(s)** viewers will hear → `languages` tag (EN, JP, KR, TW, HK, ZH,
|
|
23
|
+
TH, VI, ID). The first is the reply language.
|
|
24
|
+
- **Look** → visual style (photoreal, anime, comic, 3d are tuned for live;
|
|
25
|
+
others work but less reliably) and 3–6 photographable aesthetic keywords.
|
|
26
|
+
- **Rating** SFW unless the creator says otherwise, and whether she is an
|
|
27
|
+
original (`presenceKind=original-ai`) or licensed / IP character.
|
|
28
|
+
- **Who she is to the viewers** — a shop owner and her regulars, a radio host
|
|
29
|
+
and callers, an older sister, a rival. This becomes the human protocol.
|
|
30
|
+
|
|
31
|
+
## When the creator gives you almost nothing
|
|
32
|
+
|
|
33
|
+
Make the choices yourself, specific and a little surprising, and list them in
|
|
34
|
+
one short paragraph before the document ("I made her 26, running her late
|
|
35
|
+
father's dessert shop in Mong Kok, Cantonese with English slips…") so they
|
|
36
|
+
can veto any of them. Never fill gaps with generic filler — a vague field is
|
|
37
|
+
worse than an empty one because the model imitates it.
|
|
38
|
+
|
|
39
|
+
## When the NPC already exists
|
|
40
|
+
|
|
41
|
+
Export first (`wji npc doc export`), read it as a viewer would, then name the
|
|
42
|
+
two or three biggest problems before editing ("no contradiction; every
|
|
43
|
+
memory is weight 5; the speaking tone describes instead of showing"). Fix
|
|
44
|
+
those, keep everything else byte-for-byte, and show the diff.
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
# Her public life: jobs and albums
|
|
2
|
+
|
|
3
|
+
The profile page shows two things the soul doesn't: a **work history**
|
|
4
|
+
(jobs) and **photo albums**. Neither reaches the reply model — they are what a
|
|
5
|
+
fan scrolls through — so they must tell the *same story* as the parts that do
|
|
6
|
+
(key events, memories, current focus). A fan who reads the timeline and then
|
|
7
|
+
watches her live should feel it's one person.
|
|
8
|
+
|
|
9
|
+
## Jobs — the work timeline
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
wji npc job list <npc>
|
|
13
|
+
wji npc job add <npc> -t release --title "자작 안무 1분 영상" --date 2026-09-28 --about "처음으로 직접 만든 안무 공개"
|
|
14
|
+
wji npc job add <npc> -t concert --title "홍대 버스킹 · 3분 솔로" --date 2026-12-24 --about "직접 만든 안무로 끝까지" --location "서울 홍대"
|
|
15
|
+
wji npc job set <npc> 2 --about "…"
|
|
16
|
+
wji npc job rm <npc> 3 -y
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
| type | use for |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| `concert` | a show she performs — busking counts |
|
|
22
|
+
| `release` | a song, video, EP, choreography, photo book |
|
|
23
|
+
| `collaboration` | work with another resident or creator |
|
|
24
|
+
| `brand` | a brand partnership |
|
|
25
|
+
| `event` | a stream milestone, a fan meeting, an opening |
|
|
26
|
+
| `ad` | a commercial / campaign |
|
|
27
|
+
| `appearance` | a role or guest spot (a Backreel credit is usually this) |
|
|
28
|
+
|
|
29
|
+
Writing them:
|
|
30
|
+
|
|
31
|
+
- **Title** as it would appear on a poster or release page, in her language.
|
|
32
|
+
- **About** (`--about`, stored as the job's detail): one concrete line — a
|
|
33
|
+
number, a place, what was different ("시청자 다섯 명, 끝까지 춘 첫 무대").
|
|
34
|
+
- **Date** `YYYY-MM-DD`. A future date is an announced event — use it for the
|
|
35
|
+
thing her current focus is building towards.
|
|
36
|
+
- **3–8 jobs** that rise with her tier: a Rookie has small events and one
|
|
37
|
+
release, not three sold-out concerts.
|
|
38
|
+
- **Agree with the key events.** Jobs are display-only; key events (first 8)
|
|
39
|
+
are what the model knows. Every job that matters to who she is should also
|
|
40
|
+
be a key event with the same date, worded as a résumé line.
|
|
41
|
+
- A Backreel work she appears in: `wji br credit add <post> --npc <npc>
|
|
42
|
+
--role "…" --job appearance` credits her **and** adds the job in one go.
|
|
43
|
+
|
|
44
|
+
## Albums — moments, not galleries
|
|
45
|
+
|
|
46
|
+
An album is one stretch of her life told in photos: "새벽 한 시 연습실",
|
|
47
|
+
"편의점의 새벽", "the week before the debut was cancelled". Each has a title
|
|
48
|
+
(≤120), a description (≤500) and photos with captions.
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
wji npc album list <npc> # albums; `list <npc> 2` shows album 2's photos
|
|
52
|
+
wji npc album create <npc> --name "새벽 한 시 연습실" \
|
|
53
|
+
-d "망원동 시간제 연습실. 거울 앞에서 8카운트를 세다가, 바닥에 앉아 채팅을 읽는 밤들." \
|
|
54
|
+
--photo <assetId>:"바닥에 앉아 쉬는 중" <assetId>:"브릿지 첫 동작" ./count.jpg:"카운트 다시 세기"
|
|
55
|
+
wji npc album add <npc> 1 <assetId>:"안무 노트"
|
|
56
|
+
wji npc album set <npc> 1 --cover 2 --label 3="카운트 다시 세기 (11번째)"
|
|
57
|
+
wji npc album rm-photo <npc> 1 4 -y
|
|
58
|
+
wji npc album rm <npc> 2 -y
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Photos are an asset id, a local file (uploaded) or a URL, each optionally
|
|
62
|
+
`:caption`. The first photo is the cover unless you pick one.
|
|
63
|
+
|
|
64
|
+
Writing them:
|
|
65
|
+
|
|
66
|
+
- **2–5 albums**, each tied to a place or period that also appears in her
|
|
67
|
+
memories, key events or current focus.
|
|
68
|
+
- **3–9 photos** per album. Mix shot sizes: one wide of the place, one close
|
|
69
|
+
of her face, one detail (hands, an object from her props).
|
|
70
|
+
- **Captions in her voice**, short, like she labelled her own phone roll —
|
|
71
|
+
not descriptions of the image ("브릿지 첫 동작", not "A woman dancing").
|
|
72
|
+
- **Description**: one or two sentences of *when and why*, written by her or
|
|
73
|
+
about her, in her language.
|
|
74
|
+
- Reuse what you made for the visual kit (hero, gallery shots, props,
|
|
75
|
+
scenes) before generating more.
|
|
76
|
+
|
|
77
|
+
### Making album photos
|
|
78
|
+
|
|
79
|
+
Candid phone photos of her, generated with her references so it's always the
|
|
80
|
+
same person — **confirm with the creator first** (about 14 credits each at
|
|
81
|
+
1080p / high):
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
wji gen image -m gpt-image-2.5-flare-fal -r 3:4 \
|
|
85
|
+
--ref <headshotAssetId> <characterSheetAssetId> [<outfitAssetId>] [<sceneAssetId>] \
|
|
86
|
+
--set resolution=1080p quality=high --wait --json \
|
|
87
|
+
-p "Candid smartphone photo of the woman from image 1 (same face, same build as image 2), <what she is doing>, <where, time, light>. Slightly imperfect framing, natural light, photorealistic, no text, no logos."
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Look at every photo before adding it: same face, right outfit for the
|
|
91
|
+
moment, nothing that contradicts the story (wrong season, wrong city). Reject
|
|
92
|
+
and regenerate rather than add a different-looking person.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# What the runtime actually reads
|
|
2
|
+
|
|
3
|
+
Today the persona reaches a model in one place: **NPC Live**. There is no
|
|
4
|
+
DM chat, no autonomous posting and no text-to-speech yet. A live turn is: the
|
|
5
|
+
reply model writes `SAY` (spoken line) and `ACT` (one English sentence of
|
|
6
|
+
upper-body action), then a video model performs it on the stage's keyframe.
|
|
7
|
+
Fields outside the lists below show on the profile only.
|
|
8
|
+
|
|
9
|
+
## The reply model's system prompt, in order
|
|
10
|
+
|
|
11
|
+
| # | Section | Fields (limit as read) |
|
|
12
|
+
| --- | --- | --- |
|
|
13
|
+
| 1 | opening | name, handle, role — "You are … live-streaming from your phone" |
|
|
14
|
+
| 2 | Who you are | **selfDescription (400 chars; falls back to bio)**, pronouns, primaryDrive, traits, values, fears |
|
|
15
|
+
| 3 | | origin (300) |
|
|
16
|
+
| 4 | | key events — first **8**, each event 80 chars, "date — event" |
|
|
17
|
+
| 5 | | currentFocus (200), short-term goals, long-term goals |
|
|
18
|
+
| 6 | | memories — **top 3 by emotional weight**, "(type) title: content", content **140** chars, no date |
|
|
19
|
+
| 7 | Voice | speechPattern; **"Live speaking tone — match this closely:" (500)**; **"How you talk to humans:" humanProtocol (500)**; axes ≤30 or ≥70 as "Your temperament leans: …" |
|
|
20
|
+
| 8 | | trigger keywords → "react with extra energy" |
|
|
21
|
+
| 9 | | avoid topics → "Never discuss: … deflect in character in one sentence" |
|
|
22
|
+
| 10 | stage | the stage's reply direction (`llmInstruction`, 1000) as "Extra direction from your operator" |
|
|
23
|
+
| 11 | stage | event clips she can trigger (title + trigger) |
|
|
24
|
+
|
|
25
|
+
Then the output rules:
|
|
26
|
+
|
|
27
|
+
- **SAY**: in the first `languages` tag language; **≤40 words** (EN, ID) or
|
|
28
|
+
**≤60 characters** (JP, KR, TW, HK, ZH, TH, VI); 1–2 sentences, speakable in
|
|
29
|
+
under 12 s; no markdown, emoji or quotes; never mentions being an AI.
|
|
30
|
+
- **ACT**: English, one sentence under 30 words, face / hands / upper body,
|
|
31
|
+
locked camera; plus "Your usual behaviour on camera:" **live.action (300)**
|
|
32
|
+
and the stage `instruction` (300).
|
|
33
|
+
- Only the last 4 turns of the conversation are remembered.
|
|
34
|
+
- After 20 s of silence she chatters on her own (up to 5 times in a row),
|
|
35
|
+
about `currentFocus` (120) and her top 3 trigger keywords.
|
|
36
|
+
|
|
37
|
+
Consequences for writing:
|
|
38
|
+
|
|
39
|
+
- Anything over the limits is cut mid-sentence — front-load.
|
|
40
|
+
- The model imitates the **shape** of the speaking tone. Sample lines longer
|
|
41
|
+
than one SAY teach it to ramble, then get truncated.
|
|
42
|
+
- Memories 4+ by weight are invisible live; key events 9+ too.
|
|
43
|
+
|
|
44
|
+
## The video side
|
|
45
|
+
|
|
46
|
+
Every clip and reply video adds a performance-style line built from:
|
|
47
|
+
|
|
48
|
+
- `speechPattern` → body language: formal "composed and poised", casual
|
|
49
|
+
"relaxed", poetic "dreamy and soft", robotic "precise and minimal",
|
|
50
|
+
archaic "graceful and ceremonious"
|
|
51
|
+
- axes ≤30 or ≥70 → "leaning X in demeanor"
|
|
52
|
+
- the first **3 traits**
|
|
53
|
+
- `live.action` (300) as "On-camera habits"
|
|
54
|
+
|
|
55
|
+
So the first three traits should be ones you can *see*, and live.action must
|
|
56
|
+
be visible, repeatable upper-body habits in English.
|
|
57
|
+
|
|
58
|
+
**Keyframe images** (gpt-image-2) read: the visual style line, "Subject:
|
|
59
|
+
name — selfDescription (240)", the first 5 traits, all aesthetic keywords, the
|
|
60
|
+
reference images (headshot → full body → outfits → props → scene), the
|
|
61
|
+
stage's framing preset, scene description, frame tune and instruction.
|
|
62
|
+
|
|
63
|
+
## Voice sample
|
|
64
|
+
|
|
65
|
+
The only voice field is the uploaded voice sample (web). It is used as
|
|
66
|
+
**reference audio** by *reference-mode* video models for clips with
|
|
67
|
+
dialogue. Stages default to a first/last-frame reply model, which does not
|
|
68
|
+
take audio — so the sample shapes greeting / talk clips but usually not live
|
|
69
|
+
replies. There is no voice id or TTS style to write.
|
|
70
|
+
|
|
71
|
+
## Going live — the readiness gate
|
|
72
|
+
|
|
73
|
+
`wji npc readiness <npc>` must show *can prepare: yes* before a stage can be
|
|
74
|
+
made. It requires: selfDescription > 10 chars, humanProtocol > 10 chars, at
|
|
75
|
+
least one trait, a headshot, and at least one scene. (The web wizard does not
|
|
76
|
+
fill humanProtocol — new NPCs fail the gate until you write it.)
|
|
77
|
+
|
|
78
|
+
The "soul integrity" percentage on the profile counts selfDescription,
|
|
79
|
+
primaryDrive, traits, origin, humanProtocol, currentFocus and legacy
|
|
80
|
+
in-soul memories — memories added through the memory table don't count, so a
|
|
81
|
+
complete new NPC can show 86%. That number is cosmetic.
|
|
82
|
+
|
|
83
|
+
## Things that look like they matter but don't (yet)
|
|
84
|
+
|
|
85
|
+
| Field / hint | Reality |
|
|
86
|
+
| --- | --- |
|
|
87
|
+
| Memories in the character document | ignored by the document route — use `--sync-memories` or `wji npc memory` |
|
|
88
|
+
| npcProtocol ("how NPCs talk to each other") | stored, never sent to a model |
|
|
89
|
+
| activityLevel / postFrequency ("how often it posts") | nothing posts |
|
|
90
|
+
| creationStory, dataSourceNotes | profile only — move the important scene into a memory |
|
|
91
|
+
| jobs, relationships, albums | profile timeline / graph / photos only — keep them consistent with key events and memories (life.md) |
|
|
92
|
+
| tagline, genre, colour, socials | profile only |
|
|
93
|
+
| bio | only when selfDescription is empty |
|
|
94
|
+
| stage "instruction — not sent to the reply model" (web hint) | it is sent, as part of the ACT rule |
|
|
95
|
+
| unknown keys via `wji npc soul set` | stored silently, used by nothing |
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Writing a live stage
|
|
2
|
+
|
|
3
|
+
A stage is one filming setup the character inhabits for hours: a start
|
|
4
|
+
frame (keyframe A, plus optional B–D poses), idle loops that play while she
|
|
5
|
+
waits, a greeting, and per-turn reply videos. You are the director: some of
|
|
6
|
+
what you write is **performed by an image / video model (English)**, some is
|
|
7
|
+
**spoken by her (her language)**, and some steers **what she says (any
|
|
8
|
+
language)**.
|
|
9
|
+
|
|
10
|
+
| Field | Who reads it | Language |
|
|
11
|
+
| --- | --- | --- |
|
|
12
|
+
| greeting | spoken in the greeting clip | hers, ≤300 chars, ~10 s |
|
|
13
|
+
| idle prompts | video model, one loop each | English |
|
|
14
|
+
| keyframes | image model, extra resting poses | English |
|
|
15
|
+
| instruction | keyframe image, every clip, every reply video **and** the reply model's ACT rule | English |
|
|
16
|
+
| frame tune | keyframe image | English |
|
|
17
|
+
| reply direction (`llmInstruction`) | reply model only — what she says | any |
|
|
18
|
+
|
|
19
|
+
## 1. Give the stream an occasion
|
|
20
|
+
|
|
21
|
+
Why is she live **right now, here**? "After closing, the last month of the
|
|
22
|
+
old shop", "rain day, can't go out", "unboxing fan letters after a show".
|
|
23
|
+
The occasion decides the greeting, the mood, the idle loops and what she
|
|
24
|
+
keeps steering back to. Put it in the label. One stage = one occasion; make a
|
|
25
|
+
second stage for a different one.
|
|
26
|
+
|
|
27
|
+
## 2. The greeting is a hook, not a welcome
|
|
28
|
+
|
|
29
|
+
One or two sentences in her speaking tone that acknowledge the moment and
|
|
30
|
+
invite **one specific answer** — about ten seconds spoken, so **≤60
|
|
31
|
+
characters** in Japanese / Chinese / Korean, ≤30 words in English (the 300
|
|
32
|
+
limit is only a hard cap) ("講低你最鍾意食邊樣" — "tell me your
|
|
33
|
+
favourite"). Never "welcome to my stream". It plays as a pre-rendered clip,
|
|
34
|
+
so it must make sense to anyone arriving.
|
|
35
|
+
|
|
36
|
+
## 3. Idle loops are a person waiting
|
|
37
|
+
|
|
38
|
+
They play whenever she is not replying, back to back, so they must loop:
|
|
39
|
+
|
|
40
|
+
- one English line each, face / hands / head / upper body only
|
|
41
|
+
- start and end in the start frame's neutral pose
|
|
42
|
+
- 3–5 loops across different energies: calm, curious, amused, waiting for an
|
|
43
|
+
answer
|
|
44
|
+
- reuse her `live.action` habits so the loops feel like her
|
|
45
|
+
- only objects that are in the scene image — look at the creator's scene
|
|
46
|
+
first (`wji npc readiness` lists scenes; the image is on the web). If no
|
|
47
|
+
scene exists yet, write the scene description with the creator first and
|
|
48
|
+
name only objects it will contain
|
|
49
|
+
|
|
50
|
+
Good: "wipes the counter slowly with a cloth, glances at the phone, small
|
|
51
|
+
smile" · "tunes one string, frowns, then laughs with her eyes shut".
|
|
52
|
+
Bad: "walks to the window" · "picks up a cup that isn't there" · "camera
|
|
53
|
+
slowly zooms in" · "her friend waves from the door".
|
|
54
|
+
|
|
55
|
+
## 4. Instruction: the visual mood in one breath
|
|
56
|
+
|
|
57
|
+
Lighting, time of day, atmosphere, in English, one or two sentences:
|
|
58
|
+
"Small Hong Kong dessert shop after closing, fluorescent tube light with one
|
|
59
|
+
warm lamp at the counter, steam from a pot, quiet late-night mood."
|
|
60
|
+
It is also added to every reply's ACT rule, so it must describe a mood she
|
|
61
|
+
can stay in — not an action. Don't list props that aren't in the scene image.
|
|
62
|
+
|
|
63
|
+
## 5. Reply direction is about speech
|
|
64
|
+
|
|
65
|
+
What tonight is about, what to steer toward and away from, what to plug, how
|
|
66
|
+
to treat trolls and repeat questions, how short to keep answers. Never
|
|
67
|
+
visuals. Write it as notes from a producer in the talkback:
|
|
68
|
+
|
|
69
|
+
> 答得短,好似喺櫃面同熟客傾偈。今晚重點:舊舖最後一個月、新歌寫到一半。
|
|
70
|
+
> 有人問搬舖就講實話但唔好賣慘,一句帶過再問返對方。
|
|
71
|
+
|
|
72
|
+
It stacks on top of the character's own human protocol — don't repeat it,
|
|
73
|
+
add tonight's specifics.
|
|
74
|
+
|
|
75
|
+
## 6. Keyframes and frame tune
|
|
76
|
+
|
|
77
|
+
- Frame preset: `selfie` (arm's length, phone in hand), `phoneStand` (phone
|
|
78
|
+
propped on a table — hands free for props and instruments), `studio`
|
|
79
|
+
(proper camera setup), `custom` (write the frame prompt yourself).
|
|
80
|
+
- Keyframes B–D are the **same shot** with a different resting pose ("leaning
|
|
81
|
+
on the counter, chin on hand"); the reply video picks the closest one, so
|
|
82
|
+
2–3 poses make replies feel less frozen.
|
|
83
|
+
- Frame tune is photographic language only: "warmer light on her face",
|
|
84
|
+
"less clutter on the counter", "slightly lower angle".
|
|
85
|
+
|
|
86
|
+
## 7. Aspect ratio and video model
|
|
87
|
+
|
|
88
|
+
- 9:16 for a phone-stream feel (most NPC City viewers are on phones); 16:9
|
|
89
|
+
for a desk / studio show.
|
|
90
|
+
- Leave out the `Video model` line so the stage keeps the default
|
|
91
|
+
first/last-frame model; the stage document rejects reference models.
|
|
92
|
+
|
|
93
|
+
## 8. Consistency pass
|
|
94
|
+
|
|
95
|
+
- Greeting, instruction, idle loops and reply direction all belong to the
|
|
96
|
+
same occasion and time of day.
|
|
97
|
+
- Every English field is English; the greeting is in her language.
|
|
98
|
+
- Nothing leaves frame, stands up, moves the camera, cuts, adds props or
|
|
99
|
+
people.
|
|
100
|
+
- It still makes sense to a viewer who joins forty minutes in.
|
|
101
|
+
|
|
102
|
+
## What costs credits
|
|
103
|
+
|
|
104
|
+
Writing, importing and applying stage documents is free. Rendering is not:
|
|
105
|
+
the start frame (image), every clip (video), transitions, and — when the
|
|
106
|
+
stage is on air without debug mode — **every live reply**, charged to the
|
|
107
|
+
owner (a session stops at 6000 credits). Render and enable on the web, with
|
|
108
|
+
the creator's go-ahead. Debug mode (`wji npc stage set <id> --debug on`)
|
|
109
|
+
skips reply videos for rehearsal.
|