Skip to content

Latest commit

 

History

History
325 lines (240 loc) · 12.4 KB

File metadata and controls

325 lines (240 loc) · 12.4 KB

Perspective Roleplay Driver

Status

This document defines the intended behavior of WorldSharp's built-in Perspective Roleplay Driver. It is a Driver-specific design, not a requirement imposed on third-party Roleplay Drivers.

The implementation has turn selection, audience-keyed message projections, chronologically cached POV history, isolated Character generation, target-history-assisted outward projection, explicit no-perception records, and editable POV variants.

The authored source and all cached POVs are serialized into one Driver-owned, fully editable message document. The active Character's authored source is also that Character's POV; the document does not duplicate it in a same-named POV section.

Purpose

The Driver should simulate one continuous roleplay while giving every participant a different transcript containing only what that participant has experienced.

Each Character:

  • reads other participants' turns as second-person sensory perceptions;
  • reads their own turns in the first person;
  • receives their private Character card, memories, and known world information only when generating their own response;
  • cannot react to dialogue, actions, or private thoughts they did not perceive.

The user also has an audience projection. The UI displays that projection rather than exposing another Character's private first-person source turn.

Core invariants

  1. One participant authors each turn. Selecting Jane means only Jane generates a response. Jess and User do not also respond during projection.
  2. Projection happens before reaction. The selected Character must receive a projection of the newest source turn before generating their reply.
  3. Projection transforms one new source turn. It must not continue the scene, add a reaction, or rewrite earlier events as new events.
  4. Projection uses the target's POV history. It receives that target's established transcript and the newly authored source message, but not another audience's projections.
  5. Private context is for acting, not projecting. Character cards, memories, and private world knowledge are supplied to the Character response call after their POV transcript is complete. The projector normally needs only the target POV history and new source turn.
  6. No perception is explicit. A completed projection that perceived nothing is distinct from a projection that has not been generated.
  7. Projections are cached. Once generated, a source-message/target-audience projection is reused unless the source message or relevant POV history is edited.
  8. Each turn has one authored source. A Character response is stored as one complete first-person content value. It may include private thoughts alongside actions and dialogue; there is no second canonical or private response variant. Projectors isolate the observable portion for each audience.

Transcript form

For a transcript targeting Jane:

  • Jane's own authored messages remain first person.
  • User's and other Characters' messages are stored as what Jane perceived, normally written in second person.
  • An explicit no-perception projection appears as <empty> in model context.

For example:

User: There's a knock on the door, followed by silence.
Jane: Upon hearing the knock, I run to my planned hiding spot.
User: You hear the door crack open, and a footstep or two.
Jane: I wait patiently.

This is Jane's history. It is not an omniscient transcript and must never contain User's private narration merely because another audience saw it.

Turn pipeline

1. Persist the authored source turn

The user sends:

User: "Hello? Anyone around?" I call out.

The source turn is retained exactly as authored as one content value. Any world-state tracking derived from it is separate from the roleplay message and does not create a second actor-response field.

2. Select the next actor

A context-neutral selector chooses which Character should naturally act next. The user is not a candidate. The selector does not use private Character cards or private audience projections.

Assume it selects Jane.

3. Project the source turn into the selected actor's POV

The projector receives:

  • Jane's established POV transcript;
  • the identity of the source speaker;
  • only User's newly authored source message;
  • an instruction to transform that message into Jane's second-person sensory perspective.

Conceptually:

User: There's a knock on the door, followed by silence.
Jane: Upon hearing the knock, I run to my planned hiding spot.
User: You hear the door crack open, and a footstep or two.
Jane: I wait patiently.

INSTRUCTION:
User has just sent a new message from their perspective. Adapt only that new
message into a second-person perspective targeting Jane, consistent with the
POV history above. Do not continue the scene and do not write Jane's response.
Return <empty> if Jane cannot see, hear, smell, taste, or feel anything done in
the message.

User's new message:
"Hello? Anyone around?" I call out.

Expected projection:

You hear a voice call out, "Hello? Anyone around?"

That projection is persisted against User's source message under Jane's audience key.

4. Append the projection to the selected actor's transcript

Jane's completed input history is now:

User: There's a knock on the door, followed by silence.
Jane: Upon hearing the knock, I run to my planned hiding spot.
User: You hear the door crack open, and a footstep or two.
Jane: I wait patiently.
User: You hear a voice call out, "Hello? Anyone around?"

5. Generate only the selected actor's response

The Character-generation call receives:

  • Jane's completed POV transcript;
  • Jane's Character card;
  • Jane's memories;
  • world nodes and relationships Jane currently knows;
  • the Roleplay instructions and relevant Persona information.

It is instructed to act only as Jane in the first person and may include Jane's private thoughts.

