WIP: Fixing no events in queue

Had a bug where we'd do down a path that didn't result in calling the
nextPhase, meaning we'd end up with zero events in the queue and then
just sit there. Wasn't great.
This commit is contained in:
Tyler Marques 2025-06-13 15:10:19 -07:00
parent ef3e3a79fe
commit 9333f531bd
No known key found for this signature in database
GPG key ID: CB99EDCF41D3016F
6 changed files with 22 additions and 50 deletions

2
.vscode/launch.json vendored
View file

@ -4,7 +4,7 @@
{
"type": "pwa-chrome",
"request": "launch",
"name": "Firefox Debug 5179",
"name": "Chrome Debug 5179",
"url": "http://localhost:5179",
"webRoot": "${workspaceFolder}/ai_animation/",
"sourceMapPathOverrides": {

View file

@ -1,9 +0,0 @@
export function setupCounter(element: HTMLButtonElement) {
let counter = 0
const setCounter = (count: number) => {
counter = count
element.innerHTML = `count is ${counter}`
}
element.addEventListener('click', () => setCounter(counter + 1))
setCounter(0)
}

View file

@ -1,12 +1,9 @@
import * as THREE from "three";
import { gameState } from "../gameState";
import { config } from "../config";
import { advanceToNextPhase, scheduleNextPhase } from "../phase";
import { GamePhase, Message } from "../types/gameState";
import { getPowerDisplayName, getAllPowerDisplayNames } from '../utils/powerNames';
import { getPowerDisplayName } from '../utils/powerNames';
import { PowerENUM } from '../types/map';
import { createAnimationsForNextPhase } from "../units/animate";
import { speakSummary } from "../speech";
//TODO: Sometimes the LLMs use lists, and they don't work in the chats. The just appear as bullets within a single line.
@ -179,7 +176,7 @@ function playChatMessage(messageIndex) {
* @param phase The current game phase containing messages
* @param stepMessages Whether to animate messages one-by-word (true) or show all at once (false)
*/
export function updateChatWindows(stepMessages = false) {
export function updateChatWindows(stepMessages = false, callback?: () => void) {
// Exit early if no messages
if (!gameState.currentPhase.messages || !gameState.currentPhase.messages.length) {
console.log("No messages to display for this phase");
@ -235,7 +232,7 @@ export function updateChatWindows(stepMessages = false) {
console.log(`All messages displayed in ${Date.now() - messageStartTime}ms`);
}
console.log("Messages complete, triggering next phase");
scheduleNextPhase();
if (callback) callback();
return;
}

View file

@ -18,6 +18,9 @@ import { togglePlayback } from "./phase";
const isStreamingMode = import.meta.env.VITE_STREAMING_MODE
const phaseStartIdx = undefined;
// Panic flag to stop execution when critical errors occur
let hasPanicked = false;
// --- INITIALIZE SCENE ---
function initScene() {
gameState.createThreeScene()
@ -157,12 +160,20 @@ function updateAnimations() {
* Handles camera movement, animations, and game state transitions
*/
function animate() {
if (hasPanicked) return; // Stop the loop if we've panicked
try {
// All things that aren't ThreeJS items happen in the eventQueue. The queue if filled with the first phase before the animate is kicked off, then all subsequent events are updated when other events finish. F
// For instance, when the messages finish playing, they should kick off the check to see if we should advance turns.
gameState.eventQueue.update();
} catch (error) {
console.error('CRITICAL ERROR - STOPPING EXECUTION:', error);
hasPanicked = true;
return; // Exit without scheduling next frame
}
requestAnimationFrame(animate);
// All things that aren't ThreeJS items happen in the eventQueue. The queue if filled with the first phase before the animate is kicked off, then all subsequent events are updated when other events finish. F
// For instance, when the messages finish playing, they should kick off the check to see if we should advance turns.
gameState.eventQueue.update();
if (gameState.isPlaying) {
// Update the camera angle
// FIXME: This has to call the update functino twice inorder to avoid a bug in Tween.js, see here https://github.com/tweenjs/tween.js/issues/677

View file

@ -1,13 +0,0 @@
export function addMapMouseEvents(mapView: HTMLElement) {
const isDebugMode = process.env.NODE_ENV === 'development' || localStorage.getItem('debug') === 'true';
if (isDebugMode) {
mapView.addEventListener("mousemove", (event) => {
const rect = mapView.getBoundingClientRect();
const x = event.clientX - rect.left;
const y = event.clientY - rect.top;
// Remove: infoPanel.textContent = `Mouse: (${event.offsetX}, ${event.offsetY})`;
})
}
}

View file

@ -46,14 +46,6 @@ export function _setPhase(phaseIndex: number) {
gameState.phaseIndex = phaseIndex
displayPhase(true)
} else {
// Clear any existing animations to prevent overlap
// (playbackTimer is replaced by event queue system)
// Reset event queue for new phase with cleanup callback
gameState.eventQueue.reset(() => {
});
if (gameState.isPlaying) {
gameState.eventQueue.start();
}
@ -240,11 +232,7 @@ export function displayPhase(skipMessages = false) {
updateLeaderboard();
// Show messages with animation or immediately based on skipMessages flag
if (!skipMessages) {
updateChatWindows(true);
} else {
gameState.messagesPlaying = false;
}
updateChatWindows(true, scheduleNextPhase);
// Only animate if not the first phase and animations are requested
if (!isFirstPhase && !skipMessages) {
@ -252,12 +240,10 @@ export function displayPhase(skipMessages = false) {
try {
// Don't create animations immediately if messages are still playing
// The main loop will handle this when messages finish
if (!gameState.messagesPlaying) {
createAnimationsForNextPhase();
}
createAnimationsForNextPhase();
} catch (error) {
console.warn(`Caught below error when attempting to create animations. Moving on without them.`)
console.error(error)
console.warn(error)
initUnits(gameState.phaseIndex)
}