Skip to content
indielist (beta)

Method version v1.0

How the sales estimate is calculated

IndieList publishes a reproducible heuristic built from public Steam review counts. It is not official sales data, and its fixed range is not a statistically validated confidence interval. Every game page exposes the inputs, final multiplier and each adjustment used.

1. Scope and evidence status

The model estimates paid Steam units from the relationship between public review count and an adjustable reviews-to-units multiplier, often called a Boxleiter number.

Version v1.0 is hand-calibrated. Repository tests prove deterministic output and TypeScript/Python parity; they do not prove accuracy against a ground-truth sales dataset. We therefore publish no “X% accurate” or “Y% within ±Z” claim.

Free-to-play titles do not receive paid-copy units or revenue estimates. Results for bundles, deep discounts, Early Access, review-key distribution and old titles can differ materially from reality.

2. Units formula

NB = clamp(50 + year + price + rating + team + genre, 15, 150)

median units = review count × NB

display range = median × [0.6, 1.4]

Adjustments are fixed points added to the base NB; they are not multiplied together. The lower and upper values are a fixed heuristic display range around the median.

3. Exact additive adjustments

Release year

RuleNB points
release_year < 2018+30
2018 <= release_year <= 2021+15
2022 <= release_year <= 20240
release_year >= 2025-10

No release-year adjustment is added when the year is unknown.

Initial USD list price

RuleNB points
price_usd < 5-20
5 <= price_usd < 10-5
10 <= price_usd < 200
20 <= price_usd < 30+5
price_usd >= 30+15

When list price is missing, version v1.0 substitutes $15.00.

Positive review percentage

RuleNB points
positive_pct < 70-10
70 <= positive_pct < 850
positive_pct >= 85+10

The game-service boundary currently substitutes 80 when this field is absent; that fallback is a limitation, not observed evidence.

Studio size tier

TierNB points
solo-10
small0
medium+10
large+15
tripleI+20

No team-size adjustment is added when the tier is unknown.

Primary-genre keyword rule

First matching keyword groupNB points
casual or hyper-15
rpg or adventure+10

Rules run in the order shown. No match means zero genre points.

4. Net-revenue heuristic

net per unit = list price × 0.85 × (1 − 0.04) × (1 − 0.3)

net per unit = list price × 0.5712

estimated net revenue = estimated units × net per unit

  • 0.85 is the model's combined regional-price/discount factor.
  • 4% is the model's refund assumption.
  • 30% is the model's store-cut assumption.

This simplified result does not reconstruct price changes over time, bundles, taxes, key sales, tiered store terms, publisher splits, subscription deals or non-Steam revenue.

5. Validation status

What is tested

Deterministic fixtures, boundary behaviour and TypeScript/Python output parity for version v1.0.

What is not yet proven

Accuracy, calibration or interval coverage against a versioned ground-truth dataset of official unit sales.

A future calibrated model must publish its source policy, dataset version, sample exclusions, train/test split, error distribution and coverage before it can make an accuracy claim. That change would require a new formula version.

6. Reproducibility and corrections

The deployed specification is available at /methodology/sales-v1.json. The canonical runtime implementation is src/lib/sales-estimate.ts; the collector mirror is python_collector/src/indielist_collector/sales/algorithm.py.

If you have a public, official sales figure that materially contradicts an estimate, send the source with [sales-estimate] in the message. Corrections should improve a versioned validation dataset before they alter the formula.