MVP - Phase One Complete

This commit is contained in:
Aodhan Collins
2025-10-11 22:48:35 +01:00
parent eccd456c59
commit a1c8ae5f5b
7 changed files with 1221 additions and 46 deletions

55
main.py
View File

@@ -38,6 +38,9 @@ class Message(BaseModel):
sender: str # "character" or "storyteller"
content: str
timestamp: str = Field(default_factory=lambda: datetime.now().isoformat())
visibility: str = "private" # "public", "private", "mixed"
public_content: Optional[str] = None # For mixed messages - visible to all
private_content: Optional[str] = None # For mixed messages - only storyteller sees
class Character(BaseModel):
id: str = Field(default_factory=lambda: str(uuid.uuid4()))
@@ -58,6 +61,7 @@ class GameSession(BaseModel):
characters: Dict[str, Character] = {}
current_scene: str = ""
scene_history: List[str] = [] # All scenes narrated
public_messages: List[Message] = [] # Public messages visible to all characters
# In-memory storage (replace with database in production)
sessions: Dict[str, GameSession] = {}
@@ -140,22 +144,58 @@ async def character_websocket(websocket: WebSocket, session_id: str, character_i
await manager.connect(websocket, client_key)
try:
# Send conversation history
# Send conversation history and public messages
session = sessions[session_id]
character = session.characters[character_id]
await websocket.send_json({
"type": "history",
"messages": [msg.dict() for msg in character.conversation_history]
"messages": [msg.dict() for msg in character.conversation_history],
"public_messages": [msg.dict() for msg in session.public_messages]
})
while True:
data = await websocket.receive_json()
if data.get("type") == "message":
# Character sends message to storyteller
message = Message(sender="character", content=data["content"])
character.conversation_history.append(message)
character.pending_response = True
# Character sends message (can be public, private, or mixed)
visibility = data.get("visibility", "private")
message = Message(
sender="character",
content=data["content"],
visibility=visibility,
public_content=data.get("public_content"),
private_content=data.get("private_content")
)
# Add to appropriate feed(s)
if visibility == "public":
session.public_messages.append(message)
# Broadcast to all characters
for char_id in session.characters:
char_key = f"{session_id}_{char_id}"
if char_key in manager.active_connections:
await manager.send_to_client(char_key, {
"type": "public_message",
"character_name": character.name,
"message": message.dict()
})
elif visibility == "mixed":
session.public_messages.append(message)
# Broadcast public part to all characters
for char_id in session.characters:
char_key = f"{session_id}_{char_id}"
if char_key in manager.active_connections:
await manager.send_to_client(char_key, {
"type": "public_message",
"character_name": character.name,
"message": message.dict()
})
# Add to character's private conversation
character.conversation_history.append(message)
character.pending_response = True
else: # private
character.conversation_history.append(message)
character.pending_response = True
# Forward to storyteller
storyteller_key = f"{session_id}_storyteller"
@@ -196,7 +236,8 @@ async def storyteller_websocket(websocket: WebSocket, session_id: str):
}
for char_id, char in session.characters.items()
},
"current_scene": session.current_scene
"current_scene": session.current_scene,
"public_messages": [msg.dict() for msg in session.public_messages]
})
while True: