2. Make care change the story
Start from Lesson 1’s finished draft, or the complete start folder in this download. This lesson adds two public integers: moisture and trust, each from 0 to 2. Here trust means completed shared care, not a hidden reading of Rowan’s feelings.
Separate an observation from a rule
Section titled “Separate an observation from a rule”Add the state fields to runtime.state.schema.properties, list them in required, set their defaults to 0, and give /moisture and /trust readable display labels. The schema says what values exist; defaults say where a new visit begins.
Copy the action choice observation and record_care update rule from the worked excerpt into runtime.observations and runtime.rules. Keep the IDs and paths exactly matched. The observation asks what the reader completed. Its answers are none and tend. The rule adds 1 to each state value only when the answer is tend; limit: 2 caps repeated care.
The notice_care guidance tells the writer to acknowledge damp soil and Rowan’s thanks when moisture reaches 1. Guidance shapes the next generation; it does not itself modify state. Observation interpretation belongs to the host’s model, so clear wording matters.
Rehearse before a service trial
Section titled “Rehearse before a service trial”| Authored observation supplied to the state engine | Moisture | Trust |
|---|---|---|
| Initial state | 0 | 0 |
none — “I might water it later” |
0 | 0 |
tend — one completed care action |
1 | 1 |
tend — a second completed care action |
2 | 2 |
tend — further care |
2 | 2 |
These deterministic state transitions are checked by this site’s tests with authored observation values. They are not a claim that a model has correctly interpreted those sample sentences in a live trial. During private play, inspect both the observation and the resulting state.
Set revision to 3, then use Lesson 1’s command on your edited pack. A misspelled /moisturee can pass a simple JSON shape check yet fail host semantic validation. Compare IDs, JSON pointers and state definitions when the host rejects a structurally valid pack. Keep secrets out of these public fields.
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.
{
"state": {
"schema": {
"type": "object",
"properties": {
"scene": {
"enum": [
"greenhouse"
]
},
"moisture": {
"type": "integer",
"minimum": 0,
"maximum": 2
},
"trust": {
"type": "integer",
"minimum": 0,
"maximum": 2
}
},
"required": [
"scene",
"moisture",
"trust"
],
"additionalProperties": false
},
"defaults": {
"scene": "greenhouse",
"moisture": 0,
"trust": 0
},
"display": {
"/scene": {
"label": "Location"
},
"/moisture": {
"label": "Soil moisture"
},
"/trust": {
"label": "Shared care"
}
}
},
"observations": [
{
"id": "action",
"type": "choice",
"question": "Which action did the reader complete in this turn? Ignore intentions, suggestions, quotations and memories. Choose none if no listed action was completed.",
"choices": {
"none": "No listed action completed.",
"tend": "The reader completed one small watering/care task with Rowan."
}
}
],
"rules": [
{
"kind": "update",
"id": "record_care",
"when": {
"op": "observed",
"id": "action",
"value": "tend"
},
"effects": [
{
"op": "increment",
"path": "/moisture",
"by": 1,
"limit": 2
},
{
"op": "increment",
"path": "/trust",
"by": 1,
"limit": 2
}
]
},
{
"kind": "guidance",
"id": "notice_care",
"when": {
"op": "gte",
"path": "/moisture",
"value": 1
},
"instruction": "Notice the damp soil and Rowan's thanks. Never turn a suggested action into a completed one."
}
]
}Look up the fields: runtime