A retro-style morse code learning game where you operate a radio to defuse bombs by transmitting the correct morse code sequences.
-
Install dependencies:
npm install
-
Start the development server:
npm run dev
-
Open http://localhost:3000 in your browser
- Learning Mode: Repeat the dots and dashes shown on the bomb
- Normal Mode: Translate letters to morse code
- Advanced Mode: Words and prosigns
- Call/Response Mode: Decode audio only, then transmit back
- SPACEBAR or CLICK/TAP: Hold to transmit
- Short press = DIT (.)
- Long press = DAH (-)
- ESC: Pause game / Return to menu
- Bombs fall from the sky with morse code patterns
- Match the code to defuse them before they hit the ground
- Each bomb plays its code when it spawns
- Lose a life if a bomb hits the ground
- Score points for successful defuses
- Difficulty increases with each level
src/
├── index.jsx # Entry point
├── App.jsx # Main app with state machine
├── constants/
│ ├── morse.js # Morse code dictionary (ITU-R M.1677-1)
│ ├── timing.js # Standard morse timing constants
│ ├── settings.js # Default game settings
│ └── gameStates.js # State machine states & transitions
├── hooks/
│ ├── useGameStateMachine.js # Game state management
│ ├── useSettings.js # Settings with localStorage
│ ├── useAudio.js # Audio context management
│ └── useHighScores.js # High score tracking
├── utils/
│ ├── audio.js # Audio playback utilities
│ └── bomb.js # Bomb generation logic
├── components/
│ ├── MainMenu.jsx # Menu screen
│ ├── GameCanvas.jsx # Playing screen (canvas + input)
│ ├── PauseScreen.jsx # Pause screen
│ ├── GameOverScreen.jsx # Game over screen
│ ├── SettingsMenu.jsx # Settings modal
│ └── Button.jsx # Reusable styled button
└── styles/
└── theme.js # Shared styles/colors
The game uses a reducer-based state machine for managing game flow:
MENU ──────► PLAYING ──────► GAME_OVER
│ │
▼ │
PAUSED ◄─────────────┘
│
▼
MENU
Valid transitions are enforced to prevent bugs when moving between screens.
- Modular Components: Each screen is a separate component
- Custom Hooks: Game logic extracted into reusable hooks
- Separation of Concerns: Constants, utilities, and components are organized
- Type Safety: Game states and modes are defined as constants
- localStorage Persistence: Settings and high scores are saved
The game uses ITU-R M.1677-1 standard morse code timing:
- Dit (.) = 1 unit
- Dah (-) = 3 units
- Gap between elements = 1 unit
- Gap between characters = 3 units
- Gap between words = 7 units
Works in all modern browsers that support:
- Web Audio API
- Canvas API
- ES6+ JavaScript
# Install dependencies
npm install
# Start dev server with hot reload
npm run dev
# Build for production
npm run build
# Preview production build
npm run previewMIT