Rules Engine - Gamification
Rules Engine
The rules engine evaluates analytics events against configured rules and triggers scoring, achievement, and certification actions. Rules are the core abstraction that ties all gamification features together.
6.1 Rule Entity
| Field | Required | Description |
|---|---|---|
gameObjectType | Yes | leaderboard, certificate, badge, leadScoring |
gameObjectId | Yes | ID of the parent game object |
name | Yes | Rule display name |
conditions | Yes | Array of {fact, operator, value} — all must match (AND) |
type | Yes | sum, count, countUnique, countBoolean, external, override |
mode | Yes | distribute_points, dont_distribute_points, block_root_rule_while_in_progress, block_root_rule_if_exhausted |
metric | Yes | Event field to evaluate: playTime, kuserId, like, score, pollId |
groupBy | Yes | Scope fields, comma-separated: kuserId, kuserId,entryId |
goal | Yes | Threshold to trigger point distribution |
points | Yes | Fixed value ("50") or dynamic event field name ("score") |
maxPoints | No | Cap on total points. Fixed, dynamic, or "unlimited" |
reportFormat | No | default or in_minutes |
status | No | enabled or disabled |
subRules | No | Array of child rules for multi-stage logic |
userIdOverride | No | Map points to a different user (e.g., upvote recipient) |
6.2 Rule Types
| Type | Description | Example |
|---|---|---|
sum | Sum the metric value across events | Sum playTime — when total reaches goal seconds, distribute points |
count | Count matching events | Count pollAnswered events — when count reaches goal, distribute points |
countUnique | Count unique metric values | Count unique entryId values — "watch N different sessions" |
countBoolean | Count events where metric is truthy | Count events where like is true |
external | Accept external/3rd-party scores | Metric must be "score"; points come from the event's score field |
override | Replace existing score entirely | Override with new value instead of accumulating |
6.3 Rule Modes
| Mode | Description |
|---|---|
distribute_points | When goal is met, distribute points to the user's score |
dont_distribute_points | Track progress without adding to score (for badge rules that track activity separately) |
block_root_rule_while_in_progress | Sub-rule must complete before the root rule can accumulate |
block_root_rule_if_exhausted | Once this sub-rule reaches its max, the root rule stops accumulating |
6.4 Condition Operators
equal, notEqual, lessThan, greaterThan, in, notIn, contains, doesNotContain
6.5 Condition Facts (Event Fields)
| Fact | Description |
|---|---|
eventType | viewPeriod, quizSubmitted, pollAnswered, comment, like, registered, etc. |
entryId | Kaltura entry ID |
categories | Category IDs the entry belongs to |
virtualEventId | Virtual event ID |
Single category:
{"fact": "categories", "operator": "in", "value": "325222712"}
Multiple categories (OR):
{
"any": [
{"fact": "categories", "operator": "contains", "value": "$CATEGORY_ID_1"},
{"fact": "categories", "operator": "contains", "value": "$CATEGORY_ID_2"}
]
}
6.6 Analytics Events That Feed Rules
| Source | Event Types | Example Rules |
|---|---|---|
| Playback | viewPeriod | Watch duration, per-session completion |
| In-Video Quizzes | quizSubmitted | Quiz completion, first-to-complete bonus |
| Chat & Collaboration | pollAnswered, comment, like/upvote | Poll participation, chat engagement |
| Live Q&A | questionAsked, questionPromoted | Q&A participation |
| KME | participated, quizAnswer | Meeting attendance |
| Registration | registered | Event registration, first-to-register bonus |
6.7 Rule CRUD
# Create rule for a leaderboard
curl -X POST "$KALTURA_SCM_URL/rule/create" \
-H "Authorization: Bearer $KALTURA_KS" \
-H "Content-Type: application/json" \
-d '{
"gameObjectType": "leaderboard",
"gameObjectId": "'$LEADERBOARD_ID'",
"name": "Watch sessions",
"description": "10 points per 60 seconds watched",
"conditions": [{"fact": "eventType", "operator": "equal", "value": "viewPeriod"}],
"type": "sum",
"mode": "distribute_points",
"metric": "playTime",
"groupBy": "kuserId,entryId",
"goal": "60",
"points": "10",
"maxPoints": "100",
"reportFormat": "default"
}'
# List rules for a game object
curl -X POST "$KALTURA_SCM_URL/rule/list" \
-H "Authorization: Bearer $KALTURA_KS" \
-H "Content-Type: application/json" \
-d '{"gameObjectType": "leaderboard", "gameObjectId": "'$LEADERBOARD_ID'"}'
# Update rule (enable)
curl -X POST "$KALTURA_SCM_URL/rule/update" \
-H "Authorization: Bearer $KALTURA_KS" \
-H "Content-Type: application/json" \
-d '{"id": "'$RULE_ID'", "status": "enabled"}'
# Delete rule
curl -X POST "$KALTURA_SCM_URL/rule/delete" \
-H "Authorization: Bearer $KALTURA_KS" \
-H "Content-Type: application/json" \
-d '{"id": "'$RULE_ID'"}'
6.8 Sub-Rules
Sub-rules enable multi-stage logic. Example: root rule awards points per upvote, sub-rule caps total upvotes per user.
curl -X POST "$KALTURA_SCM_URL/rule/create" \
-H "Authorization: Bearer $KALTURA_KS" \
-H "Content-Type: application/json" \
-d '{
"gameObjectType": "leaderboard",
"gameObjectId": "'$LEADERBOARD_ID'",
"name": "Upvotes on comments",
"conditions": [{"fact": "eventType", "operator": "equal", "value": "like"}],
"type": "count",
"mode": "distribute_points",
"metric": "like",
"groupBy": "kuserId,entryId",
"goal": "1",
"points": "20",
"maxPoints": "100",
"subRules": [
{
"name": "Cap at 5 upvotes",
"type": "count",
"metric": "commentId",
"groupBy": "kuserId",
"goal": "1",
"maxPoints": "5",
"mode": "block_root_rule_if_exhausted"
}
]
}'