{UNO} Project Report
1. The Concept
Build a playable UNO experience that feels like a smartphone card game, not a website dashboard.
Core idea:
- Classic UNO rules vs AI opponents (1–3 bots)
- Easy / Medium / Hard difficulty so casual and skilled players both get a fight
- Portrait 9:16 stage so mobile and desktop share the same phone frame
- Felt-table look, official-style cards, clear turn feedback
- Fast loops: play, draw, stack, special cards, UNO call, win/lose celebration
Player goal in 3 seconds:
- See the top discard color/number
- Spot a playable card in hand
- Tap to play (or draw)
Risk / reward:
- Forget to call UNO → +2 penalty
- Stack draw cards when possible
- Wild / Wild +4 for control at the cost of revealing strategy
- Pick a harder level for smarter bots and faster turns
2. The Stack
- HTML5 + CSS3 + vanilla JavaScript (one file: index.html)
- No frameworks, no build step, no backend
- Google Fonts: Bangers + Nunito
- Layout: CSS Grid / Flexbox, 9:16 centered stage, container queries
- Audio: Web Audio API (procedural SFX — no .mp3 assets)
- Prefs: localStorage for mute + difficulty
- Run: open locally (e.g. Live Server / static file)
3. The 1 Day Sprint (+ polish pass)
Morning (Hours 1–3):
- Scaffolded title + game screens on a felt green table
- Implemented deck, shuffle, deal, discard, AI turns
- Built number / action / Wild / +4 card faces
- Wired PLAY, opponent count chips, basic turn flow
Afternoon (Hours 4–6):
- Locked UI to a 9:16 stage (mobile + desktop, visualViewport safe)
- Polished win/lose modal (badge, confetti, stacked actions)
- Replaced browser confirm() with a custom Pause menu
- Added procedural game sounds (deal, play, draw, specials, win/lose)
The Finish Line (Hour 7-8):
- Fixed large-hand layout (containment + fan tighten + scale-to-fit)
- Cleaned playable-card highlights (glow instead of broken outlines)
- Restored mute control with speaker icons; mute state remembered
- Moved in-game sound control into the action bar (no overlap on opponents)
Polish (Aug 10):
- Title screen Level picker: EASY · MEDIUM · HARD
- Bot AI scales by level (random → solid → aggressive / denial play)
- Sound button sizing and spacing tuned for the phone frame
4. The Roadblocks
- Large hand overflow
- Fixed negative margins + flex min-width:auto expanded the stage
- Cards and UNO/MENU clipped off the right edge
- Fix: min-width:0 containment, dynamic overlap, hand-track scale()
- Native browser dialogs
- MENU used confirm("Leave the match?") — looked broken in-game
- Fix: custom Pause overlay (RESUME / LEAVE)
- Sound without asset pipeline
- No .mp3/.wav in the repo
- Fix: Web Audio oscillators + noise bursts for impact SFX
- Playable outline stacking
- CSS outline looked fragmented under heavy card overlap
- Fix: yellow box-shadow glow + higher z-index on playable cards
- Mute control vs layout
- Corner sound button overlapped opponent names in multi-bot matches
- Fix: keep title mute top-right; dock game mute beside MENU
5. Key Takeaways
- A single HTML file can ship a full casual card game if rules and UX stay tight
- Mobile-first 9:16 framing keeps desktop from becoming a stretched “web page”
- Layout bugs in card hands are usually containment + measurement, not “more CSS”
- Difficulty is a cheap depth lever — same rules, different bot judgment
- Impact sounds matter more than background music for short match loops
- Controls must live where thumbs already are; floating chrome fights the table
- Custom in-game modals beat browser alerts for immersion
- Ship the feel (fan, scale, SFX, win pop) before over-engineering systems
My final thought:
UNO works when every tap is obvious and every response is instant. This sprint proved we can deliver that feeling with plain HTML/CSS/JS — as long as we protect the portrait frame, keep the hand readable under pressure, let players choose how hard the bots fight, and polish the moments they remember: the slap of a card, the UNO call, and the win screen.