> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.loreos.app/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.loreos.app/_mcp/server.

# Story Room and life simulation

LoreOS characters should not only react to user messages. They should have a life rhythm:
small obligations, quiet days, social contact, visual moments, and occasional friction.

Story Room is the runtime layer that produces that narrative state.

## What Story Room creates

Story Room does not send chat messages directly. It creates state packages that the
runtime may later use:

* **weekly soft arcs** — a non-railroading direction for the week;
* **daily-life packages** — compressed time blocks for what happened today;
* **candidate beats** — possible small events, frictions, callbacks, or quiet moments;
* **scene cards** — concrete scenes the character can safely reference;
* **proactive-hook candidates** — possible reasons to initiate a message;
* **safe runtime context** — the safe subset the chat actor may use.

## Generated does not mean true

Story Room follows lifecycle boundaries:

* generated candidates are not true;
* accepted candidates are not automatically visible;
* committed events are not automatically revealed;
* private plans and branch forecasts are never runtime input.

This lets the system explore story possibilities while preserving continuity and user
agency.

## Daily life, not daily melodrama

The goal is not to create a dramatic event every day. A believable character has:

* low-stakes routines;
* small external frictions;
* contact with supporting cast;
* quiet recovery days;
* occasional arc movement;
* user-influenced branches.

The chat runtime can then answer "what did you do today?" from a grounded state package
instead of inventing a day from scratch.

## Example: before and after

Without a stateful daily-life layer, characters often answer from a generic vibe:

```text
User: what did you do today?
Character: I was just thinking about you.
```

With LoreOS, the reply can come from state the runtime prepared earlier:

```text
User: what did you do today?
Character: I had lunch with Jungah near the flower market, then spent the afternoon
finishing a small arrangement order. Tiny thing, but I noticed my flower scissors were
getting dull — it made me realize I've been putting off tool maintenance.
```

## Example: daily-life package

The exact internal schema can vary by runtime version, but the shape of the state is:

```json
{
  "weekly_arc": "Yura becomes more realistic about opening a small flower workspace.",
  "daily_life_package": {
    "day_type": "workday_with_social_contact",
    "primary_beat": "Yura notices her flower scissors are getting dull during an arrangement order.",
    "time_blocks": [
      "morning: checks flower supply notes",
      "lunch: talks with Jungah about market prices",
      "afternoon: works on a small arrangement order",
      "evening: sends a short message about tomorrow's flower prices",
      "night: writes a note to maintain her tools"
    ],
    "safe_to_share": [
      "I had lunch with Jungah near the flower market.",
      "My flower scissors felt dull today, so I need to get them sharpened."
    ],
    "do_not_reveal": [
      "future workspace payoff",
      "private branch forecasts"
    ]
  }
}
```

This is the product difference: the chat actor is not inventing a day from nothing. It is
speaking from safe context created by the character runtime.

## What drives Story Room generation

The typed authoring fields are **wired into Story Room generation today** — they are not
planning-only placeholders. When you author a character, these fields directly shape the
weekly arcs and daily-life packages the engine produces:

* `life_template` → the ordinary daily/weekly rhythm the day is built from;
* `story_engine` → recurring tensions, allowed event sources, and supporting cast that
  events are grounded in;
* `arc_seeds` → soft weekly direction (the questions the week leans into);
* `character_direction`, `relationship_seed`, `emotion_baseline` → tone and constraints;
* `profile.aspiration` / `life_direction` / drama dials → where the evolving life is
  heading (the north-star lever against a flat, aimless character).

