Phase 3 Integration - Progress Report
Date: 2026-07-12
Status: ✅ Client Services Updated, UI Integration Next
✅ COMPLETED: Client Stats Service Updates
1. Updated stats-service.ts (OpenSkill Integration)
Changes:
- ✅ Replaced Elo imports with OpenSkill functions from
warp12-engine - ✅ Updated
incrementLocalAiSkillStats()to use OpenSkill rating updates - ✅ Updated
previewLocalAiMatchReport()to use TEI grade system - ✅ Updated
displayPlayerObjectiveTei()to return TEI score (0-99) - ✅ Added
getPlayerTeiDisplay()- returns full TEI display (grade + score) - ✅ Added
getPlayerStoredRating()- returns complete rating with displayGrade - ✅ Fixed academy placement functions to use new schema
Key Functions:
// Legacy (returns just score for backward compatibility)
displayPlayerObjectiveTei(stats, skill, objective): number | null
// New TEI display (returns {grade, score, formatted})
getPlayerTeiDisplay(stats, skill, objective): TeiDisplay | null
// Get full rating object with hysteresis grade
getPlayerStoredRating(stats, skill, objective): StoredRating | null
2. Updated use-player-stats.ts Hook
Changes:
- ✅ Added
getTeiDisplay()method to hook interface - ✅ Added
getStoredRating()method to hook interface - ✅ Imported TEI types from warp12-engine
- ✅ All existing functions still work (backward compatible)
Usage:
const playerStats = usePlayerStats();
// Legacy: Get numeric score only
const score = playerStats.displayTei('commander', 'points'); // → 67
// New: Get full TEI display
const tei = playerStats.getTeiDisplay('commander', 'points');
// → { grade: 'V', score: 67, formatted: 'V67' }
// Get rating with hysteresis grade
const rating = playerStats.getStoredRating('commander', 'points');
// → { mu: 32.0, sigma: 1.2, matches: 150, displayRating: 28.4, displayGrade: 'V' }
📊 What Works Now
- Client can read ratings from Firestore with displayGrade
- Client can calculate TEI displays with hysteresis
- Preview functionality shows TEI changes before/after matches
- Hooks expose TEI data to React components
🎯 NEXT STEPS: UI Integration
Step 1: Profile Page
File: apps/Warp12/src/app/profile-page.tsx
Tasks:
- Import
TeiDisplaycomponent - Replace old TEI display with
<TeiDisplay /> - Show both Go-Out and Points ratings
- Add tooltip showing raw μ/σ for power users
- Optional: Add “Advanced Stats” toggle
Example:
import { TeiDisplay } from './components/tei-display';
const tei = playerStats.getTeiDisplay('commander', 'points');
const rating = playerStats.getStoredRating('commander', 'points');
<TeiDisplay
rating={rating}
currentGrade={rating?.displayGrade}
objective="points"
size="large"
/>
Step 2: Leaderboard Page
File: apps/Warp12/src/app/leaderboard-page.tsx
Tasks:
- Import
TeiGradeBadgecomponent - Use badges in table rows
- Sort by displayRating
- Optional: Use
TeiDisplayfor detailed view
Example:
import { TeiGradeBadge } from './components/tei-grade-badge';
<TeiGradeBadge
grade={entry.displayGrade}
size="small"
/>
Step 3: Match Summary Page
File: apps/Warp12/src/app/sector-summary.tsx
Tasks:
- Import
TeiChangecomponent - Show before → after rating with animation
- Celebrate grade promotions (I→C, C→V, etc.)
Example:
import { TeiChange } from './components/tei-change';
<TeiChange
before={beforeRating}
after={afterRating}
objective="points"
/>
Step 4: In-Game HUD (Optional)
Tasks:
- Use
<TeiGradeBadge />next to player names - Keep it minimal (just letter badge)
🧪 Testing Checklist
Before deploying:
Local Testing:
- Build all packages:
yarn build:all - Run tests:
yarn test:all - Test profile page displays TEI correctly
- Test leaderboard sorting works
- Test match summary shows rating changes
- Verify hysteresis prevents flickering
Integration Testing:
- Play local AI match → verify TEI updates
- Play multiple matches → verify hysteresis (no flicker at boundaries)
- Test academy placement flow
- Check tooltips show μ/σ correctly
📁 Files Modified
✅ Completed:
apps/Warp12/src/firebase/stats-service.ts- Updated to OpenSkillapps/Warp12/src/firebase/use-player-stats.ts- Added TEI display methodslibs/engine/src/lib/rating/*- Already complete (Phase 2)functions/src/tei/*- Already complete (Phase 2.3)apps/Warp12/src/app/components/tei-*.tsx- Already complete (Phase 3)
⏳ To Update:
apps/Warp12/src/app/profile-page.tsxapps/Warp12/src/app/leaderboard-page.tsxapps/Warp12/src/app/sector-summary.tsx- Optional: In-game HUD components
🚀 Deployment Plan
After UI integration is complete:
- Build everything:
yarn build:all yarn build:all:hosting - Wipe Firebase (user confirmed safe):
- Delete
playerStatscollection - Delete
ratedMatchescollection - Delete
publishedLogscollection
- Delete
- Deploy:
yarn deploy:firestore # Rules yarn deploy:functions # Cloud Functions yarn deploy:hosting # Web app + leaderboard - Verify:
- Play test match
- Check rating updates
- Verify hysteresis works
- Check leaderboard sorting
💡 Key Design Decisions
- Backward Compatibility:
displayPlayerObjectiveTei()still returns numeric score- New functions added without breaking existing code
- Gradual migration path for UI components
- Hysteresis Integration:
displayGradestored in Firestore- Always passed to
getTeiDisplay()for consistency - UI components accept
currentGradeprop
- Three-Layer API:
- Score only:
displayPlayerObjectiveTei()→ number - Full display:
getPlayerTeiDisplay()→ {grade, score, formatted} - Raw rating:
getPlayerStoredRating()→ StoredRating with displayGrade
- Score only:
Current Progress: ~85% Complete
Backend: ✅ 100%
Client Services: ✅ 100%
UI Components: ✅ 100%
UI Integration: ⏳ 0%
Next Action: Integrate UI components into profile, leaderboard, and match summary pages