Recommendation co-occurrence (records-cooccur)
Nightly batch artifact for the hybrid game recommender on the front end. Computes PMI-normalized co-occurrence between meta-games from player play history, with an optional stars boost.
Output
| Key | Producer |
|---|---|
recommendations/cooccur.json |
records-cooccur |
Public URL: https://records.abstractplay.com/recommendations/cooccur.json
Schedule
Daily 03:00 UTC — runs in parallel with records, records-move-times, records-ttm, and tournament-data. Reads the latest completed DynamoDB ION dump (same pattern as other dump consumers). Does not depend on player/*.json from records (those are written in the same parallel window).
Picked up by records-manifest at 04:00 UTC (or 07:30 after summarize and player-summary fan-out).
Inputs
| Source (ION dump) | Field | Use |
|---|---|---|
Completed games pk=GAME, sk contains #1# |
metaGame, players[].id |
Per player: set of completed meta-games |
pk=USER |
sk (user id), stars[] |
Optional boost: starred meta-games |
Stars boost
For each player, the co-play set is:
coPlaySet = completedMetaGames ∪ starredMetaGames
Starred games count as co-played with each other and with completed games, even when the player has not finished a game in that meta-game. This matches the user_names / profile stars signal described in the recommendation design.
Set includeStarredBoost: true in the artifact when stars were unioned in (always true for the current job).
Algorithm
-
For each player with a non-empty
coPlaySet, increment counts for every unordered pair(A, B)in the set. -
count(A)= number of players whosecoPlaySetcontainsA. -
N= number of players with a non-emptycoPlaySet. -
PMI:
PMI(A, B) = log( count(A,B) * N / (count(A) * count(B)) ) -
Keep pairs with
count(A,B) >= 5(DEFAULT_MIN_COOCCURRENCE). -
For each game
A, store the top 20 neighbors by PMI descending.
Implementation: src/utils/cooccurPmi.ts (pure functions + unit tests). Handler: src/functions/records-cooccur.ts.
JSON schema
{
"generatedAt": "2026-08-13T00:00:00.000Z",
"minCooccurrence": 5,
"includeStarredBoost": true,
"games": {
"go": [
{ "metaGame": "amazons", "pmi": 1.42, "count": 87 },
{ "metaGame": "hex", "pmi": 1.18, "count": 54 }
]
}
}
| Field | Meaning |
|---|---|
generatedAt |
ISO timestamp when the artifact was written |
minCooccurrence |
Minimum raw pair count threshold |
includeStarredBoost |
Whether stars[] were unioned into co-play sets |
games |
Map of meta-game → PMI neighbors (max 20 each) |
Front-end consumption
The front-end useGameRecommendations hook fetches this artifact and passes it to buildGameRecommendations as cooccurData. Missing or failed fetch degrades to content + popularity only (cooccurScore = 0).
Hybrid warm-tier weights (reference): 45% content, 35% co-occurrence, 15% popularity, 10% recency.
Related
- Records pipeline
- S3 outputs
- Backend recommendations subsystem — impression tracking (
RECOMMENDS#) - Recommendation analytics — nightly funnel rollups (ops S3)