Example:

I wait for the right time to jump out. Should I jump out now? Ah, screw it! I
leap from my hiding spot. "RAHHHH!" I storm toward User as fast as I can.

This is Jane's authored source turn and Jane's own projection. No other participant authors text in this call.

6. Project the new Character turn outward

The same projection operation is repeated independently for each required audience, beginning with the user so the message can be displayed.

For User, the projector receives:

  • User's established POV transcript;
  • Jane as the source speaker;
  • Jane's newly authored content, including all scene-setting, sensory details, actions, dialogue, and any private thoughts that the projector must filter.

The source content is not split before projection. The projector must omit private thoughts and other imperceptible material, while introducing newly established locations, objects, people, spatial relationships, environmental conditions, movement, dialogue, and other details that User could perceive. It must not summarize those details away merely because they were not already present in User's history.

It returns what User can perceive, for example:

Jane suddenly leaps from a hiding spot. "RAHHHH!" She charges toward you.

The projector must not add User's reaction. A sentence such as You stumble backward in surprise would be invalid because User has not authored another turn.

WorldSharp projects to the user and every other current Roleplay participant before generating the selected actor's response. The active Character's source line is used directly for that Character and is not reprojected to itself. It does not pre-classify who can perceive the source; each isolated projector makes that determination and may store a no-perception result. By default these are separate requests, all using history ending immediately before the source turn.

For large scenes, the Perspective Driver supports an optional batched mode:

{ "batchReprojection": true }

When enabled, the user and all non-author audiences are sent in one game-master request. The request identifies each target by its unique visible Character or Persona name and includes a separately delimited POV history for each target. The model must return one JSON projection object per name. The Driver validates that every requested audience appears exactly once and that no unknown name is returned. This reduces request overhead without allowing one audience's history to be used as another audience's knowledge.

7. Repeat

The resulting source turn and cached audience projections become history. On the next turn, the selector chooses an actor, that actor's missing newest projection is completed, and only then may they respond.

No-perception projections

<empty> means the projection operation completed successfully and the target audience perceived nothing from that source turn. It must not mean:

  • generation has not run;
  • generation failed;
  • content was deleted;
  • the source message itself was empty.

The durable representation still records perception state separately from content. The model-facing representation uses <empty> as the explicit no-perception sentinel, while the persistence layer stores the equivalent boolean and empty content.

An absent projection record means not generated. A stored record with perceived: false means generated and nothing perceived. Model transcripts serialize the latter as <empty> to preserve turn timing without revealing the private source content.

UI treatment for no-perception turns

The user-facing transcript should not render an empty projection as a normal Character message bubble. It should use a compact interstitial row inspired by Marinara Engine's system/day-separator treatment:

  • a subtle horizontal divider;
  • centered muted text such as Nothing seems to have happened.;
  • no Character avatar or ordinary speech bubble;
  • the normal edit/inspect action remains available.

The display sentence is presentation only and must not be stored as perceived roleplay content or sent back to the model. Nothing seems to have happened. is preferable to (Thought) as the default because it does not reveal that the unseen source turn contained a private thought rather than some other imperceptible action.

Editing or inspecting the row may expose the authored source and all cached POV variants to the user, but hidden variants remain unavailable to Character model calls.

Model response contract

The turn-generation and audience-projection calls return plain roleplay text, not JSON. The actor call returns only the selected Character's authored prose:

I wait for the right moment, then leap from my hiding spot.

The projection call returns only the target's sensory rendering:

You hear movement behind you, followed by a sudden shout.

If nothing was perceived, it returns exactly:

<empty>

The driver still keeps structured parsing for orchestration-only operations such as selecting the next Character. Those control values are not roleplay prose.

Validation should reject:

  • blank actor or projection output;
  • any projection output other than exactly <empty> when it represents no perception;
  • extra dialogue, action, thought, or reaction authored for the target;
  • multiple audience outputs in one isolated projection request.

Context and privacy boundaries

Operation Receives target POV history Receives source turn Receives target private context
Turn selection No Authored/source chronology No
Source-to-target projection Yes Exactly one new turn No
Selected Character response Yes, including newest projection No separate unprojected turn Yes
User/other-audience display projection Yes Exactly one new turn No

The important distinction is that the all-seeing game-master role is an orchestration role, not an invitation to place omniscient context into every request. Each projection call is still bounded by the target's established POV.

Editing and invalidation

The editor should continue to show the authored source and cached POV variants separately. Explicit no-perception projections must also be inspectable and editable.

Editing an authored source turn invalidates all projections derived from it and all later generated turns that depend on those projections. Editing one cached projection invalidates later responses generated from that audience's POV history. Regeneration must never silently combine stale and updated histories.