@@ -1521,13 +1521,63 @@ <h3 id="removeReminderTitle">Remove Reminder</h3>
15211521 messages . forEach ( messageWrapper => {
15221522 // PubNub history wraps messages in an object with timetoken
15231523 const message = messageWrapper . entry ;
1524+ reconstructGameStateFromMessage ( message ) ;
15241525 handleIncomingMessage ( message , true ) ; // true = from history
15251526 } ) ;
15261527 }
15271528 } ) . catch ( ( error ) => {
15281529 console . log ( 'Error fetching message history:' , error ) ;
15291530 } ) ;
15301531 }
1532+
1533+ function reconstructGameStateFromMessage ( message ) {
1534+ // Only reconstruct for storytellers in reconnect mode
1535+ if ( userType !== 'storyteller' || gameMode !== 'reconnect' ) {
1536+ return ;
1537+ }
1538+
1539+ // Find the most recent game_setup message to establish current game
1540+ if ( message . type === 'game_setup' && message . gameId ) {
1541+ if ( ! currentGameId || message . timestamp > mostRecentSetupTimestamp ) {
1542+ currentGameId = message . gameId ;
1543+ mostRecentSetupTimestamp = message . timestamp ;
1544+
1545+ // Reconstruct basic game state
1546+ if ( message . players ) {
1547+ players = message . players ;
1548+ }
1549+ if ( message . script ) {
1550+ if ( typeof message . script === 'string' ) {
1551+ currentScript = Object . values ( EMBEDDED_SCRIPTS ) . find ( s => s . name === message . script ) ||
1552+ EMBEDDED_SCRIPTS [ message . script ] ;
1553+ } else {
1554+ currentScript = message . script ;
1555+ }
1556+ }
1557+ if ( message . playerRoles ) {
1558+ playerRoles = message . playerRoles ;
1559+ }
1560+ if ( message . playerReminders ) {
1561+ playerReminders = message . playerReminders ;
1562+ }
1563+ }
1564+ }
1565+
1566+ // Update role assignments from more recent role_assignment messages
1567+ if ( message . type === 'role_assignment' && message . gameId === currentGameId && message . playerRoles ) {
1568+ playerRoles = { ...playerRoles , ...message . playerRoles } ;
1569+ }
1570+
1571+ // Update reminders from more recent reminder_update messages
1572+ if ( message . type === 'reminder_update' && message . gameId === currentGameId && message . playerReminders ) {
1573+ playerReminders = { ...playerReminders , ...message . playerReminders } ;
1574+ }
1575+
1576+ // Reconstruct phase state from daybreak/nightfall messages
1577+ if ( ( message . type === 'daybreak' || message . type === 'nightfall' ) && message . gameId === currentGameId ) {
1578+ isNightTime = ( message . type === 'nightfall' ) ;
1579+ }
1580+ }
15311581
15321582 function handleConnectionStatus ( statusEvent ) {
15331583 const statusEl = document . getElementById ( 'connectionStatus' ) ;
@@ -1541,7 +1591,18 @@ <h3 id="removeReminderTitle">Remove Reminder</h3>
15411591 statusEl . textContent = 'Connection lost' ;
15421592 statusEl . className = 'status disconnected' ;
15431593 }
1594+
1595+ // After connection is established and history is processed, update UI for reconnecting storytellers
1596+ if ( statusEvent . category === 'PNConnectedCategory' && userType === 'storyteller' && gameMode === 'reconnect' ) {
1597+ setTimeout ( ( ) => {
1598+ updatePlayersList ( ) ;
1599+ updatePhaseUI ( ) ;
1600+ populateTargetPlayerDropdown ( ) ;
1601+ } , 2000 ) ; // Give time for history processing
1602+ }
15441603 }
1604+
1605+
15451606
15461607 function sendGameSetup ( ) {
15471608 console . log ( 'sendGameSetup called, currentScript:' , currentScript ) ; // Add this line
@@ -1771,6 +1832,19 @@ <h3 id="removeReminderTitle">Remove Reminder</h3>
17711832 }
17721833 }
17731834
1835+ function populateTargetPlayerDropdown ( ) {
1836+ if ( userType === 'storyteller' && players . length > 0 ) {
1837+ const targetSelect = document . getElementById ( 'targetPlayer' ) ;
1838+ targetSelect . innerHTML = '<option value="">Select player...</option>' ;
1839+ players . forEach ( player => {
1840+ const option = document . createElement ( 'option' ) ;
1841+ option . value = player ;
1842+ option . textContent = player ;
1843+ targetSelect . appendChild ( option ) ;
1844+ } ) ;
1845+ }
1846+ }
1847+
17741848 function getRoleById ( roleId ) {
17751849 return ROLES [ roleId ] || null ;
17761850 }
@@ -3485,4 +3559,8 @@ <h3 id="removeReminderTitle">Remove Reminder</h3>
34853559
34863560 F: I don't think that's the fix; my players still cannot join the room while I am on the role selection screen. Is there something important from the "Continue to Game" button that we need to do as soon as we get to the Role Selection screen?
34873561
3562+ F: Look at this code. Pay attention to the instructions for CLAUDE at the top. Immediate task: When I reconnect as the storyteller, I do not get a reconstruction of the game state, even though I think I should be able to derive much of it from the pubnub messages. E.g. the set of players and the messages that I have sent to them and their responses.
3563+
3564+ TODO: while this does re-establish the set of players, it does not load up past messages that we have sent. Also, we could easily include the player assignments in the pubnub messages for later retrieval in these situations.
3565+
34883566-->
0 commit comments