Skip to content

Repository files navigation

Tecta — Planning Poker, But Fun

🚧 Work in Progress — Active development, things are moving fast.

Tecta is not another Planning Poker tool. It's a video game.

Turn story point estimation into a real-time, arcade-style multiplayer card game with CRT scanlines, card flips, screen shake, confetti, and synthwave sound effects. No login, no accounts, no backend — just share a link and play.


What Makes Tecta Different?

Not your average Planning Poker. Here's what sets it apart:

  • It's a video game, not a spreadsheet — CRT scanline overlay, 3D card flip animations, screen shake on reveal, confetti explosions on consensus, synthwave SFX, ambient music. Every interaction feels like something.
  • Zero infrastructure, peer-to-peer — No servers, no databases, no accounts. Uses WebRTC mesh networking via Yjs. Share a link, that's it. $0 to run.
  • Cryptographically secret voting — SHA-256 commit-reveal scheme prevents the last voter from anchoring to the group. No one sees your vote until everyone has locked in.
  • Bring your own soundtrack — Drop an .mp3/.ogg/.wav into public/music/ and it loops during gameplay. Falls back to a generative synth drone if no file is found.

Quick Start

Play with your team (no setup)

  1. Host opens the app and shares the room URL
  2. Team opens the link — no login, no accounts, no install
  3. Start estimating — import tickets, vote, reveal, discuss

Or run locally

bash setup.sh
# or manually:
npm install
npm run dev

Open the URL printed in your terminal and share your room link. Works the same way — just on your machine.


How to Play

The Flow

You and your team enter a room. One ticket at a time, you estimate story points — but it feels like a game show.

  1. Lobby — Join a room via link. See who's here. Ready up when your team's complete. The room code is in the URL — bookmark it, share it, done.
  2. Vote — The current ticket appears. Everyone secretly picks an estimate (0, ½, 1, 2, 3, 5, 8, 13, 21, ?, ☕). Your vote is SHA-256 hashed before it leaves your browser — nobody sees it until the reveal.
  3. Reveal — Everyone has voted. Cards flip simultaneously with a 3D animation. The table sees all estimates at once. No anchoring, no bias.
  4. Discuss — Votes diverged? Outliers explain their reasoning. The screen shakes on big swings. Synth effects punctuate the moment.
  5. Results — Consensus reached? Confetti fires. Move to the next ticket or export the session.

The Magic

Every vote is commit-reveal: submit a hash first, reveal the plaintext after everyone commits. Cryptographically impossible to cheat. Browser-native SubtleCrypto — no external dependencies.


Features

Multiplayer Magic

  • Share a link, that's it — Zero-friction join. No login, no accounts, no signup flow.
  • Real-time P2P — WebRTC mesh via Yjs. Every player connected directly. No backend, no server costs, no data leaves your mesh.
  • Room-based sessions — Unique room ID in the URL. Share it, bookmark it, done.

Arcade Juice

  • CRT scanline overlay — That retro monitor feel, baked into the UI
  • 3D card flips — Framer-motion animated reveal with perspective transforms
  • Screen shake — CSS animation on vote reveal and high-impact moments
  • Confetti explosions — Canvas-confetti fires on consensus
  • Synthwave SFX — Web Audio API generated sound effects for every action
  • Ambient music — Generative synth drone or custom file-based soundtrack

Power Features

  • CSV/JSON import — Drag-and-drop ticket loading via PapaParse
  • Jira/Linear export — Download formatted CSV of final estimates
  • Secret voting — SHA-256 commit-reveal prevents anchoring bias
  • Custom deck presets — Choose your estimation scale
  • Voting timer — Set a countdown for each round
  • Custom music — Drop theme.mp3/.ogg/.wav in public/music/ to set your own soundtrack

Tech Stack

Layer Technology
Framework React 18 + TypeScript
Build Vite 5
Styling Tailwind CSS 3
Real-time sync Yjs + y-webrtc
Animations framer-motion 11
Drag & drop @dnd-kit
Audio Web Audio API (synth SFX + ambient music)
Voting SHA-256 commit-reveal (SubtleCrypto)
CSV parsing PapaParse
File export file-saver
Confetti canvas-confetti

Project Structure

tecta/
├── public/
│   ├── favicon.svg          # App icon (spade in gold)
│   └── music/               # Drop custom theme audio here
├── src/
│   ├── App.tsx              # Main app — orchestration, state, routing
│   ├── main.tsx             # React entry point
│   ├── index.css            # Tailwind + custom animations
│   ├── lib/
│   │   ├── cards.ts         # Card values, colors, glow styles
│   │   ├── crdt-schema.ts   # Yjs shared types (Phase, Player, Ticket, VoteEntry)
│   │   └── room.ts          # Room ID generation & URL helpers
│   ├── hooks/
│   │   ├── useYjsDoc.ts     # Yjs + WebRTC connection
│   │   ├── useGameState.ts  # Game state from Yjs doc
│   │   ├── useCurrentUser.ts# Persistent player ID (localStorage)
│   │   ├── useCommitReveal.ts   # SHA-256 voting scheme
│   │   ├── useAmbientMusic.ts   # Background music (file or synth)
│   │   ├── useSynthAudio.ts     # Sound effects
│   │   ├── useScreenShake.ts    # Screen shake animation
│   │   └── useTimer.ts          # Countdown timer
│   └── components/
│       ├── AnimatedBackground.tsx    # Canvas radial gradients
│       ├── CRTEffect.tsx             # Scanline overlay
│       ├── ErrorBoundary.tsx         # Error catch + reload
│       ├── ExportView.tsx            # Jira/Linear CSV export
│       ├── GameView.tsx              # Vote → Reveal → Discuss → Results
│       ├── ImportView.tsx            # CSV/JSON drag-and-drop import
│       ├── Lobby.tsx                 # Pre-game lobby
│       ├── PlayingCard.tsx           # 3D flip card (framer-motion)
│       ├── SettingsPanel.tsx         # Timer, deck, sound controls
│       ├── TicketList.tsx            # Sortable ticket list (dnd-kit)
│       ├── TicketView.tsx            # Single ticket display
│       └── VoteDistribution.tsx      # Vote bar chart
├── index.html               # HTML shell
├── package.json
├── tsconfig.json
├── vite.config.ts
├── tailwind.config.js
└── postcss.config.js

Scripts

Command Description
npm run dev Start dev server (hot reload)
npm run build Typecheck + production build
npm run preview Preview production build locally
npm run lint ESLint check (ts, tsx)
npm run typecheck TypeScript type check only

Custom Music

Place a file in public/music/ named theme.mp3, theme.ogg, or theme.wav. The app loads it via Web Audio API and loops it during voting/reveal/discussion phases. Falls back to a synth drone if no file is found. Respects the volume slider and mute toggle in Settings.

See public/music/README.md for details.

About

Arcade-style Planning Poker game. No login, no backend, just share a link and play. P2P multiplayer, secret voting, smooth animations, sounds, ticket import/export. Built with React, TypeScript, WebRTC & Yjs.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages