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 🙏

© 2025 – Pkg Stats / Ryan Hefner

cbt-game-engine

v1.0.0

Published

Platform-agnostic game engine for Interactive Autism Quiz Game

Readme

cbt-game-engine

A platform-agnostic game engine for Interactive Autism Quiz Game that works seamlessly with both React web applications and React Native mobile apps.

🚀 Features

  • Platform Agnostic: Same logic works on web and mobile
  • TypeScript: Full type safety and IntelliSense support
  • Callback System: Comprehensive event system for platform-specific implementations
  • Extensible: Easy to add new segments and features
  • Error Handling: Robust error handling with callbacks
  • Analytics Ready: Built-in analytics event tracking

📦 Installation

npm install cbt-game-engine

🎯 Quick Start

React Web App

import { useGameEngine, createDefaultConfig } from 'cbt-game-engine';

const webPlatformServices = {
  textToSpeech: {
    speak: async (text: string) => {
      const utterance = new SpeechSynthesisUtterance(text);
      speechSynthesis.speak(utterance);
    },
    stop: () => speechSynthesis.cancel(),
    isSupported: () => 'speechSynthesis' in window
  },
  microphone: {
    requestPermission: async () => {
      try {
        await navigator.mediaDevices.getUserMedia({ audio: true });
        return true;
      } catch {
        return false;
      }
    },
    startListening: async () => navigator.mediaDevices.getUserMedia({ audio: true }),
    stopListening: (stream) => stream?.getTracks().forEach(track => track.stop()),
    isSupported: () => 'mediaDevices' in navigator
  }
};

const WebQuizGame = () => {
  const gameConfig = createDefaultConfig();
  
  const gameCallbacks = {
    onSegmentStart: (segment, progress) => {
      console.log('Segment started:', segment.id);
    },
    onCelebrationStart: (segment) => {
      // Show confetti animation
    }
  };

  const gameEngine = useGameEngine(gameConfig, gameCallbacks, webPlatformServices);
  
  return (
    <div>
      <button onClick={gameEngine.startSegment} disabled={!gameEngine.canStartSegment}>
        Start Segment
      </button>
      <p>State: {gameEngine.gameState}</p>
      <p>Time Left: {gameEngine.timeLeft}</p>
    </div>
  );
};

React Native App

import { useGameEngine, createDefaultConfig } from 'cbt-game-engine';
import Tts from 'react-native-tts';
import { AudioRecord } from 'react-native-audio-record';

const nativePlatformServices = {
  textToSpeech: {
    speak: async (text: string) => {
      return new Promise((resolve) => {
        Tts.speak(text);
        Tts.addEventListener('tts-finish', resolve);
      });
    },
    stop: () => Tts.stop(),
    isSupported: () => true
  },
  microphone: {
    requestPermission: async () => {
      // Request native permissions
      return true;
    },
    startListening: async () => {
      AudioRecord.start();
      return null;
    },
    stopListening: () => AudioRecord.stop(),
    isSupported: () => true
  },
  haptics: {
    light: () => Haptics.trigger('impactLight'),
    medium: () => Haptics.trigger('impactMedium'),
    heavy: () => Haptics.trigger('impactHeavy')
  }
};

const NativeQuizGame = () => {
  const gameEngine = useGameEngine(
    createDefaultConfig(),
    gameCallbacks,
    nativePlatformServices
  );
  
  // Same API as web version!
};

📚 API Reference

useGameEngine Hook

const {
  // State
  gameState,           // 'idle' | 'question' | 'listening' | 'celebrating' | 'completed'
  currentSegment,      // Current segment index
  timeLeft,           // Seconds remaining in listening phase
  progress,           // Game progress object
  isAudioPlaying,     // Whether TTS is active
  isMicrophoneActive, // Whether microphone is recording
  error,              // Current error message
  
  // Controls
  startSegment,       // Start current segment
  nextSegment,        // Move to next segment
  resetGame,          // Reset entire game
  skipSegment,        // Skip current segment (debug)
  
  // Utilities
  canStartSegment,    // Can start current segment
  canNextSegment,     // Can move to next segment
  isGameComplete,     // Is game finished
  hasError,           // Has error occurred
  getCurrentSegment   // Get current segment data
} = useGameEngine(config, callbacks, platformServices);

Configuration

const gameConfig = {
  segments: [
    {
      id: 1,
      question: "What is this?",
      animationFile: "apple.riv",
      timeLimit: 3,
      completed: false
    }
  ],
  defaultTimeLimit: 3,
  enableMicrophone: true,
  enableTextToSpeech: true,
  celebrationDuration: 3000
};

Callbacks

const gameCallbacks = {
  onSegmentStart: (segment, progress) => {},
  onQuestionAsked: (question, segment) => {},
  onListeningStart: (timeLeft, segment) => {},
  onListeningTick: (timeLeft, segment) => {},
  onListeningEnd: (segment) => {},
  onCelebrationStart: (segment) => {},
  onCelebrationEnd: (segment) => {},
  onSegmentComplete: (segment, progress) => {},
  onGameComplete: (finalProgress) => {},
  onError: (error, context) => {}
};

🔧 Platform Services

Implement these interfaces for your platform:

interface PlatformServices {
  textToSpeech: {
    speak: (text: string, options?: any) => Promise<void>;
    stop: () => void;
    isSupported: () => boolean;
  };
  microphone: {
    requestPermission: () => Promise<boolean>;
    startListening: () => Promise<MediaStream | null>;
    stopListening: (stream?: MediaStream) => void;
    isSupported: () => boolean;
  };
  haptics?: {
    light: () => void;
    medium: () => void;
    heavy: () => void;
  };
  analytics?: {
    trackEvent: (event: string, properties?: Record<string, any>) => void;
  };
}

📱 React Native Dependencies

For React Native projects, install these additional packages:

npm install react-native-tts react-native-audio-record react-native-haptic-feedback

🤝 Contributing

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Designed for autism-friendly educational experiences
  • Built with accessibility and inclusivity in mind
  • Supports both web and mobile platforms seamlessly