Skip to content

kayasax/Awale

Repository files navigation

🎮 Awale: Experimental TypeScript "Vibe Coding" Journey

Build Pages Deploy Release Version License

▶ Live Experience: https://kayasax.github.io/Awale/

🚀 Microsoft Hackathon 2025 - An experimental journey into modern web development using AI-assisted "vibe coding" techniques. What happens when someone with zero TypeScript knowledge attempts to build a complete multiplayer game experience? This project is the answer!

🎯 Hackathon Context & Philosophy

The Challenge: Build a sophisticated web application using technologies I've never touched before The Method: AI-assisted "vibe coding" - learning through doing, guided by AI pair programming The Goal: Push the boundaries of what's possible with modern development tools and AI assistance

🧪 What is "Vibe Coding"?

  • Learning by Building: No tutorials, no courses - just dive in and solve real problems
  • AI as Co-Pilot: Leverage GitHub Copilot and AI assistants for real-time guidance
  • Iterative Discovery: Let the project evolve organically based on what works
  • Modern Toolchain: Embrace the latest in TypeScript, React, WebSockets, Azure, and PWA technologies

Result: A fully functional online multiplayer Awale (African Mancala) game with lobby system, real-time gameplay, PWA capabilities, and Azure deployment - all built by someone who didn't know TypeScript existed 1 week ago! 🤯

✨ What We Built (Against All Odds)

🎮 Game Features

  • Authentic Awale Rules: Traditional African Mancala with proper capture logic and starvation prevention
  • Stunning Visuals: Animated seed sowing, capture sparkles, delta badges, and thematic backgrounds
  • Smart AI: Greedy strategy opponent for offline play
  • Dual Themes: Dark modern and warm wood aesthetics
  • Accessibility: Screen reader friendly, keyboard navigation, aria-live updates

🌐 Online Multiplayer (The Plot Twist!)

  • Real-time WebSocket Gameplay: Authoritative server with move validation
  • Lobby System: See online players, send/receive game invitations
  • Live Chat: Community interaction in the lobby
  • Player Presence: Track who's available, in-game, or away
  • Game Spectating: View ongoing games and player activity

💻 Technical Achievements

  • Progressive Web App: Offline play, installable, service worker caching
  • Monorepo Architecture: Clean separation of engine, web client, and server
  • Azure Container Apps: Scalable cloud deployment with WebSocket support
  • Modern Build Pipeline: Vite dev server, esbuild production, automated CI/CD
  • Type Safety: Full TypeScript throughout (learned on the job!)

🗂 Architecture (Vibe-Driven Design)

🏗 Monorepo Structure (packages/)
├── core/      # Pure game engine + AI (The Brain)
├── shared/    # Common types & protocols (The Contract)
├── web/       # React PWA frontend (The Face)
├── server/    # Node.js WebSocket server (The Conductor)
└── bot/       # Legacy Teams bot (The Ghost of Plans Past)

🎭 The Evolution Story

  1. Original Vision: Microsoft Teams bot (blocked by enterprise restrictions)
  2. Pivot 1: Simple web game (too boring!)
  3. Pivot 2: PWA with offline play (getting warmer...)
  4. Final Form: Full multiplayer with lobby, chat, and Azure deployment (JACKPOT! 🎰)

🚀 Getting Started (For Fellow Adventurers)

Prerequisites

# Just Node.js - we'll figure out the rest together!
node --version  # v18+ recommended
npm --version   # Comes with Node

Quick Launch

# Clone the experimental madness
git clone https://github.com/kayasax/Awale.git
cd Awale

# Install dependencies (trust the process)
npm install

# Launch development (prepare for magic)
npm run dev -w @awale/web

# Open http://localhost:5173 and witness the chaos!

Production Build (Deploy Your Creation)

# Build optimized bundle
npm run build -w @awale/web

# Preview locally
npm run preview -w @awale/web

# Deploy to your favorite static host!

🌐 Online Multiplayer Setup (Advanced Wizardry)

Want to run your own multiplayer server? Here's the Azure magic:

Server Deployment (Azure Container Apps)

# Create resource group
az group create -n awale-rg -l francecentral

