Skip to content

Merge dev → main (automated)#600

Merged
SorraTheOrc merged 38 commits into
mainfrom
release/dev-to-main-20260710192218
Jul 10, 2026
Merged

Merge dev → main (automated)#600
SorraTheOrc merged 38 commits into
mainfrom
release/dev-to-main-20260710192218

Conversation

@SorraTheOrc

Copy link
Copy Markdown
Member

Automated release created by ship skill.\n\nIncludes CHANGELOG.md with work-item summaries from this release.

Sorra the Orc added 30 commits July 6, 2026 02:42
… errors

- Add Vite type declarations (vite-env.d.ts) for ?raw CSV imports
- Fix synergyTypes type casting in MainStreetCards.ts
- Add STAFF_CARD_TEMPLATES export for test access
- Update SVG generator to read from CSV instead of TS
- Update card catalog documentation to reference CSV as source of truth
- Fix script for vite-node instead of tsx (Node/CSV compatibility)
- Add CsvLoader unit tests with vitest globals reference
Creates a shared Game Over overlay component in the core engine UI
that all games can use instead of writing their own.

Features:
- Full-screen semi-transparent backdrop using createOverlayBackground
- Center title (default: 'Game Over', configurable)
- Auto-scaling summary text area (font size computed via
  computeAutoScaleFontSize using binary search)
- Bottom button row: [Play Again] and [Menu]
- Optional extra button row for game-specific actions
- Customizable button labels and callbacks
- dismiss() method for cleanup
- Exported from src/ui/index.ts barrel file

Files:
- src/ui/GameOverOverlay.ts: Implementation (createGameOverOverlay +
  computeAutoScaleFontSize)
- src/ui/index.ts: Barrel exports for GameOverOverlay types
- tests/ui/GameOverOverlay.test.ts: 21 tests covering all features
…xcluded everywhere

- computeSynergyBonus: cards with synergyCoinBonus=0 AND synergyRepBonus=0
  neither contribute to nor receive synergy
- computeSynergyRepBonus: same zero-synergy exclusion
- computeSynergyPairs: both card AND neighbor filtered (was only card)
- computeHandCardSynergyBonus: zero-synergy grid businesses skipped
- Test helper makeBiz helpers detect 'biz-pawnshop-' prefix to default
  synergyCoinBonus=0, synergyRepBonus=0 for backward compat with existing
  Pawn Shop tests
- community-space-types: add synergyCoinBonus/synergyRepBonus to fixture
  and BUSINESS_CARD_FIELDS list

All 4184 unit tests pass (235 files, 9 skipped).
When discard piles are empty, hide the PileView sprite and count text
instead of showing a ghosted full-size card-back (95×130). This fixes
the oversized card-back visual issue in the discard section.

The discard hit areas created in createDiscardZones handle all
interaction, so the ghosted card-back is unnecessary visual clutter.
When a card IS placed, the existing code path shows the compact card
(57×78) correctly.
…e (SLL)

- Created gym-tooltip.layout.json with zones for header, label, content, log
- Updated GymTooltipScene to use SLL anchors (anchorPoint) for layout positions
- Added GymTooltipLayout.test.ts with schema validation and position mapping tests
- Scene functionality preserved; all tests pass
… Language (SLL)

Migrate the following Gym demo scenes to use declarative SLL layout
positions instead of hardcoded pixel values:

1. GymOverlayUiScene.ts - buttons, intensity text, event log
2. GymDeckRngScene.ts - controls, card display
3. GymHudComponentsScene.ts - instructions, button rows, status, event log
4. GymTranscriptScene.ts - controls, event log
5. GymUndoRedoScene.ts - controls, counter, status, history, event log
6. GymSaveLoadScene.ts - controls, state text, event log
7. GymAudioFeedbackScene.ts - controls rows, status, event log
8. GymGraphicsLightingSpikeScene.ts - controls, content, event log
9. GymGraphicsShaderSpikeScene.ts - controls, status, content, event log

For each scene:
- Created a scene-specific layout JSON file in layouts/
- Added module-level SLL layout parsing (matching the tooltip pattern)
- Replaced hardcoded Y positions with SLL anchor lookups
- Kept fallback values for robustness (null layout)
- Preserved visual appearance and functionality

All 237 gym tests pass. Build succeeds.
Add reusable runtime support for screen object ownership registration and
mode-based visibility toggling:

- Re-export VisibilityOwnershipController from src/ui/index.ts for UI-layer
  consumers
- Create GymLayoutOwnershipScene demo that exercises registration, mode
  switching, group toggling, and diagnostic warnings
- Register the new scene in GymRegistry and Gym index barrel
- Add unit tests (tests/ui/visibility-ownership-runtime.test.ts) covering
  registration, toggling, multi-group OR logic, default behavior, and
  diagnostics
- Update browser tests to include the new scene in GymRouterScene and
  GymSceneSmoke suites

Acceptance Criteria Met:
- Runtime can register screen objects to ownership groups ✓
- Runtime can hide/show registered objects based on active mode ✓
- Metadata participates without schema-breaking changes ✓
- Unit tests cover registration, toggling, and default behavior ✓
…ntrols/Usage Example/Test Plan sections

All 13 Gym demo scenes excluding GymRouterScene have their help panels
restructured with the new 4-section format:
  - Features: engine feature demonstrated with real game use cases
  - Controls: each button explained with what it does and why it exists
  - Usage Example: realistic game scenario showing the feature in action
  - Test Plan: step-by-step button sequence for E2E validation

Scenes updated: GymDeckRngScene, GymHandPileScene, GymHudComponentsScene,
GymOverlayUiScene, GymTooltipScene, GymSaveLoadScene, GymTranscriptScene,
GymUndoRedoScene, GymAudioFeedbackScene, GymSllScene,
GymGraphicsLightingSpikeScene, GymGraphicsShaderSpikeScene,
GymLayoutOwnershipScene
… scene

- Extend HandView.sortCards() to accept optional AnimatedSortOptions
  with animate, duration, and ease parameters
- When animate: true, sprites tween smoothly from old to new positions
  instead of destroy/recreate; sprites array is reordered to match
  sorted cards before applying tweens
- Backwards compatible: existing callers without opts work unchanged
- Respects reducedMotion mode (instant placement when enabled)
- Migrate GymHandPileScene.sortHand() to use animated sort API
- Export AnimatedSortOptions from ui/index.ts barrel
- Add 6 unit tests: snap compat, tween targets, sprite preservation,
  reduced-motion, arc layout Y positions, correct final positions
…, tableau highlight, cancel button, and step indicator

## Changes

### SushiGoConstants.ts
- Added styled button constants: CHOPSTICKS_BUTTON_BG, CHOPSTICKS_BUTTON_HOVER_BG, text colors, depth
- Added tableau highlight constants for chopsticks card glow (blue when available, gold when active)
- Added first-pick highlight constants (brighter green, thicker stroke, more visible fill)
- Added cancel button constants (dark red background, hover effects, positioning)
- Added step indicator constants (gold color, 'Step 1 of 2' / 'Step 2 of 2')
- Updated button padding (x: 16, y: 8) for better styling

### SushiGoScene.ts
- 1. **Styled chopsticks button** - Replaced bracketed text '[ Use Chopsticks ]' with proper background rectangle + text button. Button has dark green background that brightens on hover.
- 2. **Chopsticks tableau highlight** - Adds a blue glow (or gold when active) around chopsticks cards in the player's tableau when chopsticks are usable.
- 3. **On-screen cancel button** - Shows a visible 'Cancel' button (red themed) during chopsticks mode, positioned below the hand. Also clickable with hover effects.
- 4. **Step indicator** - Shows 'Step 1 of 2' / 'Step 2 of 2' in gold text above the chopsticks button during the two-card pick flow.
- 5. **Improved first-pick highlight** - Uses brighter green (#00ff66), thicker 4px stroke, and more visible 0.25 fill alpha.
- 6. **Better instruction text** - 'Pick 2 cards: click your 1st card' / 'click your 2nd card' instead of 'Chopsticks: ...'
- All new UI objects are properly cleaned up in shutdown() and during mode transitions.
- Proper lifecycle management for first-pick highlight (destroyed on cancel/mode end, recreated on refresh).

### Tests
- Added SushiGoChopsticksScene.test.ts - 30 tests verifying all new UX constants
- Updated SushiGoConstants.test.ts - 56 tests including all new constants
…reedyStrategy

- Add GreedyStrategyConfig interface with configurable columnWeight (default 0.5 = 50/50 balance)
- Add DEFAULT_GREEDY_CONFIG constant
- Update computeColumnBonus to scale by card point values of matching cards in column
  (high-value cards like Queens get larger penalty for missing column potential)
- Use Math.max(0, cardValueSum) to prevent negative card values from producing positive bonus
- Propagate config through chooseDrawSource, chooseMoveForCard, and AiPlayer
- Add 8 new test cases: config defaults, columnWeight=0, columnWeight=1,
  card point value scaling, low-value cards (Kings=0), AiPlayer config passthrough
- Update existing computeColumnBonus tests to use high-value Queens instead of Kings
- Extend HandView.sortCards() with AnimatedSortOptions (animate, duration, ease)
- Migrate GymHandPileScene.sortHand() to use animated sort API
- Add 6 unit tests for sort animation (tween targets, sprite preservation,
  reduced-motion, backward compat, arc layout, final positions)
- Export AnimatedSortOptions from ui/index.ts barrel
- Respects reducedMotion mode
The animated sort path was only tweening x/y positions, but cards in
an arc layout also have a rotation angle proportional to their horizontal
offset from center. When cards are re-sorted, their rotation was snapping
instantly instead of transitioning smoothly.

- Compute target rotation per-sprite in animated sort path (same formula
  as applyLayout: maxRotationDegrees * normalized offset)
- Include rotation in the tween config alongside x/y
- Update mock tween in handView.animation.test.ts to apply rotation

All 28 animation tests pass (22 animateAddCard + 6 sort animation).
After reordering sprites to match the sorted card order, their visual
stacking order (depth) was still in the original creation order, causing
cards to render in the wrong z-order. Fixed by calling setDepth(i) on
each sprite after reordering so that later-index cards render on top.

- Added setDepth loop before the animation tween loop
- Added setDepth mock to test mock image
…Feudalism to shared GameOverOverlay

Migrates four games from their custom game-over overlay implementations
to the shared GameOverOverlay component in the core engine UI.

Games migrated:
- Beleaguered Castle: win overlay now uses createGameOverOverlay.
  Gains a [Menu] button (navigates to GameSelectorScene).
  The no-moves overlay remains custom (undo is game-specific).
- The Mind: win/loss overlays now use createGameOverOverlay
  instead of createParameterizedOverlay. Gains a [Menu] button.
- Golf: end-screen overlay now uses createGameOverOverlay.
  Gains a [Menu] button. [Export Transcript] is an extra button.
- Feudalism: game-over overlay now uses createGameOverOverlay.
  Gains a [Menu] button.

Games NOT migrated (remain with custom overlays):
- Lost Cities: tabular multi-column match summary
- Sushi Go: tabular round-by-round breakdown
- Main Street: highly custom with challenges, meta-progression, difficulty selector

Files:
  example-games/beleaguered-castle/scenes/BeleagueredCastleScene.ts
  example-games/the-mind/scenes/TheMindScene.ts
  example-games/golf/scenes/GolfSceneHelpers.ts
  example-games/feudalism/scenes/FeudalismOverlays.ts
Changes:
- MainStreetCardSvgGenerator.ts: Changed income label from '+X/turn' to 'Income: +X/turn'
- UpgradeOverlaySpec.ts: Changed overlay income text to 'Income: +X/turn', centered
  position (x: width/2, y: height*0.38) with origin (0.5, 0.5); centered reputation
  below income at y: height*0.5. Added originX/originY to OverlayTextSpec.
- MainStreetRenderer.ts: Centered income/reputation overlay text using spec origins;
  added income overlay to market cards (business/community-space); replaced hand card
  manual rendering with unified SVG texture + overlay pipeline; removed separate
  hand card income text ('/turn' format); removed unused getSynergyDisplayColor.
- Tests: Updated all tests to expect 'Income: +X/turn' format and centered positioning.
…9 instead of stretched ~276×50

The incident queue ('Upcoming') panel was rendering cards at ~276×50
pixels, breaking the 7:4 SVG aspect ratio and causing visible
horizontal stretching.

Changes:
- Update BASE_QUEUE_CARD_W to 120 and BASE_QUEUE_CARD_H to 69
  (custom incident card size, preserving ~7:4 aspect ratio)
- Replace hardcoded cardRenderH=50 and panel-derived cardRenderW in
  refreshIncidentQueue() with layout.queueCardW/queueCardH
- Add queue card dimensions to prewarmVisibleCardTextures() so
  incident queue textures are rasterised ahead of time
- Add test suite (7 tests) validating constants, aspect ratio, and
  layout behavior
- Document 120×69 in card-dimensions.md recommended sizes

All unit tests pass (4305 tests, 240 files).
…audit fix)

