{"id":30895405,"url":"https://github.com/totokartonio/next-arcade","last_synced_at":"2026-04-07T07:47:36.825Z","repository":{"id":303107013,"uuid":"1014426515","full_name":"totokartonio/next-arcade","owner":"totokartonio","description":"Mini arcade in Next.js 15 (App Router, SSR). Hangman, Snake, Matching Pairs. TypeScript, Zustand, Vitest/Cypress, sound.","archived":false,"fork":false,"pushed_at":"2025-09-04T17:54:17.000Z","size":14396,"stargazers_count":3,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-04-07T07:47:34.568Z","etag":null,"topics":["app-router","arcade","css-modules","cypress","games","hangman","memory-game","nextjs","react","snake","ssr","turbopack","typescript","vitest","zustand"],"latest_commit_sha":null,"homepage":"https://next-arcade.netlify.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/totokartonio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-07-05T17:46:40.000Z","updated_at":"2025-09-07T19:31:38.000Z","dependencies_parsed_at":"2025-07-05T19:07:07.582Z","dependency_job_id":"ecef86fb-a45b-4794-b8fa-c1c3927b5610","html_url":"https://github.com/totokartonio/next-arcade","commit_stats":null,"previous_names":["totokartonio/next-arcade"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/totokartonio/next-arcade","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totokartonio%2Fnext-arcade","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totokartonio%2Fnext-arcade/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totokartonio%2Fnext-arcade/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totokartonio%2Fnext-arcade/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/totokartonio","download_url":"https://codeload.github.com/totokartonio/next-arcade/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/totokartonio%2Fnext-arcade/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31504897,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T03:10:19.677Z","status":"ssl_error","status_checked_at":"2026-04-07T03:10:13.982Z","response_time":105,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["app-router","arcade","css-modules","cypress","games","hangman","memory-game","nextjs","react","snake","ssr","turbopack","typescript","vitest","zustand"],"created_at":"2025-09-08T22:03:13.805Z","updated_at":"2026-04-07T07:47:36.800Z","avatar_url":"https://github.com/totokartonio.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Next Arcade\n\nA collection of small classic games built with [Next.js](https://nextjs.org), featuring Hangman, Snake, and Matching Pairs with immersive sound effects and responsive design.\n\n## Games\n\n- **Hangman** – Guess the word before you run out of attempts\n- **Snake** – Classic snake game with keyboard and touch controls\n- **Matching Pairs** – Memory card game with pixel art icons and timer\n\n## Features\n\n- **Immersive Audio** – sound effects across interactions, plus a global **mute** toggle\n- **Mobile Responsive** – touch-friendly controls and layouts optimized for small screens\n- **Retro Design** – pixel-inspired arcade aesthetic\n- **Fast Performance** – built on **Next.js 15** and **React 19** using the App Router\n- **Three Difficulty Levels** – Easy, Medium, and Hard for each game\n- **TypeScript** – fully typed for better development experience\n- **Tested** – Unit (Vitest) and E2E (Cypress) tests cover core flows\n\n## Quick Start\n\n### Prerequisites\n\n- Node.js 18+\n- npm, yarn, or pnpm\n\n### Installation\n\n1. **Clone the repository**\n\n   ```bash\n   git clone https://github.com/yourusername/next-arcade.git\n   cd next-arcade\n   ```\n\n2. **Install dependencies**\n\n   ```bash\n   npm install\n   ```\n\n3. **Start development server**\n\n   ```bash\n   npm run dev\n   ```\n\n4. **Open your browser**\n   Navigate to [http://localhost:3000](http://localhost:3000)\n\n## Available Scripts\n\n```bash\n# Development\nnpm run dev          # Start development server with Turbopack\nnpm run build        # Build for production\nnpm run start        # Start production server\nnpm run lint         # Run ESLint\n\n# Testing\nnpm run test         # Run unit tests with Vitest\nnpm run test:ui      # Run tests with UI\nnpm run test:coverage # Generate coverage report\nnpm run test:watch   # Run tests in watch mode\n\n# E2E Testing\nnpm run cypress:open # Open Cypress UI\nnpm run cypress:run  # Run Cypress tests headlessly\nnpm run e2e          # Run E2E tests against production build\nnpm run e2e:dev      # Run E2E tests against dev server\n```\n\n## Game Controls\n\n### Hangman\n\n- **Desktop**: Click letters or use physical keyboard\n- **Mobile**: Touch virtual keyboard\n\n### Snake\n\n- **Desktop**: Arrow keys or WASD\n- **Mobile**: Touch D-pad controls\n\n### Matching Pairs\n\n- **Desktop**: Click cards or use Tab + Enter/Space\n- **Mobile**: Touch cards\n\n## Technical Architecture\n\n### Tech Stack\n\n- **Framework**: Next.js 15 with App Router\n- **Frontend**: React 19, TypeScript\n- **Styling**: CSS Modules with CSS Variables\n- **State Management**: Zustand\n- **Audio**: use-sound library\n- **Testing**: Vitest + Cypress\n- **Build Tool**: Turbopack (dev) / Webpack (prod)\n\n### Project Structure\n\n```\nsrc/\n├── app/                    # Next.js App Router pages\n│   ├── arcade/[game]/     # Dynamic game routes\n│   ├── about/             # About page\n│   └── layout.tsx         # Root layout\n├── components/            # Shared components\n│   ├── ui/               # UI primitives (MagicButton)\n│   ├── GameSelector/     # Game selection interface\n│   ├── GameOver/         # Game over screen\n│   └── ...\n├── features/             # Game-specific code\n│   ├── hangman/         # Hangman game logic\n│   ├── snake/           # Snake game logic\n│   └── matchingPairs/   # Memory game logic\n├── hooks/               # Custom React hooks\n├── stores/              # Zustand stores\n├── styles/              # Global styles\n├── utils/               # Utility functions\n└── types.ts             # Global TypeScript types\n```\n\n### Key Features Implementation\n\n#### Audio System\n\n- Global mute/unmute functionality via Zustand store\n- Context-aware sound effects (hover, click, win, lose, etc.)\n- Lazy-loaded audio files for performance\n\n#### Mobile Support\n\n- Responsive design with CSS media queries\n- Touch-optimized controls for Snake game\n- Mobile detection hook for conditional UI\n\n#### Game State Management\n\n- Custom hooks for each game's logic\n- Consistent game status types (`idle`, `running`, `won`, `lost`)\n- URL-based difficulty selection with fallbacks\n\n## Testing\n\n### Unit Tests (Vitest)\n\n```bash\nnpm run test              # Run all tests\nnpm run test:coverage     # Generate coverage report\nnpm run test:ui          # Interactive test UI\n```\n\n### E2E Tests (Cypress)\n\n```bash\nnpm run e2e:dev          # Test against dev server\nnpm run e2e              # Test against production build\n```\n\n### Test Coverage\n\n- Game logic and state management\n- Component rendering and interactions\n- User workflows and edge cases\n- Mobile and desktop experiences\n\n## Configuration\n\n### Custom Fonts\n\nThe project uses Google Fonts loaded via Next.js:\n\n- **Monoton**: Logo and headers\n- **Press Start 2P**: Game titles\n- **VT323**: Body text (retro monospace)\n\n### Asset Optimization\n\n- SVG icons processed with SVGR\n- Images optimized with Next.js Image component\n\n## Customization\n\n### Styling\n\n- CSS Variables defined in `src/styles/globals.css`\n- Component-scoped styles using CSS Modules\n- Responsive breakpoints: 525px, 768px, 1900px, 2560px\n\n## Browser Support\n\n- **Modern browsers** (Chrome 90+, Firefox 90+, Safari 14+, Edge 90+)\n- **Mobile browsers** (iOS Safari 14+, Chrome Mobile 90+)\n- **Features used**: CSS Grid, Flexbox, CSS Variables, ES2017+\n\n## License\n\nThis project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.\n\n## Acknowledgments\n\n### Graphics\n\n- Pixel icons by [Admurin](https://admurin.itch.io/)\n- 3D \"Magic Button\" design by [Josh W. Comeau](https://www.joshwcomeau.com/animation/3d-button/)\n\n### Code Inspiration\n\n- Snake game implementation inspired by [Menard Maranan's tutorial](https://dev.to/menard_codes/i-built-a-snake-game-in-react-48b6)\n\n### Audio\n\n- Sound effects from [Freesound.org](https://freesound.org) (Creative Commons)\n- Audio playback powered by [use-sound](https://www.npmjs.com/package/use-sound)\n\nSee more detailed acknowledgments on the **About** page.\n\n## Links\n\n- **Repository**: [GitHub Repository](https://github.com/totokartonio/next-arcade)\n\n---\n\n## Dev Notes\n\nThis project was a small playground to experiment with different ideas — primarily **Next.js** and **SSR**. I also wanted to practice **Zustand**, so the global **mute** is powered by it (arguably overkill for a single toggle, but that was the point of the exercise). In general, I consider sound an essential part of arcade games, so adding SFX felt important.\n\nThings I’d still like to add:\n\n- Theme switching (light/dark)\n- Scorekeeping in each game\n- Local leaderboards\n\nMaybe I’ll circle back and ship these later. I really enjoyed creating this project and hope at least someone on the web has fun messing with it 😅\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftotokartonio%2Fnext-arcade","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftotokartonio%2Fnext-arcade","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftotokartonio%2Fnext-arcade/lists"}