MVP - Phase One Complete
This commit is contained in:
55
main.py
55
main.py
@@ -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:
|
||||
|
||||
Reference in New Issue
Block a user