Retro, WarGames-inspired decryption/countdown counter with a CRT feel. Pure ESM, framework-agnostic, customizable, and controllable via a small API.
- 🎮 WarGames-inspired retro terminal aesthetic
- 🎨 Fully customizable - colors, timing, UI elements
- 🔊 Audio effects - authentic beeps and bloops
- ⏰ Countdown mode - solve by specific date/time
- 🎯 Character sets - alphanumeric or custom glyphs
- 📱 Framework-agnostic - works with React, Vue, vanilla JS, etc.
- 🎪 Interactive demos included
- 📦 Zero dependencies - pure TypeScript/JavaScript
npm i wopr-decryptorimport { WOPRDecryptor } from 'wopr-decryptor';
import 'wopr-decryptor/dist/styles.css';
const wopr = new WOPRDecryptor({
container: document.getElementById('app'),
codes: ['CPE1704TKS', 'DEFCON-1'],
direction: 'random', // 'ltr', 'rtl', or 'random'
cycles: 0, // 0 = infinite loop through codes
timing: {
durationMs: 10000,
tickInterval: 70,
// Optional: solve by specific date/time
// endDateTime: '2025-12-31 23:59:59',
},
audio: {
enabled: true,
volume: 0.12,
},
ui: {
blinkOnSolved: true, // Blink effect when code is solved
},
});
wopr.on('complete', (code) => {
console.log('Decrypted:', code);
});
wopr.start();codes: Array of code strings to decryptcharset: Character set to use for scrambling (default: A-Z, 0-9)direction:'ltr' | 'rtl' | 'random'- Character lock sequence direction'ltr'(default): Locks characters from left to right'rtl': Locks characters from right to left'random': Locks characters in random order
cycles: Number of times to loop through codes (default: 0)0: Infinite loop1-N: Loop that many times then stop
timing.durationMs: Total duration of the decryption animation (ms)timing.tickInterval: Time between character scrambles (ms)timing.startDateTime: When to start (Date or string)timing.endDateTime: When to complete solving (Date or string)- When set,
durationMsis calculated automatically - Useful for countdown timers that solve at specific times
- When set,
ui.showHeader: Show header with titleui.showFooter: Show footer with checksumui.showProgress: Show progress barui.showOverlay: Show initial overlay buttonui.showBackground: Show retro background effects (default: true)ui.blinkOnSolved: Blink effect when code is solved (default: false)ui.blinkDuration: Duration of blink effect in seconds (0 = blink forever, default: 3)ui.showCycles: Show cycles counter in UI (default: true)ui.title: Custom title text
audio.enabled: Enable/disable sound effectsaudio.volume: Volume level (0-1)audio.tickFreq: Frequency for tick sounds (Hz)audio.lockFreqStart: Starting frequency for lock sounds (Hz)audio.lockFreqStep: Frequency increment per lock (Hz)
probability.enabled: Show probability percentageprobability.base: Starting probability %probability.max: Ending probability %stream.enabled: Show intercept buffer streamstream.lines: Number of stream linesstream.width: Width of stream lines
See example.html for a basic example and demo.html for an interactive configuration playground.
start()- Start the decryption animationstop()- Stop the animationreset()- Reset to the first codenext()- Move to the next codedestroy()- Clean up and remove all elements
wopr.on('tick', () => {
/* Called on each character scramble */
});
wopr.on('lock', (index, char) => {
/* Called when a character locks */
});
wopr.on('complete', (code) => {
/* Called when code is fully solved */
});
wopr.on('render', (state) => {
/* Called on each render */
});npm run buildnpm run previewThis will build the project and start a dev server at http://localhost:3000. Open example.html to see the decryptor in action.
npm run devWatches and rebuilds TypeScript files on change.
Contributions are welcome! Please read CONTRIBUTING.md for guidelines.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
MIT © Phillip Beazley
See LICENSE for details.
Inspired by the 1983 film WarGames and the WOPR computer system.
Made with 💚 by NomadicDaddy