feat: implement AI Director & Narrative Voting System (Phase 9)

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>
This commit is contained in:
empty
2026-01-02 03:37:41 +08:00
parent 93fed8b9ca
commit 8915a4b074
10 changed files with 2048 additions and 3 deletions

View File

@@ -75,6 +75,15 @@ namespace TheIsland.Network
public event Action<GiveItemEventData> OnGiveItem; // Phase 23: Item Exchange
public event Action<GroupActivityEventData> OnGroupActivity; // Phase 24: Group Activities
public event Action<VFXEventData> OnVFXEvent; // Phase 8: VFX
// AI Director & Narrative Voting (Phase 9)
public event Action<ModeChangeData> OnModeChange;
public event Action<NarrativePlotData> OnNarrativePlot;
public event Action<VoteStartedData> OnVoteStarted;
public event Action<VoteUpdateData> OnVoteUpdate;
public event Action<VoteEndedData> OnVoteEnded;
public event Action<VoteResultData> OnVoteResult;
public event Action<ResolutionAppliedData> OnResolutionApplied;
#endregion
#region Private Fields
@@ -380,8 +389,6 @@ namespace TheIsland.Network
var randomEventData = JsonUtility.FromJson<RandomEventData>(dataJson);
OnRandomEvent?.Invoke(randomEventData);
Debug.Log($"[Random Event] {randomEventData.event_type}: {randomEventData.message}");
OnRandomEvent?.Invoke(randomEventData);
Debug.Log($"[Random Event] {randomEventData.event_type}: {randomEventData.message}");
break;
case EventTypes.GIVE_ITEM:
@@ -399,6 +406,42 @@ namespace TheIsland.Network
OnVFXEvent?.Invoke(vfxData);
break;
// AI Director & Narrative Voting (Phase 9)
case EventTypes.MODE_CHANGE:
var modeData = JsonUtility.FromJson<ModeChangeData>(dataJson);
OnModeChange?.Invoke(modeData);
break;
case EventTypes.NARRATIVE_PLOT:
var plotData = JsonUtility.FromJson<NarrativePlotData>(dataJson);
OnNarrativePlot?.Invoke(plotData);
break;
case EventTypes.VOTE_STARTED:
var voteStarted = JsonUtility.FromJson<VoteStartedData>(dataJson);
OnVoteStarted?.Invoke(voteStarted);
break;
case EventTypes.VOTE_UPDATE:
var voteUpdate = JsonUtility.FromJson<VoteUpdateData>(dataJson);
OnVoteUpdate?.Invoke(voteUpdate);
break;
case EventTypes.VOTE_ENDED:
var voteEnded = JsonUtility.FromJson<VoteEndedData>(dataJson);
OnVoteEnded?.Invoke(voteEnded);
break;
case EventTypes.VOTE_RESULT:
var voteResult = JsonUtility.FromJson<VoteResultData>(dataJson);
OnVoteResult?.Invoke(voteResult);
break;
case EventTypes.RESOLUTION_APPLIED:
var resolution = JsonUtility.FromJson<ResolutionAppliedData>(dataJson);
OnResolutionApplied?.Invoke(resolution);
break;
default:
Debug.Log($"[NetworkManager] Unhandled event type: {baseMessage.event_type}");
break;