Skip to content

Quick Start

Arnel Robles edited this page Oct 1, 2026 · 1 revision

Quick Start

Three ways in, from least to most.

1. Rewards only

No DOM, no CSS. You render the result yourself.

import { RewardSystem, DataService } from 'dopaminejs';

const rewards = new RewardSystem(new DataService());
await rewards.init();

rewards.on('xp_gained', ({ amount, total }) => console.log(`+${amount}, now ${total}`));
rewards.on('level_up', ({ oldLevel, newLevel }) => console.log(oldLevel, 'to', newLevel));
rewards.on('achievement_unlocked', (achievement) => console.log(achievement.name));

await rewards.addXP(250, 'Finished a lesson');

const { total, needed, progress } = rewards.getXPForNextLevel();
// total 300, needed 50, progress 0.75

init() must resolve before addXP or recordGame. Calling them earlier throws an error that says so.

Progress is saved to localStorage under dopamine_player. See Storage and Saved State.

2. Rewards with the overlay

import { RewardSystem, DataService, GameUI, ParticleSystem } from 'dopaminejs';
import 'dopaminejs/style.css';

const rewards = new RewardSystem(new DataService());
const ui = new GameUI(new ParticleSystem());

await rewards.init();

const draw = () => {
    const { total, needed, progress } = rewards.getXPForNextLevel();
    ui.updateXP(rewards.player.xp, needed, total, progress);
    ui.updateLevel(rewards.player.level);
    ui.updateStreak(rewards.player.streak.current);
};

draw();
rewards.on('xp_gained', draw);
rewards.on('streak_updated', draw);
rewards.on('level_up', ({ oldLevel, newLevel }) => ui.showLevelUp(oldLevel, newLevel));
rewards.on('achievement_unlocked', (achievement) => ui.showAchievement(achievement));

3. The facade

The default export does the wiring in section 2 for you and adds sound.

import Dopamine from 'dopaminejs';
import 'dopaminejs/style.css';

const dopamine = new Dopamine();
const { rewardSystem } = await dopamine.init();

await rewardSystem.recordGame('quiz', { score: 80 });

// when the view goes away
dopamine.destroy();

See Dopamine Facade.

Recording a game

addXP awards a number you choose. recordGame takes a result and works the XP out: it counts the play, tracks the high score, applies the streak multiplier and checks achievements, with one storage write.

await rewards.recordGame('quiz', { score: 80, correct: 8 });

rewards.player.stats.quiz;
// { totalPlays: 1, highScore: 80, correct: 8 }

See Reward System for the XP formula.

Cleaning up

on returns a function that removes the listener.

const stop = rewards.on('level_up', handler);
stop();

GameUI, ParticleSystem, SoundManager and the facade each have destroy(). Call it when the view unmounts.

Clone this wiki locally