See [Character authoring](https://docs.loreos.app/guides/character-authoring),
[Recipe: a production-grade dating character](https://docs.loreos.app/guides/recipe-a-production-grade-dating-character),
and [Character bundle imports](https://docs.loreos.app/guides/character-bundle-imports)
for how to set these fields from either direct character authoring or an import bundle.

## API status

Available today:

* managed runtime replies;
* sessions and event logs;
* character readiness and runtime preview;
* visual assets, visual readiness, and image probes;
* Story Room state generated from your authored fields and used inside the managed runtime;
* redacted Character World life, agenda, offscreen heartbeat, scene, and candidate-review APIs.

### Run modes are not read-only

`POST /v1/characters/{slug}/story-room/runs` always creates an inspectable run
ledger. Choose the mode by its persisted and activated outcome:

| Mode         | Persists                                        | Activates runtime safe slice                | Commits canon                |
| ------------ | ----------------------------------------------- | ------------------------------------------- | ---------------------------- |
| `db_shadow`  | Run ledger and life-event candidates            | No                                          | No                           |
| `review`     | Run ledger, candidates, and review safe slice   | Only when `activate_review_safe_slice=true` | No                           |
| `autocommit` | Run ledger, candidates, and admitted life state | Yes                                         | Subject to runtime admission |

Do not classify `db_shadow` as a read or dry run: it writes the database and can
create review candidates even though it does not activate runtime/canon state.
OpenAPI exposes the same distinction in `x-loreos-mode-effects` so an agent does
not need a path-name heuristic.

Use these Character World APIs to read and steer generated life state without opening the admin
cockpit:

```http
GET   /v1/characters/{slug}/life
GET   /v1/characters/{slug}/agenda
GET   /v1/characters/{slug}/agenda/items
GET   /v1/characters/{slug}/agenda/items/{agenda_item_id}
PATCH /v1/characters/{slug}/agenda/items/{agenda_item_id}

GET   /v1/characters/{slug}/offscreen/heartbeat
GET   /v1/characters/{slug}/offscreen/opportunities
GET   /v1/characters/{slug}/offscreen/scenes
GET   /v1/characters/{slug}/offscreen/deltas

GET   /v1/characters/{slug}/life-event-candidates
POST  /v1/characters/{slug}/life-event-candidates/{candidate_id}/approve
POST  /v1/characters/{slug}/life-event-candidates/{candidate_id}/approve-with-edits
POST  /v1/characters/{slug}/life-event-candidates/{candidate_id}/reject
POST  /v1/characters/{slug}/life-event-candidates/{candidate_id}/request-alternatives

GET   /v1/characters/{slug}/storylines
POST  /v1/characters/{slug}/storylines
POST  /v1/characters/{slug}/story-room/runs
GET   /v1/characters/{slug}/story-room/runs/{run_id}
GET   /v1/characters/{slug}/storylines/{storyline_id}
PATCH /v1/characters/{slug}/storylines/{storyline_id}
POST  /v1/characters/{slug}/storylines/{storyline_id}/activate
POST  /v1/characters/{slug}/storylines/{storyline_id}/archive

GET    /v1/characters/{slug}/daily-arc-influences
POST   /v1/characters/{slug}/daily-arc-influences
GET    /v1/characters/{slug}/daily-arc-influences/{influence_id}
PATCH  /v1/characters/{slug}/daily-arc-influences/{influence_id}
DELETE /v1/characters/{slug}/daily-arc-influences/{influence_id}
```

`PATCH /agenda/items/{agenda_item_id}` records operational status, hold time, and a developer note.
It does not expose or edit private agenda payloads. To author new story pressure, use storylines or
daily arc influences.

Use `POST /storylines` for multi-day or multi-beat pressure you planned in advance. Use
`POST /daily-arc-influences` when you want to steer one date's Story Room generation. A
`planner_hint` influence stays as planning pressure. A `scene_hook` influence can also
materialize an operational offscreen arc, so the character has a concrete reason for the
day to move without exposing the private source payload. `forbidden_reveals` stay out of
safe beat reveals and are treated as do-not-force constraints.

Life-event candidate review is separate from the Story Room safe-slice approval API. Candidate review
marks a proposed trajectory as accepted, rejected, or deferred for alternatives; it does not directly
activate a runtime safe slice. Raw prompts, provider payloads, source inputs, private agenda payloads,
and raw offscreen transcripts are excluded from these projections.