Skip to main content

Scale Engine Overview

The ScaleEngine is a stateful engine for computing, persisting, and aggregating ranking points and ratings across tournaments. It combines the Ranking Governor (ranking points computation, aggregation, and write-back) with ratings functions (dynamic ratings, rating calculations) into a single engine that manages all participant competitive metrics.

When to Use ScaleEngine vs rankingGovernor

Use CaseRecommended
Compute ranking points for a tournamentScaleEngine
Persist ranking points to participant recordsScaleEngine
Generate multi-tournament ranking listsScaleEngine
Get per-participant point breakdownsScaleEngine
Compute quality win bonusesScaleEngine
Generate dynamic ratingsScaleEngine
Stateless point computation with explicit tournamentRecordrankingGovernor
Custom pipeline orchestrationrankingGovernor
Profile selection without full tournament contextrankingGovernor

Key Capabilities

  • Policy-driven point calculationRanking policies define position points, per-win points, bonuses, and quality win profiles
  • Specificity scoring — Award profiles are selected by counting populated scope fields; more constrained profiles automatically win over catch-all profiles
  • CategoryScope matching — Profiles match against gender, age category, ball type, wheelchair class, rating type, and more
  • Quality win bonuses — Bonus points for defeating ranked opponents, with configurable ranking snapshot strategies
  • Multi-tournament aggregation — Best-of-N counting buckets, rolling time windows, per-level caps, and tiebreakers
  • Write-back mutation — Persist computed points as scale items retrievable for future tournaments
  • Doubles attribution — Full-to-each or split-even point distribution from pair to individual participants
  • FIC/multi-structure support — Feed-in consolation draws produce distinct finishing positions; participants get their best finish across structures
  • Dynamic ratings — Generate and update participant ratings based on match outcomes

Basic Usage

import { scaleEngine } from 'tods-competition-factory';

// Load a tournament with completed matchUps
scaleEngine.setState(tournamentRecord);

// Compute ranking points using a policy
const { personPoints, success } = scaleEngine.getTournamentPoints({
policyDefinitions: rankingPolicy,
level: 3,
});

// Persist points to participant scaleItems
const result = scaleEngine.applyTournamentRankingPoints({
policyDefinitions: rankingPolicy,
scaleName: 'NATIONAL_RANKING',
level: 3,
});

// Aggregate across multiple tournaments
import { generateRankingList } from 'tods-competition-factory';

const rankingList = generateRankingList({
pointAwards: allTournamentAwards, // collected from multiple tournaments
aggregationRules: {
countingBuckets: [
{
bucketName: 'Singles',
eventTypes: ['SINGLES'],
pointComponents: ['positionPoints', 'perWinPoints'],
bestOfCount: 6,
},
{
bucketName: 'Doubles',
eventTypes: ['DOUBLES'],
pointComponents: ['positionPoints', 'perWinPoints'],
bestOfCount: 2,
},
{ bucketName: 'Quality Wins', pointComponents: ['qualityWinPoints'], bestOfCount: 0 },
],
rollingPeriodDays: 365,
tiebreakCriteria: ['highestSingleResult', 'mostWins'],
},
asOfDate: '2025-12-31',
});

Architecture

The ScaleEngine follows the Competition Factory pattern where governors provide pure functions and engines provide stateful facades:

+------------------------------+
| ScaleEngine | Stateful facade (setState, methods)
| (rankings + ratings) |
+---------------+--------------+
| | |
| rankingGovernor ratingsGovernor | Pure function modules
| (points, QW, (dynamic |
| aggregation, ratings, |
| write-back) calculations)|
+---------------+--------------+
| CODES Tournament Record | Standard data model
| (participants, scaleItems, |
| matchUps, policies) |
+------------------------------+

The engine holds tournament state via setState(). All ranking methods access participant data, match results, and finishing positions through the factory's getParticipants({ withRankingProfile: true }) pipeline.

Ranking Points Pipeline

The core pipeline for computing tournament ranking points:

  1. Policy resolution — Find attached or provided ranking policy
  2. Participant hydrationgetParticipants({ withRankingProfile: true }) provides structureParticipation with finishingPositionRange, winCount, draw metadata
  3. Profile selectiongetAwardProfile matches each participation against awardProfiles using specificity scoring
  4. Position pointsfinishingPositionRanges[accessor] resolved via Math.max(finishingPositionRange)
  5. Per-win points — Accumulated from pointsPerWin or level-keyed perWinPoints, subject to maxCountableMatches
  6. Bonus points — Champion/finalist bonus from bonusPoints config
  7. Quality win points — Bonus for beating ranked opponents (see Quality Win Points)
  8. Doubles attribution — Pair points distributed to individuals

See Ranking Points Pipeline for detailed documentation.