npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

math-game-sdk

v3.0.1

Published

Math Game SDK v3 — utility library for building HTML math games

Readme

Math Game SDK v3 — AI Reference

QUAN TRỌNG — Namespace: SDK expose global object tên MathGameSDK (PascalCase). KHÔNG dùng mathGameSDK, mathgameSDK hay bất kỳ biến thể nào khác. SDK v3 có 5 namespace: bridge · math · utils · geo · ease

KHÔNG viết fallback logic nội bộ. Nếu SDK không load được, hiển thị lỗi rõ ràng và dừng lại. Không tự viết lại shuffle, calcScore, hay bất kỳ utility nào có sẵn trong SDK.

<script src="https://cdn.jsdelivr.net/npm/math-game-sdk@3/math-game-sdk.js"></script>

bridge — Platform (bắt buộc gọi)

MathGameSDK.bridge.reportScore(correct, total)   // sau mỗi câu đúng — 2 số nguyên
MathGameSDK.bridge.reportProgress(current, total) // mỗi câu mới — 2 số nguyên
MathGameSDK.bridge.reportComplete()              // khi kết thúc game
MathGameSDK.bridge.onReady(callback)             // callback khi platform sẵn sàng
MathGameSDK.bridge.getPlayerName()               // Promise<string> — tên người chơi
MathGameSDK.bridge.saveState(key, data)          // lưu state
MathGameSDK.bridge.loadState(key)                // Promise<unknown> — đọc state

Lỗi thường gặp cần tránh:

// ❌ SAI namespace
window.mathGameSDK.bridge.reportScore(...)
// ❌ SAI — reportProgress nhận ratio thay vì 2 số
MathGameSDK.bridge.reportProgress(score / total)
// ✅ ĐÚNG
MathGameSDK.bridge.reportScore(correct, total)   // (correct, total) — 2 số nguyên
MathGameSDK.bridge.reportProgress(current, total) // (current, total) — 2 số nguyên

math — Toán học

generate(options) → MathQuestion[]

Tạo câu hỏi toán. Dùng khi cần sinh câu hỏi ngẫu nhiên.

const qs = MathGameSDK.math.generate({ type: 'addition', difficulty: 1, count: 10 })
// qs[0] = { type, prompt: "3 + 4 = ?", answer: 7, difficulty: 1 }

type: 'addition'|'subtraction'|'multiplication'|'division'|'comparison'|'missing-number'|'fractions'|'word-problem' difficulty: 1 (dễ) | 2 (trung bình) | 3 (khó)

checkAnswer(question, userAnswer) → { correct, correctAnswer }

MathGameSDK.math.checkAnswer(qs[0], 7) // { correct: true, correctAnswer: 7 }

combination(n, k) → number

MathGameSDK.math.combination(5, 2) // → 10  C(5,2)

permutation(n, k) → number

MathGameSDK.math.permutation(5, 2) // → 20  P(5,2)

getAllCombinations(n, k) → number[][]

Trả về mảng các tổ hợp dưới dạng index 0-based (không phải giá trị phần tử). Số lượng phần tử = combination(n, k).

MathGameSDK.math.getAllCombinations(4, 2)
// → [[0,1],[0,2],[0,3],[1,2],[1,3],[2,3]]

calculateStars(score, maxScore, thresholds?) → 1 | 2 | 3

MathGameSDK.math.calculateStars(8, 10)           // → 3  (80% ≥ 0.8)
MathGameSDK.math.calculateStars(6, 10)           // → 2  (60% ∈ [0.5, 0.8))
MathGameSDK.math.calculateStars(3, 10)           // → 1  (30% < 0.5)
MathGameSDK.math.calculateStars(8, 10, [0.6, 0.9]) // → 2  (custom)

thresholds: mảng 2 phần tử [low, high], giá trị 0–1. Mặc định [0.5, 0.8].

distance(x1, y1, x2, y2) → number

MathGameSDK.math.distance(0, 0, 3, 4) // → 5  (Euclidean)

degToRad(degrees) → number

MathGameSDK.math.degToRad(180) // → Math.PI

radToDeg(radians) → number

MathGameSDK.math.radToDeg(Math.PI) // → 180

utils — Tiện ích

shuffle(array) → array

Fisher-Yates, phân phối đều. Mutates và trả về array.

MathGameSDK.utils.shuffle([1, 2, 3, 4]) // → [3, 1, 4, 2]

createScoreTracker(maxScore?) → tracker

const s = MathGameSDK.utils.createScoreTracker(10)
s.add()        // +10 điểm
s.subtract()   // -5 điểm (không xuống dưới 0)
s.get()        // điểm hiện tại
s.percentage() // 0-100

createTimer(seconds) → timer

