A Universe is the single owner of mutable roleplay/world state. Every runtime experience belongs to exactly one Universe. Interfaces may observe and propose changes, but none silently maintains a competing copy of the world.
Reusable templates are different from Universe state. Character Cards and future Content Packs can be reused; Character Instances, messages, chronology, memories, world state, and accepted history belong to one Universe and must not leak back into reusable material.
Undefined space is valid state. A Universe does not need a complete generated map or place hierarchy before play begins. Places become canonical when play establishes them or the user explicitly designs them. A tracker should prefer no node over an unsupported one, and lorebook mentions are not instructions to instantiate every location.
This is deliberate headroom for collaborative invention. Speculative pre-generation can constrain later scenes; explicit setting or map generation should instead be a reviewable creative operation.
The intended world model combines a canonical containment tree with typed relationships:
- containment answers "inside", navigation, and primary placement questions;
- directed typed relationships answer other factual questions;
- ordinary entities may have no canonical parent;
- specialized concepts such as Character Instances remain specialized while having a world-graph representation.
Do not begin with one universal property-bag Node. Concrete types for
Locations, Items, Memories, schedules, and other concepts should be introduced
when real invariants are known. Their graph identity is a cooperation seam, not
an excuse to erase specialized state.
Personas are library identities, but a Persona selected by a conversation is also represented by one root World Node in that Universe. The node keeps a durable Persona identity rather than relying on its display name, so reused Personas do not create duplicates. Persona descriptions remain profile/source material and are not silently promoted to transcript-backed canon.
Canonical state is a projection of accepted append-only commits. Driver and import experiments stage typed events on branches and do not mutate the projection directly. Summaries, messages, lorebook entries, and imported ranges are evidence; they are not world events merely because they describe something.
Knowledge must remain explainable at the same boundary. A model-extracted fact, state, or memory is not acceptable as an unattributed sentence inside a larger text block. It must retain the message or exact range that supports it. Imported or user-authored setting context may have source-record provenance without a chat message, but it must be labelled as context rather than pretending to be an observed event.
For live conversation, the intended commit unit is a completed in-universe day, not an arbitrary Tracker invocation. A Vibe-Time Roleplay should offer a review when narration crosses into the next day. A Real-Time Convo should offer the same review at 4:00 AM in the Universe timezone, matching Marinara's daily summary rollover. The review seals the exact range, runs Tracker, stages typed changes in a temporary world-change review, and asks whether to apply them to canon. Committing closes that chat segment without rewriting its immutable messages; the accepted events are then projected into the canonical world-node tree.
The graph should grow through focused typed events and models rather than arbitrary metadata. Likely additions include explicit Location and Item semantics, Character location/status, object transfer, stable Character memories, schedules, availability, and temporal boundary events.
WorldNode.Content is too coarse to be the long-term source of truth. The
intended model stores independently reviewable knowledge records and projects
the currently relevant records into Driver context. Initial semantic kinds are:
- Context: authored or imported background material and activation-driven prompt context. It may be useful without claiming that play established it.
- Fact: a durable claim about the world. A "fun fact" is presentation, not a different persistence invariant.
- State: a condition that may start, end, or become historical, such as a Character being stressed during a particular week.
- Memory: a Character-owned recollection, learned association, belief, or remembered event, such as associating a squeaky chair with a rubber duck.
Each record should have stable identity, target node and optional Character subject, text, activation metadata, semantic kind, review/supersession state, created time, and immutable source provenance. Generated facts, states, and memories require exact evidence message IDs or a sealed source range. Imported lore may instead cite its immutable source record. A manual entry cites the user as its author; it does not need a fictional chat source.
Temporal metadata must distinguish when a record was created from when it was true or experienced. A record can use a real instant/interval, Story Day or Story Week, Game Session, or explicitly unknown narrative time. Applicability dates are not universally mandatory: timeless context and durable facts do not need invented dates, while a state must be capable of ending and a historical memory should retain an experienced/learned time when the evidence supplies it. Unknown is better than fabricated precision.
The UI should present these as separate entries, expose their source, and jump from message-backed entries to the referenced transcript. Chat context assembly may still inject all relevant entries through activation words, but expired states should be historical context rather than current state and Character memories should be scoped to that Character.
Import should ingest lore and raw source metadata early without immediately flattening it into node prose. Historical chat replay should run first. A final reviewable reconciliation pass can then compare imported context with message-backed records, propose exact duplicate merges, preserve complementary details, and surface contradictions. The model may propose reconciliation, but must never destructively combine or discard source records on its own.
Cross-tree relationships should continue to be separate from containment. The relationship type is currently a normalized string so real usage can reveal the vocabulary before freezing a registry. A future registry may add validation and extension contributions without rewriting existing identity.
Rollback should remain history-preserving: prepare changes from a historical commit, inspect them, and either discard them or promote compensating events as a new canonical commit. Database reset or history rewriting is not the desired model. Persistent parallel world snapshots, if added later, require their own explicit product model and must not borrow conversation-timeline terminology.
Time remains a required Core policy because it affects every Interface, schedule, summary, tracker run, and historical query. Future work includes automatic conversation day-close boundaries, Story Day and Game Session boundaries, schedules, boundary Drivers, and Real-Time ambient updates. Optional modes must not own the meaning of Universe chronology. Boundary detection may be automatic, but canonical commits remain review-first; a background 4:00 AM rollover must create a recoverable review prompt rather than silently commit.
The long-term import/content model should retain source provenance, separate deterministic Content Packs from mutable Universes, and make AI reconstruction review-first. See Tavern Compatibility and Imports.
Universe has stable identity, name, a strongly typed TimeModel, and a stable
time-policy ID. Built-in policies are:
worldsharp.time.real;worldsharp.time.vibe;worldsharp.time.game.
TimeModel.GameTime is the current Core name; TurnBased remains only as an
obsolete source-compatibility alias. UniverseTimeState persists timezone,
pause state, logical/update instants, Story Day, and Game Session counters. Real
Time advances from its logical anchor while running. Pause, resume, explicit
catch-up, and jump are distinct operations; catch-up is Real-Time-only.
Modes have built-in preferred/supported time compatibility metadata. Policy-typed
Real-Time weekly and Vibe Story Day event rules now materialize provenance-bearing
planned activities explicitly. Conversation presence schedules are separate
weekly plans for approximate Online, Idle, Do Not Disturb, and Offline status;
they are continuity/UI evidence, not activities and never materialize world
history. The explicit Vibe-Time Roleplay [Next Day] control marker now
prepares a summary-plus-Tracker DayCloseReview for the preceding exact range;
the raw marker remains in message/context content but is hidden by normal
rendering and shown when editing. A hosted Real-Time 4:00 AM worker now creates
one recoverable review per eligible Convo, using the exact messages before the
local boundary and reopening after the latest completed/discarded range.
Automatic Story Day rollover, background event execution, and ambient Real-Time
updates are not implemented.
WorldNode stores Universe, display name, optional canonical parent, general
description, normalized activation words, and message provenance for
Tracker-created nodes. New knowledge is stored as atomic node entries and is
supplied with the description to Convo and Roleplay Drivers when a node or
entry activation word appears in recent messages.
WorldRelationship is a separately persisted directed typed fact whose
endpoints must belong to that Universe. Persistence validates parent and
cross-Universe rules; canonical commits reject containment cycles atomically.
The tree is current state: uncertain placement should be top-level rather than
speculative, and current-location/current-activity State entries require
special care when later evidence supersedes them. Completed experiences are
normally Memories rather than lingering current State.
State keys are normalized across punctuation and separators, so variants such as
current_location and current-location share one active State slot. Tracker
node proposals also reject same-parent nodes whose names match an existing
activation-word alias, and use shared source-message provenance as additional
duplicate evidence.
CharacterCard is reusable source material. CharacterInstance is
Universe-owned and has one linked World Node, allowing specialized Character
state to participate in containment and relationships. Card edits do not
silently rewrite existing instances or history. Removing an instance is a
canonical DeleteCharacterWorldEvent; it removes the instance and linked node
when no active Interface or world record still references them, while the
reusable Card remains available in the Library.
History supports commits, active/committed/discarded technical branches, staged
typed events, optimistic concurrency, and revert branches. The UI presents these
branches as world-change reviews. Alternate exists as an unreachable legacy
status and is not a conversation timeline or supported parallel-world
operation. Current typed events cover creating/renaming/moving/deleting/merging nodes,
adding/removing relationships, and creating/deleting Character Instances.
The history page can reconstruct a read-only node/relationship/active-knowledge
projection at any canonical commit. A rollback to that point is prepared as a
new active branch containing compensating events for every later commit; it
must be reviewed and explicitly committed, or can be discarded without
rewriting the canonical log. This is a safe linear rollback, not yet an
independent alternate-world snapshot.
Duplicate-node merge is reversible and retargets children, knowledge,
relationships, sources, scenes, imported destinations, schedules, and
activities atomically. A review-first consolidation pass can propose
high-confidence renames, moves, merges, and relationship cleanup.
Broader typed entity/event vocabularies remain future work.
Conversation currently backs Convo, Roleplay, and Scene transcripts. A visible
conversation Interface owns a family of paths but persists exactly one selected
timeline to continue. A path inherits history through its fork message; later
messages belong only to that path. Once another timeline inherits a message, the
parent can no longer edit the shared history. Non-selected paths are readable but
not writable and are not candidates for autonomous processing.
Completed/no-change/discarded DayCloseReview ranges are the boundary between
ordinary timeline experimentation and canonical-Universe rollback. A path can be
selected only when it contains the selected history's wrapped boundary messages;
an older divergence requires a duplicated, rolled-back Universe. Preparing or
awaiting-review ranges prevent selection changes, while failed reviews do not
close history. Legacy freezing remains read-only compatibility state and does not
apply anything to canonical World History.
Messages have User, Character, or System roles. Local messages can be edited while their timeline remains active and no child timeline has inherited them. Imported messages preserve source kind/ID, timestamps, and optional managed-artwork attachments and cannot be edited.
Personas are application-level user identities that may be selected by
conversations and bounded Roleplay sessions (Scenes). A conversation's explicit
Persona takes precedence; otherwise Roleplay generation resolves the Universe
default Persona, then the Library default Persona. Scenes launched from a
Convo inherit its explicit Persona, and can override or return to the Universe
default while active. WorldInterface holds common identity, mode,
display/archive state, and participants where applicable. Conversation-backed
modes and Social Feed currently create these rows; preview Game does not.
Roleplay generation is selected per conversation through a registered Driver. The application owns the conversation, transcript, timeline, and persistence contracts; a Driver owns prompt construction and response interpretation. Driver settings are validated JSON objects stored opaquely by Core so extensions can define their own options without hardwiring them into the application. Forked conversation paths preserve the selected Driver and its settings.
A Driver returns canonical scene truth separately from optional audience
projections. The canonical Character message is the observable, shared account
of what happened and must not contain private thoughts, hidden knowledge, or
audience-specific wording. An audience projection is a rendered view for one
audience and is stored separately from transcript messages. The current
audience-aware Driver eagerly produces the user projection and one
character:{instance-guid-without-hyphens} projection for every participant.
The Roleplay UI displays the user projection when available and falls back to
canonical content when a Driver does not provide one.
Audience projections are not message swipe variants. Swipes are alternate candidate responses for the same message; projections are views of one accepted canonical response. Editing or regenerating canonical content invalidates its projections, while timeline forks continue to address the inherited message identities. Future Drivers may use different audience keys, projection timing, or rendering rules through the same generic contracts.
WorldKnowledgeEntry remains the immutable imported-lore source record and may
be staged, kept, or rejected. Keeping imported prose no longer appends it to
WorldNode.Content or creates a location merely because a lorebook named one.
Character destinations still retain their exact imported instance/node pairing
for a later reconciliation pass. Tracker receives kept entries as labelled
background context but must verify claims against transcript evidence before
proposing canon.
WorldNodeKnowledgeEntry is the canonical atomic model. Context, Fact, State,
and Memory entries retain stable identity, node, activation words, source
reference, source interval, optional Story Time, confidence, rationale, and
exact evidence message IDs. Message-backed entries link back to the correct
Convo, Roleplay, or Scene. The node editor lists active and historical entries
and lets a user add a dated source-referenced entry or archive an active one.
WorldNode.Content remains editable as the node Description for static or
imported descriptive context; new Tracker knowledge does not rewrite it.
RecordNodeKnowledgeWorldEvent and RemoveNodeKnowledgeWorldEvent make atomic
entries part of the same append-only World History commit as graph changes.
Recording a State with the same node and stable key supersedes the prior active
State, while reverting that commit restores the prior State. Tracker proposals
and canonical entries both retain confidence, rationale, and evidence IDs.
Tracker context includes an authoritative Character Instance/Card to World Node
map and stable authored-message identity. Character knowledge is owned by the
character node, not by a location mentioned in the same evidence; node-list
order and alphabetical position are never meaningful. Explicitly confirmed
people, locations, objects, and other entities remain separate graph nodes.
RangeSummary records an exact message range, kind, sealing state, source
revision, branch, provenance, references, and text. Scene, Story Day, Story
Week, Game Session, and Manual summaries are sealed evidence. Rolling context
summaries are unsealed replaceable caches. Sealed revisions preserve immutable
lineage through SupersedesSummaryId, and context consumers select the current
lineage head.
Imported historical day ranges are durable ImportReplayRange records that move
through staged, failed, review, no-change, committed, or discarded states.
Staged ranges are idle until a boundary workflow or the explicit World Tracker
recovery action starts them; they are not processed by a background queue.
Replay runs chronologically per Interface and stops at each review boundary so
the next range sees accepted earlier state. The Tracker page can continue by
preparing the next range immediately after each explicit accept/discard
decision; this removes repetitive analyze clicks without speculatively analyzing
the full backlog against stale state. New runs can select any saved
OpenAI-compatible connection and retain that provider as run provenance.
Tracker prompts use compact request-local aliases (m1 for source messages,
n1 for nodes, r1 for relationships, and k1 for active knowledge entries)
instead of asking a local model to reproduce GUIDs. The server resolves those
aliases back to durable GUIDs before staging events; aliases are never persisted.
Full GUIDs and unambiguous node names remain accepted for compatibility, while
unknown or malformed references are reported as validation errors. A root node
must omit parentId or use JSON null; common model placeholders such as
"none" are tolerated for recovery but are not part of the protocol.
The JSON Tracker performs one bounded repair generation when provider output cannot be parsed, including the exact validation error and a bounded excerpt of the rejected response. A proposal that parses but fails server-side graph validation receives one additional feedback-guided generation. Provider and cancellation failures are not hidden. Failed runs remain durable and can be retried from the Tracker page with the currently selected connection, driver, and analysis settings while preserving the original message range.
Tracker and summary prompts treat every analyzed range as historical evidence: completed events and changes are written in past tense; present tense is reserved for durable facts or states explicitly still true at the range end. Injected atomic State entries are labelled with their observed source time and possible supersession, while Memory entries are labelled as source-backed recollections rather than current truth. Source and Story Time metadata are preserved instead of inventing dates or mechanically rewriting stored content. The reconstruction UI pins the current decision above the queue and shows an in-progress state while preparing the next range. An explicitly risky auto-accept option uses the same sequential validated commit path but skips human inspection; review remains the default.
Imported Marinara Story Week summaries are preserved as overlapping evidence, not replayed as another world-change pass. Marinara itself creates them only after every message-bearing day in the completed week has a daily summary; the weekly model consolidates still-relevant details, resolves items completed later in the week, and captures the relationship/emotional arc. WorldSharp therefore keeps that useful second-pass evidence without duplicating daily canonical mutations.
There is no generalized node property bag, node-type registry, relationship-type registry, fully automatic temporal boundary system, or native shared Content Pack implementation. Imported lore reconciliation and richer logical-time editing remain future work.