149 lines
4.4 KiB
Python
149 lines
4.4 KiB
Python
"""
|
|
Origin data models - character backstory and starting conditions.
|
|
|
|
Origins are saved to the character and referenced by the AI DM throughout
|
|
the game to create personalized narrative experiences, quest hooks, and
|
|
story-driven interactions.
|
|
"""
|
|
|
|
from dataclasses import dataclass, field
|
|
from typing import Dict, List, Any
|
|
|
|
|
|
@dataclass
|
|
class StartingLocation:
|
|
"""
|
|
Represents where a character begins their journey.
|
|
|
|
Attributes:
|
|
id: Unique location identifier
|
|
name: Display name of the location
|
|
region: Larger geographical area this location belongs to
|
|
description: Brief description of the location
|
|
"""
|
|
id: str
|
|
name: str
|
|
region: str
|
|
description: str
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""Serialize to dictionary."""
|
|
return {
|
|
"id": self.id,
|
|
"name": self.name,
|
|
"region": self.region,
|
|
"description": self.description,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> 'StartingLocation':
|
|
"""Deserialize from dictionary."""
|
|
return cls(
|
|
id=data["id"],
|
|
name=data["name"],
|
|
region=data["region"],
|
|
description=data["description"],
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class StartingBonus:
|
|
"""
|
|
Represents mechanical benefits from an origin choice.
|
|
|
|
Attributes:
|
|
trait: Name of the trait/ability granted
|
|
description: What the trait represents narratively
|
|
effect: Mechanical game effect (stat bonuses, special abilities, etc.)
|
|
"""
|
|
trait: str
|
|
description: str
|
|
effect: str
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""Serialize to dictionary."""
|
|
return {
|
|
"trait": self.trait,
|
|
"description": self.description,
|
|
"effect": self.effect,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> 'StartingBonus':
|
|
"""Deserialize from dictionary."""
|
|
return cls(
|
|
trait=data["trait"],
|
|
description=data["description"],
|
|
effect=data["effect"],
|
|
)
|
|
|
|
|
|
@dataclass
|
|
class Origin:
|
|
"""
|
|
Represents a character's backstory and starting conditions.
|
|
|
|
Origins are permanent character attributes that the AI DM uses to
|
|
create personalized narratives, generate relevant quest hooks, and
|
|
tailor NPC interactions throughout the game.
|
|
|
|
Attributes:
|
|
id: Unique origin identifier (e.g., "soul_revenant")
|
|
name: Display name (e.g., "Soul Revenant")
|
|
description: Full backstory text that explains the origin
|
|
starting_location: Where the character begins their journey
|
|
narrative_hooks: List of story elements the AI can reference
|
|
starting_bonus: Mechanical benefits from this origin
|
|
"""
|
|
id: str
|
|
name: str
|
|
description: str
|
|
starting_location: StartingLocation
|
|
narrative_hooks: List[str] = field(default_factory=list)
|
|
starting_bonus: StartingBonus = None
|
|
|
|
def to_dict(self) -> Dict[str, Any]:
|
|
"""
|
|
Serialize origin to dictionary for JSON storage.
|
|
|
|
Returns:
|
|
Dictionary containing all origin data
|
|
"""
|
|
return {
|
|
"id": self.id,
|
|
"name": self.name,
|
|
"description": self.description,
|
|
"starting_location": self.starting_location.to_dict(),
|
|
"narrative_hooks": self.narrative_hooks,
|
|
"starting_bonus": self.starting_bonus.to_dict() if self.starting_bonus else None,
|
|
}
|
|
|
|
@classmethod
|
|
def from_dict(cls, data: Dict[str, Any]) -> 'Origin':
|
|
"""
|
|
Deserialize origin from dictionary.
|
|
|
|
Args:
|
|
data: Dictionary containing origin data
|
|
|
|
Returns:
|
|
Origin instance
|
|
"""
|
|
starting_location = StartingLocation.from_dict(data["starting_location"])
|
|
starting_bonus = None
|
|
if data.get("starting_bonus"):
|
|
starting_bonus = StartingBonus.from_dict(data["starting_bonus"])
|
|
|
|
return cls(
|
|
id=data["id"],
|
|
name=data["name"],
|
|
description=data["description"],
|
|
starting_location=starting_location,
|
|
narrative_hooks=data.get("narrative_hooks", []),
|
|
starting_bonus=starting_bonus,
|
|
)
|
|
|
|
def __repr__(self) -> str:
|
|
"""String representation of the origin."""
|
|
return f"Origin({self.name}, starts at {self.starting_location.name})"
|