const t = MathGameSDK.utils.createTimer(60)
t.onTick(remaining => updateUI(remaining))
t.onEnd(() => showResult())
t.start() // t.pause() / t.stop()

createGrid(rows, cols, defaultValue?) → grid

Mutable 2D grid. isFull() = không có ô nào là null.

const grid = MathGameSDK.utils.createGrid(4, 4, null)
grid.set(0, 0, 'X')
grid.get(0, 0)           // 'X'
grid.fill(null)          // reset
grid.count()             // số ô !== null
grid.isFull()            // true khi không còn ô null
grid.toArray()           // 2D array
grid.forEach((val, r, c) => console.log(r, c, val))

clamp(value, min, max) → number

MathGameSDK.utils.clamp(15, 0, 10) // → 10
MathGameSDK.utils.clamp(-3, 0, 10) // → 0

lerp(a, b, t) → number

Linear interpolation. t ∈ [0, 1].

MathGameSDK.utils.lerp(0, 100, 0.3) // → 30

Dùng với easing: lerp(start, end, ease.quadOut(progress))

wrap(value, min, max) → number

Cyclical — giá trị vượt max sẽ quay về min.

MathGameSDK.utils.wrap(11, 0, 10) // → 1
MathGameSDK.utils.wrap(-1, 0, 10) // → 9

randomInt(min, max) → number

Inclusive — bao gồm cả min và max.

MathGameSDK.utils.randomInt(1, 6) // → 4  (xúc xắc)

randomPick(array) → T

MathGameSDK.utils.randomPick(['A', 'B', 'C']) // → 'B'

percent(value, min, max) → number

Vị trí của value trong [min, max] dưới dạng 0–1. Trả về 0 khi min === max.

MathGameSDK.utils.percent(7, 0, 10)   // → 0.7
MathGameSDK.utils.percent(150, 0, 200) // → 0.75

geo — Hình học (cho game Venn/circle)

isPointInCircle(point, circle) → boolean

MathGameSDK.geo.isPointInCircle({ x: 100, y: 100 }, { x: 150, y: 150, radius: 80 })
// → true

determineZone(point, circleA, circleB) → 'A' | 'B' | 'AB' | 'outside'

MathGameSDK.geo.determineZone({ x: 200, y: 200 }, circleA, circleB)
// → 'AB'  (điểm nằm trong cả 2 vùng)

ease — Animation easing

Tất cả nhận t ∈ [0, 1] và trả về số (thường 0–1). Dùng kết hợp với utils.lerp.

const x = MathGameSDK.utils.lerp(startX, endX, MathGameSDK.ease.quadOut(progress))

linear(t) → t

MathGameSDK.ease.linear(0.5) // → 0.5  (tốc độ đều)

quadIn(t) → t²

Tăng tốc từ đầu.

MathGameSDK.ease.quadIn(0.5) // → 0.25

quadOut(t) → t(2-t)

Giảm tốc về cuối — dùng phổ biến nhất cho slide/fade.

MathGameSDK.ease.quadOut(0.5) // → 0.75

bounceOut(t) → number

Nảy cuối animation, settle về 1.

MathGameSDK.ease.bounceOut(1.0) // → 1.0
MathGameSDK.ease.bounceOut(0.8) // → ~0.97 (đang nảy)

elasticOut(t) → number

Spring — vượt quá điểm đích rồi quay về. Overshoot tối đa ~1.03.

MathGameSDK.ease.elasticOut(0.8) // → ~1.03
MathGameSDK.ease.elasticOut(1.0) // → 1.0

Minimal game template

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"></head>
<body>
<script src="https://cdn.jsdelivr.net/npm/math-game-sdk@3/math-game-sdk.js"></script>
<script>
MathGameSDK.bridge.onReady(() => {
  const questions = MathGameSDK.math.generate({ type: 'addition', difficulty: 1, count: 5 })
  let current = 0

  function showQuestion() {
    MathGameSDK.bridge.reportProgress(current + 1, questions.length)
    document.getElementById('q').textContent = questions[current].prompt
  }

  document.getElementById('submit').addEventListener('click', () => {
    const userAnswer = Number(document.getElementById('answer').value)
    const result = MathGameSDK.math.checkAnswer(questions[current], userAnswer)
    if (result.correct) {
      current++
      MathGameSDK.bridge.reportScore(current, questions.length)
      if (current === questions.length) {
        MathGameSDK.bridge.reportComplete()
      } else {
        showQuestion()
      }
    }
  })

  showQuestion()
})
</script>

<div id="q"></div>
<input id="answer" type="number">
<button id="submit">Trả lời</button>
</body>
</html>

Chỉ trả về 1 file HTML duy nhất.