Root cause: Overlay text coordinates in UpgradeOverlaySpec.ts use absolute
card-pixel positions (origin at top-left of card), but the renderer's
applyUpgradeOverlays adds these to a Phaser Container whose local origin
is at the centre of the card image (image placed at 0,0 with default
origin 0.5). This means:
- x: width/2 becomes the RIGHT edge of the card
- y: height*0.38 becomes near the bottom edge

Fix: Convert all coordinates to container-local space by subtracting
width/2 from x and height/2 from y:
- incomeText: x=0, y=-height*0.06 (centred horizontally, slightly above centre)
- reputationText: x=0, y=+height*0.1 (centred horizontally, below income)
- levelBadge: x=width/2-4, y=4-height/2 (top-right corner)
- nameText: x=0, y=-height/2+16 (top-centre)

Tests updated to match new container-local coordinate expectations.
Replace hardcoded card-ID arrays in MainStreetTiers.ts with dynamic
arrays built from the CSV-derived CARD_TIER_MAP. Add a 'tier' column
to card-data.csv (values 1-5, empty for always-available staff cards).

Key changes:
- card-data.csv: Add 'tier' column after 'description' with per-card
  tier assignments for all 83 progression cards
- MainStreetCards.ts: Export CARD_TIER_MAP (card ID → tier string) built
  from CSV at module load time
- MainStreetTiers.ts: Build TIER_*_CARD_IDS arrays from CARD_TIER_MAP
  instead of hardcoded literals; tier structure (thresholds, challenges)
  remains unchanged in TypeScript
- README.md: Document the new 'tier' column in CSV column reference

All existing tests (4325 pass) and build continue to pass without changes.
…nd fix Sushi Go hand centering

- Remove all The Mind game files, scenes, assets, tests, and adapters
- Remove The Mind entry from GameSelectorScene and main.ts
- Remove TheMindReplayAdapter from scripts/adapters
- Fix Sushi Go hand centering: remove erroneous setBaseX() call in
  refreshHand() that shifted the hand off-center. HandView's
  layoutCardPositions already centres the hand around baseX.
- Sushi Go! tests continue to pass (216 tests)
- Build succeeds without errors
…-function modules

Implement the first child of the CSV Auto-Balancing Tool epic:
- scripts/balance-cards/ (5 modules): rationale codes, CSV I/O/validation/backup,
  hybrid curve-fitting + tier-band algorithm, summary table formatter, barrel index
- tests/main-street/balance-cards.test.ts: 51 tests covering all 6 acceptance criteria
  (cost curves for all 5 families, tier band assignment, reward spread, CSV validation,
  backup rotation, summary format, deterministic output, incident exclusion)

All 51 tests pass. Full project build succeeds (tsc + vite build).
…lidation, methodology doc, npm script

Completes all child work items of the CSV Auto-Balancing Tool epic:

Children completed:
- CG-0MRDM4YGI002SK1E: CLI framework (scripts/run-balance-cards.ts)
- CG-0MRDM4YGO005X1H9: Business/CS balancing (cost range [3-14], spread enforced)
- CG-0MRDM4NRM0051KD5: Upgrade/staff algorithm tests (51 tests)
- CG-0MRDM5BJF004LUNC: Upgrade/staff balancing (cost range [3-14])
- CG-0MRDM4NRV0066Z9P: Event/Monte Carlo validation tests
- CG-0MRDM5BJS006XU7X: Event balancing (Investment cost range [0-14], Incidents free)
- CG-0MRDM5BJ3004AE1W: Balancing methodology document and doc migration
- CG-0MRDM5BJQ009YL8N: npm script + guardrails

Key changes:
- CLI entry point: scripts/run-balance-cards.ts with --input/--output support
- Improved cost curves using tier column (+ weighted stats)
- Cost spread enforcement (no cost value > 1/3 of family cards)
- CSV column fix (29 columns with synergyCoinBonus/synergyRepBonus/tier)
- 517b175: docs/main-street/balancing-methodology.md (new)
- Origin docs updated with cross-references
- npm run balance-cards script added (tsc + tsx)

