Skip to content

Commit 7c6e4fe

Browse files
committed
vibe-debugged the storyteller reconnect experience. Not yet perfect but good enough for now.
1 parent 5ed8c64 commit 7c6e4fe

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

pnkfelix/pagelets/demo-botc-pubnub.html

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)