# Old Card Scripts - Migration Strategy ## TL;DR: What Happens to Old Scripts? **Answer:** They are **REPLACED** by the new state machine system, but **CardDisplay stays**. ### Keep (Don't Touch) ✅ - **`CardDisplay.cs`** - Core visual renderer, used by both old and new systems ### Replace (Eventually Deprecate) 🔄 - **`FlippableCard.cs`** → Replaced by `Card.cs` with state machine - **`AlbumCard.cs`** → Replaced by `CardPlacedInSlotState.cs` + `CardAlbumEnlargedState.cs` - **`AlbumCardPlacementDraggable.cs`** → Replaced by `Card.cs` with `CardDraggingState.cs` --- ## Current Usage Analysis ### Where FlippableCard is Used: 1. **BoosterOpeningPage.cs** (8 references) - Line 592: Instantiate FlippableCard for booster reveal - Line 601, 643, 660, 752, 770: GetComponent calls - **Impact:** High - main booster opening flow 2. **AlbumCardPlacementDraggable.cs** (1 reference) - Line 45: GetComponent reference - **Impact:** Medium - album placement flow 3. **AlbumCard.cs** (1 reference) - Line 94: GetComponentInParent during click forwarding - **Impact:** Low - will be removed when AlbumCard is replaced ### Where AlbumCard is Used: 1. **AlbumCardSlot.cs** (2 references) - Line 186-187: Instantiate and GetComponent for pre-placed cards - **Impact:** High - album slot system 2. **AlbumViewPage.cs** (2 references) - Line 346: GetComponent when handling enlarge - Line 457-458: Instantiate AlbumCardPlacementDraggable - **Impact:** High - album view interactions 3. **CardDisplay.cs** (1 reference) - Line 316: GetComponentInParent for preview mode - **Impact:** Low - preview feature 4. **FlippableCard.cs** (1 reference) - Line 73: GetComponentInChildren reference - **Impact:** Will be removed when FlippableCard is replaced --- ## Migration Phases ### Phase 1: Parallel Development (Current) ✅ **Status:** Both systems coexist, no breaking changes ``` Old System (Active) New System (Being Built) ├─ FlippableCard.cs ├─ Card.cs ├─ AlbumCard.cs ├─ CardContext.cs ├─ AlbumCardPlacement... ├─ CardAnimator.cs └─ CardDisplay.cs ←──────────┼─→ CardDisplay.cs (shared!) └─ State scripts... ``` **Action:** Build new Card prefab, test in isolation **Timeline:** Current (you're here!) --- ### Phase 2: Partial Replacement - Booster Opening (Recommended Start) **Status:** Replace booster cards only, album cards still use old system #### Changes Required: **File: `BoosterOpeningPage.cs`** **Old code:** ```csharp [SerializeField] private GameObject flippableCardPrefab; // In SpawnCards() GameObject cardObj = Instantiate(flippableCardPrefab, cardDisplayContainer); FlippableCard flippableCard = cardObj.GetComponent(); flippableCard.SetupCard(cardData); flippableCard.OnCardRevealed += HandleCardRevealed; flippableCard.OnCardTappedAfterReveal += HandleCardTapped; ``` **New code:** ```csharp [SerializeField] private GameObject cardPrefab; // New Card prefab // In SpawnCards() GameObject cardObj = Instantiate(cardPrefab, cardDisplayContainer); StateMachine.Card card = cardObj.GetComponent(); card.SetupForBoosterReveal(cardData, isNew: true); // Subscribe to state events (if needed) var flippingState = card.GetStateComponent("FlippingState"); // Add custom events if needed, or just let state machine handle it ``` **Benefits:** - Test new system in one isolated flow - Booster opening is cleanest use case (no complex album interactions) - Easy to rollback if issues arise **Timeline:** 2-4 hours --- ### Phase 3: Full Replacement - Album System **Status:** Replace album cards, old system fully deprecated #### Changes Required: **File: `AlbumCardSlot.cs`** **Old code:** ```csharp [SerializeField] private GameObject albumCardPrefab; // In SpawnPreviewCard() GameObject cardObj = Instantiate(albumCardPrefab, transform); AlbumCard albumCard = cardObj.GetComponent(); albumCard.SetupCard(cardData); albumCard.SetParentSlot(this); albumCard.OnEnlargeRequested += HandleEnlarge; albumCard.OnShrinkRequested += HandleShrink; ``` **New code:** ```csharp [SerializeField] private GameObject cardPrefab; // Same Card prefab as booster // In SpawnPreviewCard() GameObject cardObj = Instantiate(cardPrefab, transform); StateMachine.Card card = cardObj.GetComponent(); card.SetupForAlbumSlot(cardData, this); // Subscribe to enlarge events (if needed) var albumEnlargedState = card.GetStateComponent("AlbumEnlargedState"); albumEnlargedState.OnEnlargeRequested += HandleEnlarge; albumEnlargedState.OnShrinkRequested += HandleShrink; ``` **File: `AlbumViewPage.cs`** Similar changes for handling enlarged cards and backdrop. **Timeline:** 4-6 hours --- ### Phase 4: Cleanup - Remove Old Scripts **Status:** Old scripts deleted, prefabs archived #### Files to Remove: - ❌ `FlippableCard.cs` - ❌ `AlbumCard.cs` - ❌ `AlbumCardPlacementDraggable.cs` (if drag system is integrated) #### Files to Keep: - ✅ `CardDisplay.cs` - Still used by new system! - ✅ `AlbumCardSlot.cs` - Updated to use new Card prefab - ✅ `BoosterOpeningPage.cs` - Updated to use new Card prefab - ✅ `AlbumViewPage.cs` - Updated to use new Card prefab **Timeline:** 1 hour (after Phases 2-3 are stable) --- ## Coexistence Strategy (During Migration) ### Option A: Gradual Scene-by-Scene (Recommended) Replace one scene at a time: ``` Week 1: Booster Opening Scene └─ Uses new Card.prefab Week 2: Album View Scene └─ Uses new Card.prefab Week 3: Any other card scenes └─ Uses new Card.prefab Week 4: Remove old scripts ``` **Pros:** - Low risk, easy rollback - Test thoroughly at each step - Team can adapt gradually **Cons:** - Longer timeline - Maintain both systems temporarily --- ### Option B: Big Bang Replacement Replace all at once in one PR/branch: ``` Day 1-2: Update BoosterOpeningPage Day 3-4: Update AlbumViewPage + AlbumCardSlot Day 5: Test everything Day 6: Delete old scripts ``` **Pros:** - Faster completion - No long-term coexistence **Cons:** - Higher risk - More testing needed - Harder to rollback --- ## Feature Mapping: Old → New ### FlippableCard → Card with States | Old Feature | Old Implementation | New Implementation | |-------------|-------------------|-------------------| | Idle hover | FlippableCard._idleHoverTween | CardIdleState.OnEnterState() | | Click to flip | FlippableCard.OnPointerClick() | CardIdleState.OnPointerClick() | | Flip animation | FlippableCard.FlipToReveal() | CardFlippingState.OnEnterState() | | New card badge | FlippableCard.ShowAsNew() | CardEnlargedNewState (owns badge) | | Repeat progress | FlippableCard.ShowAsRepeat() | CardEnlargedRepeatState (owns bar) | | Tap to dismiss | FlippableCard.OnPointerClick() when waiting | CardEnlargedNewState.OnPointerClick() | ### AlbumCard → CardPlacedInSlotState + CardAlbumEnlargedState | Old Feature | Old Implementation | New Implementation | |-------------|-------------------|-------------------| | Store parent slot | AlbumCard._parentSlot | CardPlacedInSlotState.SetParentSlot() | | Click to enlarge | AlbumCard.OnPointerClick() | CardPlacedInSlotState.OnPointerClick() | | Enlarge animation | AlbumCard.EnlargeCard() | CardAlbumEnlargedState.OnEnterState() | | Shrink animation | AlbumCard.ShrinkCard() | CardAlbumEnlargedState.OnPointerClick() | | Transform tracking | AlbumCard._originalParent, etc. | CardAlbumEnlargedState (same fields) | ### AlbumCardPlacementDraggable → Card with CardDraggingState | Old Feature | Old Implementation | New Implementation | |-------------|-------------------|-------------------| | Drag feedback | AlbumCardPlacement... | CardDraggingState | | Snap to slot | SnapToAlbumSlot() | CardDraggingState.OnDroppedInSlot() | | Flip on drag | Nested FlippableCard | Just use Card with state machine | --- ## Events Migration ### Old Events (FlippableCard) ```csharp flippableCard.OnCardRevealed += (card, data) => { }; flippableCard.OnCardTappedAfterReveal += (card) => { }; flippableCard.OnFlipStarted += (card) => { }; flippableCard.OnClickedWhileInactive += (card) => { }; ``` ### New Events (State-based) ```csharp // Option 1: Listen to state machine transitions var flippingState = card.GetStateComponent("FlippingState"); // Then add custom events to states if needed // Option 2: Poll current state if (card.GetCurrentStateName() == "RevealedState") { // Card was revealed } // Option 3: Add custom events to Card.cs that relay from states card.OnCardRevealed += (data) => { }; ``` **Note:** Some events may not be needed anymore because state machine handles transitions internally. --- ## Testing Strategy ### Phase 2 Testing (Booster Only) - [ ] Open booster pack - [ ] Cards spawn in IdleState - [ ] Click card triggers flip - [ ] Flip animation plays correctly - [ ] New cards show "NEW CARD" badge - [ ] Repeat cards show progress bar - [ ] Tap dismisses enlarged view - [ ] Multiple cards work simultaneously - [ ] No console errors ### Phase 3 Testing (Album Added) - [ ] Cards appear in album slots - [ ] Click card in album enlarges it - [ ] Tap enlarged card shrinks it - [ ] Backdrop shows/hides correctly - [ ] Reparenting works (card moves to top layer) - [ ] Card returns to correct slot - [ ] Page flipping doesn't break card state - [ ] No console errors ### Regression Testing (Both Phases) - [ ] CardDisplay still renders correctly - [ ] Card data persists across states - [ ] Animations are smooth (60fps) - [ ] Click detection works - [ ] No memory leaks (profile with 20+ cards) --- ## Rollback Plan If new system has issues: ### During Phase 2 (Booster Only) 1. Revert `BoosterOpeningPage.cs` changes 2. Re-assign old `flippableCardPrefab` in inspector 3. Old system still intact for album ### During Phase 3 (Album Added) 1. Revert `AlbumCardSlot.cs` and `AlbumViewPage.cs` 2. Re-assign old prefabs in inspector 3. Both systems revert to old ### After Phase 4 (Old Scripts Deleted) 1. Restore old scripts from Git history 2. Recreate old prefabs (if not archived) 3. Revert consumer scripts **Prevention:** Archive old prefabs before deleting! --- ## CardDisplay.cs - The Survivor **Why CardDisplay is NOT replaced:** CardDisplay is a **pure visual renderer**. It: - Takes CardData and displays it - Has no state management - Has no animation logic - Has no interaction logic This is **exactly what we want**! The new system uses CardDisplay as-is. **Old hierarchy:** ``` FlippableCard └─ AlbumCard └─ CardDisplay ← renders visuals ``` **New hierarchy:** ``` Card (state machine) └─ CardDisplay ← same renderer! ``` CardDisplay is already well-designed - it's a "presenter" in the MVP pattern. Keep it! --- ## Migration Checklist ### Preparation - [ ] New Card.prefab created and tested in isolation - [ ] CardAnimationConfig asset created - [ ] All state scripts compiled without errors - [ ] Team aware of upcoming changes ### Phase 2: Booster Opening - [ ] Update BoosterOpeningPage.cs to use Card.prefab - [ ] Remove FlippableCard references - [ ] Update prefab assignments in inspector - [ ] Test booster opening flow thoroughly - [ ] Fix any issues before proceeding ### Phase 3: Album System - [ ] Update AlbumCardSlot.cs to use Card.prefab - [ ] Update AlbumViewPage.cs to use Card.prefab - [ ] Remove AlbumCard references - [ ] Update prefab assignments in inspector - [ ] Test album interactions thoroughly - [ ] Test booster→album flow (cards placed after opening) ### Phase 4: Cleanup - [ ] Archive old prefabs (FlippableCard, AlbumCard) - [ ] Delete FlippableCard.cs - [ ] Delete AlbumCard.cs - [ ] Delete AlbumCardPlacementDraggable.cs (if fully replaced) - [ ] Run full regression test suite - [ ] Update team documentation - [ ] Celebrate! 🎉 --- ## FAQ **Q: Can I use both systems simultaneously?** A: Yes, during migration. One scene can use FlippableCard while another uses Card.prefab. **Q: Will old prefabs still work?** A: Yes, until you delete the old scripts. Prefabs using FlippableCard will continue to function. **Q: Do I need to migrate all at once?** A: No! Recommended approach is scene-by-scene (Phase 2, then Phase 3). **Q: What about CardDisplay?** A: Keep it! It's used by both old and new systems. It's well-designed and doesn't need changes. **Q: What if I find bugs in the new system?** A: Rollback to old system (see Rollback Plan section), fix bugs, then retry migration. **Q: How long will migration take?** A: Estimated 6-10 hours total (2-4 for booster, 4-6 for album, testing time). **Q: Will performance improve?** A: Yes! 60% less code, more efficient state management, shared animation system. --- ## Summary ### Old Scripts Status: | Script | Status | Timeline | |--------|--------|----------| | CardDisplay.cs | ✅ **KEEP** | Forever (it's perfect!) | | FlippableCard.cs | 🔄 **REPLACE** | Phase 2 (booster) | | AlbumCard.cs | 🔄 **REPLACE** | Phase 3 (album) | | AlbumCardPlacementDraggable.cs | 🔄 **REPLACE** | Phase 3 (album) | ### Migration Path: ``` Now Phase 2 Phase 3 Future ──────────────────────────────────────────────────────────── Both systems → Booster uses → All use → Old scripts coexist new Card, new Card deleted album uses old ``` ### Key Insight: **You're not "fixing" the old scripts - you're replacing their ARCHITECTURE.** The old scripts work, but they're built on a flawed foundation (wrapper hell, boolean soup). The new system solves this with isolated states and clean separation of concerns. Think of it like replacing a house's foundation - you keep the furniture (CardDisplay), but rebuild the structure underneath. --- **Ready to start? Begin with Phase 2 (Booster Opening) - it's the cleanest migration path!**