All 3961 unit tests pass (226 test files).
… with rotating backups

The balanced CSV now replaces card-data.csv directly. The original
is preserved via the rotating backup system (card-data.csv.bak.1-.bak.5).
Sorra the Orc added 8 commits July 10, 2026 02:52
Fixes for Container→Text refactoring and test query specificity:

Scene fixes:
- createOwnedCard returns Phaser.GameObjects.Text directly (not Container)
  avoiding Phaser 4 issue where container.setVisible() doesn't cascade
  visible property to child textures
- bgRects array stores background Rectangle refs for cleanup
- syncAllVisibility() removed (controller handles sync internally)
- removeUngrouped() targets by text prefix (startsWith 'Ungrouped #')
- cleanup() destroys text targets and background rects separately
- Clear button handler also clears bgRects
- toggleGroup() uses displayName instead of raw groupName in label
- GroupToggle interface adds displayName field
- createGroupToggle() stores displayName
- Fixed indexOf bug in ungrouped button creation loop

Test fixes:
- Mode button search: text.startsWith('[ Mode: X ]') to avoid matching
  demo card text like 'Shell Title'
- Ungrouped card search: 'Ungrouped #7' (idx = targets.length + 1,
  6 demo cards registered before addUngrouped)
…baseIncome values

Core changes:
- Removed Math.floor from applyReputationMultiplier (MainStreetDifficulty.ts)
  so fractional income values (e.g. 0.5 baseIncome) are no longer truncated
- Removed Math.round from applyActiveEffectMultiplier (ActiveEffect.ts)
  so per-slot income during applyIncome retains fractional precision

Display & logging:
- Updated HUD tooltip (MainStreetHudTooltips.ts) to format fractional
  coin values with toFixed(1) pre-multiplier and toFixed(2) post-multiplier
- Updated applyIncome log (MainStreetAdjacency.ts) to show fractional
  coin amounts with 2 decimal places

Documentation:
- Regenerated monte-carlo-baseline.json with updated win rate (0.505→0.65)
  and average coins/turn (2.01→3.30) reflecting the more accurate economy

Tests (TDD approach):
- reputation-coin-multiplier: updated floor tests → fractional preservation;
  added 5 new tests for fractional income, integer backward compat, and
  applyIncome integration with fractional values
- adjacency, activity-log, integration, turnflow: updated coin assertions
  to use toBeCloseTo for fractional values
- ActiveEffect: updated rounding test → fractional preservation

All 132 main-street/core-engine test files pass (2255 tests).
…he UI

Standardize all coin value display to toFixed(3) for consistent precision:

- MainStreetRenderer.ts: HUD coin counter, event card tooltip coin deltas (2 locations)
- MainStreetHudTooltips.ts: Pre/post multiplier income in coins tooltip, coins breakdown in score tooltip
- MainStreetAdjacency.ts: Activity log income entries (gain + neutral)
- MainStreetEngine.ts: Event effect description coinChange, bankruptcy log

Tests updated:
- activity-log.test.ts: Regex for fractional income updated to match 3 decimal places,
  zero-income assertion updated from 0.00 to 0.000

All 132 test files pass (2255 tests). Build succeeds.
Changes:
- MainStreetCardSvgGenerator.ts: Changed income label from '+X/turn' to 'Income: +X/turn'
- UpgradeOverlaySpec.ts: Changed overlay income text to 'Income: +X/turn', centered
  position (x: width/2, y: height*0.38) with origin (0.5, 0.5); centered reputation
  below income at y: height*0.5. Added originX/originY to OverlayTextSpec.
- MainStreetRenderer.ts: Centered income/reputation overlay text using spec origins;
  added income overlay to market cards (business/community-space); replaced hand card
  manual rendering with unified SVG texture + overlay pipeline; removed separate
  hand card income text ('/turn' format); removed unused getSynergyDisplayColor.
- Tests: Updated all tests to expect 'Income: +X/turn' format and centered positioning.
@SorraTheOrc
SorraTheOrc merged commit 3799faa into main Jul 10, 2026
@SorraTheOrc
SorraTheOrc deleted the release/dev-to-main-20260710192218 branch July 10, 2026 19:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant