3. Give Rowan a voice and offer choices
Use the previous finished pack. Split its opening into three strings: the bench, Rowan’s spoken invitation, and the dry soil. A paragraph is one string without embedded newlines. Create an actor reader card with stable ID rowan; this gives the dialogue a named, public speaker.
Attach speech to exact text
Section titled “Attach speech to exact text”The dialogue annotation points to paragraph index 1 (indices begin at zero), the SHA-256 of that paragraph’s exact UTF-8 bytes, actor rowan, and the exact quote. occurrence: 1 means the first matching quote. This example makes the spoken quote its whole paragraph, which will also support VN performance later.
After changing punctuation, spacing or language, recompute the digest. From the extracted bundle folder:
python3 -c 'import json,hashlib; p=json.load(open("start/pack.json",encoding="utf-8")); print(hashlib.sha256(p["entries"][0]["opening"][1].encode()).hexdigest())'On Windows use py -3 instead of python3. Paste the result into the annotation’s paragraph_digest. Do not hash the JSON quotation marks or escaped representation. The Chinese and English editions therefore have different digests.
Choose how suggestions appear
Section titled “Choose how suggestions appear”| Mode | What you author | What to expect |
|---|---|---|
disabled |
count: 0, empty items |
No runtime action suggestions |
semantic_match |
A nonempty authored pool and count 1–3 | The host selects relevant authored options; it does not invent this pool |
inline_llm |
Count 1–3, no authored items | The host generates contextual suggestions with the prose |
The bundle’s variants/disabled, variants/semantic_match, and variants/inline_llm are complete alternatives. Validate each pack.json; copy the chosen suggestions object into your draft. The finished example uses inline_llm. Suggestions offer actions; they are not proof that an action occurred and must not increment the state by themselves.
Set revision to 4. Expected structural result: all three variants pass. Expected private trial: Rowan’s quote has the correct speaker; disabled yields no suggestions; authored mode draws from your pool. If dialogue loses its speaker, check the actor card, quote, occurrence and digest. Do not assume a raw schema check detects stale text anchors.
Check your work locally
From the extracted bundle folder, create the environment and install the pinned dependencies once. Then check both files, and repeat the start check after your edits. The same commands work for every lesson.
macOS / Linux
python3 -m venv .venv
.venv/bin/python -m pip install -r requirements.txt
.venv/bin/python check.py start/pack.json
.venv/bin/python check.py finished/pack.jsonWindows PowerShell
py -3 -m venv .venv
.venv\Scripts\python.exe -m pip install -r requirements.txt
.venv\Scripts\python.exe check.py start/pack.json
.venv\Scripts\python.exe check.py finished/pack.jsonExpected for the finished pack: Structural check passed: Creator Pack 0.3 followed by the exact Schema SHA-256. This is a structural check, not host admission or a live playtest.
Working excerpt from the finished pack
This excerpt is generated from the tested download. It is not a complete pack; edit the named fields inside start/pack.json or compare finished/pack.json.
{
"suggestions": {
"mode": "inline_llm",
"count": 3
},
"text_annotations": [
{
"paragraph_index": 1,
"paragraph_digest": "a47644e19452bd7a211d0bdd48fd61bc621c6f8b15e2928d78c3e2abbe7201dd",
"annotations": [
{
"kind": "dialogue",
"actor_id": "rowan",
"quote": "“I haven't closed up yet. Would you like to look at this little one with me?”",
"occurrence": 1
}
]
}
]
}Look up the fields: entries · reader_cards