Agent skill
analytics
Understand and work with EPA and OPR analytics algorithms in FTC Metrics. Use when calculating team ratings, implementing match predictions, troubleshooting analytics calculations, or understanding the scoring methodology.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/analytics-ftc8569-ftcmetrics
Metadata
Additional technical details for this skill
- author
- ftcmetrics
- version
- 1.0.0
- category
- analytics
SKILL.md
FTC Metrics Analytics
FTC Metrics uses two primary rating systems to evaluate team performance:
- EPA (Expected Points Added) - Bayesian-style incremental updates
- OPR (Offensive Power Rating) - Linear algebra matrix solution
Quick Reference
| Metric | Best For | Updates |
|---|---|---|
| EPA | Predicting future performance | After each match |
| OPR | Analyzing historical contribution | Recalculated per event |
EPA (Expected Points Added)
EPA represents how many points above/below average a team contributes to their alliance score.
Algorithm Overview
- Start with season baseline (average scores)
- After each match, calculate expected vs actual
- Distribute score difference to teams
- Apply adaptive K-factor for learning rate
Usage
import { calculateEPA, type MatchForEPA } from "@ftcmetrics/api/lib/stats";
const matches: MatchForEPA[] = [
{
matchNumber: 1,
redTeam1: 12345,
redTeam2: 12346,
blueTeam1: 12347,
blueTeam2: 12348,
redScore: 45,
blueScore: 38,
redAutoScore: 12,
redTeleopScore: 28,
redEndgameScore: 5,
// ... blue scores
},
];
const epaResults = calculateEPA(matches);
const team12345 = epaResults.get(12345);
// { epa: 5.2, autoEpa: 1.5, teleopEpa: 3.2, endgameEpa: 0.5, ... }
EPA Result Structure
interface EPAResult {
teamNumber: number;
epa: number; // Total EPA
autoEpa: number; // Autonomous phase
teleopEpa: number; // Teleop phase
endgameEpa: number; // Endgame phase
matchCount: number; // Matches played
recentEpa?: number; // Last 5 matches average
trend?: "up" | "down" | "stable";
}
Adaptive K-Factor
K-factor determines how much each new match affects the rating:
// High K (0.4) for new teams = ratings change quickly
// Low K (0.1) for experienced teams = ratings stabilize
function getAdaptiveKFactor(matchCount: number): number {
const minK = 0.1;
const maxK = 0.4;
const decayRate = 0.1;
return Math.max(minK, maxK * Math.exp(-decayRate * matchCount));
}
OPR (Offensive Power Rating)
OPR uses linear algebra to decompose alliance scores into individual team contributions.
Algorithm Overview
- Build matrix of alliance compositions
- Build vector of alliance scores
- Solve using iterative least squares
- Each team's OPR = their contribution to alliance score
Usage
import { calculateOPR, type MatchForOPR } from "@ftcmetrics/api/lib/stats";
const matches: MatchForOPR[] = [...]; // Match data
const oprResults = calculateOPR(matches);
const team12345 = oprResults.get(12345);
// { opr: 22.5, autoOpr: 6.0, teleopOpr: 14.0, endgameOpr: 2.5, dpr: 3.2, ccwm: 19.3 }
OPR Result Structure
interface OPRResult {
teamNumber: number;
opr: number; // Offensive Power Rating
autoOpr: number; // Auto contribution
teleopOpr: number; // Teleop contribution
endgameOpr: number; // Endgame contribution
dpr: number; // Defensive Power Rating
ccwm: number; // Calculated Contribution to Winning Margin
}
Match Predictions
Predictions combine EPA values to estimate match outcomes:
interface PredictionResult {
redExpectedScore: number;
blueExpectedScore: number;
redWinProbability: number;
blueWinProbability: number;
predictedMargin: number;
}
Prediction Formula
// Sum EPAs and add baseline
const redExpected = baseline + redTeam1EPA + redTeam2EPA;
const blueExpected = baseline + blueTeam1EPA + blueTeam2EPA;
// Win probability using logistic function
const margin = redExpected - blueExpected;
const redWinProb = 1 / (1 + Math.exp(-margin / SCORE_VARIANCE));
DECODE Season Baselines
const DECODE_BASELINE = {
autoScore: 8, // Average auto per alliance
teleopScore: 25, // Average teleop per alliance
endgameScore: 5, // Average endgame per alliance
totalScore: 38, // Average total per alliance
};
These baselines are updated dynamically based on actual match data.
Common Patterns
Calculate Rankings for Event
async function getEventRankings(eventCode: string) {
const matches = await fetchMatchesWithScores(eventCode);
const epaResults = calculateEPA(matches);
const oprResults = calculateOPR(matches);
// Combine and sort by EPA
const rankings = Array.from(epaResults.values())
.map((epa) => ({
...epa,
opr: oprResults.get(epa.teamNumber),
}))
.sort((a, b) => b.epa - a.epa);
return rankings;
}
Track EPA Over Time
// Store EPA after each match for trend analysis
interface EPAHistory {
teamNumber: number;
eventCode: string;
matchNumber: number;
epaValue: number;
recordedAt: Date;
}
Anti-Patterns
- ❌ Using OPR for predictions (use EPA instead - OPR overfits to past data)
- ❌ Calculating EPA without sorting matches chronologically
- ❌ Using static K-factor (adaptive K improves accuracy)
- ❌ Ignoring component scores (auto/teleop/endgame give better insights)
Implementation Files
packages/api/src/lib/stats/epa.ts- EPA calculatorpackages/api/src/lib/stats/opr.ts- OPR calculatorpackages/api/src/routes/analytics.ts- Analytics API endpoints
References
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?