# Build and deploy server
docker build -t awale-server -f packages/server/Dockerfile .
# ... (full deployment guide in original docs)

Local Development Server

# Start local multiplayer server
npm run dev -w @awale/server

# Frontend connects to localhost:8080
npm run dev -w @awale/web

🧠 Lessons Learned (Vibe Coding Insights)

💡 What Worked

  • AI Pair Programming: GitHub Copilot was genuinely helpful for TypeScript syntax and patterns
  • Iterative Development: Small, testable changes made complex features achievable
  • Modern Tooling: Vite, esbuild, and TypeScript created a surprisingly smooth developer experience
  • Real-time Debugging: Console logging and browser dev tools were game-changers

🤔 Surprising Challenges

  • WebSocket State Management: Harder than expected to keep client/server in sync
  • CSS Z-index Wars: Who knew pseudo-elements could be so troublesome?
  • TypeScript Interfaces: Still learning when to use type vs interface vs class
  • Azure Deployment: Container Apps are powerful but the CLI dance is complex

🎯 Key Discoveries

  • Monorepo Benefits: Shared types between frontend/backend prevented so many bugs
  • Service Workers: PWA capabilities added with surprisingly little code
  • React Hooks: useEffect cleanup patterns are crucial for WebSocket connections
  • Git Workflow: Feature branches and semantic commits actually help!

🔮 Future Experiments

🎮 Game Enhancements

  • Stronger AI with minimax algorithm
  • Tournament mode with brackets
  • Replay system with move history
  • Custom game variants and rules

🌐 Multiplayer Evolution

  • Spectator mode for live games
  • Player rankings and statistics
  • Private rooms and friend systems
  • Mobile app using Capacitor or React Native

🛠 Technical Deep Dives

  • Real-time testing with Playwright
  • Performance monitoring with Application Insights
  • Kubernetes deployment for scale
  • GraphQL API for richer data queries

� Acknowledgements & Credits

Microsoft Hackathon 2025 - For creating the perfect excuse to experiment with cutting-edge tech

AI Assistants - GitHub Copilot, Claude, and GPT for being patient teachers and debugging partners

Open Source Community - Every Stack Overflow answer, GitHub issue, and documentation page that saved the day

The Awale Game - Ancient African wisdom meets modern web technology

📊 Project Stats (Because Numbers are Fun)

  • Lines of Code: ~15,000+ (mostly TypeScript!)
  • Development Time: 3 days!
  • AI Assistance: ~80% of code had some AI input (vibe coding!)
  • Bug Count: Lost count after 200 (learning experience!)
  • Coffee Consumed: Immeasurable ☕
  • Fun Had: Absolutely priceless 🎉

🎭 The Honest Truth

This project started as "let me try TypeScript" and somehow became a full-featured multiplayer game platform. The code probably violates several best practices, the architecture evolved organically (some might say chaotically), and I'm still not 100% sure how some parts work.

But it works! Players can join from around the world, chat in the lobby, start games, and have a genuinely fun experience. Sometimes the best way to learn is to just start building and figure it out as you go.

That's the magic of vibe coding. 🪄


📄 License

MIT License - Feel free to learn from this experimental journey!

🐛 Issues & Contributions

Found a bug? Have a suggestion? Want to see how NOT to write TypeScript?

Open an issue or submit a PR - all feedback welcome from fellow experimenters and experienced developers alike!



📚 Technical Documentation

🧪 Testing & Development

Running Tests

# Run all tests
npm test

# Test specific package
npm test -w @awale/core

Build System Details

  • Dev: Vite handles module graph & fast HMR
  • Prod: Custom build-esbuild.cjs bundles optimized app.js
  • CI/CD: GitHub Actions for build, release, and Pages deployment
🌐 Full Azure Deployment Guide

Complete Server Setup on Azure Container Apps

1. Resource Group

az group create -n awale-rg -l francecentral

2. Azure Container Registry (ACR)

ACR_NAME=awaleacr$RANDOM
az acr create -n $ACR_NAME -g awale-rg --sku Basic --admin-enabled true
az acr login -n $ACR_NAME

3. Build & Push Image

IMG_TAG=v0.1.0
docker build -t $ACR_NAME.azurecr.io/awale-server:$IMG_TAG -f packages/server/Dockerfile .
docker push $ACR_NAME.azurecr.io/awale-server:$IMG_TAG

4. Deploy Container App

az extension add --name containerapp --upgrade
az provider register --namespace Microsoft.App --wait
az containerapp env create -n awale-env -g awale-rg -l francecentral

FRONT_ORIGIN=https://kayasax.github.io
az containerapp create \
  -n awale-server \
  -g awale-rg \
  --environment awale-env \
  --image $ACR_NAME.azurecr.io/awale-server:$IMG_TAG \
  --target-port 8080 \
  --ingress external \
  --transport auto \
  --registry-server $ACR_NAME.azurecr.io \
  --env-vars ALLOWED_ORIGIN=$FRONT_ORIGIN RATE_LIMIT_BURST=20 RATE_LIMIT_REFILL_MS=1000 \
  --query properties.configuration.ingress.fqdn -o tsv

5. Verify & Configure

FQDN=$(az containerapp show -n awale-server -g awale-rg --query properties.configuration.ingress.fqdn -o tsv)
curl https://$FQDN/health

# Configure frontend
VITE_AWALE_SERVER_WS=wss://$FQDN/ws npm run build -w @awale/web

Troubleshooting

Issue Solution
WebSocket connection fails Check ALLOWED_ORIGIN matches exactly
No game creation Verify VITE_AWALE_SERVER_WS environment variable
Rate limiting Adjust RATE_LIMIT_BURST setting
🎮 Game Engine & Protocol

Engine Architecture

  • 12-pit array: Positions 0-5 (player), 6-11 (AI/opponent)
  • Capture logic: Final seed in opponent row with 2-3 seeds
  • Starvation prevention: Must leave opponent with moves when possible

WebSocket Protocol (Client ↔ Server)

// Client → Server
{ type: "create", name: "Alice" }
{ type: "join", gameId: "abc123", name: "Bob" }
{ type: "move", gameId: "abc123", pit: 4 }

// Server → Client
{ type: "created", gameId: "abc123", playerToken: "..." }
{ type: "joined", gameId: "abc123", role: "guest", opponent: "Alice" }
{ type: "state", gameId: "abc123", version: 7, state: {...} }
{ type: "moveApplied", gameId: "abc123", captured: 3 }

