An AI character can sound consistent while getting a basic scene fact wrong. In a short test, our opening message placed a brass key on a desk. When asked to list the current state, the model assigned the key to the character instead.
That is a small error with a large consequence: the next scene may now depend on an item transfer that never happened.
This tutorial separates character personality from scene state and implements a small, human-reviewed state worksheet. It does not add memory to a model. It gives the person writing the story a way to inspect what changed before asking the model to continue.
Disclosure: this project is maintained by the CrushOn.AI team. The demonstration used CrushOn.AI, and the worksheet is platform-neutral. AI assisted with drafting and implementation. The chat observations below are from a recorded manual demonstration, not a benchmark or a comparison with other products.
Personality and state answer different questions
A character brief answers questions such as “What does Iris value?” and “How does she respond under pressure?” A scene snapshot answers “Where is Iris now?” and “Who has the key?”
Do not rewrite a stable personality description every time someone moves to another room. Keep a separate, compact snapshot for facts that change during the story.
For a small scene, start with seven fields:
| Field | What belongs here |
|---|---|
| Location | The current established setting |
| Time | The latest established time |
| Items | Each important item's location or holder |
| Goal | What remains unresolved |
| Constraints | Locked doors, unavailable resources, or other current limits |
| Unknowns | Facts that must not be filled in silently |
| Creative scope | Details the model may invent without changing the facts |
The last two fields matter. “Unknown” is a useful state, not an incomplete sentence that needs a plausible ending.
What happened in the demonstration
On September 5, 2026, we created a private, filtered, safe-for-work character on CrushOn.AI. Iris was an original 32-year-old museum conservator. The interface identified the model as Carina 8K. We sent three messages in one conversation, without regenerating or selecting between replies.
The opening established:
It is 5 pm. We are in the museum archive, and the brass key is on the desk.
We asked the model to list the established location, time, key holder, and unresolved goal, marking anything unestablished as unknown. It returned:
Location: Museum archive
Time: 5 pm
Key holder: Iris Vale
Unresolved goal: Unknown
The location and time matched. The holder did not: nothing established that Iris held the key. This is why reviewing a fluent summary is not enough. Check each claim against the conversation.
Our second message explicitly corrected the earlier state and established a new one: 5:20 pm, museum courtyard, key carried by the adult visitor, ledger carried by Iris, archive locked, and a missing inventory label to investigate.
The reply correctly listed the updated location, time, key holder, and goal. It did not list the ledger or locked archive, so that reply alone could not confirm those additional facts.
Finally, we asked for two sentences proposing a next step without deciding the visitor's actions. The reply was:
Iris shifts the heavy ledger under her arm, glancing toward the row of display cases lining the courtyard.
"Since we can't access the archive files right now, we should probably do a manual sweep of the gallery."
It preserved the ledger's holder and treated the archive as inaccessible. But it also added display cases in the courtyard, which we had not established. Depending on the story, that may be welcome improvisation or an unwanted change to the map.
This is the reason for an explicit creative scope: allow gestures and tone while reserving changes to layout, access, and item ownership for user confirmation.
Store a reviewed snapshot, not an AI verdict
Our browser worksheet uses plain text fields. Here is a shortened version of the updated state:
const current = {
location: "Museum courtyard",
time: "5:20 pm",
items: "Brass key: adult visitor. Ledger: Iris.",
goal: "Find the case with the missing inventory label.",
constraints: "The archive is locked.",
unknowns: "Which case; whether the key opens the archive.",
freedom: "Gestures and tone; ask before changing the layout."
};
The unknowns field contains an important distinction: possessing a key does not establish which lock it opens. The sample worksheet spells this out as an author-written safeguard. It was not an additional fact retrieved from the model.
Keep this representation small enough to check. For a large world, a separate lore system may be useful, but a scene snapshot should not become a second encyclopedia.
Compare checkpoints with a deterministic function
A comparison function can identify changed text without calling a model:
function diffState(previous, current, keys) {
return keys.flatMap(key => {
const before = (previous[key] ?? "").trim();
const after = (current[key] ?? "").trim();
return before === after ? [] : [{ key, before, after }];
});
}
This example assumes string-valued fields. The accompanying implementation normalizes input, validates imported files, and rejects unsupported formats.
Text comparison has deliberate limits. It will flag “5 pm” changing to “17:00,” even though those may mean the same time. It will not recognize a contradiction hidden inside a paragraph. Do not label its output “verified state” or a memory score.
Render user-entered content with textContent, not innerHTML. The worksheet does not need executable markup. When importing a saved file, validate it before replacing the current work, then ask for confirmation.
Review, export, continue
The practical workflow is:
- Record the established state and save it as a checkpoint.
- Edit the current state when the story establishes a change.
- Compare both snapshots. Check transfers, access, and unresolved goals against the conversation.
- Export a handoff and paste it into the chosen chat interface, if that interface supports ordinary text updates.
- Inspect the next reply for contradictions and unsupported additions.
A handoff can begin:
Use this human-reviewed state as the latest scene update.
It supersedes conflicting earlier scene facts.
Unknown fields are not permission to guess.
Do not decide the user's actions or dialogue.
Ask if the next action depends on a missing fact.
Then include the actual snapshot. Merely saying “remember everything” gives neither the model nor the reader a concrete state to inspect.
The worksheet exports a Markdown prompt and a JSON file containing both snapshots. JSON is for reopening the worksheet—not a native CrushOn.AI, World Card, Target Play, or SillyTavern import format. There is no automatic connection to your chat.
What this does not prove
Three messages in one session do not establish long-term memory, cross-session recall, or a measured improvement from using a worksheet. We did not run a controlled comparison. We also did not test the product's native Target Play functionality.
The useful result is narrower: we observed an unsupported ownership claim, corrected it explicitly, and found another kind of unestablished detail in the continuation. The worksheet turns those observations into questions a reader can check in their own story.
Try the Scene State Worksheet on Hugging Face: choose Open the Scene State Worksheet from the character-brief page. The usage guide, complete demonstration inputs and outputs, and v0.2.0 offline download are available in the repository. The full demonstration record also notes the settings we did not record, so it should not be treated as an exactly reproducible benchmark.
A convincing character voice is not a substitute for a correct scene. Keep the voice in the brief, the changing facts in a snapshot, and the final judgment with the reader.
Top comments (0)