RoleRealm-A-Story-Driven-Roleplay

RoleRealm API Reference

Table of Contents


Data Models

All data models are defined in data_models.py using Pydantic.

TimelineEvent (Base Class)

Description: Base class for all timeline events.

class TimelineEvent(BaseModel):
    timeline_id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    timestamp: datetime = Field(default_factory=datetime.now)

Fields:


Message

Description: Represents a character’s spoken dialogue with accompanying action.

class Message(TimelineEvent):
    character: str
    dialouge: str
    action_description: str

Fields:

Example:

message = Message(
    character="Captain",
    dialouge="Avast! We sail at dawn!",
    action_description="slams fist on the table"
)

Scene

Description: Represents an environmental or transitional narrative event.

class Scene(TimelineEvent):
    scene_type: str
    location: str
    description: str

Fields:

Example:

scene = Scene(
    scene_type="environmental",
    location="Ship Deck",
    description="Dark storm clouds gather on the horizon as waves crash against the hull"
)

Action

Description: Represents a character’s physical action or decision point.

class Action(TimelineEvent):
    character: str
    description: str

Fields:

Example:

action = Action(
    character="Marina",
    description="carefully unfurls the ancient map on the table"
)

CharacterEntry

Description: Represents a character joining the conversation.

class CharacterEntry(TimelineEvent):
    character: str
    description: str

Fields:

Example:

entry = CharacterEntry(
    character="Jack",
    description="Jack bursts through the door, out of breath"
)

CharacterExit

Description: Represents a character leaving the conversation.

class CharacterExit(TimelineEvent):
    character: str
    description: str

Fields:


CharacterPersona

Description: Defines a character’s immutable personality and characteristics.

class CharacterPersona(BaseModel):
    name: str
    traits: List[str]
    relationships: Dict[str, str]
    speaking_style: str
    background: str
    goals: Optional[List[str]] = None
    knowledge_base: Optional[Dict[str, Any]] = None
    temperature: Optional[float] = 0.75
    top_p: Optional[float] = 0.9
    frequency_penalty: Optional[float] = 0.2

Fields:

Example:

{
  "name": "Captain Morgan",
  "traits": ["wise", "authoritative", "protective"],
  "relationships": {
    "Marina": "Impressed by her skills",
    "Jack": "Appreciates his spirit"
  },
  "speaking_style": "Speaks with gravitas, uses seafaring expressions",
  "background": "Decades of sailing experience",
  "goals": ["Lead crew to fortune", "Keep everyone safe"],
  "knowledge_base": {
    "secret_routes": "Knows hidden passages through dangerous waters"
  }
}

CharacterMemory

Description: Stores what a character has witnessed from their perspective.

class CharacterMemory(BaseModel):
    name: str
    event: List[TimelineEvent] = Field(default_factory=list)

Fields:

Note: Each character only remembers events they were present for.


CharacterState

Description: Represents a character’s current, mutable state.

class CharacterState(BaseModel):
    name: str
    current_objective: Optional[str] = None

Fields:


Character

Description: Complete representation of an AI character.

class Character(BaseModel):
    persona: CharacterPersona
    memory: Optional[CharacterMemory] = None
    state: Optional[CharacterState] = None

Fields:


TimelineHistory

Description: Master timeline containing all chronological events.

