Skip to content

Metrics Reference

How every student metric is measured and calculated. A plain-language breakdown of the 14 metrics tracked in Campus — where each number comes from and the exact formula behind it. Scoring and gamification are calculated on our servers; the app displays the results.

  • Get — where the raw data comes from
  • Calculate — the formula applied to it

Each metric below is also tagged with its current state:

TagMeaning
UsedLive in Campus today
PartialExists, with caveats
Not a featureNot implemented

Everything in this section is derived from four values stored per quiz: correct answers, questions attempted, total questions, and time taken.

Each question is worth a point value (default 1). A correct answer earns the full points; a wrong answer earns zero. Questions can also be grouped — a group is all-or-nothing, so its points are only earned if every question inside it is correct. Points per quiz roll up into the student’s lifetime coin balance, which drives badges and the leaderboard.

How we get it

Each question’s settings.points; summed per correct answer (and per fully-correct group) into that day’s obtainedMarks, then added to the wallet coin balance.

How we calculate

obtainedMarks (day) = Σ (points of correctly-answered questions that day)
+ Σ (points of each group where every question in it is correct)
lifetime coins = Σ (obtainedMarks across all days)

Tab cards on Points: Total Earned = Σ obtainedMarks; Highest Score = MAX(daily obtainedMarks); Average Daily = round(Total Earned ÷ number of active days).

There is no letter grade or GPA. A “grade” is the student’s average accuracy percentage, plus a simple pass/fail flag on each quiz.

How we get it

Average of the per-day accuracy figures already stored for the student.

How we calculate

grade = average( accuracy of all quiz-days )
pass? = correct ÷ attempted > 80% → PASSED, else FAILED

A tiered icon placed on each quiz once completed, based on accuracy — and a special tier for a flawless, fast run.

How we get it

From the quiz’s accuracy %, mistake count, and average time per question at completion.

How we calculate

Status / TierColorIconWhen it shows
ExcellencePurple/Indigomastery-1.svg0 mistakes and average under 7 seconds per question
MasteredGreencrown-green.svgAccuracy ≥ 100%
CompetentYellowcrown-yellow.svgAccuracy ≥ 90%
ProficientOrangemastery-2.svgAccuracy ≥ 70%
FamiliarPink/Redmastery-3.svgAccuracy ≥ 50%
In Progress (fallback)Bluemaster-4.svgCompleted, accuracy below 50%

Excellence is checked first, ahead of the accuracy bands. A completed quiz under 50% accuracy falls back to the same icon used for an unfinished attempt.

The Awards → Grades tab shows a coarser, 4-band label per lesson, bucketed from that lesson’s average accuracy across all completed attempts — not the per-attempt tiers above.

How we get it

The lesson row’s average accuracy, computed across every completed attempt on that lesson (falling back to obtainedMarks ÷ totalMarks × 100 when an attempt has no stored accuracy).

How we calculate

Average accuracyMastery label
100%Expert
≥ 85%Proficient
≥ 70%Competent
below 70%Beginner

The Grades tab’s three headline cards read a pre-computed overview: Lessons Completed = totalCompleted, Accuracy = averageGrade, Questions Answered = totalQuestions.

Where a student stands on a lesson: Not Started → In Progress → Completed.

How we get it

From whether a quiz result exists and how many questions have been answered.

How we calculate

no result → Not Started
some answers → In Progress
attempted ≥ total → Completed
StatusColorIcon
Not StartedGraycrown-gray.svg
In ProgressBluemaster-4.svg

Every retake is recorded as a new attempt. Attempts are counted but never limited — there is currently no maximum-retake cap in the system.

How we get it

One quiz-result record is created each time a student starts the quiz.

How we calculate

total attempts = count of quiz-result records for that lesson
re-attempts (reporting) = Σ total quizzes started

Earned automatically on the server as quizzes complete. Coins are the shared currency underneath badges and ranking.

14 tiers (Bronze → Vibranium), 10 levels each = 140 badges. A badge unlocks the moment the student’s total coins reach that badge’s threshold.

How we get it

Compared against the student’s lifetime coin balance.

How we calculate

award every badge where coin_threshold ≤ student's coins
tier level unlocks at: start + (gap × level)
current badge = highest tier & level whose threshold ≤ student's total points
(below the first threshold of 100 → Bronze, level 0)
#TierStarts at (XP)Per levelTops out at
1Bronze01001,000
2Graphite1,0004005,000
3Quartz5,00050010,000
4Silver10,00050015,000
5Jade15,0001,00025,000
6Gold25,0002,50050,000
7Pearl50,0005,000100,000
8Titanium100,0005,000150,000
9Platinum150,0005,000200,000
10Emerald200,00010,000300,000
11Sapphire300,00010,000400,000
12Ruby400,00015,000550,000
13Diamond550,00020,000750,000
14Vibranium750,00025,0001,000,000

Awarded per lesson according to the score achieved on its quiz. The tier is decided and stored by the backend the moment the lesson completes — there’s no client-side calculation, the app just reads the counts and the list of earned trophies.

How we get it

From the lesson’s correct-answer ratio at completion.

How we calculate

Platinum 100%
Gold ≥ 85%
Silver ≥ 70%
Bronze below 70%

This is the teacher behaviour-points system (conduct), separate from quiz coins. Teachers assign positive or negative points to students.

How we get it

From behaviour records assigned to the student by staff. All records are fetched (not just the first page), so the totals always cover full history.

How we calculate

Positive total = Σ points of "Positive" behaviours
Negative total = Σ |points| of "Negative" behaviours (always subtracted, regardless of sign)

Rewards showing up day after day. The count grows by one for each consecutive active day and resets after a missed day.

How we get it

From the daily time-spent record and the date of the last active day.

How we calculate

if last active day was yesterday → streak + 1
otherwise → streak resets to 1
(a day counts once its time-spent target is met)

Campus has more than one leaderboard, and they don’t rank the same way. Computed live and refreshed on a schedule.

How we get it

From each student’s daily points summary (points, time, accuracy, speed). With no date filter, the leaderboard is served from a pre-computed table; adding a date range runs a live query over that window instead.

How we calculate

Overall Leaderboard (org/class-wide, across all quizzes combined) — points win first:

order by: total points ↓ (highest first)
then total time ↑ (faster wins ties)
then average accuracy ↓
then average speed ↓
then account age (older account wins remaining ties)

Lesson Leaderboard (one specific lesson, best completed attempt per student) — speed wins first instead:

order by: time ↑ (fastest first)
then points ↓
then accuracy ↓
then speed ↓
then earliest attempt

How much and how consistently a student is working, drawn from daily quiz and time-spent rollups.

There is no single ”% of course complete” number. Progress is shown as change over time — how this period compares to the last.

How we get it

From point/time totals of the current period versus the previous one.

How we calculate

progress % = (current − previous) ÷ previous × 100
(also shown as this-week vs last-week change)

The volume of questions a student answers over time — shown as a daily / weekly / monthly chart. This is a count chart, not a social feed.

How we get it

From the daily quiz summary, grouped by day, week, month, or year.

How we calculate

activity = Σ questions answered (per time bucket)

There is no “Streams” feature in Campus. The word is reused internally for two unrelated things: the live presence-tracking connection, and a data endpoint that (despite its name) only returns daily time-spent figures. There is no social stream or feed to calculate.