Lobby System Features

  • Real-time presence: Track online/offline/in-game status
  • Game invitations: Send/accept/decline game invites
  • Chat system: Community interaction in lobby
  • Player visibility: See all online players including those in games
{ "type": "error", "code": "ILLEGAL", "message": "Illegal move" } ```

Environment Variables (Server)

Variable Purpose Default
PORT Listen port 8080
ALLOWED_ORIGIN Restrict WebSocket Origin (optional) (unset = allow)
RATE_LIMIT_BURST Max immediate messages per connection 20
RATE_LIMIT_REFILL_MS Token refill interval (ms) 1000
STALE_DISCONNECT_MS Purge game after both players disconnected for this long 300000 (5m)
MAX_GAME_AGE_MS Hard cap to remove very old games 3600000 (1h)

Local Run (Multiplayer Server)

npm run build -w @awale/core
npm run build -w @awale/shared
npm run build -w @awale/server
node packages/server/dist/index.js
curl http://localhost:8080/health

Docker

docker build -t awale-server:dev packages/server
docker run -p 8080:8080 awale-server:dev

Planned Frontend Additions

  • Mode selector (Play vs AI / Play Online)
  • Create flow (display game code + share button)
  • Join flow (enter code → live board sync)
  • Reconnect handling (token reuse – future)

Azure Deployment (Planned Outline)

  1. Build & push image to ACR or Docker Hub.
  2. Deploy Azure Container App with ingress (external) on wss path /ws.
  3. Configure env vars for origin + limits.
  4. Point frontend to server WebSocket URL (e.g. wss://<yourapp>.azurecontainerapps.io/ws).
  5. Future: add persistence (Redis or Table Storage) for reconnection & stats.

Status

Backend core logic merged in feature branch. Frontend integration & documentation polishing in progress. Track tasks in repo TODO / issues.

🟦 Azure Deployment (Container Apps – France Central)

The bot-era Azure Function is NOT used for realtime multiplayer. Deploy the new WebSocket server as a container.

Choose Region

Using francecentral for all resources (low latency from EU). Adjust names to be globally unique.

1. Resource Group

az group create -n awale-rg -l francecentral

2. Azure Container Registry (ACR)

ACR_NAME=awaleacr$RANDOM   # choose a unique name if needed
az acr create -n $ACR_NAME -g awale-rg --sku Basic --admin-enabled true
az acr login -n $ACR_NAME

3. Build & Push Image

From repo root (Dockerfile in packages/server):

IMG_TAG=v0.1.0
docker build -t $ACR_NAME.azurecr.io/awale-server:$IMG_TAG -f packages/server/Dockerfile .
docker push $ACR_NAME.azurecr.io/awale-server:$IMG_TAG

4. Create Container Apps Environment

az extension add --name containerapp --upgrade
az provider register --namespace Microsoft.App --wait
az containerapp env create -n awale-env -g awale-rg -l francecentral

5. Deploy Container App

FRONT_ORIGIN=https://kayasax.github.io
az containerapp create \
  -n awale-server \
  -g awale-rg \
  --environment awale-env \
  --image $ACR_NAME.azurecr.io/awale-server:$IMG_TAG \
  --target-port 8080 \
  --ingress external \
  --transport auto \
  --registry-server $ACR_NAME.azurecr.io \
  --env-vars ALLOWED_ORIGIN=$FRONT_ORIGIN RATE_LIMIT_BURST=20 RATE_LIMIT_REFILL_MS=1000 \
  --query properties.configuration.ingress.fqdn -o tsv

Note the FQDN returned (e.g. awale-server.<hash>.francecentral.azurecontainerapps.io).

6. Verify Health

FQDN=$(az containerapp show -n awale-server -g awale-rg --query properties.configuration.ingress.fqdn -o tsv)
curl https://$FQDN/health

Expect {"status":"ok","games":0}.

7. Frontend Configuration

Set WebSocket env variable for dev/prod builds:

VITE_AWALE_SERVER_WS=wss://$FQDN/ws

For GitHub Pages you can inject it at build time:

VITE_AWALE_SERVER_WS=wss://$FQDN/ws npm run build -w @awale/web

Then deploy (existing Pages workflow will publish dist).

8. Test

Open two browser windows of the GitHub Pages site:

  1. Create Online Game → copy code
  2. Join Online Game → paste code Moves should sync and captures broadcast.

9. Updating the Server

NEW_TAG=v0.1.1
docker build -t $ACR_NAME.azurecr.io/awale-server:$NEW_TAG -f packages/server/Dockerfile .
docker push $ACR_NAME.azurecr.io/awale-server:$NEW_TAG
az containerapp update -n awale-server -g awale-rg --image $ACR_NAME.azurecr.io/awale-server:$NEW_TAG

Clients reconnect automatically (basic reconnect backoff already implemented).

10. Optional Scaling / Hardening

  • Add min / max replicas:
    az containerapp scale update -n awale-server -g awale-rg --min-replicas 0 --max-replicas 3
  • Add a simple concurrent connection rule (future): KEDA websocket scaling or HTTP RPS rule once metrics needed.
  • Consider instrumentation (App Insights / OpenTelemetry) later.

11. Cleanup

az group delete -n awale-rg --no-wait -y

Troubleshooting

Symptom Check
WebSocket fails immediately ALLOWED_ORIGIN matches exact scheme + origin? Ingress FQDN correct?
No created message Wrong VITE_AWALE_SERVER_WS or network blocked; verify /health works first
Rate limit errors Lower burst or too many rapid clicks; adjust RATE_LIMIT_BURST
Stale games accumulate Tune STALE_DISCONNECT_MS / MAX_GAME_AGE_MS

This section finalizes the previously "Planned Outline" into actionable Azure CLI steps.

About

An Awale board game created for Microsoft Hackathon 2025, play against AI or online with other players

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors