Add complete AI Director system that transforms the survival simulation into a user-driven interactive story with audience voting. Backend: - Add DirectorService for LLM-powered plot generation with fallback templates - Add VoteManager for dual-channel voting (Twitch + Unity) - Integrate 4-phase game loop: Simulation → Narrative → Voting → Resolution - Add vote command parsing (!1, !2, !A, !B) in Twitch service - Add type-safe LLM output handling with _coerce_int() helper - Normalize voter IDs for case-insensitive duplicate prevention Unity Client: - Add NarrativeUI for cinematic event cards and voting progress bars - Add 7 new event types and data models for director/voting events - Add delayed subscription coroutine for NetworkManager timing - Sync client timer with server's remaining_seconds to prevent drift Documentation: - Update README.md with AI Director features, voting commands, and event types 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
112 lines
4.2 KiB
Python
112 lines
4.2 KiB
Python
"""
|
|
Pydantic models for the JSON protocol.
|
|
Defines standardized structures for game events and messages.
|
|
"""
|
|
|
|
from enum import Enum
|
|
from typing import Any
|
|
from pydantic import BaseModel, Field
|
|
import time
|
|
|
|
|
|
class EventType(str, Enum):
|
|
"""Enumeration of all possible game event types."""
|
|
COMMENT = "comment"
|
|
TICK = "tick"
|
|
SYSTEM = "system"
|
|
ERROR = "error"
|
|
|
|
# Island survival events
|
|
AGENTS_UPDATE = "agents_update" # All agents status broadcast
|
|
AGENT_DIED = "agent_died" # An agent has died
|
|
AGENT_SPEAK = "agent_speak" # Agent says something (LLM response)
|
|
FEED = "feed" # User fed an agent
|
|
USER_UPDATE = "user_update" # User gold/status update
|
|
WORLD_UPDATE = "world_update" # World state update
|
|
CHECK = "check" # Status check response
|
|
|
|
# Day/Night cycle (Phase 2)
|
|
TIME_UPDATE = "time_update" # Time tick update
|
|
PHASE_CHANGE = "phase_change" # Dawn/day/dusk/night transition
|
|
DAY_CHANGE = "day_change" # New day started
|
|
|
|
# Weather system (Phase 3)
|
|
WEATHER_CHANGE = "weather_change" # Weather changed
|
|
MOOD_UPDATE = "mood_update" # Agent mood changed
|
|
|
|
# New commands (Phase 4)
|
|
HEAL = "heal" # User healed an agent
|
|
TALK = "talk" # User talked to an agent
|
|
ENCOURAGE = "encourage" # User encouraged an agent
|
|
REVIVE = "revive" # User revived a dead agent
|
|
|
|
# Social system (Phase 5)
|
|
SOCIAL_INTERACTION = "social_interaction" # Agents interacted
|
|
RELATIONSHIP_CHANGE = "relationship_change" # Relationship status changed
|
|
AUTO_REVIVE = "auto_revive" # Agent auto-revived (casual mode)
|
|
|
|
# Autonomous Agency (Phase 13)
|
|
AGENT_ACTION = "agent_action" # Agent performs an action (move, gather, etc.)
|
|
|
|
# Crafting System (Phase 16)
|
|
CRAFT = "craft" # Agent crafted an item
|
|
USE_ITEM = "use_item" # Agent used an item
|
|
|
|
# Random Events (Phase 17-C)
|
|
RANDOM_EVENT = "random_event" # Random event occurred
|
|
|
|
# Economy (Phase 23)
|
|
GIVE_ITEM = "give_item" # Agent gives item to another
|
|
|
|
# Group Activities (Phase 24)
|
|
# Group Activities (Phase 24)
|
|
GROUP_ACTIVITY = "group_activity" # Storytelling, dancing, etc.
|
|
|
|
# VFX & Gifts (Phase 8)
|
|
VFX_EVENT = "vfx_event" # Visual effect trigger
|
|
GIFT_EFFECT = "gift_effect" # Twitch bits/sub effect
|
|
|
|
# AI Director & Narrative Voting (Phase 9)
|
|
MODE_CHANGE = "mode_change" # Game mode transition
|
|
NARRATIVE_PLOT = "narrative_plot" # Director generated plot point
|
|
VOTE_STARTED = "vote_started" # Voting session started
|
|
VOTE_UPDATE = "vote_update" # Real-time vote count update
|
|
VOTE_ENDED = "vote_ended" # Voting closed
|
|
VOTE_RESULT = "vote_result" # Final voting result
|
|
RESOLUTION_APPLIED = "resolution_applied" # Plot resolution executed
|
|
|
|
|
|
class GameEvent(BaseModel):
|
|
"""
|
|
Standardized game event structure for WebSocket communication.
|
|
|
|
Attributes:
|
|
event_type: The type of event (comment, agent_response, tick, etc.)
|
|
timestamp: Unix timestamp when the event was created
|
|
data: Arbitrary payload data for the event
|
|
"""
|
|
event_type: str = Field(..., description="Type of the game event")
|
|
timestamp: float = Field(default_factory=time.time, description="Unix timestamp")
|
|
data: dict[str, Any] = Field(default_factory=dict, description="Event payload")
|
|
|
|
class Config:
|
|
json_schema_extra = {
|
|
"example": {
|
|
"event_type": "comment",
|
|
"timestamp": 1704067200.0,
|
|
"data": {"user": "User123", "message": "Attack!"}
|
|
}
|
|
}
|
|
|
|
|
|
class ClientMessage(BaseModel):
|
|
"""
|
|
Message structure for client-to-server communication.
|
|
|
|
Attributes:
|
|
action: The action the client wants to perform
|
|
payload: Data associated with the action
|
|
"""
|
|
action: str = Field(..., description="Action to perform")
|
|
payload: dict[str, Any] = Field(default_factory=dict, description="Action payload")
|