Merge dev → main (automated)#596
Closed
SorraTheOrc wants to merge 109 commits into
Closed
Conversation
added 30 commits
June 10, 2026 02:33
Replace manual hand and pile rendering with shared HandView and PileView components. The Mind now uses: - HandView for human and AI hand layout (card positioning, selection, click handling). - PileView for the play pile (top card sprite, count overlay). Mind-specific adaptations: - CardTextureResolver type made generic (any parameter) to support MindCard which has numeric instead of /. - Lazy texture loading via applyEnsuredTexture for human hand cards (placeholder back texture, updated when real textures are ready). - Pile value text overlay (numeric display) remains Mind-specific. - HandView.setCards accepts Card[]; MindCard[] cast via 'as any' for texture resolver compatibility. Tests updated: - MindRenderer tests now call createHands() before render methods. - HandView/PileView mocks return proper mock sprites for inspection. Files changed: - src/ui/HandView.ts: Generic CardTextureResolver, Card[] parameter - example-games/the-mind/scenes/MindRenderer.ts: HandView + PileView usage - example-games/the-mind/scenes/TheMindScene.ts: call createHands() - tests/the-mind/mind-renderer.test.ts: Updated mocks and setup
…eractivity control Fix critical bug where Golf's discard pile was wrapped in ArrayPileAdapter (which expects a plain array) but was actually a Pile<Card> object. This caused peek() to return undefined and getCardTexture to crash on undefined.faceUp. Changes: - GolfRenderer: Pass discard Pile directly to setPile() instead of wrapping - GolfRenderer: Use CardPile<Card> type for discard parameter - PileView: Add setVisible() handling for empty/non-empty piles - PileView: Add setInteractive(flag) method for replay mode support - GolfRenderer: Disable pile view interactivity in replay mode - GolfScene.browser.test.ts: Fix Stock/Discard assertions to use startsWith - pileView.test.ts: Add setVisible mock - GymHandPile.test.ts: Add setVisible mock
…Migration smoke test Root cause: Test assertions used incorrect region coordinates and label text expectations that didn't match the actual rendered output after HandView/PileView migration. Fixes: 1. 'pile renders non-trivial content' - Updated region coordinates to match actual PileView position (center of screen) and increased wait frames for rendering. 2. 'status text renders non-trivial content' - Updated region to top-right corner where status labels are rendered (level/lives). 3. 'scene contains expected display objects' - Replaced assertions for 'PILE', 'Your Hand', 'AI Hand' labels (which don't exist after migration) with assertions for actual text objects present: 'The Mind' header, 'Level N / 8', 'Lives: ❤', and card-back images. Also increased wait frames from 8 to 16 for reliable rendering.
- Keep human-played card sprites visible at pile position after animation - Keep AI-played card sprites visible at pile position after animation - Set correct face-up texture and depth for played cards - Cards now remain visible showing the card that was played Fixes: Cards disappearing at end of animation
…Market Rows step
Replaced DOM button elements with Phaser Text objects using the input
system (setInteractive + on('pointerdown')). The original DOM buttons
lost their onclick handlers after the measurement detach/reattach cycle
required for tooltip positioning in Phaser 4 RC.
Changes:
- Replaced DOM button creation with Phaser Text objects for Exit Tutorial
and Continue/Start Full Game buttons
- Used setInteractive({ useHandCursor: true }) for proper cursor feedback
- Added pointerover/pointerout hover effects for visual feedback
- Maintained the same visual appearance and styling as before
- Removed the DOM measurement cycle that caused event handler loss
…red tutorial steps The Continue button was showing for all steps but only worked for steps with requiredAction 'confirm' or 'acknowledge'. For steps requiring actual game actions (select-business, place-business, etc.), clicking Continue did nothing because confirmTutorialStep() returns early. Fix: Only show the Continue button for steps where it actually works. Action-required steps (T3-T9) now only show 'Exit Tutorial' button, while confirm/acknowledge steps (T1-T2, T10) show both buttons.
…on-required tutorial steps" This reverts commit 324b6fb.
…ibility
1. Updated T3 (Market Rows) body text to give clear instructions:
- Changed from 'Businesses go on your street...' to 'Click a business
card (top row) to buy it. Businesses go on your street to earn income.
Investments (bottom row) give one-time effects.'
2. Only show Continue button for steps where it actually works:
- Steps with requiredAction 'confirm' or 'acknowledge' show Continue
- Steps requiring actual game actions (select-business, etc.) only show
Exit Tutorial button
- Last step (T10) shows Start Full Game button
This ensures all visible buttons are functional and the player knows what
action to take during action-required tutorial steps.
…business
The tutorial wasn't advancing from T3 (select-business) to T4 (place-business)
because onTutorialActionComplete('select-business') was never called after the
player selected a business card. This caused onSlotClick to reject the placement
because isTutorialActionAllowed('place-business') returned false (tutorial still
at T3).
Fix: Call onTutorialActionComplete('select-business') after the player
successfully selects a business card and enters placement mode.
Reordered tutorial steps so that T5 is now 'Incident Queue' (was T6) and T6 is now 'End Turn' (was T5). This makes more sense narratively because players should learn about incidents before ending their turn. Updated tests to reflect the new step order.
The Incident Queue step (T5) has requiredAction 'acknowledge-queue', but the Continue button was only shown for 'confirm' or 'acknowledge'. Updated the condition to include 'acknowledge-queue' so players can click Continue after acknowledging the incident queue.
…ctions
1. Updated T7 body text to specifically mention 'Grand Opening Sale' event
card so the player knows which card to buy.
2. Added onTutorialActionComplete('buy-event') call in the afterTransfer
callback of onEventCardClick. Previously the tutorial never advanced
after buying an event card because this call was missing.
Now the tutorial correctly advances from T7 (Held Event Card) to T8
(Upgrade Concept) after the player buys an event card.
… tutorial Update TutorialOverlayManager.browser.test.ts and TutorialOverlayHighlights.browser.test.ts to cover all 13 unified tutorial steps (T1-T13). Changes: - MainStreetTutorialHints.ts: Fix step badge to use UNIFIED_TUTORIAL_STEPS/UNIFIED_TUTORIAL_STEP_COUNT and change isLast check from T10 to T13 for the 13-step unified system - TutorialOverlayManager.browser.test.ts: Use step IDs instead of numeric indices for showStepAndGetHighlight; add tests for T8, T11, T12, T13 steps; cover all 9 highlight zones including completionModal and centerModal - TutorialOverlayHighlights.browser.test.ts: Fix step index mapping for end-turn (T6, index 5) and help-button (T10, index 9) screenshots; add investments row T12 and completion modal T13 screenshot tests; add coverage test for all 13 unified step highlight zones Related-Work: CG-0MQ8MWTK7003FF9S
…ial system - Export resolveZoneToAnchor for testability - Add NULL_ZONE_NAMES constant (centerModal, completionModal) - Update null zone tests to use simulated resolveZoneToAnchor logic that exercises SLL composition directly - Add per-zone tests verifying known zones return valid rects - Add bounds-matching test comparing simulate to computeExpectedZoneBounds - Add unknown zone test verifying composed layout returns undefined Related-Work: CG-0MQ8MX4XK002PN6Q
…ied set Remove legacy TUTORIAL_STEPS array and TutorialStep interface from MainStreetTutorialHints.ts. Remove TUTORIAL_STEP_DEFS and TUTORIAL_STEP_COUNT from TutorialFlow.ts. Migrate the reference-mode showStep() method to use UNIFIED_TUTORIAL_STEPS with SLL-based highlight zone resolution via zoneToAnchor(), replacing the old anchor-function-based rendering. Remove the corresponding legacy test block from tutorial-flow.test.ts. Related-Work: CG-0MQ8MXYN8008GC22
…method - Replace showStep(stepIndex, isActionComplete?) with single-param showStep(stepIndex) - Add setActionCompletePredicate() method for action gate callback registration - Remove showActionGatedStep() method (fully replaced by unified showStep) - Update MainStreetLifecycleManager.showTutorialStepOverlay() to use setActionCompletePredicate() + showStep() pattern - Update test files to use showStep() instead of showActionGatedStep() - Remove unused imports (getCurrentStep, UNIFIED_TUTORIAL_STEPS, TutorialControllerState) from TutorialHints and LifecycleManager Related-Work: CG-0MQ8MZH310009T3Q
…e lifecycle manager - Remove tce:play-tutorial and tce:replay-tutorial event listeners from MainStreetLifecycleManager (reference mode is gone) - Remove Tutorial Replay button and confirmation modal from SettingsPanel - Update Tools help section to remove tutorial replay reference - Remove replay-tutorial test from tutorial-offer-modal.test.ts - TutorialOfferModal still offers guided mode to first-time players - Tutorial completion persists via the unified system Related-Work: CG-0MQ8MZZPY002LG6V
- Update TutorialFlow.ts and MainStreetTutorialHints.ts module comments to reflect the unified tutorial system - Update MainStreetLifecycleManager.ts comment to reference T1-T13 instead of T1-T10 - Update docs/DEVELOPER.md tutorial section to reference T1-T13 and TutorialActionType - Update docs/main-street/playtest-scenarios.md to reference UNIFIED_TUTORIAL_STEPS and UnifiedTutorialStepDef instead of stale TUTORIAL_STEPS references to removed MainStreetTutorialOverlayManager.ts - Remove stale 'non-interactive' description from MainStreetTutorialHints module comment Related-Work: CG-0MQ8N0EY0006IYSD
- MainStreetLifecycleManager: Added forceShowOffer option when ?tutorial=1 URL param is present - TutorialOfferModal: Removed stale 'Settings menu' reference from body text since replay tutorial was removed This allows players to force the tutorial to show by visiting: http://localhost:3000/?tutorial=1
1. Fixed marketBusinessRow height in main-street-tutorial.layout.json - Reduced height from 0.302778 to 0.158333 to not overlap investments row 2. Fixed setActionCompletePredicate in MainStreetLifecycleManager - Now reads current controller state from scene instead of captured closure - Returns true when step has advanced (action is complete) vs false when still active - This enables the Continue button after place-business action completes 3. Removed stale 'Settings menu' reference from TutorialOfferModal
- Removed disabled state check on DOM Continue button - now re-evaluates predicate at click time - Removed disabled state check on canvas fallback Continue button - same fix - This allows the Continue button to work after place-business action completes
- Renamed step title from 'Market Rows' to 'Market Business Row' - Added clarification that bottom row shows Investment cards separately
…ation - Changed h from 0.158333 to 0.144444 (104px) to correctly highlight only business row - Updated test to expect single-row height instead of combined two-row height
- When Continue is clicked on action step after action already completed, the method now shows the next step overlay instead of returning early - This ensures the flow continues smoothly when user clicks Continue after performing the required action
- Removed 600ms delay in onTutorialActionComplete so the next step overlay shows immediately after the action completes - This ensures smooth transition from select-business to place-business step
- When clicking Continue on an action step that has already completed, the method now properly calls completeCurrentStep to advance the tutorial - This ensures the flow continues from select-business to place-business
- Added getActionCompletePredicate method to MainStreetTutorialHints - Updated confirmTutorialStep to check predicate result before advancing - This ensures the Continue button works correctly after action completes
Covers all 13 tutorial steps (T1-T13): - Confirm steps: verify Next button advances correctly - Action steps: perform required game actions, verify overlay transitions - Screenshot at key transition points for debugging Tests live at tests/e2e/main-street-tutorial-e2e.browser.test.ts Run with: npm run test:browser -- tests/e2e/main-street-tutorial-e2e.browser.test.ts
added 28 commits
June 15, 2026 23:34
… in E2E tutorial tests Commit 512de51 renamed state.market.business to state.market.development when implementing the Development market row, but the E2E test helpers still referenced the old property name, causing all interactive tutorial tests to silently no-op. Changes: - Rename s.state?.market?.business to s.state?.market?.development in clickRequiredBusinessCard, clickStreetSlot, and the seed verification test - Update deterministic card assertion (index 1 is now Barbershop instead of Laundromat due to community-space cards in the development deck) Tests: 12/12 browser tests pass, 3310/3310 unit tests pass, build succeeds.
…stle - Add BeleagueredCastleSaveLoad.ts with: - State serialization/deserialization (serializeBCState / deserializeBCState) - bcStateSerializer compatible with SaveLoadStore - saveBCSnapshot / loadBCSnapshot checkpoint helpers - Constants for schema version, game type, and slot ID - Modify BeleagueredCastleScene.ts: - Initialize SaveLoadStore and TranscriptStore in create() - Save checkpoint after deal completes (onDealComplete) - Auto-save transcript on game end (win, loss, auto-complete win) - Add saveCheckpoint() and autoSaveTranscript() helper methods - Modify BeleagueredCastleTurnController.ts: - Add onSaveCheckpoint callback to TurnControllerCallbacks - Call onSaveCheckpoint after each player move and after auto-complete - Add tests/beleaguered-castle/save-load-autosave.test.ts: - Save/load round-trip with state equality verification - Post-deal checkpoint restoration - Serialization round-trip verification - SaveLoadStore direct API usage test - Transcript autosave persistence (win and loss) - Full round-trip: checkpoint + transcript persisted and retrievable All AC-1 through AC-7 satisfied.
…d Castle - Add checkForSavedGameAndStart() in create() that loads checkpoint on boot - Add showResumeOverlay() with 'Resume' and 'New Game' buttons - Add restoreFromCheckpoint() to restore game state, skip deal animation - Add clearCheckpointAndStartFresh() to overwrite checkpoint and restart - Add startFreshGame() extracted from original create() logic - Add 5 new tests covering checkpoint existence, state restoration, separate store instances, autosave compatibility, and checkpoint clearing All 128 BC tests pass.
- Fix state object replacement bug: restoreFromCheckpoint() now mutates the existing game state's piles (clear + push) instead of replacing the state object. The renderer and turn controller hold references to the original object — replacing it left them pointing at stale state. - Fix async deal-animation timing: startFreshGame() is now called synchronously in create() (preserving original timing for layout tests), and the async checkpoint check runs on the next frame via Phaser's time.delayedCall. This prevents the deal animation from being deferred to a Promise microtask. - Fix 'New Game' on resume overlay: clearCheckpointAndStartFresh() now uses clearBCSnapshot() to DELETE the checkpoint before restarting, instead of saving a fresh state (which would re-trigger the resume overlay on restart). - Add clearBCSnapshot() to BeleagueredCastleSaveLoad.ts — wraps SaveLoadStore.remove() for clean checkpoint deletion.
… fresh deal - No deal animation starts until after the async checkpoint check resolves - If checkpoint found: show resume overlay over empty board (no fake deal) so when user clicks Resume the board appears from saved state instantly - If no checkpoint: start deal animation on the next frame via Phaser time.delayedCall(0, ...) - If loadBCSnapshot errors: fall through to a fresh game so BC is still playable even if storage is unavailable This eliminates the jarring UX of seeing a fresh deal start, then getting interrupted by the resume overlay, then having the state replaced.
…n failure The discardSelected() method previously moved card data model updates (card.faceUp = false; discardPile.push(card)) to the animation completion callback. If the animation never fired its completion event (e.g., texture missing, scene destroyed), the card became orphaned - removed from hand but never added to discardPile. Fix: Synchronously update the data model (faceUp, push to discardPile) before starting the discard animation. The animation now only handles UI cleanup (selection, highlights, HandView/PileView refresh). This ensures the card is always in discardPile (or hand before splice) at all times. Added 10 tests in tests/gym/GymHandPileDiscardConsistency.test.ts covering: - Card immediately in discardPile after splice, before animation completes - Card not orphaned when animation completion event never fires - Card is in either hand or discardPile at all times - Normal animated discard still works - Reduced-motion discard works - Invalid/out-of-range selection does nothing - Sequential discards all land in discardPile - Source-level verification of fix pattern
…-contained per slider (only active during drag) Changes: - src/ui/GymSceneUtils.ts: createSlider now self-manages pointermove/pointerup listeners, registering only on pointerdown and unregistering on pointerup/destroy - example-games/gym/scenes/GymHandPileScene.ts: removed scene-level pointermove/pointerup forwarding; sliders handle their own lifecycle - tests/gym/GymHandPileDiscardConsistency.test.ts: removed source-inspection test for old shutdown pattern (no longer needed) - tests/gym/GymSceneUtils.smoke.test.ts: added 5 new tests covering self-contained listener registration, unregistration, backward-compatible external calls, destroy cleanup, and multi-slider isolation Resolves acceptance criteria: - Zero active pointermove handlers when no slider is dragged - Each dragged slider gets its own handler (not forwarded to all three) - All sliders continue to work identically - Full test suite passes
…PileScene Added a method to GymHandPileScene that properly cleans up all scene-created objects when the scene shuts down. Registered the method as a event listener in to integrate with Phaser 4's scene lifecycle. Cleanup includes: - Stopping and nullifying activeMoveTween - Destroying highlightGraphics (if created) and clearing highlightLabels - Destroying arcSlider, spacingSlider, and rotationSlider components - Destroying HandView, deckView, and discardView UI components - Destroying layoutLabel, dragLabel, and dragButton text objects - Destroying logTexts and clearing internal state arrays - Unregistering the shutdown listener to prevent double-calls All cleanup is wrapped in try/catch guards and null-checks for safety. The base class (GymSceneBase) already handles helpPanel/helpButton cleanup via its own shutdown listener. Added test file tests/gym/GymHandPileShutdown.test.ts with 12 tests verifying method presence, event registration, and cleanup completeness.
…mHandPileScene - Unified CardDiscardedPayload in GameEventEmitter.ts: added cardId?, made playerIndex optional (backward compatible) - Added 'card:discarded' (colon) event to GameEventMap in GameEventEmitter.ts - Removed duplicate CardDiscardedPayload from discardCard.ts, now imports from core-engine and re-exports - Removed all (gameEvents as any) casts from GymHandPileScene.ts discardSelected() — .on(), .removeAllListeners(), and discardCard() gameEvents parameter now type-checked properly - Fixed (slider.hitArea.input as any).enabled cast in setSliderVisible() — Phaser's InteractiveObject.enabled is properly typed - Updated GymHandPileDiscardConsistency.test.ts to remove casts - All 188 unit test files pass, TypeScript and Vite builds clean
… createSlider - Create src/ui/Slider.ts with a Slider class (constructor, setValue, getValue, destroy, onValueChange) - Self-contained pointermove/pointerup listeners (only active during drag) - No handlePointerMove/handlePointerUp on the public API - Remove createSlider, SliderOptions, SliderResult from src/ui/GymSceneUtils.ts - Update src/ui/index.ts barrel to export Slider/SliderOptions from ./Slider - Update GymHandPileScene to use new Slider(...) instead of createSlider(...) - Migrate slider tests from tests/gym/GymSceneUtils.smoke.test.ts to tests/ui/Slider.test.ts - Add 15 unit tests for the new Slider class covering construction, value management, self-contained listener lifecycle, and cleanup - All 27 relevant tests pass (15 slider + 11 remaining smoke + 1 spacing check) - npm test and npm run build both succeed
…GymHandPileScene - Add src/ui/HighlightManager.ts — lightweight class managing named highlight zones with two styles (fill/border), individual lifetimes, and timer cleanup - Add tests/ui/HighlightManager.test.ts — 19 unit tests covering zone creation, auto-clear, manual clear, style switching, and destroy - Export HighlightManager from src/ui/index.ts barrel file - Migrate example-games/gym/scenes/GymHandPileScene.ts: - Remove HIGHLIGHT_COLOR / HIGHLIGHT_ALPHA constants - Replace highlightGraphics/highlightLabels with highlightManager - showValidMoves() uses addZone() with 3000ms lifetime - highlightDropZones() uses addZone() for drag feedback - clearHighlights() delegates to highlightManager.clearAll() - shutdown() calls highlightManager.destroy() - Update GymHandPileShutdown.test.ts for new highlightManager property - Update GymHandPileHighlights.browser.test.ts for new API
…r layout - Add optional 'centerX' property to HandViewOptions - Store as private _centerX, used in computeCardPositions() and animateAddCard() to anchor hand at a fixed horizontal centre - Add setCenterX(x: number | undefined) public method for runtime updates - Update GymHandPileScene to use centerX: GAME_W/2 instead of static HAND_BASE_X - Carry forward pre-existing Slider import migration in Gym scene - Add 21 unit tests in tests/ui/handView.centerX.test.ts covering: construction, spacing changes, addCard/removeCard, arc layout, backward compatibility, vertical mode, setCenterX runtime updates, reduced-motion mode, and edge cases Acceptance criteria: hand stays centered at GAME_W/2 after spacing, draw, discard, and recall operations.
Adds [ < Prev ] and [ Next > ] buttons to all Gym demo scenes extending GymSceneBase.initHeader(), positioned to the right of the [ Menu ] button on the same Y line (SCENE_HEADER_Y = 14). Navigation wraps around using the GYM_SCENE_CATALOGUE ordering. Changes: - GymRegistry.ts: Added getAdjacentGymSceneKey() exported helper function for wrap-around scene navigation logic - GymSceneBase.ts: Added prevButton/nextButton protected properties and createNavButton() private method; modified initHeader() to create the buttons with style matching [ Menu ] (12px font, #aaccaa color, #88ff88 hover) - GymSceneHeaderNavigation.test.ts: 8 new unit tests verifying wrap-around navigation (first→last, last→first), middle-adjacent navigation, unknown key handling, and Router scene exclusion - docs/gym/GYM_INDEX.md, example-games/gym/README.md: Updated with navigation documentation
- Add triggerTranscriptDownload() helper for browser file download - Add 'Export Transcript' button to end-of-round overlay in GolfScene - Add showErrorExportOverlay() for crash-time transcript export - Add window.onerror handler in GolfScene for error-triggered export - Increase overlay box height from 300 to 350 to accommodate new button - Add browser test verifying export button exists and is interactive
- Create scripts/contact-sheet.ts using sharp to composite turn screenshots into a grid with turn number labels (4 columns, 225x175 thumbnails, labeled SVG overlays) - Integrate contact sheet generation into replay.ts: call after replay loop completes, include contactSheetPath in summary - Update ReplaySummary interface with optional contactSheetPath - Build and all tests pass
- Add Engine Event System section to docs/DEVELOPER.md with event types table, subscribing/emitting examples, global access (window.__GAME_EVENTS__), and PhaserEventBridge docs - Add Contact Sheet section documenting contact-sheet.png output, grid layout, and sharp-based generation - Add In-Game Transcript Export Button section documenting end-of-round and error-triggered export - Add troubleshooting entries for: dev server not running, unsupported transcript version, IndexedDB quota issues, Playwright not installed
…n mechanism and tests Implementation: - Add initUndoRedoButtons(onUndo, onRedo) to CardGameScene - Add refreshUndoRedoButtons(canUndo, canRedo) to CardGameScene - Resolution-independent positioning relative to settings button - Buttons parented into hudContainer at depth 1000 - shutdownBase() cleanup for undo/redo buttons Tests: - 14 unit tests for button creation, alpha state, cleanup, opt-in - 4 browser tests for overlap verification at 1280x720, 1024x768, 1920x1080 - All 3413 unit tests + 4 browser tests pass
…o shared undo/redo mechanism - Removed undoButton/redoButton from BeleagueredCastleRenderer - Removed createActionButton calls and refreshUndoRedoButtons method - Added this.initUndoRedoButtons() in BeleagueredCastleScene.create() - Added this.initUndoRedoButtons() in restoreFromCheckpoint() - Replaced bcRenderer.refreshUndoRedoButtons with this.refreshUndoRedoButtons - Added 4 browser tests verifying migration and no overlap - All 3413 unit tests + 8 BC browser tests pass
…d undo/redo mechanism - Removed undo/redo button creation from refreshActionButtons() - Removed smallW local variable (no longer needed) - Updated getSectionRectsForTest() action width calculation - Added initUndoRedoButtons() call in MainStreetLifecycleManager - All 3413 unit tests + 13 MS browser tests pass
- Updated docs/DEVELOPER.md CardGameScene section with initUndoRedoButtons and refreshUndoRedoButtons API docs - Added usage example in the scene lifecycle pattern - Added description of resolution-independent positioning - JSDoc was already added in the implementation commit
…buttons - Replace text-based [ Undo ] / [ Redo ] buttons with createActionButton visual buttons - Store button references and mirror refreshUndoRedoButtons alpha pattern (1.0 enabled, 0.5 disabled) in updateDisplay() - Update help text to reference 'action buttons' instead of bracketed labels - All 7 Gym undo/redo unit tests pass
…dUndoRedoButtons utility Extract undo/redo button creation + positioning logic from CardGameScene.initUndoRedoButtons() into a standalone exported function createStandardUndoRedoButtons() in Renderer/index.ts. This allows any scene (including GymUndoRedoScene which extends Phaser.Scene, not CardGameScene) to use the standard-positioned undo/redo buttons via the shared mechanism. Changes: - src/ui/Renderer/index.ts: Add createStandardUndoRedoButtons() standalone function with StandardUndoRedoButtons interface - src/ui/CardGameScene.ts: initUndoRedoButtons() now delegates to createStandardUndoRedoButtons() - example-games/gym/scenes/GymUndoRedoScene.ts: Replace custom createActionButton calls with createStandardUndoRedoButtons() - tests/ui/CardGameScene.test.ts: Update mock and tests for the new delegation pattern; remove opt-in test no longer valid (BC always initializes undo/redo in create()) All 3411 unit + 11 browser tests pass.
- Added COMMON_SFX_KEYS constant object in SoundManager.ts for cross-game keys (UI_CLICK, TURN_CHANGE, ROUND_END, SCORE_REVEAL) - Added namespace collision protection to SoundManager via namespace option - Added clearRegistrations(), has(), keys() methods to SoundManager - Added audioPathWithFallback() helper to CardGameScene for per-game audio dirs with default fallback - Migrated Beleaguered Castle, Lost Cities, The Mind from game-specific prefixes (bc-sfx-, lc-sfx-, mind-sfx-) to standard sfx- prefix - Migrated Main Street from ms- prefix to sfx- prefix - Added namespace-scoped Phaser audio keys for collision protection across all 8 games (golf, sushi-go, feudalism, beleaguered-castle, lost-cities, the-mind, main-street) - Created assets/audio/default/ with shared fallback sounds - Created per-game audio directories (assets/audio/golf/, sushi-go/, feudalism/) with copies of shared audio files - Created docs/SFX_CONVENTION.md documenting the naming convention - Updated docs/DEVELOPER.md with SFX convention reference - Updated all tests to use new sfx- prefix convention - Updated sfx-tf-mapping.ts with new sfx- prefix keys
… feedback for safe auto-moves in Beleaguered Castle
- Added isSafeAutoMove parameter to TurnControllerCallbacks.onAutoCompleteVisual
to distinguish safe auto-moves from endgame auto-complete
- Modified executePlayerMove to pass isSafeAutoMove=true when triggering
auto-move visual playback
- Updated BeleagueredCastleScene.runAutoCompleteVisuals to accept the
isSafeAutoMove flag and use card-to-foundation sound/event for safe
auto-moves vs auto-complete-card for endgame auto-complete
- For safe auto-moves: plays sfx-card-to-foundation end sound via
moveGameObject and emits card-to-foundation game event per card,
providing consistent audio feedback with manual foundation moves
- Interaction remains blocked during playback via existing
turnController.autoCompleting flag
- Added 3 new tests:
* Verifies onAutoCompleteVisual is called with isSafeAutoMove=true
when safe auto-moves are triggered (seed 5)
* Verifies callback is NOT called when no safe auto-moves exist
(seed 4, tableau-to-tableau move)
* Verifies startAutoComplete calls callback without isSafeAutoMove
for endgame auto-complete
Member
Author
|
Closed as superceded by 597 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Automated release created by ship skill.
Version: v0.1.1