class TimelineHistory(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    title: Optional[str] = None
    events: List[TimelineEvent] = Field(default_factory=list)
    participants: List[str] = Field(default_factory=list)
    current_participants: List[str] = Field(default_factory=list)
    timeline_summary: Optional[str] = None
    visible_to_user: bool = True

Fields:


Story

Description: Story structure with sequential objectives.

class Story(BaseModel):
    id: str = Field(default_factory=lambda: str(uuid.uuid4()))
    title: str
    description: str
    objectives: List[str]
    current_objective_index: int = 0

Fields:

Example:

{
  "title": "The Quest for the Phantom Pearl",
  "description": "A treasure hunt through cursed waters",
  "objectives": [
    "Decipher the mysterious map",
    "Navigate through the Siren's Strait",
    "Find the abandoned island"
  ],
  "current_objective_index": 0
}

Managers

CharacterManager

Location: managers/characterManager.py

Description: Manages character lifecycle, memory, and decision-making.

Methods

__init__()
def __init__(self) -> None

Initialize CharacterManager with default model configuration.


create_character()
def create_character(
    persona: CharacterPersona,
    memory: Optional[CharacterMemory] = None,
    state: Optional[CharacterState] = None
) -> Character

Create a new AI character instance.

Parameters:

Returns: Character instance

Example:

persona = CharacterPersona(name="Jack", traits=["brave", "reckless"], ...)
character = character_manager.create_character(persona)

update_character_memory()
def update_character_memory(
    character: Character,
    event: TimelineEvent
) -> None

Add a timeline event to character’s memory.

Parameters:

Example:

message = Message(character="Captain", dialouge="Set sail!", ...)
character_manager.update_character_memory(jack, message)

update_character_state()
def update_character_state(
    character: Character,
    current_objective: Optional[str] = None
) -> None

Update character’s current state.

Parameters:


build_persona_context()
def build_persona_context(character: Character) -> str

Build character personality context for LLM prompts.

Parameters:

Returns: Formatted string with persona information


build_state_context()
def build_state_context(character: Character) -> str

Build character state context including current objective.

Returns: Formatted string with state information


build_memory_context()
def build_memory_context(
    character: Character,
    last_n_messages: Optional[int] = None
) -> str

Build memory context from character’s perspective.

Parameters:

Returns: Formatted string with memory from character’s POV


decide_turn_response()
def decide_turn_response(
    character: Character
) -> Tuple[str, float, str, Optional[str], Optional[str]]

Determine if character should speak, act, or stay silent.

Parameters:

Returns: Tuple of:


generate_character_response()
def generate_character_response(
    character: Character,
    response_type: str
) -> Tuple[str, str]

Generate actual character response (dialogue and/or action).

Parameters:

Returns: Tuple of (dialogue, action)


TimelineManager

Location: managers/timelineManager.py

Description: Manages timeline events and context building.

Methods

__init__()
def __init__(self) -> None

Initialize TimelineManager.


create_timeline_history()
def create_timeline_history(
    title: Optional[str] = None,
    participants: Optional[List[str]] = None,
    visible_to_user: bool = True
) -> TimelineHistory

Create a new timeline.

Parameters:

Returns: TimelineHistory instance


add_event()
def add_event(
    timeline: TimelineHistory,
    event: TimelineEvent
) -> None

Add event to timeline and update participants.

Parameters:


create_message()
def create_message(
    character: str,
    dialouge: str,
    action_description: str
) -> Message

Factory method for creating messages.

Parameters:

Returns: Message instance


create_scene()
def create_scene(
    scene_type: str,
    location: str,
    description: str
) -> Scene

Factory method for creating scenes.

Parameters:

Returns: Scene instance


get_recent_events()
def get_recent_events(
    timeline: TimelineHistory,
    n: Optional[int] = 10,
    event_type: Optional[str] = None
) -> List[TimelineEvent]

Get recent events from timeline.

Parameters:

Returns: List of events


get_current_location()
def get_current_location(timeline: TimelineHistory) -> Optional[str]

Get current location from most recent scene.

Returns: Location string or None


get_timeline_context()
def get_timeline_context(
    timeline: TimelineHistory,
    recent_event_count: int = 10
) -> str

Build formatted timeline string.

Parameters:

Returns: Formatted timeline string


TurnManager

Location: managers/turn_manager.py

Description: Coordinates conversation flow and turn selection.

Methods

__init__()
def __init__(
    characters: List[Character],
    timeline: TimelineHistory,
    max_consecutive_ai_turns: int = None,
    priority_randomness: float = None,
    save_callback: Optional[callable] = None
)

Initialize turn manager.

Parameters:


process_ai_responses()
def process_ai_responses(
    max_turns: Optional[int] = None,
    force_one_response: bool = False
) -> List[Message]

Main conversation loop - process consecutive AI responses.

Parameters:

Returns: List of generated messages

Flow:

  1. Collect decisions from all characters (parallel)
  2. Select speaker based on priority
  3. Generate and add response
  4. Check meta-narrative events
  5. Evaluate story progression
  6. Repeat until silence or max turns

StoryManager

Location: managers/storyManager.py

Description: Manages story progression and objectives.

Methods

__init__()
def __init__(story: Optional[Story] = None)

Initialize story manager.

Parameters:


get_current_objective()
def get_current_objective() -> Optional[str]

Get current story objective.

Returns: Current objective string or None


is_story_complete()
def is_story_complete() -> bool

Check if all objectives are complete.

Returns: True if story is complete


get_progress_percentage()
def get_progress_percentage() -> float

Get completion percentage.

Returns: 0.0-100.0 progress percentage


get_story_context()
def get_story_context() -> str

Get formatted story context for LLM prompts.

Returns: Story context string


evaluate_and_assign_objectives()
def evaluate_and_assign_objectives(
    active_characters: List[Character],
    timeline: TimelineHistory
) -> Dict[str, Any]

Evaluate completion and assign objectives.

Parameters:

Returns: Dictionary with:

{
    "character_updates": {
        "CharacterName": {
            "objective": "...",
            "status": "assigned|completed|continuing",
            "reasoning": "..."
        }
    },
    "story_objective_complete": bool,
    "reasoning": "..."
}

Loaders

CharacterLoader

Location: loaders/character_loader.py

Description: Load character personas from JSON files.

Methods

__init__()
def __init__(base_dir: str)

Initialize loader.

Parameters:

Automatically looks in [base_dir]/characters/ subdirectory.


load_character()
def load_character(character_name: str) -> CharacterPersona

Load single character.

Parameters:

Returns: CharacterPersona instance

Raises:


load_multiple_characters()
def load_multiple_characters(character_names: List[str]) -> List[CharacterPersona]

Load multiple characters.

Parameters:

Returns: List of CharacterPersona instances


list_available_characters()
def list_available_characters() -> List[str]

List all available character files.

Returns: List of character names


StoryLoader

Location: loaders/story_loader.py

Description: Load story configuration from JSON.

Methods

__init__()
def __init__(base_dir: str)

Initialize loader.

Parameters:

Automatically looks in [base_dir]/story/ subdirectory.


load_story()
def load_story() -> Story

Load story from JSON file.

Returns: Story instance

Raises:

Note: Only one story file allowed per directory.


RoleplaySystem

Location: roleplay_system.py

Description: Main coordinator for the roleplay system.

Methods

__init__()
def __init__(
    player_name: str,
    characters: List[CharacterPersona],
    model_name: str = None,
    chat_storage_dir: str = None,
    story_manager = None,
    story_name: str = "default",
    initial_location: str = "Common Room",
    initial_scene_description: str = None
)

Initialize roleplay system.

Parameters:

Raises:

Example:

system = RoleplaySystem(
    player_name="Henry",
    characters=[captain_persona, jack_persona, marina_persona],
    story_manager=story_manager,
    story_name="Pirate Adventure",
    initial_location="Ship Deck",
    initial_scene_description="The adventure begins..."
)

get_conversation_file_path()
def get_conversation_file_path() -> Path

Get path to conversation save file.

Returns: Path object


Configuration

Location: config.py

Config Class

class Config:
    # API Settings
    OPENROUTER_API_KEY: Optional[str]
    OPENROUTER_BASE_URL: str = "https://openrouter.ai/api/v1"
    
    # Model Settings
    DEFAULT_MODEL: str = "x-ai/grok-4.1-fast"
    MODEL_TEMPERATURE: float = 0.7
    MAX_TOKENS: int = 1024
    RESPONSE_TIMEOUT: int = 20
    
    # Conversation Settings
    DEFAULT_CONTEXT_WINDOW: int = 100
    MAX_CONSECUTIVE_AI_TURNS: int = 3
    PRIORITY_RANDOMNESS: float = 0.1
    
    # Storage Settings
    CHAT_STORAGE_DIR: str = "Chat_Logs"

Environment Variables

Create .env file:

OPENROUTER_API_KEY=your_api_key_here

Utilities

ResponseParser

Location: helpers/response_parser.py

Methods

parse_json_response()
def parse_json_response(response_text: str) -> Dict[str, Any]

Parse JSON from LLM response, handling markdown code blocks.

Parameters:

Returns: Parsed JSON dictionary

Raises:

Example:

response = model.generate_content(prompt)
data = parse_json_response(response.text)

GenerativeModel

Location: openrouter_client.py

Methods

__init__()
def __init__(model_name: str, api_key: Optional[str] = None)

Initialize OpenRouter API client.

Parameters:


generate_content()
def generate_content(prompt: str, **kwargs)

Generate content from prompt.

Parameters:

Returns: Response object with .text attribute

Raises:


Error Handling

Common Exceptions

FileNotFoundError:

ValueError:

Exception (API Errors):

Best Practices

  1. Always validate input:
    if not character_name:
     raise ValueError("character_name cannot be empty")
    
  2. Provide helpful error messages:
    raise FileNotFoundError(
     f"Character file not found: {filepath}\n"
     f"Available characters: {self.list_available_characters()}"
    )
    
  3. Handle API errors gracefully:
    try:
     response = model.generate_content(prompt)
    except Exception as e:
     if "429" in str(e):
         print("Rate limit exceeded. Please wait and try again.")
     else:
         raise
    

Last Updated: December 2025
Author: Jit Roy
License: MIT